@@ -228,6 +228,12 @@ volatile bool JvmtiVTMSTransitionDisabler::_SR_mode = false;
228228// Notifications from VirtualThread about VTMS events are enabled.
229229bool JvmtiVTMSTransitionDisabler::_VTMS_notify_jvmti_events = false ;
230230
231+ // The JvmtiVTMSTransitionDisabler sync protocol is enabled if this count > 0.
232+ volatile int JvmtiVTMSTransitionDisabler::_sync_protocol_enabled_count = 0 ;
233+
234+ // JvmtiVTMSTraansitionDisabler sync protocol is enabled permanently after seeing a suspender.
235+ volatile bool JvmtiVTMSTransitionDisabler::_sync_protocol_enabled_permanently = false ;
236+
231237#ifdef ASSERT
232238void
233239JvmtiVTMSTransitionDisabler::print_info () {
@@ -255,6 +261,9 @@ JvmtiVTMSTransitionDisabler::JvmtiVTMSTransitionDisabler(jthread thread)
255261 if (Thread::current_or_null () == nullptr ) {
256262 return ; // Detached thread, can be a call from Agent_OnLoad.
257263 }
264+ if (!sync_protocol_enabled_permanently ()) {
265+ JvmtiVTMSTransitionDisabler::inc_sync_protocol_enabled_count ();
266+ }
258267 if (_thread != nullptr ) {
259268 VTMS_transition_disable_for_one (); // disable VTMS transitions for one virtual thread
260269 } else {
@@ -272,6 +281,12 @@ JvmtiVTMSTransitionDisabler::JvmtiVTMSTransitionDisabler(bool is_SR)
272281 if (Thread::current_or_null () == nullptr ) {
273282 return ; // Detached thread, can be a call from Agent_OnLoad.
274283 }
284+ if (!sync_protocol_enabled_permanently ()) {
285+ JvmtiVTMSTransitionDisabler::inc_sync_protocol_enabled_count ();
286+ if (is_SR) {
287+ Atomic::store (&_sync_protocol_enabled_permanently, true );
288+ }
289+ }
275290 VTMS_transition_disable_for_all ();
276291}
277292
@@ -287,6 +302,9 @@ JvmtiVTMSTransitionDisabler::~JvmtiVTMSTransitionDisabler() {
287302 } else {
288303 VTMS_transition_enable_for_all (); // enable VTMS transitions for all virtual threads
289304 }
305+ if (!sync_protocol_enabled_permanently ()) {
306+ JvmtiVTMSTransitionDisabler::dec_sync_protocol_enabled_count ();
307+ }
290308}
291309
292310// disable VTMS transitions for one virtual thread
@@ -404,14 +422,21 @@ JvmtiVTMSTransitionDisabler::VTMS_transition_enable_for_all() {
404422void
405423JvmtiVTMSTransitionDisabler::start_VTMS_transition (jthread vthread, bool is_mount) {
406424 JavaThread* thread = JavaThread::current ();
407- HandleMark hm (thread);
408- Handle vth = Handle (thread, JNIHandles::resolve_external_guard (vthread));
409- int attempts = 50000 ;
425+ oop vt = JNIHandles::resolve_external_guard (vthread);
426+ assert (!thread->is_in_VTMS_transition (), " VTMS_transition sanity check" );
410427
411428 // Avoid using MonitorLocker on performance critical path, use
412429 // two-level synchronization with lock-free operations on counters.
413430 Atomic::inc (&_VTMS_transition_count); // Try to enter VTMS transition section optmistically.
414- java_lang_Thread::set_is_in_VTMS_transition (vth (), true );
431+ java_lang_Thread::set_is_in_VTMS_transition (vt, true );
432+
433+ if (!sync_protocol_enabled ()) {
434+ thread->set_is_in_VTMS_transition (true );
435+ return ;
436+ }
437+ HandleMark hm (thread);
438+ Handle vth = Handle (thread, vt);
439+ int attempts = 50000 ;
415440
416441 // Do not allow suspends inside VTMS transitions.
417442 // Block while transitions are disabled or there are suspend requests.
@@ -458,7 +483,6 @@ JvmtiVTMSTransitionDisabler::start_VTMS_transition(jthread vthread, bool is_moun
458483 }
459484#endif
460485 // Enter VTMS transition section.
461- assert (!thread->is_in_VTMS_transition (), " VTMS_transition sanity check" );
462486 thread->set_is_in_VTMS_transition (true );
463487}
464488
@@ -469,11 +493,14 @@ JvmtiVTMSTransitionDisabler::finish_VTMS_transition(jthread vthread, bool is_mou
469493 assert (thread->is_in_VTMS_transition (), " sanity check" );
470494 thread->set_is_in_VTMS_transition (false );
471495 oop vt = JNIHandles::resolve_external_guard (vthread);
472- int64_t thread_id = java_lang_Thread::thread_id (vt);
473496 java_lang_Thread::set_is_in_VTMS_transition (vt, false );
474-
475497 Atomic::dec (&_VTMS_transition_count);
476498
499+ if (!sync_protocol_enabled ()) {
500+ return ;
501+ }
502+ int64_t thread_id = java_lang_Thread::thread_id (vt);
503+
477504 // Unblock waiting VTMS transition disablers.
478505 if (_VTMS_transition_disable_for_one_count > 0 ||
479506 _VTMS_transition_disable_for_all_count > 0 ) {
0 commit comments