8292917: [JVMCI] Extend InstalledCode API to make an nmethod non entrant.
Reviewed-by: never
This commit is contained in:
parent
1500d3dfb2
commit
b0e0b87891
src
hotspot/share/jvmci
jdk.internal.vm.ci/share/classes
jdk.vm.ci.code/src/jdk/vm/ci/code
jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot
test/hotspot/jtreg/compiler/jvmci/common/patches/jdk.internal.vm.ci/jdk/vm/ci/hotspot
@ -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");
|
||||
}
|
||||
@ -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))
|
||||
@ -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)},
|
||||
|
@ -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);
|
||||
}
|
||||
@ -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.
|
||||
|
@ -412,9 +412,11 @@ public:
|
||||
// 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);
|
||||
|
||||
|
@ -29,12 +29,13 @@ package jdk.vm.ci.code;
|
||||
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;
|
||||
|
||||
@ -50,7 +51,8 @@ public class InstalledCode {
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
@ -94,8 +96,7 @@ public class InstalledCode {
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
@ -109,11 +110,27 @@ public class InstalledCode {
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates this installed code such that any subsequent
|
||||
* {@linkplain #executeVarargs(Object...) invocation} will throw an
|
||||
* {@link InvalidInstalledCodeException} and all existing invocations will be deoptimized.
|
||||
* 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}.
|
||||
*
|
||||
* 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(boolean deoptimize) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
@ -715,12 +715,12 @@ final class CompilerToVM {
|
||||
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.
|
||||
|
@ -157,7 +157,8 @@ public class HotSpotCodeCacheProvider implements CodeCacheProvider {
|
||||
@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());
|
||||
}
|
||||
|
@ -123,8 +123,8 @@ public class HotSpotNmethod extends HotSpotInstalledCode {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate() {
|
||||
compilerToVM().invalidateHotSpotNmethod(this);
|
||||
public void invalidate(boolean deoptimize) {
|
||||
compilerToVM().invalidateHotSpotNmethod(this, deoptimize);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -244,7 +244,7 @@ public class CompilerToVMHelper {
|
||||
}
|
||||
|
||||
public static void invalidateHotSpotNmethod(HotSpotNmethod nmethodMirror) {
|
||||
CTVM.invalidateHotSpotNmethod(nmethodMirror);
|
||||
CTVM.invalidateHotSpotNmethod(nmethodMirror, true);
|
||||
}
|
||||
|
||||
public static long[] collectCounters() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user