On Fri, 22 May 2026 07:22:45 GMT, Serguei Spitsyn <[email protected]> wrote:

>> Great. FTR the extra overhead I noticed was only when requesting 
>> capabilities that included one of the `interp_events` events. I thought I 
>> had also seen it even with other non-interpreter events but that is not the 
>> case. I also double checked now and see that even with `interp_events` 
>> capabilities enabled there are no extra calls to the VM.
>> 
>> I’m thinking if the case where we enable method_exit event globally works 
>> correct for virtual threads that are unmounted. Isn’t it the case that 
>> unmounted vthreads might not have a `JvmtiThreadState` yet? In that case, 
>> once the vthread is mounted again we won’t post this event until the 
>> `JvmtiThreadState` is created. I know we have lazy creation of the state, 
>> but where would that happen in that case? I see we have a call to create the 
>> state in `JVMTIEndTransition` but only for the `_is_thread_start` case. This 
>> question also applies to the previous code where we were only checking for 
>> `_interp_only_mode`, since that would be set in 
>> `JvmtiThreadState::process_pending_interp_only` during mount, but only if 
>> there is already a `JvmtiThreadState`. No need to fix it here if this is a 
>> preexisting issue, but was wondering about this case.
>
> Thank you for the concern. But as I see the `JvmtiThreadState`  for unmounted 
> virtual threads will be lazily created in the `post_method_exit()`:
> 
> 
> void JvmtiExport::post_method_exit(JavaThread* thread, Method* method, frame 
> current_frame) {
>   . . .
>   JRT_BLOCK
>     bool interp_only = thread->is_interp_only_mode();
>     // Avoid calls to get_jvmti_thread_state if is_interp_only_mode was not 
> enabled.
>     state = interp_only ? get_jvmti_thread_state(thread) : 
> thread->jvmti_thread_state();   <== !!!
> 
> The `get_jvmti_thread_state()` is called if `interp_only` is set. The 
> `interp_only` has to be set if `MethodExit` events are enabled globally. 
> Please, let me know if I miss anything here.

The problem is that `InterpreterRuntime::post_method_exit` is only called if 
the `JvmtiThreadState` is not null already. Also, even previously where we only 
checked `_interp_only_mode` in `InterpreterMacroAssembler::notify_method_exit` 
we had this same issue. That field is set at mount point for the unmounted 
vthread case, but only if there is a `JvmtiThreadState` already created 
(https://github.com/openjdk/jdk/blob/3a9cb9a7c271d58a960e940cb4051217337d86a9/src/hotspot/share/prims/jvmtiThreadState.inline.hpp#L152).
 I see we are missing a test case for this.
A fix could be to check `seen_interp_only_mode()` at mount time and create the 
state if not present. We do that in `~JVMTIEndTransition()` but only for the 
thread start case. Since this issue is preexisting we could address it in a 
separate bug though with an additional reproducer test.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/28407#discussion_r3289843902

Reply via email to