diff --git a/src/hotspot/share/c1/c1_Runtime1.cpp b/src/hotspot/share/c1/c1_Runtime1.cpp index e2760689daa07..57d22a3832496 100644 --- a/src/hotspot/share/c1/c1_Runtime1.cpp +++ b/src/hotspot/share/c1/c1_Runtime1.cpp @@ -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) { @@ -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()); @@ -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); } } @@ -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(); diff --git a/src/hotspot/share/ci/ciReplay.cpp b/src/hotspot/share/ci/ciReplay.cpp index f9829e88c4ac5..72ec2866c6e18 100644 --- a/src/hotspot/share/ci/ciReplay.cpp +++ b/src/hotspot/share/ci/ciReplay.cpp @@ -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, diff --git a/src/hotspot/share/code/codeCache.cpp b/src/hotspot/share/code/codeCache.cpp index 3a5da1d7cd2ae..f193627d78e39 100644 --- a/src/hotspot/share/code/codeCache.cpp +++ b/src/hotspot/share/code/codeCache.cpp @@ -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(); } } diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index acebaae6ba4f8..8e1f93e72884f 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -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(); @@ -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) { @@ -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; @@ -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(); @@ -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 @@ -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 diff --git a/src/hotspot/share/code/nmethod.hpp b/src/hotspot/share/code/nmethod.hpp index 7453bdfa0efd6..55e63c33e1ab2 100644 --- a/src/hotspot/share/code/nmethod.hpp +++ b/src/hotspot/share/code/nmethod.hpp @@ -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"); @@ -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; } @@ -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; diff --git a/src/hotspot/share/compiler/compilationPolicy.cpp b/src/hotspot/share/compiler/compilationPolicy.cpp index bab437eaade14..9aea022e83dfb 100644 --- a/src/hotspot/share/compiler/compilationPolicy.cpp +++ b/src/hotspot/share/compiler/compilationPolicy.cpp @@ -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); } @@ -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 diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index 001a40f74bcea..22ced5a441155 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -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"); } @@ -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(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(); @@ -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(); @@ -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(nmethod::InvalidationReason::C1_CODEPATCH); + int last = static_cast(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(invalidation_reason), JVMCI_CHECK); C2V_END C2V_VMENTRY_NULL(jlongArray, collectCounters, (JNIEnv* env, jobject)) @@ -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...) @@ -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)}, @@ -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)}, diff --git a/src/hotspot/share/jvmci/jvmciEnv.cpp b/src/hotspot/share/jvmci/jvmciEnv.cpp index 8c9facf848929..fd2b1dbd6b6f5 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.cpp +++ b/src/hotspot/share/jvmci/jvmciEnv.cpp @@ -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); } @@ -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 @@ -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(); diff --git a/src/hotspot/share/jvmci/jvmciEnv.hpp b/src/hotspot/share/jvmci/jvmciEnv.hpp index b7b7c8f677174..b49bba88b6b1d 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.hpp +++ b/src/hotspot/share/jvmci/jvmciEnv.hpp @@ -462,7 +462,7 @@ class JVMCIEnv : public ResourceObj { // 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, nmethod::ChangeReason change_reason, JVMCI_TRAPS); + void invalidate_nmethod_mirror(JVMCIObject mirror, bool deoptimze, nmethod::InvalidationReason invalidation_reason, JVMCI_TRAPS); void initialize_installed_code(JVMCIObject installed_code, CodeBlob* cb, JVMCI_TRAPS); diff --git a/src/hotspot/share/jvmci/jvmciJavaClasses.hpp b/src/hotspot/share/jvmci/jvmciJavaClasses.hpp index d5fcd2aaaba30..432fefe56d17a 100644 --- a/src/hotspot/share/jvmci/jvmciJavaClasses.hpp +++ b/src/hotspot/share/jvmci/jvmciJavaClasses.hpp @@ -102,6 +102,7 @@ boolean_field(HotSpotNmethod, isDefault) \ long_field(HotSpotNmethod, compileIdSnapshot) \ object_field(HotSpotNmethod, method, "Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;") \ + int_field(HotSpotNmethod, invalidationReason) \ jvmci_constructor(HotSpotNmethod, "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;Ljava/lang/String;ZJ)V") \ end_class \ start_class(HotSpotCompiledCode, jdk_vm_ci_hotspot_HotSpotCompiledCode) \ diff --git a/src/hotspot/share/jvmci/jvmciRuntime.cpp b/src/hotspot/share/jvmci/jvmciRuntime.cpp index 1f10e132eff1e..24ea4936822ce 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.cpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp @@ -797,7 +797,7 @@ void JVMCINMethodData::set_nmethod_mirror(nmethod* nm, oop new_mirror) { Universe::heap()->register_nmethod(nm); } -void JVMCINMethodData::invalidate_nmethod_mirror(nmethod* nm) { +void JVMCINMethodData::invalidate_nmethod_mirror(nmethod* nm, nmethod::InvalidationReason invalidation_reason) { oop nmethod_mirror = get_nmethod_mirror(nm); if (nmethod_mirror == nullptr) { return; @@ -816,12 +816,20 @@ void JVMCINMethodData::invalidate_nmethod_mirror(nmethod* nm) { HotSpotJVMCI::InstalledCode::set_address(jvmciEnv, nmethod_mirror, 0); HotSpotJVMCI::InstalledCode::set_entryPoint(jvmciEnv, nmethod_mirror, 0); HotSpotJVMCI::HotSpotInstalledCode::set_codeStart(jvmciEnv, nmethod_mirror, 0); + if (HotSpotJVMCI::HotSpotNmethod::invalidationReason(jvmciEnv, nmethod_mirror) == + static_cast(nmethod::InvalidationReason::NOT_INVALIDATED)) { + HotSpotJVMCI::HotSpotNmethod::set_invalidationReason(jvmciEnv, nmethod_mirror, static_cast(invalidation_reason)); + } } else if (nm->is_not_entrant()) { // Zero the entry point so any new invocation will fail but keep // the address link around that so that existing activations can // be deoptimized via the mirror (i.e. JVMCIEnv::invalidate_installed_code). HotSpotJVMCI::InstalledCode::set_entryPoint(jvmciEnv, nmethod_mirror, 0); HotSpotJVMCI::HotSpotInstalledCode::set_codeStart(jvmciEnv, nmethod_mirror, 0); + if (HotSpotJVMCI::HotSpotNmethod::invalidationReason(jvmciEnv, nmethod_mirror) == + static_cast(nmethod::InvalidationReason::NOT_INVALIDATED)) { + HotSpotJVMCI::HotSpotNmethod::set_invalidationReason(jvmciEnv, nmethod_mirror, static_cast(invalidation_reason)); + } } } @@ -2184,7 +2192,7 @@ JVMCI::CodeInstallResult JVMCIRuntime::register_method(JVMCIEnv* JVMCIENV, tty->print_cr("Replacing method %s", method_name); } if (old != nullptr) { - old->make_not_entrant(nmethod::ChangeReason::JVMCI_register_method); + old->make_not_entrant(nmethod::InvalidationReason::JVMCI_REPLACED_WITH_NEW_CODE); } LogTarget(Info, nmethod, install) lt; diff --git a/src/hotspot/share/jvmci/jvmciRuntime.hpp b/src/hotspot/share/jvmci/jvmciRuntime.hpp index b49e09a1884d8..95c7d32f928d3 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.hpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.hpp @@ -121,7 +121,7 @@ class JVMCINMethodData : public ResourceObj { // Clears the HotSpotNmethod.address field in the mirror. If nm // is dead, the HotSpotNmethod.entryPoint field is also cleared. - void invalidate_nmethod_mirror(nmethod* nm); + void invalidate_nmethod_mirror(nmethod* nm, nmethod::InvalidationReason invalidation_reason); // Gets the mirror from nm's oops table. oop get_nmethod_mirror(nmethod* nm); diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp index e26c815946dab..bc930b1e1dc07 100644 --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp @@ -564,7 +564,30 @@ declare_constant_with_value("LockStack::_end_offset", LockStack::end_offset()) \ declare_constant_with_value("OMCache::oop_to_oop_difference", OMCache::oop_to_oop_difference()) \ declare_constant_with_value("OMCache::oop_to_monitor_difference", OMCache::oop_to_monitor_difference()) \ - \ + \ + declare_constant(nmethod::InvalidationReason::NOT_INVALIDATED) \ + declare_constant(nmethod::InvalidationReason::C1_CODEPATCH) \ + declare_constant(nmethod::InvalidationReason::C1_DEOPTIMIZE) \ + declare_constant(nmethod::InvalidationReason::C1_DEOPTIMIZE_FOR_PATCHING) \ + declare_constant(nmethod::InvalidationReason::C1_PREDICATE_FAILED_TRAP) \ + declare_constant(nmethod::InvalidationReason::CI_REPLAY) \ + declare_constant(nmethod::InvalidationReason::UNLOADING) \ + declare_constant(nmethod::InvalidationReason::UNLOADING_COLD) \ + declare_constant(nmethod::InvalidationReason::JVMCI_INVALIDATE) \ + declare_constant(nmethod::InvalidationReason::JVMCI_MATERIALIZE_VIRTUAL_OBJECT) \ + declare_constant(nmethod::InvalidationReason::JVMCI_REPLACED_WITH_NEW_CODE) \ + declare_constant(nmethod::InvalidationReason::JVMCI_REPROFILE) \ + declare_constant(nmethod::InvalidationReason::MARKED_FOR_DEOPTIMIZATION) \ + declare_constant(nmethod::InvalidationReason::MISSING_EXCEPTION_HANDLER) \ + declare_constant(nmethod::InvalidationReason::NOT_USED) \ + declare_constant(nmethod::InvalidationReason::OSR_INVALIDATION_BACK_BRANCH) \ + declare_constant(nmethod::InvalidationReason::OSR_INVALIDATION_FOR_COMPILING_WITH_C1) \ + declare_constant(nmethod::InvalidationReason::OSR_INVALIDATION_OF_LOWER_LEVEL) \ + declare_constant(nmethod::InvalidationReason::SET_NATIVE_FUNCTION) \ + declare_constant(nmethod::InvalidationReason::UNCOMMON_TRAP) \ + declare_constant(nmethod::InvalidationReason::WHITEBOX_DEOPTIMIZATION) \ + declare_constant(nmethod::InvalidationReason::ZOMBIE) \ + \ declare_constant(CodeInstaller::VERIFIED_ENTRY) \ declare_constant(CodeInstaller::UNVERIFIED_ENTRY) \ declare_constant(CodeInstaller::OSR_ENTRY) \ diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp index 32d7943e1e855..55e75a806427a 100644 --- a/src/hotspot/share/oops/instanceKlass.cpp +++ b/src/hotspot/share/oops/instanceKlass.cpp @@ -3492,7 +3492,7 @@ void InstanceKlass::add_osr_nmethod(nmethod* n) { for (int l = CompLevel_limited_profile; l < n->comp_level(); l++) { nmethod *inv = lookup_osr_nmethod(n->method(), n->osr_entry_bci(), l, true); if (inv != nullptr && inv->is_in_use()) { - inv->make_not_entrant(nmethod::ChangeReason::OSR_invalidation_of_lower_level); + inv->make_not_entrant(nmethod::InvalidationReason::OSR_INVALIDATION_OF_LOWER_LEVEL); } } } diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp index 1a36fce23aaa4..bb7a0576eecfd 100644 --- a/src/hotspot/share/oops/method.cpp +++ b/src/hotspot/share/oops/method.cpp @@ -1028,7 +1028,7 @@ void Method::set_native_function(address function, bool post_event_flag) { // If so, we have to make it not_entrant. nmethod* nm = code(); // Put it into local variable to guard against concurrent updates if (nm != nullptr) { - nm->make_not_entrant(nmethod::ChangeReason::set_native_function); + nm->make_not_entrant(nmethod::InvalidationReason::SET_NATIVE_FUNCTION); } } diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp index cf3b48c11b5ab..9114b54a6f73c 100644 --- a/src/hotspot/share/prims/whitebox.cpp +++ b/src/hotspot/share/prims/whitebox.cpp @@ -794,7 +794,7 @@ class VM_WhiteBoxDeoptimizeFrames : public VM_WhiteBoxOperation { if (_make_not_entrant) { nmethod* nm = CodeCache::find_nmethod(f->pc()); assert(nm != nullptr, "did not find nmethod"); - nm->make_not_entrant(nmethod::ChangeReason::whitebox_deoptimization); + nm->make_not_entrant(nmethod::InvalidationReason::WHITEBOX_DEOPTIMIZATION); } ++_result; } diff --git a/src/hotspot/share/runtime/deoptimization.cpp b/src/hotspot/share/runtime/deoptimization.cpp index a0d9dd00339fd..ae51ae5ba7e5b 100644 --- a/src/hotspot/share/runtime/deoptimization.cpp +++ b/src/hotspot/share/runtime/deoptimization.cpp @@ -1826,7 +1826,7 @@ void Deoptimization::deoptimize(JavaThread* thread, frame fr, DeoptReason reason #if INCLUDE_JVMCI address Deoptimization::deoptimize_for_missing_exception_handler(nmethod* nm) { // there is no exception handler for this pc => deoptimize - nm->make_not_entrant(nmethod::ChangeReason::missing_exception_handler); + nm->make_not_entrant(nmethod::InvalidationReason::MISSING_EXCEPTION_HANDLER); // Use Deoptimization::deoptimize for all of its side-effects: // gathering traps statistics, logging... @@ -2455,7 +2455,7 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* current, jint tr // Recompile if (make_not_entrant) { - if (!nm->make_not_entrant(nmethod::ChangeReason::uncommon_trap)) { + if (!nm->make_not_entrant(nmethod::InvalidationReason::UNCOMMON_TRAP)) { return; // the call did not change nmethod's state } diff --git a/src/hotspot/share/runtime/javaThread.cpp b/src/hotspot/share/runtime/javaThread.cpp index f3ad0e0a3258c..5c26bf84484b2 100644 --- a/src/hotspot/share/runtime/javaThread.cpp +++ b/src/hotspot/share/runtime/javaThread.cpp @@ -1337,7 +1337,7 @@ void JavaThread::make_zombies() { // it is a Java nmethod nmethod* nm = CodeCache::find_nmethod(fst.current()->pc()); assert(nm != nullptr, "did not find nmethod"); - nm->make_not_entrant(nmethod::ChangeReason::zombie); + nm->make_not_entrant(nmethod::InvalidationReason::ZOMBIE); } } } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java index 0cb56354498c9..b25f7a092560c 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java @@ -654,6 +654,8 @@ native int installCode0(long compiledCodeBuffer, long failedSpeculationsAddress, byte[] speculations); + native String getInvalidationReasonDescription(int invalidationReason); + /** * Gets flags specifying optional parts of code info. Only if a flag is set, will the * corresponding code info being included in the {@linkplain HotSpotCompiledCodeStream @@ -842,7 +844,7 @@ void reprofile(HotSpotResolvedJavaMethodImpl method) { * {@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, boolean deoptimize); + native void invalidateHotSpotNmethod(HotSpotNmethod nmethodMirror, boolean deoptimize, int invalidationReason); /** * Collects the current values of all JVMCI benchmark counters, summed up over all threads. diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java index a0130d1bda9e9..9545c9aa9ec2b 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java @@ -154,16 +154,20 @@ public InstalledCode installCode(ResolvedJavaMethod method, CompiledCode compile return logOrDump(resultInstalledCode, compiledCode); } - @Override - public void invalidateInstalledCode(InstalledCode installedCode) { + public void invalidateInstalledCode(InstalledCode installedCode, int invalidationReason) { if (installedCode instanceof HotSpotNmethod) { HotSpotNmethod nmethod = (HotSpotNmethod) installedCode; - nmethod.invalidate(true); + nmethod.invalidate(true, invalidationReason); } else { throw new IllegalArgumentException("Cannot invalidate a " + Objects.requireNonNull(installedCode).getClass().getName()); } } + @Override + public void invalidateInstalledCode(InstalledCode installedCode) { + invalidateInstalledCode(installedCode, jvmciInvalidationReason()); + } + @Override public TargetDescription getTarget() { return target; @@ -201,4 +205,8 @@ public int interpreterFrameSize(BytecodeFrame pos) { public void resetCompilationStatistics() { runtime.getCompilerToVM().resetCompilationStatistics(); } + + private static int jvmciInvalidationReason() { + return HotSpotJVMCIRuntime.runtime().config.getConstant("nmethod::InvalidationReason::JVMCI_INVALIDATE", Integer.class); + } } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotNmethod.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotNmethod.java index 9ed03f9749e3a..5c7089da6cb69 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotNmethod.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotNmethod.java @@ -27,6 +27,7 @@ import jdk.vm.ci.code.InstalledCode; import jdk.vm.ci.code.InvalidInstalledCodeException; +import jdk.vm.ci.common.JVMCIError; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.meta.ResolvedJavaMethod; @@ -76,12 +77,19 @@ boolean inOopsTable() { */ private final long compileIdSnapshot; + /** + * Identify the reason that caused this nmethod to be invalidated. + * A value of -1 means that the nmethod was not invalidated. + */ + private int invalidationReason; + HotSpotNmethod(HotSpotResolvedJavaMethodImpl method, String name, boolean isDefault, long compileId) { super(name); this.method = method; this.isDefault = isDefault; boolean inOopsTable = !IS_IN_NATIVE_IMAGE && !isDefault; this.compileIdSnapshot = inOopsTable ? 0L : compileId; + this.invalidationReason = -1; assert inOopsTable || compileId != 0L : this; } @@ -122,9 +130,19 @@ public ResolvedJavaMethod getMethod() { return method; } + /** + * Invalidate this nmethod using the reason specified in {@code invalidationReason} and + * optionally deoptimize the method if {@code deoptimize} is set. + * @param deoptimize whether or not to deoptimize the method. + * @param invalidationReason invalidation reason code. + */ + public void invalidate(boolean deoptimize, int invalidationReason) { + compilerToVM().invalidateHotSpotNmethod(this, deoptimize, invalidationReason); + } + @Override public void invalidate(boolean deoptimize) { - compilerToVM().invalidateHotSpotNmethod(this, deoptimize); + invalidate(deoptimize, jvmciInvalidationReason()); } @Override @@ -188,4 +206,22 @@ public Object executeVarargs(Object... args) throws InvalidInstalledCodeExceptio public long getStart() { return isValid() ? super.getStart() : 0; } + + /** + * @return an integer representing the reason why this nmethod was invalidated. + */ + public int getInvalidationReason() { + return invalidationReason; + } + + /** + * @return a String describing the reason why this nmethod was invalidated. + */ + public String getInvalidationReasonDescription() { + return compilerToVM().getInvalidationReasonDescription(this.getInvalidationReason()); + } + + private static int jvmciInvalidationReason() { + return HotSpotJVMCIRuntime.runtime().config.getConstant("nmethod::InvalidationReason::JVMCI_INVALIDATE", Integer.class); + } } diff --git a/test/hotspot/jtreg/compiler/jvmci/common/patches/jdk.internal.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java b/test/hotspot/jtreg/compiler/jvmci/common/patches/jdk.internal.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java index 4285000e27f3e..4c8e63d0a4226 100644 --- a/test/hotspot/jtreg/compiler/jvmci/common/patches/jdk.internal.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java +++ b/test/hotspot/jtreg/compiler/jvmci/common/patches/jdk.internal.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java @@ -229,8 +229,8 @@ public static void reprofile(HotSpotResolvedJavaMethod method) { CTVM.reprofile((HotSpotResolvedJavaMethodImpl)method); } - public static void invalidateHotSpotNmethod(HotSpotNmethod nmethodMirror, boolean deoptimize) { - CTVM.invalidateHotSpotNmethod(nmethodMirror, deoptimize); + public static void invalidateHotSpotNmethod(HotSpotNmethod nmethodMirror, boolean deoptimize, int invalidationReason) { + CTVM.invalidateHotSpotNmethod(nmethodMirror, deoptimize, invalidationReason); } public static long[] collectCounters() { diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/CodeInvalidationReasonTest.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/CodeInvalidationReasonTest.java new file mode 100644 index 0000000000000..624a2290509eb --- /dev/null +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/CodeInvalidationReasonTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @requires vm.jvmci + * @requires vm.simpleArch == "x64" | vm.simpleArch == "aarch64" | vm.simpleArch == "riscv64" + * @library /test/lib / + * @modules jdk.internal.vm.ci/jdk.vm.ci.hotspot + * jdk.internal.vm.ci/jdk.vm.ci.meta + * jdk.internal.vm.ci/jdk.vm.ci.code + * jdk.internal.vm.ci/jdk.vm.ci.code.site + * jdk.internal.vm.ci/jdk.vm.ci.runtime + * jdk.internal.vm.ci/jdk.vm.ci.aarch64 + * jdk.internal.vm.ci/jdk.vm.ci.amd64 + * jdk.internal.vm.ci/jdk.vm.ci.riscv64 + * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java TestHotSpotVMConfig.java amd64/AMD64TestAssembler.java aarch64/AArch64TestAssembler.java riscv64/RISCV64TestAssembler.java + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler jdk.vm.ci.code.test.CodeInvalidationReasonTest + */ + +package jdk.vm.ci.code.test; + +import jdk.test.lib.Asserts; +import jdk.vm.ci.code.Register; +import jdk.vm.ci.hotspot.HotSpotNmethod; + +import org.junit.Test; + +import java.lang.reflect.Method; + +/** + * Test if setting HotSpotNmethod invalidation reason around works. + */ +public class CodeInvalidationReasonTest extends CodeInstallationTest { + + public static int add(int a, int b) { + return a + b; + } + + private static void compileAdd(TestAssembler asm) { + Register arg0 = asm.emitIntArg0(); + Register arg1 = asm.emitIntArg1(); + Register ret = asm.emitIntAdd(arg0, arg1); + asm.emitIntRet(ret); + } + + @Test + public void test() { + Method method = getMethod("add", int.class, int.class); + + HotSpotNmethod nmethod = test(CodeInvalidationReasonTest::compileAdd, method, 5, 7); + Asserts.assertEquals(-1 /* since it was not invalidated yet. */, nmethod.getInvalidationReason()); + + nmethod.invalidate(true, config.NMETHOD_INVALIDATION_REASON_JVMCI_INVALIDATE); + Asserts.assertEquals(config.NMETHOD_INVALIDATION_REASON_JVMCI_INVALIDATE, nmethod.getInvalidationReason()); + } +} diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleCodeInstallationTest.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleCodeInstallationTest.java index c9c88024d99fd..4c76aea7a4095 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleCodeInstallationTest.java +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleCodeInstallationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,13 +71,13 @@ public void test() { Asserts.assertNotEquals(nmethod.getStart(), 0L); // Make nmethod non-entrant but still alive - nmethod.invalidate(false); + nmethod.invalidate(false, config.NMETHOD_INVALIDATION_REASON_JVMCI_INVALIDATE); Asserts.assertFalse(nmethod.isValid(), "code is valid, i = " + nmethod); Asserts.assertTrue(nmethod.isAlive(), "code is not alive, i = " + nmethod); Asserts.assertEquals(nmethod.getStart(), 0L); // Deoptimize the nmethod and cut the link to it from the HotSpotNmethod - nmethod.invalidate(true); + nmethod.invalidate(true, config.NMETHOD_INVALIDATION_REASON_JVMCI_INVALIDATE); Asserts.assertFalse(nmethod.isValid(), "code is valid, i = " + nmethod); Asserts.assertFalse(nmethod.isAlive(), "code is alive, i = " + nmethod); Asserts.assertEquals(nmethod.getStart(), 0L); diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/TestHotSpotVMConfig.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/TestHotSpotVMConfig.java index db30229d34f31..1e6c771b77b33 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/TestHotSpotVMConfig.java +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/TestHotSpotVMConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,6 +55,8 @@ public TestHotSpotVMConfig(HotSpotVMConfigStore config, Architecture arch) { public final int maxOopMapStackOffset = getFieldValue("CompilerToVM::Data::_max_oop_map_stack_offset", Integer.class, "int"); public final int heapWordSize = getConstant("HeapWordSize", Integer.class); + public final int NMETHOD_INVALIDATION_REASON_JVMCI_INVALIDATE = getConstant("nmethod::InvalidationReason::JVMCI_INVALIDATE", Integer.class); + public final boolean ropProtection; private Boolean initNmethodEntryBarrierConcurrentPatch(Architecture arch) {