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

Reply via email to