On Thu, 14 Aug 2025 09:15:03 GMT, Serguei Spitsyn <sspit...@openjdk.org> wrote:
>> src/hotspot/share/prims/jvmtiExport.cpp line 1838: >> >>> 1836: { >>> 1837: ThreadInVMfromJava tiv(thread); >>> 1838: state = get_jvmti_thread_state(thread); >> >> The issue I see is that `get_jvmti_thread_state()` can safepoint for virtual >> threads (and now also for platform threads because of >> `~ThreadInVMfromJava`), which brings us back to the bug 8255452 was trying >> to fix: if there is a return oop at the top of the stack, it could become >> invalid if a GC occurs. I think we will have to unconditionally save the >> return value in case it's an oop, before doing anything else. > > Thank you, Patricio! Good catch and suggestion. This can be kind of intrusive, something like below (without changes from Leonid): @@ -1830,6 +1830,16 @@ void JvmtiExport::post_method_entry(JavaThread *thread, Method* method, frame cu void JvmtiExport::post_method_exit(JavaThread* thread, Method* method, frame current_frame) { HandleMark hm(thread); methodHandle mh(thread, method); + Handle result; + jvalue value; + oop oop_result; + BasicType type = current_frame.interpreter_frame_result(&oop_result, &value); + + value.j = 0L; + if (is_reference_type(type)) { + result = Handle(thread, oop_result); + value.l = JNIHandles::make_local(thread, result()); + } JvmtiThreadState *state = get_jvmti_thread_state(thread); @@ -1841,21 +1851,15 @@ void JvmtiExport::post_method_exit(JavaThread* thread, Method* method, frame cur // return a flag when a method terminates by throwing an exception // i.e. if an exception is thrown and it's not caught by the current method bool exception_exit = state->is_exception_detected() && !state->is_exception_caught(); - Handle result; - jvalue value; - value.j = 0L; if (state->is_enabled(JVMTI_EVENT_METHOD_EXIT)) { // if the method hasn't been popped because of an exception then we populate // the return_value parameter for the callback. At this point we only have // the address of a "raw result" and we just call into the interpreter to // convert this into a jvalue. - if (!exception_exit) { - oop oop_result; - BasicType type = current_frame.interpreter_frame_result(&oop_result, &value); + if (exception_exit) { if (is_reference_type(type)) { - result = Handle(thread, oop_result); - value.l = JNIHandles::make_local(thread, result()); + value.j = 0L; } } } Not sure yet how to make it simpler. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/26713#discussion_r2276882958