On Thu, 16 Nov 2023 21:36:28 GMT, Chris Plummer <cjplum...@openjdk.org> wrote:

>> This is a fix of a performance/scalability related issue. The 
>> `JvmtiThreadState` objects for virtual thread filtered events enabled 
>> globally are created eagerly because it is needed when the 
>> `interp_only_mode` is enabled. Otherwise, some events which are generated in 
>> `interp_only_mode` from the debugging version of interpreter chunks can be 
>> missed.
>> However, it has to be okay to avoid eager creation of these object if no 
>> `interp_only_mode` has ever been requested.
>> It seems to be an extremely important optimization to create 
>> JvmtiThreadState objects lazily in such cases.
>> It is done by introducing the flag 
>> `JvmtiThreadState::_seen_interp_only_mode` which indicates when the 
>> `JvmtiThreadState` objects have to be created eagerly.
>> 
>> Additionally, the fix includes the following related changes:
>>  - Use condition double checking idiom for `MutexLocker 
>> mu(JvmtiThreadState_lock)` in the function 
>> `JvmtiVTMSTransitionDisabler::VTMS_mount_end` which is on a 
>> performance-critical path and looks like this:
>> 
>>   JvmtiThreadState* state = thread->jvmti_thread_state();
>>   if (state != nullptr && state->is_pending_interp_only_mode()) {
>>     MutexLocker mu(JvmtiThreadState_lock);
>>     state = thread->jvmti_thread_state();
>>     if (state != nullptr && state->is_pending_interp_only_mode()) {
>>       JvmtiEventController::enter_interp_only_mode();
>>     }
>>   }
>> 
>> 
>>  - Add extra check of `JvmtiExport::can_support_virtual_threads()` when 
>> virtual thread mount and unmount are posted.
>>  - Minor: Added a `ThreadsListHandle` to the 
>> `JvmtiEventControllerPrivate::enter_interp_only_mode`. It is needed because 
>> of the dynamic creation of compensating carrier threads which is racy for 
>> JVMTI `SetEventNotificationMode` implementation.
>> 
>> Performance mesurements:
>> - Without this fix the test provided by the bug submitter gives execution 
>> numbers:
>>   - no ClassLoad events enabled:     3251 ms
>>   - ClassLoad events are enabled: 40534 ms
>>   
>> - With the fix:
>>   - no ClassLoad events enabled:    3270 ms
>>   - ClassLoad events are enabled:   3385 ms
>>   
>> Testing:
>>  - Ran mach5 tiers 1-6, no regressions are noticed
>
> src/hotspot/share/prims/jvmtiEventController.cpp line 372:
> 
>> 370:     return;  // EnterInterpOnlyModeClosure will be executed right after 
>> mount.
>> 371:   }
>> 372:   ThreadsListHandle tlh(current);
> 
> Why was this added?

This is explained in the PR description.
Do you think, a just comment is needed or this has to be separated from this 
fix?

> src/hotspot/share/prims/jvmtiThreadState.cpp line 531:
> 
>> 529: 
>> 530:   // JvmtiThreadState objects for virtual thread filtered events 
>> enabled globally
>> 531:   // must be created eagerly if the interp_only_mode is enabled. 
>> Otherwise,
> 
> This sentence is hard to read. How about:
> 
> "If interp_only_mode is enabled then we must eagerly create JvmtiThreadState 
> objects for globally enabled virtual thread filtered events."

Okay, thanks. The suggestion is taken.

> src/hotspot/share/prims/jvmtiThreadState.cpp line 579:
> 
>> 577:     VTMS_mount_end(vthread);
>> 578:     if (JvmtiExport::can_support_virtual_threads() &&
>> 579:         JvmtiExport::should_post_vthread_mount()) {
> 
> It seems odd that "can_support" can be false when "should_post" is true. I 
> would think that "should_post" would always be false when "can_support" is 
> false, and therefore there would be no need to check "can_support".

Right, thanks. It is why this check was missed in the first place. Will undo 
this change.

> src/hotspot/share/prims/jvmtiThreadState.hpp line 234:
> 
>> 232:   inline void set_head_env_thread_state(JvmtiEnvThreadState* ets);
>> 233: 
>> 234:   static bool _seen_interp_only_mode; // needed for optimization
> 
> Say what the flag represents, not why we have it.

Thank you for looking at this PR!
Okay, thanks. Will do.

> src/hotspot/share/prims/jvmtiThreadState.hpp line 257:
> 
>> 255:   // JvmtiThreadState objects for virtual thread filtered events 
>> enabled globally
>> 256:   // must be created eagerly if the interp_only_mode is enabled. 
>> Otherwise,
>> 257:   // it is an important optimization to create JvmtiThreadState objects 
>> lazily.
> 
> No need for this comment here. It is already at the call site, which is where 
> it belongs. Instead the comment here should say what this API does (return 
> true if any thread has entered interp_only_mode at any point during the JVMs 
> execution).

Thanks, good suggestion.

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

PR Review Comment: https://git.openjdk.org/jdk/pull/16686#discussion_r1396725938
PR Review Comment: https://git.openjdk.org/jdk/pull/16686#discussion_r1396728778
PR Review Comment: https://git.openjdk.org/jdk/pull/16686#discussion_r1396728297
PR Review Comment: https://git.openjdk.org/jdk/pull/16686#discussion_r1396727211
PR Review Comment: https://git.openjdk.org/jdk/pull/16686#discussion_r1396729089

Reply via email to