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