Skip to content

Commit 1ba77d9

Browse files
Man Caojianglizhou
Man Cao
authored andcommitted
8312174: missing JVMTI events from vthreads parked during JVMTI attach
Backport-of: fda142ff6cfefa12ec1ea4d4eb48b3c1b285bc04
1 parent 81eaed2 commit 1ba77d9

File tree

9 files changed

+404
-48
lines changed

9 files changed

+404
-48
lines changed

src/hotspot/share/prims/jvmtiEventController.cpp

+23-8
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,8 @@ class JvmtiEventControllerPrivate : public AllStatic {
309309
static void clear_to_frame_pop(JvmtiEnvThreadState *env_thread, JvmtiFramePop fpop);
310310
static void change_field_watch(jvmtiEvent event_type, bool added);
311311

312+
static bool is_any_thread_filtered_event_enabled_globally();
313+
static void recompute_thread_filtered(JvmtiThreadState *state);
312314
static void thread_started(JavaThread *thread);
313315
static void thread_ended(JavaThread *thread);
314316

@@ -729,6 +731,20 @@ JvmtiEventControllerPrivate::recompute_enabled() {
729731
EC_TRACE(("[-] # recompute enabled - after " JULONG_FORMAT_X, any_env_thread_enabled));
730732
}
731733

734+
bool
735+
JvmtiEventControllerPrivate::is_any_thread_filtered_event_enabled_globally() {
736+
julong global_thread_events = JvmtiEventController::_universal_global_event_enabled.get_bits() & THREAD_FILTERED_EVENT_BITS;
737+
return global_thread_events != 0L;
738+
}
739+
740+
void
741+
JvmtiEventControllerPrivate::recompute_thread_filtered(JvmtiThreadState *state) {
742+
assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check");
743+
744+
if (is_any_thread_filtered_event_enabled_globally()) {
745+
JvmtiEventControllerPrivate::recompute_thread_enabled(state);
746+
}
747+
}
732748

733749
void
734750
JvmtiEventControllerPrivate::thread_started(JavaThread *thread) {
@@ -738,17 +754,11 @@ JvmtiEventControllerPrivate::thread_started(JavaThread *thread) {
738754
EC_TRACE(("[%s] # thread started", JvmtiTrace::safe_get_thread_name(thread)));
739755

740756
// if we have any thread filtered events globally enabled, create/update the thread state
741-
if ((JvmtiEventController::_universal_global_event_enabled.get_bits() & THREAD_FILTERED_EVENT_BITS) != 0) {
742-
MutexLocker mu(JvmtiThreadState_lock);
743-
// create the thread state if missing
744-
JvmtiThreadState *state = JvmtiThreadState::state_for_while_locked(thread);
745-
if (state != nullptr) { // skip threads with no JVMTI thread state
746-
recompute_thread_enabled(state);
747-
}
757+
if (is_any_thread_filtered_event_enabled_globally()) { // intentionally racy
758+
JvmtiThreadState::state_for(thread);
748759
}
749760
}
750761

751-
752762
void
753763
JvmtiEventControllerPrivate::thread_ended(JavaThread *thread) {
754764
// Removes the JvmtiThreadState associated with the specified thread.
@@ -1114,6 +1124,11 @@ JvmtiEventController::change_field_watch(jvmtiEvent event_type, bool added) {
11141124
JvmtiEventControllerPrivate::change_field_watch(event_type, added);
11151125
}
11161126

1127+
void
1128+
JvmtiEventController::recompute_thread_filtered(JvmtiThreadState *state) {
1129+
JvmtiEventControllerPrivate::recompute_thread_filtered(state);
1130+
}
1131+
11171132
void
11181133
JvmtiEventController::thread_started(JavaThread *thread) {
11191134
// operates only on the current thread

src/hotspot/share/prims/jvmtiEventController.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ class JvmtiEventController : AllStatic {
234234

235235
static void change_field_watch(jvmtiEvent event_type, bool added);
236236

237+
static void recompute_thread_filtered(JvmtiThreadState *state);
237238
static void thread_started(JavaThread *thread);
238239
static void thread_ended(JavaThread *thread);
239240

src/hotspot/share/prims/jvmtiExport.cpp

+50-40
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,15 @@ JvmtiExport::get_jvmti_interface(JavaVM *jvm, void **penv, jint version) {
417417
}
418418
}
419419

420+
JvmtiThreadState*
421+
JvmtiExport::get_jvmti_thread_state(JavaThread *thread) {
422+
assert(thread == JavaThread::current(), "must be current thread");
423+
if (thread->is_vthread_mounted() && thread->jvmti_thread_state() == nullptr) {
424+
JvmtiEventController::thread_started(thread);
425+
}
426+
return thread->jvmti_thread_state();
427+
}
428+
420429
void
421430
JvmtiExport::add_default_read_edges(Handle h_module, TRAPS) {
422431
if (!Universe::is_module_initialized()) {
@@ -920,7 +929,7 @@ class JvmtiClassFileLoadHookPoster : public StackObj {
920929
_has_been_modified = false;
921930

922931
assert(!_thread->is_in_any_VTMS_transition(), "CFLH events are not allowed in any VTMS transition");
923-
_state = _thread->jvmti_thread_state();
932+
_state = JvmtiExport::get_jvmti_thread_state(_thread);
924933
if (_state != nullptr) {
925934
_class_being_redefined = _state->get_class_being_redefined();
926935
_load_kind = _state->get_class_load_kind();
@@ -1209,7 +1218,7 @@ void JvmtiExport::post_raw_breakpoint(JavaThread *thread, Method* method, addres
12091218
HandleMark hm(thread);
12101219
methodHandle mh(thread, method);
12111220

1212-
JvmtiThreadState *state = thread->jvmti_thread_state();
1221+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
12131222
if (state == nullptr) {
12141223
return;
12151224
}
@@ -1307,7 +1316,7 @@ void JvmtiExport::at_single_stepping_point(JavaThread *thread, Method* method, a
13071316
methodHandle mh(thread, method);
13081317

13091318
// update information about current location and post a step event
1310-
JvmtiThreadState *state = thread->jvmti_thread_state();
1319+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
13111320
if (state == nullptr) {
13121321
return;
13131322
}
@@ -1326,15 +1335,15 @@ void JvmtiExport::at_single_stepping_point(JavaThread *thread, Method* method, a
13261335

13271336

13281337
void JvmtiExport::expose_single_stepping(JavaThread *thread) {
1329-
JvmtiThreadState *state = thread->jvmti_thread_state();
1338+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
13301339
if (state != nullptr) {
13311340
state->clear_hide_single_stepping();
13321341
}
13331342
}
13341343

13351344

13361345
bool JvmtiExport::hide_single_stepping(JavaThread *thread) {
1337-
JvmtiThreadState *state = thread->jvmti_thread_state();
1346+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
13381347
if (state != nullptr && state->is_enabled(JVMTI_EVENT_SINGLE_STEP)) {
13391348
state->set_hide_single_stepping();
13401349
return true;
@@ -1349,7 +1358,7 @@ void JvmtiExport::post_class_load(JavaThread *thread, Klass* klass) {
13491358
}
13501359
HandleMark hm(thread);
13511360

1352-
JvmtiThreadState* state = thread->jvmti_thread_state();
1361+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
13531362
if (state == nullptr) {
13541363
return;
13551364
}
@@ -1387,7 +1396,7 @@ void JvmtiExport::post_class_prepare(JavaThread *thread, Klass* klass) {
13871396
}
13881397
HandleMark hm(thread);
13891398

1390-
JvmtiThreadState* state = thread->jvmti_thread_state();
1399+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
13911400
if (state == nullptr) {
13921401
return;
13931402
}
@@ -1516,7 +1525,7 @@ void JvmtiExport::post_thread_end(JavaThread *thread) {
15161525
EVT_TRIG_TRACE(JVMTI_EVENT_THREAD_END, ("[%s] Trg Thread End event triggered",
15171526
JvmtiTrace::safe_get_thread_name(thread)));
15181527

1519-
JvmtiThreadState *state = thread->jvmti_thread_state();
1528+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
15201529
if (state == nullptr) {
15211530
return;
15221531
}
@@ -1564,7 +1573,7 @@ void JvmtiExport::post_vthread_start(jobject vthread) {
15641573
EVT_TRIG_TRACE(JVMTI_EVENT_VIRTUAL_THREAD_START, ("[%p] Trg Virtual Thread Start event triggered", vthread));
15651574

15661575
JavaThread *cur_thread = JavaThread::current();
1567-
JvmtiThreadState *state = cur_thread->jvmti_thread_state();
1576+
JvmtiThreadState *state = get_jvmti_thread_state(cur_thread);
15681577
if (state == nullptr) {
15691578
return;
15701579
}
@@ -1598,7 +1607,7 @@ void JvmtiExport::post_vthread_end(jobject vthread) {
15981607
EVT_TRIG_TRACE(JVMTI_EVENT_VIRTUAL_THREAD_END, ("[%p] Trg Virtual Thread End event triggered", vthread));
15991608

16001609
JavaThread *cur_thread = JavaThread::current();
1601-
JvmtiThreadState *state = cur_thread->jvmti_thread_state();
1610+
JvmtiThreadState *state = get_jvmti_thread_state(cur_thread);
16021611
if (state == nullptr) {
16031612
return;
16041613
}
@@ -1633,7 +1642,7 @@ void JvmtiExport::post_vthread_mount(jobject vthread) {
16331642
HandleMark hm(thread);
16341643
EVT_TRIG_TRACE(EXT_EVENT_VIRTUAL_THREAD_MOUNT, ("[%p] Trg Virtual Thread Mount event triggered", vthread));
16351644

1636-
JvmtiThreadState *state = thread->jvmti_thread_state();
1645+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
16371646
if (state == nullptr) {
16381647
return;
16391648
}
@@ -1668,7 +1677,7 @@ void JvmtiExport::post_vthread_unmount(jobject vthread) {
16681677
HandleMark hm(thread);
16691678
EVT_TRIG_TRACE(EXT_EVENT_VIRTUAL_THREAD_UNMOUNT, ("[%p] Trg Virtual Thread Unmount event triggered", vthread));
16701679

1671-
JvmtiThreadState *state = thread->jvmti_thread_state();
1680+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
16721681
if (state == nullptr) {
16731682
return;
16741683
}
@@ -1701,7 +1710,7 @@ void JvmtiExport::continuation_yield_cleanup(JavaThread* thread, jint continuati
17011710
}
17021711

17031712
assert(thread == JavaThread::current(), "must be");
1704-
JvmtiThreadState *state = thread->jvmti_thread_state();
1713+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
17051714
if (state == nullptr) {
17061715
return;
17071716
}
@@ -1795,7 +1804,7 @@ void JvmtiExport::post_method_entry(JavaThread *thread, Method* method, frame cu
17951804
HandleMark hm(thread);
17961805
methodHandle mh(thread, method);
17971806

1798-
JvmtiThreadState* state = thread->jvmti_thread_state();
1807+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
17991808
if (state == nullptr || !state->is_interp_only_mode()) {
18001809
// for any thread that actually wants method entry, interp_only_mode is set
18011810
return;
@@ -1835,7 +1844,7 @@ void JvmtiExport::post_method_exit(JavaThread* thread, Method* method, frame cur
18351844
HandleMark hm(thread);
18361845
methodHandle mh(thread, method);
18371846

1838-
JvmtiThreadState *state = thread->jvmti_thread_state();
1847+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
18391848

18401849
if (state == nullptr || !state->is_interp_only_mode()) {
18411850
// for any thread that actually wants method exit, interp_only_mode is set
@@ -1956,7 +1965,7 @@ void JvmtiExport::post_single_step(JavaThread *thread, Method* method, address l
19561965
HandleMark hm(thread);
19571966
methodHandle mh(thread, method);
19581967

1959-
JvmtiThreadState *state = thread->jvmti_thread_state();
1968+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
19601969
if (state == nullptr) {
19611970
return;
19621971
}
@@ -1998,7 +2007,7 @@ void JvmtiExport::post_exception_throw(JavaThread *thread, Method* method, addre
19982007
// ensure the stack is sufficiently processed.
19992008
KeepStackGCProcessedMark ksgcpm(thread);
20002009

2001-
JvmtiThreadState *state = thread->jvmti_thread_state();
2010+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
20022011
if (state == nullptr) {
20032012
return;
20042013
}
@@ -2086,7 +2095,7 @@ void JvmtiExport::notice_unwind_due_to_exception(JavaThread *thread, Method* met
20862095
methodHandle mh(thread, method);
20872096
Handle exception_handle(thread, exception);
20882097

2089-
JvmtiThreadState *state = thread->jvmti_thread_state();
2098+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
20902099
if (state == nullptr) {
20912100
return;
20922101
}
@@ -2202,7 +2211,7 @@ void JvmtiExport::post_field_access(JavaThread *thread, Method* method,
22022211
HandleMark hm(thread);
22032212
methodHandle mh(thread, method);
22042213

2205-
JvmtiThreadState *state = thread->jvmti_thread_state();
2214+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
22062215
if (state == nullptr) {
22072216
return;
22082217
}
@@ -2358,7 +2367,7 @@ void JvmtiExport::post_field_modification(JavaThread *thread, Method* method,
23582367
HandleMark hm(thread);
23592368
methodHandle mh(thread, method);
23602369

2361-
JvmtiThreadState *state = thread->jvmti_thread_state();
2370+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
23622371
if (state == nullptr) {
23632372
return;
23642373
}
@@ -2600,7 +2609,7 @@ void JvmtiExport::post_dynamic_code_generated_while_holding_locks(const char* na
26002609
// jvmti thread state.
26012610
// The collector and/or state might be null if JvmtiDynamicCodeEventCollector
26022611
// has been initialized while JVMTI_EVENT_DYNAMIC_CODE_GENERATED was disabled.
2603-
JvmtiThreadState* state = thread->jvmti_thread_state();
2612+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
26042613
if (state != nullptr) {
26052614
JvmtiDynamicCodeEventCollector *collector = state->get_dynamic_code_event_collector();
26062615
if (collector != nullptr) {
@@ -2719,17 +2728,17 @@ void JvmtiExport::post_data_dump() {
27192728

27202729
void JvmtiExport::post_monitor_contended_enter(JavaThread *thread, ObjectMonitor *obj_mntr) {
27212730
oop object = obj_mntr->object();
2722-
JvmtiThreadState *state = thread->jvmti_thread_state();
2731+
HandleMark hm(thread);
2732+
Handle h(thread, object);
2733+
2734+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
27232735
if (state == nullptr) {
27242736
return;
27252737
}
27262738
if (thread->is_in_any_VTMS_transition()) {
27272739
return; // no events should be posted if thread is in any VTMS transition
27282740
}
27292741

2730-
HandleMark hm(thread);
2731-
Handle h(thread, object);
2732-
27332742
EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTER,
27342743
("[%s] monitor contended enter event triggered",
27352744
JvmtiTrace::safe_get_thread_name(thread)));
@@ -2752,17 +2761,17 @@ void JvmtiExport::post_monitor_contended_enter(JavaThread *thread, ObjectMonitor
27522761

27532762
void JvmtiExport::post_monitor_contended_entered(JavaThread *thread, ObjectMonitor *obj_mntr) {
27542763
oop object = obj_mntr->object();
2755-
JvmtiThreadState *state = thread->jvmti_thread_state();
2764+
HandleMark hm(thread);
2765+
Handle h(thread, object);
2766+
2767+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
27562768
if (state == nullptr) {
27572769
return;
27582770
}
27592771
if (thread->is_in_any_VTMS_transition()) {
27602772
return; // no events should be posted if thread is in any VTMS transition
27612773
}
27622774

2763-
HandleMark hm(thread);
2764-
Handle h(thread, object);
2765-
27662775
EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED,
27672776
("[%s] monitor contended entered event triggered",
27682777
JvmtiTrace::safe_get_thread_name(thread)));
@@ -2786,17 +2795,17 @@ void JvmtiExport::post_monitor_contended_entered(JavaThread *thread, ObjectMonit
27862795

27872796
void JvmtiExport::post_monitor_wait(JavaThread *thread, oop object,
27882797
jlong timeout) {
2789-
JvmtiThreadState *state = thread->jvmti_thread_state();
2798+
HandleMark hm(thread);
2799+
Handle h(thread, object);
2800+
2801+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
27902802
if (state == nullptr) {
27912803
return;
27922804
}
27932805
if (thread->is_in_any_VTMS_transition()) {
27942806
return; // no events should be posted if thread is in any VTMS transition
27952807
}
27962808

2797-
HandleMark hm(thread);
2798-
Handle h(thread, object);
2799-
28002809
EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_WAIT,
28012810
("[%s] monitor wait event triggered",
28022811
JvmtiTrace::safe_get_thread_name(thread)));
@@ -2820,17 +2829,17 @@ void JvmtiExport::post_monitor_wait(JavaThread *thread, oop object,
28202829

28212830
void JvmtiExport::post_monitor_waited(JavaThread *thread, ObjectMonitor *obj_mntr, jboolean timed_out) {
28222831
oop object = obj_mntr->object();
2823-
JvmtiThreadState *state = thread->jvmti_thread_state();
2832+
HandleMark hm(thread);
2833+
Handle h(thread, object);
2834+
2835+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
28242836
if (state == nullptr) {
28252837
return;
28262838
}
28272839
if (thread->is_in_any_VTMS_transition()) {
28282840
return; // no events should be posted if thread is in any VTMS transition
28292841
}
28302842

2831-
HandleMark hm(thread);
2832-
Handle h(thread, object);
2833-
28342843
EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_WAITED,
28352844
("[%s] monitor waited event triggered",
28362845
JvmtiTrace::safe_get_thread_name(thread)));
@@ -2883,7 +2892,10 @@ void JvmtiExport::post_vm_object_alloc(JavaThread *thread, oop object) {
28832892
}
28842893

28852894
void JvmtiExport::post_sampled_object_alloc(JavaThread *thread, oop object) {
2886-
JvmtiThreadState *state = thread->jvmti_thread_state();
2895+
HandleMark hm(thread);
2896+
Handle h(thread, object);
2897+
2898+
JvmtiThreadState *state = get_jvmti_thread_state(thread);
28872899
if (state == nullptr) {
28882900
return;
28892901
}
@@ -2893,8 +2905,6 @@ void JvmtiExport::post_sampled_object_alloc(JavaThread *thread, oop object) {
28932905
if (thread->is_in_any_VTMS_transition()) {
28942906
return; // no events should be posted if thread is in any VTMS transition
28952907
}
2896-
HandleMark hm(thread);
2897-
Handle h(thread, object);
28982908

28992909
EVT_TRIG_TRACE(JVMTI_EVENT_SAMPLED_OBJECT_ALLOC,
29002910
("[%s] Trg sampled object alloc triggered",

src/hotspot/share/prims/jvmtiExport.hpp

+5
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,11 @@ class JvmtiExport : public AllStatic {
298298
static void decode_version_values(jint version, int * major, int * minor,
299299
int * micro) NOT_JVMTI_RETURN;
300300

301+
// If the jvmti_thread_state is absent and any thread filtered event
302+
// is enabled globally then it is created.
303+
// Otherwise, the thread->jvmti_thread_state() is returned.
304+
static JvmtiThreadState* get_jvmti_thread_state(JavaThread *thread);
305+
301306
// single stepping management methods
302307
static void at_single_stepping_point(JavaThread *thread, Method* method, address location) NOT_JVMTI_RETURN;
303308
static void expose_single_stepping(JavaThread *thread) NOT_JVMTI_RETURN;

0 commit comments

Comments
 (0)