Skip to content

Commit

Permalink
8292917: [JVMCI] Extend InstalledCode API to make an nmethod non entr…
Browse files Browse the repository at this point in the history
…ant.

Reviewed-by: never
  • Loading branch information
Doug Simon committed Aug 27, 2022
1 parent 1500d3d commit b0e0b87
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 26 deletions.
8 changes: 4 additions & 4 deletions src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -975,7 +975,7 @@ C2V_VMENTRY_0(jint, installCode0, (JNIEnv *env, jobject,
assert(JVMCIENV->isa_HotSpotNmethod(installed_code_handle), "wrong type");
// Clear the link to an old nmethod first
JVMCIObject nmethod_mirror = installed_code_handle;
JVMCIENV->invalidate_nmethod_mirror(nmethod_mirror, JVMCI_CHECK_0);
JVMCIENV->invalidate_nmethod_mirror(nmethod_mirror, true, JVMCI_CHECK_0);
} else {
assert(JVMCIENV->isa_InstalledCode(installed_code_handle), "wrong type");
}
Expand Down Expand Up @@ -1145,9 +1145,9 @@ C2V_VMENTRY(void, reprofile, (JNIEnv* env, jobject, ARGUMENT_PAIR(method)))
C2V_END


C2V_VMENTRY(void, invalidateHotSpotNmethod, (JNIEnv* env, jobject, jobject hs_nmethod))
C2V_VMENTRY(void, invalidateHotSpotNmethod, (JNIEnv* env, jobject, jobject hs_nmethod, jboolean deoptimize))
JVMCIObject nmethod_mirror = JVMCIENV->wrap(hs_nmethod);
JVMCIENV->invalidate_nmethod_mirror(nmethod_mirror, JVMCI_CHECK);
JVMCIENV->invalidate_nmethod_mirror(nmethod_mirror, deoptimize, JVMCI_CHECK);
C2V_END

C2V_VMENTRY_NULL(jlongArray, collectCounters, (JNIEnv* env, jobject))
Expand Down Expand Up @@ -2862,7 +2862,7 @@ JNINativeMethod CompilerToVM::methods[] = {
{CC "getLocalVariableTableStart", CC "(" HS_METHOD2 ")J", FN_PTR(getLocalVariableTableStart)},
{CC "getLocalVariableTableLength", CC "(" HS_METHOD2 ")I", FN_PTR(getLocalVariableTableLength)},
{CC "reprofile", CC "(" HS_METHOD2 ")V", FN_PTR(reprofile)},
{CC "invalidateHotSpotNmethod", CC "(" HS_NMETHOD ")V", FN_PTR(invalidateHotSpotNmethod)},
{CC "invalidateHotSpotNmethod", CC "(" HS_NMETHOD "Z)V", FN_PTR(invalidateHotSpotNmethod)},
{CC "collectCounters", CC "()[J", FN_PTR(collectCounters)},
{CC "getCountersSize", CC "()I", FN_PTR(getCountersSize)},
{CC "setCountersSize", CC "(I)Z", FN_PTR(setCountersSize)},
Expand Down
11 changes: 8 additions & 3 deletions src/hotspot/share/jvmci/jvmciEnv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1510,7 +1510,7 @@ void JVMCIEnv::initialize_installed_code(JVMCIObject installed_code, CodeBlob* c
}


void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, JVMCI_TRAPS) {
void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, bool deoptimize, JVMCI_TRAPS) {
if (mirror.is_null()) {
JVMCI_THROW(NullPointerException);
}
Expand All @@ -1529,8 +1529,13 @@ void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, JVMCI_TRAPS) {
"Cannot invalidate HotSpotNmethod object in shared library VM heap from non-JavaThread");
}

// Invalidating the HotSpotNmethod means we want the nmethod to be deoptimized.
Deoptimization::deoptimize_all_marked(nm);
if (!deoptimize) {
// Prevent future executions of the nmethod but let current executions complete.
nm->make_not_entrant();
} else {
// We want the nmethod to be deoptimized immediately.
Deoptimization::deoptimize_all_marked(nm);
}

// A HotSpotNmethod instance can only reference a single nmethod
// during its lifetime so simply clear it here.
Expand Down
8 changes: 5 additions & 3 deletions src/hotspot/share/jvmci/jvmciEnv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -412,9 +412,11 @@ class JVMCIEnv : public ResourceObj {
// Destroys a JNI global handle created by JVMCIEnv::make_global.
void destroy_global(JVMCIObject object);

// Deoptimizes the nmethod (if any) in the HotSpotNmethod.address
// field of mirror. The field is subsequently zeroed.
void invalidate_nmethod_mirror(JVMCIObject mirror, JVMCI_TRAPS);
// Updates the nmethod (if any) in the HotSpotNmethod.address
// field of `mirror` to prevent it from being called.
// If `deoptimize` is true, the nmethod is immediately deoptimized.
// The HotSpotNmethod.address field is zero upon returning.
void invalidate_nmethod_mirror(JVMCIObject mirror, bool deoptimze, JVMCI_TRAPS);

void initialize_installed_code(JVMCIObject installed_code, CodeBlob* cb, JVMCI_TRAPS);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@
public class InstalledCode {

/**
* Raw address address of entity representing this installed code.
* Address of the entity (e.g., HotSpot {@code nmethod} or {@code RuntimeStub}) representing
* this installed code.
*/
protected long address;

/**
* Raw address of entryPoint of this installed code.
* Address of the entryPoint of this installed code.
*/
protected long entryPoint;

Expand All @@ -50,7 +51,8 @@ public InstalledCode(String name) {
}

/**
* @return the address of entity representing this installed code.
* @return the address of entity (e.g., HotSpot {@code nmethod} or {@code RuntimeStub})
* representing this installed code
*/
public long getAddress() {
return address;
Expand Down Expand Up @@ -94,8 +96,7 @@ public boolean isValid() {
}

/**
* @return true if the code represented by this object still exists and might have live
* activations, false otherwise (may happen due to deopt, etc.)
* @return true if this object still points to installed code
*/
public boolean isAlive() {
return address != 0;
Expand All @@ -108,12 +109,28 @@ public byte[] getCode() {
return null;
}

/**
* Equivalent to calling {@link #invalidate(boolean)} with a {@code true} argument.
*/
public void invalidate() {
invalidate(true);
}

/**
* Invalidates this installed code such that any subsequent
* {@linkplain #executeVarargs(Object...) invocation} will throw an
* {@link InvalidInstalledCodeException} and all existing invocations will be deoptimized.
* {@link InvalidInstalledCodeException}.
*
* If this installed code is already {@linkplain #isValid() invalid}, this method has no effect.
* A subsequent call to {@link #isAlive()} or {@link #isValid()} on this object will return
* {@code false}.
*
* @param deoptimize if {@code true}, all existing invocations will be immediately deoptimized.
* If {@code false}, any existing invocation will continue until it completes or
* there is a subsequent call to this method with {@code deoptimize == true} before
* the invocation completes.
*/
public void invalidate() {
public void invalidate(boolean deoptimize) {
throw new UnsupportedOperationException();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -715,12 +715,12 @@ void reprofile(HotSpotResolvedJavaMethodImpl method) {
private native void reprofile(HotSpotResolvedJavaMethodImpl method, long methodPointer);

/**
* Invalidates {@code nmethodMirror} such that {@link InvalidInstalledCodeException} will be
* raised the next time {@code nmethodMirror} is {@linkplain #executeHotSpotNmethod executed}.
* The {@code nmethod} associated with {@code nmethodMirror} is also made non-entrant and any
* current activations of the {@code nmethod} are deoptimized.
* Updates {@code nmethodMirror} such that {@link InvalidInstalledCodeException} will be raised
* the next time {@code nmethodMirror} is {@linkplain #executeHotSpotNmethod executed}. The
* {@code nmethod} associated with {@code nmethodMirror} is also made non-entrant and if
* {@code deoptimize == true} any current activations of the {@code nmethod} are deoptimized.
*/
native void invalidateHotSpotNmethod(HotSpotNmethod nmethodMirror);
native void invalidateHotSpotNmethod(HotSpotNmethod nmethodMirror, boolean deoptimize);

/**
* Collects the current values of all JVMCI benchmark counters, summed up over all threads.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ public InstalledCode installCode(ResolvedJavaMethod method, CompiledCode compile
@Override
public void invalidateInstalledCode(InstalledCode installedCode) {
if (installedCode instanceof HotSpotNmethod) {
runtime.getCompilerToVM().invalidateHotSpotNmethod((HotSpotNmethod) installedCode);
HotSpotNmethod nmethod = (HotSpotNmethod) installedCode;
nmethod.invalidate(true);
} else {
throw new IllegalArgumentException("Cannot invalidate a " + Objects.requireNonNull(installedCode).getClass().getName());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ public ResolvedJavaMethod getMethod() {
}

@Override
public void invalidate() {
compilerToVM().invalidateHotSpotNmethod(this);
public void invalidate(boolean deoptimize) {
compilerToVM().invalidateHotSpotNmethod(this, deoptimize);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ public static void reprofile(HotSpotResolvedJavaMethod method) {
}

public static void invalidateHotSpotNmethod(HotSpotNmethod nmethodMirror) {
CTVM.invalidateHotSpotNmethod(nmethodMirror);
CTVM.invalidateHotSpotNmethod(nmethodMirror, true);
}

public static long[] collectCounters() {
Expand Down

1 comment on commit b0e0b87

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.