Skip to content

Commit 41daa3b

Browse files
author
Serguei Spitsyn
committed
8320239: add dynamic switch for JvmtiVTMSTransitionDisabler sync protocol
Reviewed-by: lmesnik, pchilanomate, amenkov
1 parent 7c135c3 commit 41daa3b

File tree

2 files changed

+43
-7
lines changed

2 files changed

+43
-7
lines changed

src/hotspot/share/prims/jvmtiThreadState.cpp

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,12 @@ volatile bool JvmtiVTMSTransitionDisabler::_SR_mode = false;
228228
// Notifications from VirtualThread about VTMS events are enabled.
229229
bool 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
232238
void
233239
JvmtiVTMSTransitionDisabler::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() {
404422
void
405423
JvmtiVTMSTransitionDisabler::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) {

src/hotspot/share/prims/jvmtiThreadState.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ class JvmtiVTMSTransitionDisabler {
8383
static volatile int _VTMS_transition_disable_for_all_count; // transitions for all virtual threads are disabled while it is positive
8484
static volatile bool _SR_mode; // there is an active suspender or resumer
8585
static volatile int _VTMS_transition_count; // current number of VTMS transitions
86+
static volatile int _sync_protocol_enabled_count; // current number of JvmtiVTMSTransitionDisablers enabled sync protocol
87+
static volatile bool _sync_protocol_enabled_permanently; // seen a suspender: JvmtiVTMSTraansitionDisabler protocol is enabled permanently
8688

8789
bool _is_SR; // is suspender or resumer
8890
jthread _thread; // virtual thread to disable transitions for, no-op if it is a platform thread
@@ -100,6 +102,13 @@ class JvmtiVTMSTransitionDisabler {
100102

101103
static void set_VTMS_transition_count(bool val) { _VTMS_transition_count = val; }
102104

105+
static void inc_sync_protocol_enabled_count() { Atomic::inc(&_sync_protocol_enabled_count); }
106+
static void dec_sync_protocol_enabled_count() { Atomic::dec(&_sync_protocol_enabled_count); }
107+
static int sync_protocol_enabled_count() { return Atomic::load(&_sync_protocol_enabled_count); }
108+
static bool sync_protocol_enabled_permanently() { return Atomic::load(&_sync_protocol_enabled_permanently); }
109+
110+
static bool sync_protocol_enabled() { return sync_protocol_enabled_permanently() || sync_protocol_enabled_count() > 0; }
111+
103112
// parameter is_SR: suspender or resumer
104113
JvmtiVTMSTransitionDisabler(bool is_SR = false);
105114
JvmtiVTMSTransitionDisabler(jthread thread);

0 commit comments

Comments
 (0)