Skip to content
8 changes: 4 additions & 4 deletions src/hotspot/share/c1/c1_Runtime1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,7 @@ JRT_ENTRY(void, Runtime1::deoptimize(JavaThread* current, jint trap_request))
Deoptimization::DeoptReason reason = Deoptimization::trap_request_reason(trap_request);

if (action == Deoptimization::Action_make_not_entrant) {
if (nm->make_not_entrant(nmethod::ChangeReason::C1_deoptimize)) {
if (nm->make_not_entrant(nmethod::InvalidationReason::C1_DEOPTIMIZE)) {
if (reason == Deoptimization::Reason_tenured) {
MethodData* trap_mdo = Deoptimization::get_method_data(current, method, true /*create_if_missing*/);
if (trap_mdo != nullptr) {
Expand Down Expand Up @@ -1110,7 +1110,7 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* current, C1StubId stub_id ))
// safepoint, but if it's still alive then make it not_entrant.
nmethod* nm = CodeCache::find_nmethod(caller_frame.pc());
if (nm != nullptr) {
nm->make_not_entrant(nmethod::ChangeReason::C1_codepatch);
nm->make_not_entrant(nmethod::InvalidationReason::C1_CODEPATCH);
}

Deoptimization::deoptimize_frame(current, caller_frame.id());
Expand Down Expand Up @@ -1358,7 +1358,7 @@ void Runtime1::patch_code(JavaThread* current, C1StubId stub_id) {
// Make sure the nmethod is invalidated, i.e. made not entrant.
nmethod* nm = CodeCache::find_nmethod(caller_frame.pc());
if (nm != nullptr) {
nm->make_not_entrant(nmethod::ChangeReason::C1_deoptimize_for_patching);
nm->make_not_entrant(nmethod::InvalidationReason::C1_DEOPTIMIZE_FOR_PATCHING);
}
}

Expand Down Expand Up @@ -1486,7 +1486,7 @@ JRT_ENTRY(void, Runtime1::predicate_failed_trap(JavaThread* current))

nmethod* nm = CodeCache::find_nmethod(caller_frame.pc());
assert (nm != nullptr, "no more nmethod?");
nm->make_not_entrant(nmethod::ChangeReason::C1_predicate_failed_trap);
nm->make_not_entrant(nmethod::InvalidationReason::C1_PREDICATE_FAILED_TRAP);

methodHandle m(current, nm->method());
MethodData* mdo = m->method_data();
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/ci/ciReplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ class CompileReplay : public StackObj {
// Make sure the existence of a prior compile doesn't stop this one
nmethod* nm = (entry_bci != InvocationEntryBci) ? method->lookup_osr_nmethod_for(entry_bci, comp_level, true) : method->code();
if (nm != nullptr) {
nm->make_not_entrant(nmethod::ChangeReason::CI_replay);
nm->make_not_entrant(nmethod::InvalidationReason::CI_REPLAY);
}
replay_state = this;
CompileBroker::compile_method(methodHandle(THREAD, method), entry_bci, comp_level,
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/code/codeCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1361,7 +1361,7 @@ void CodeCache::make_marked_nmethods_deoptimized() {
while(iter.next()) {
nmethod* nm = iter.method();
if (nm->is_marked_for_deoptimization() && !nm->has_been_deoptimized() && nm->can_be_deoptimized()) {
nm->make_not_entrant(nmethod::ChangeReason::marked_for_deoptimization);
nm->make_not_entrant(nmethod::InvalidationReason::MARKED_FOR_DEOPTIMIZATION);
nm->make_deoptimized();
}
}
Expand Down
16 changes: 9 additions & 7 deletions src/hotspot/share/code/nmethod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1975,12 +1975,12 @@ void nmethod::invalidate_osr_method() {
}
}

void nmethod::log_state_change(ChangeReason change_reason) const {
void nmethod::log_state_change(InvalidationReason invalidation_reason) const {
if (LogCompilation) {
if (xtty != nullptr) {
ttyLocker ttyl; // keep the following output all in one block
xtty->begin_elem("make_not_entrant thread='%zu' reason='%s'",
os::current_thread_id(), change_reason_to_string(change_reason));
os::current_thread_id(), invalidation_reason_to_string(invalidation_reason));
log_identity(xtty);
xtty->stamp();
xtty->end_elem();
Expand All @@ -1989,7 +1989,7 @@ void nmethod::log_state_change(ChangeReason change_reason) const {

ResourceMark rm;
stringStream ss(NEW_RESOURCE_ARRAY(char, 256), 256);
ss.print("made not entrant: %s", change_reason_to_string(change_reason));
ss.print("made not entrant: %s", invalidation_reason_to_string(invalidation_reason));

CompileTask::print_ul(this, ss.freeze());
if (PrintCompilation) {
Expand All @@ -2004,7 +2004,7 @@ void nmethod::unlink_from_method() {
}

// Invalidate code
bool nmethod::make_not_entrant(ChangeReason change_reason) {
bool nmethod::make_not_entrant(InvalidationReason invalidation_reason) {
// This can be called while the system is already at a safepoint which is ok
NoSafepointVerifier nsv;

Expand Down Expand Up @@ -2073,7 +2073,7 @@ bool nmethod::make_not_entrant(ChangeReason change_reason) {
assert(success, "Transition can't fail");

// Log the transition once
log_state_change(change_reason);
log_state_change(invalidation_reason);

// Remove nmethod from method.
unlink_from_method();
Expand All @@ -2084,7 +2084,7 @@ bool nmethod::make_not_entrant(ChangeReason change_reason) {
// Invalidate can't occur while holding the NMethodState_lock
JVMCINMethodData* nmethod_data = jvmci_nmethod_data();
if (nmethod_data != nullptr) {
nmethod_data->invalidate_nmethod_mirror(this);
nmethod_data->invalidate_nmethod_mirror(this, invalidation_reason);
}
#endif

Expand Down Expand Up @@ -2122,7 +2122,9 @@ void nmethod::unlink() {
// Clear the link between this nmethod and a HotSpotNmethod mirror
JVMCINMethodData* nmethod_data = jvmci_nmethod_data();
if (nmethod_data != nullptr) {
nmethod_data->invalidate_nmethod_mirror(this);
nmethod_data->invalidate_nmethod_mirror(this, is_cold() ?
nmethod::InvalidationReason::UNLOADING_COLD :
nmethod::InvalidationReason::UNLOADING);
}
#endif

Expand Down
107 changes: 52 additions & 55 deletions src/hotspot/share/code/nmethod.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,77 +471,74 @@ class nmethod : public CodeBlob {
void oops_do_set_strong_done(nmethod* old_head);

public:
enum class ChangeReason : u1 {
C1_codepatch,
C1_deoptimize,
C1_deoptimize_for_patching,
C1_predicate_failed_trap,
CI_replay,
JVMCI_invalidate_nmethod,
JVMCI_invalidate_nmethod_mirror,
JVMCI_materialize_virtual_object,
JVMCI_new_installation,
JVMCI_register_method,
JVMCI_replacing_with_new_code,
JVMCI_reprofile,
marked_for_deoptimization,
missing_exception_handler,
not_used,
OSR_invalidation_back_branch,
OSR_invalidation_for_compiling_with_C1,
OSR_invalidation_of_lower_level,
set_native_function,
uncommon_trap,
whitebox_deoptimization,
zombie,
// If you change anything in this enum please patch
// vmStructs_jvmci.cpp accordingly.
enum class InvalidationReason : s1 {
NOT_INVALIDATED = -1,
C1_CODEPATCH,
C1_DEOPTIMIZE,
C1_DEOPTIMIZE_FOR_PATCHING,
C1_PREDICATE_FAILED_TRAP,
CI_REPLAY,
UNLOADING,
UNLOADING_COLD,
JVMCI_INVALIDATE,
JVMCI_MATERIALIZE_VIRTUAL_OBJECT,
JVMCI_REPLACED_WITH_NEW_CODE,
JVMCI_REPROFILE,
MARKED_FOR_DEOPTIMIZATION,
MISSING_EXCEPTION_HANDLER,
NOT_USED,
OSR_INVALIDATION_BACK_BRANCH,
OSR_INVALIDATION_FOR_COMPILING_WITH_C1,
OSR_INVALIDATION_OF_LOWER_LEVEL,
SET_NATIVE_FUNCTION,
UNCOMMON_TRAP,
WHITEBOX_DEOPTIMIZATION,
ZOMBIE,
INVALIDATION_REASONS_COUNT
};


static const char* change_reason_to_string(ChangeReason change_reason) {
switch (change_reason) {
case ChangeReason::C1_codepatch:
static const char* invalidation_reason_to_string(InvalidationReason invalidation_reason) {
switch (invalidation_reason) {
case InvalidationReason::C1_CODEPATCH:
return "C1 code patch";
case ChangeReason::C1_deoptimize:
case InvalidationReason::C1_DEOPTIMIZE:
return "C1 deoptimized";
case ChangeReason::C1_deoptimize_for_patching:
case InvalidationReason::C1_DEOPTIMIZE_FOR_PATCHING:
return "C1 deoptimize for patching";
case ChangeReason::C1_predicate_failed_trap:
case InvalidationReason::C1_PREDICATE_FAILED_TRAP:
return "C1 predicate failed trap";
case ChangeReason::CI_replay:
case InvalidationReason::CI_REPLAY:
return "CI replay";
case ChangeReason::JVMCI_invalidate_nmethod:
return "JVMCI invalidate nmethod";
case ChangeReason::JVMCI_invalidate_nmethod_mirror:
return "JVMCI invalidate nmethod mirror";
case ChangeReason::JVMCI_materialize_virtual_object:
case InvalidationReason::JVMCI_INVALIDATE:
return "JVMCI invalidate";
case InvalidationReason::JVMCI_MATERIALIZE_VIRTUAL_OBJECT:
return "JVMCI materialize virtual object";
case ChangeReason::JVMCI_new_installation:
return "JVMCI new installation";
case ChangeReason::JVMCI_register_method:
return "JVMCI register method";
case ChangeReason::JVMCI_replacing_with_new_code:
return "JVMCI replacing with new code";
case ChangeReason::JVMCI_reprofile:
case InvalidationReason::JVMCI_REPLACED_WITH_NEW_CODE:
return "JVMCI replaced with new code";
case InvalidationReason::JVMCI_REPROFILE:
return "JVMCI reprofile";
case ChangeReason::marked_for_deoptimization:
case InvalidationReason::MARKED_FOR_DEOPTIMIZATION:
return "marked for deoptimization";
case ChangeReason::missing_exception_handler:
case InvalidationReason::MISSING_EXCEPTION_HANDLER:
return "missing exception handler";
case ChangeReason::not_used:
case InvalidationReason::NOT_USED:
return "not used";
case ChangeReason::OSR_invalidation_back_branch:
case InvalidationReason::OSR_INVALIDATION_BACK_BRANCH:
return "OSR invalidation back branch";
case ChangeReason::OSR_invalidation_for_compiling_with_C1:
case InvalidationReason::OSR_INVALIDATION_FOR_COMPILING_WITH_C1:
return "OSR invalidation for compiling with C1";
case ChangeReason::OSR_invalidation_of_lower_level:
case InvalidationReason::OSR_INVALIDATION_OF_LOWER_LEVEL:
return "OSR invalidation of lower level";
case ChangeReason::set_native_function:
case InvalidationReason::SET_NATIVE_FUNCTION:
return "set native function";
case ChangeReason::uncommon_trap:
case InvalidationReason::UNCOMMON_TRAP:
return "uncommon trap";
case ChangeReason::whitebox_deoptimization:
case InvalidationReason::WHITEBOX_DEOPTIMIZATION:
return "whitebox deoptimization";
case ChangeReason::zombie:
case InvalidationReason::ZOMBIE:
return "zombie";
default: {
assert(false, "Unhandled reason");
Expand Down Expand Up @@ -712,8 +709,8 @@ class nmethod : public CodeBlob {
// alive. It is used when an uncommon trap happens. Returns true
// if this thread changed the state of the nmethod or false if
// another thread performed the transition.
bool make_not_entrant(ChangeReason change_reason);
bool make_not_used() { return make_not_entrant(ChangeReason::not_used); }
bool make_not_entrant(InvalidationReason invalidation_reason);
bool make_not_used() { return make_not_entrant(InvalidationReason::NOT_USED); }

bool is_marked_for_deoptimization() const { return deoptimization_status() != not_marked; }
bool has_been_deoptimized() const { return deoptimization_status() == deoptimize_done; }
Expand Down Expand Up @@ -1026,7 +1023,7 @@ class nmethod : public CodeBlob {
// Logging
void log_identity(xmlStream* log) const;
void log_new_nmethod() const;
void log_state_change(ChangeReason change_reason) const;
void log_state_change(InvalidationReason invalidation_reason) const;

// Prints block-level comments, including nmethod specific block labels:
void print_nmethod_labels(outputStream* stream, address block_begin, bool print_section_labels=true) const;
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/compiler/compilationPolicy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -924,7 +924,7 @@ void CompilationPolicy::compile(const methodHandle& mh, int bci, CompLevel level
nmethod* osr_nm = mh->lookup_osr_nmethod_for(bci, CompLevel_simple, false);
if (osr_nm != nullptr && osr_nm->comp_level() > CompLevel_simple) {
// Invalidate the existing OSR nmethod so that a compile at CompLevel_simple is permitted.
osr_nm->make_not_entrant(nmethod::ChangeReason::OSR_invalidation_for_compiling_with_C1);
osr_nm->make_not_entrant(nmethod::InvalidationReason::OSR_INVALIDATION_FOR_COMPILING_WITH_C1);
}
compile(mh, bci, CompLevel_simple, THREAD);
}
Expand Down Expand Up @@ -1516,7 +1516,7 @@ void CompilationPolicy::method_back_branch_event(const methodHandle& mh, const m
int osr_bci = nm->is_osr_method() ? nm->osr_entry_bci() : InvocationEntryBci;
print_event(MAKE_NOT_ENTRANT, mh(), mh(), osr_bci, level);
}
nm->make_not_entrant(nmethod::ChangeReason::OSR_invalidation_back_branch);
nm->make_not_entrant(nmethod::InvalidationReason::OSR_INVALIDATION_BACK_BRANCH);
}
}
// Fix up next_level if necessary to avoid deopts
Expand Down
26 changes: 20 additions & 6 deletions src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1207,7 +1207,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, true, nmethod::ChangeReason::JVMCI_replacing_with_new_code, JVMCI_CHECK_0);
JVMCIENV->invalidate_nmethod_mirror(nmethod_mirror, true, nmethod::InvalidationReason::JVMCI_REPLACED_WITH_NEW_CODE, JVMCI_CHECK_0);
} else {
assert(JVMCIENV->isa_InstalledCode(installed_code_handle), "wrong type");
}
Expand All @@ -1218,6 +1218,14 @@ C2V_VMENTRY_0(jint, installCode0, (JNIEnv *env, jobject,
return result;
C2V_END

C2V_VMENTRY_0(jobject, getInvalidationReasonDescription, (JNIEnv *env, jobject, jint invalidation_reason))
HandleMark hm(THREAD);
JNIHandleMark jni_hm(thread);
nmethod::InvalidationReason reason = static_cast<nmethod::InvalidationReason>(invalidation_reason);
JVMCIObject desc = JVMCIENV->create_string(nmethod::invalidation_reason_to_string(reason), JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(desc);
C2V_END

C2V_VMENTRY(void, resetCompilationStatistics, (JNIEnv* env, jobject))
JVMCICompiler* compiler = JVMCICompiler::instance(true, CHECK);
CompilerStatistics* stats = compiler->stats();
Expand Down Expand Up @@ -1383,7 +1391,7 @@ C2V_VMENTRY(void, reprofile, (JNIEnv* env, jobject, ARGUMENT_PAIR(method)))

nmethod* code = method->code();
if (code != nullptr) {
code->make_not_entrant(nmethod::ChangeReason::JVMCI_reprofile);
code->make_not_entrant(nmethod::InvalidationReason::JVMCI_REPROFILE);
}

MethodData* method_data = method->method_data();
Expand All @@ -1396,9 +1404,14 @@ C2V_VMENTRY(void, reprofile, (JNIEnv* env, jobject, ARGUMENT_PAIR(method)))
C2V_END


C2V_VMENTRY(void, invalidateHotSpotNmethod, (JNIEnv* env, jobject, jobject hs_nmethod, jboolean deoptimize))
C2V_VMENTRY(void, invalidateHotSpotNmethod, (JNIEnv* env, jobject, jobject hs_nmethod, jboolean deoptimize, jint invalidation_reason))
int first = static_cast<int>(nmethod::InvalidationReason::C1_CODEPATCH);
int last = static_cast<int>(nmethod::InvalidationReason::INVALIDATION_REASONS_COUNT);
if (invalidation_reason < first || invalidation_reason >= last) {
JVMCI_THROW_MSG(IllegalArgumentException, err_msg("Invalid invalidation_reason: %d", invalidation_reason));
}
JVMCIObject nmethod_mirror = JVMCIENV->wrap(hs_nmethod);
JVMCIENV->invalidate_nmethod_mirror(nmethod_mirror, deoptimize, nmethod::ChangeReason::JVMCI_invalidate_nmethod, JVMCI_CHECK);
JVMCIENV->invalidate_nmethod_mirror(nmethod_mirror, deoptimize, static_cast<nmethod::InvalidationReason>(invalidation_reason), JVMCI_CHECK);
C2V_END

C2V_VMENTRY_NULL(jlongArray, collectCounters, (JNIEnv* env, jobject))
Expand Down Expand Up @@ -1823,7 +1836,7 @@ C2V_VMENTRY(void, materializeVirtualObjects, (JNIEnv* env, jobject, jobject _hs_
if (!fst.current()->is_compiled_frame()) {
JVMCI_THROW_MSG(IllegalStateException, "compiled stack frame expected");
}
fst.current()->cb()->as_nmethod()->make_not_entrant(nmethod::ChangeReason::JVMCI_materialize_virtual_object);
fst.current()->cb()->as_nmethod()->make_not_entrant(nmethod::InvalidationReason::JVMCI_MATERIALIZE_VIRTUAL_OBJECT);
}
Deoptimization::deoptimize(thread, *fst.current(), Deoptimization::Reason_none);
// look for the frame again as it has been updated by deopt (pc, deopt state...)
Expand Down Expand Up @@ -3352,6 +3365,7 @@ JNINativeMethod CompilerToVM::methods[] = {
{CC "getResolvedJavaType0", CC "(Ljava/lang/Object;JZ)" HS_KLASS, FN_PTR(getResolvedJavaType0)},
{CC "readConfiguration", CC "()[" OBJECT, FN_PTR(readConfiguration)},
{CC "installCode0", CC "(JJZ" HS_COMPILED_CODE "[" OBJECT INSTALLED_CODE "J[B)I", FN_PTR(installCode0)},
{CC "getInvalidationReasonDescription", CC "(I)" STRING, FN_PTR(getInvalidationReasonDescription)},
{CC "getInstallCodeFlags", CC "()I", FN_PTR(getInstallCodeFlags)},
{CC "resetCompilationStatistics", CC "()V", FN_PTR(resetCompilationStatistics)},
{CC "disassembleCodeBlob", CC "(" INSTALLED_CODE ")" STRING, FN_PTR(disassembleCodeBlob)},
Expand All @@ -3360,7 +3374,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 "Z)V", FN_PTR(invalidateHotSpotNmethod)},
{CC "invalidateHotSpotNmethod", CC "(" HS_NMETHOD "ZI)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
6 changes: 3 additions & 3 deletions src/hotspot/share/jvmci/jvmciEnv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1750,7 +1750,7 @@ void JVMCIEnv::initialize_installed_code(JVMCIObject installed_code, CodeBlob* c
}


void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, bool deoptimize, nmethod::ChangeReason change_reason, JVMCI_TRAPS) {
void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, bool deoptimize, nmethod::InvalidationReason invalidation_reason, JVMCI_TRAPS) {
if (mirror.is_null()) {
JVMCI_THROW(NullPointerException);
}
Expand All @@ -1773,7 +1773,7 @@ void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, bool deoptimize, nm

if (!deoptimize) {
// Prevent future executions of the nmethod but let current executions complete.
nm->make_not_entrant(change_reason);
nm->make_not_entrant(invalidation_reason);

// Do not clear the address field here as the Java code may still
// want to later call this method with deoptimize == true. That requires
Expand All @@ -1782,7 +1782,7 @@ void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, bool deoptimize, nm
// Deoptimize the nmethod immediately.
DeoptimizationScope deopt_scope;
deopt_scope.mark(nm);
nm->make_not_entrant(change_reason);
nm->make_not_entrant(invalidation_reason);
nm->make_deoptimized();
deopt_scope.deoptimize_marked();

Expand Down
Loading