Skip to content

Commit 79ccc79

Browse files
author
Serguei Spitsyn
committed
8293613: need to properly handle and hide tmp VTMS transitions
Reviewed-by: cjplummer, lmesnik
1 parent 5e1e449 commit 79ccc79

File tree

10 files changed

+145
-68
lines changed

10 files changed

+145
-68
lines changed

make/data/hotspot-symbols/symbols-unix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,4 +224,5 @@ JVM_VirtualThreadMountBegin
224224
JVM_VirtualThreadMountEnd
225225
JVM_VirtualThreadUnmountBegin
226226
JVM_VirtualThreadUnmountEnd
227+
JVM_VirtualThreadHideFrames
227228
#

src/hotspot/share/include/jvm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,6 +1150,9 @@ JVM_VirtualThreadUnmountBegin(JNIEnv* env, jobject vthread, jboolean last_unmoun
11501150
JNIEXPORT void JNICALL
11511151
JVM_VirtualThreadUnmountEnd(JNIEnv* env, jobject vthread, jboolean last_unmount);
11521152

1153+
JNIEXPORT void JNICALL
1154+
JVM_VirtualThreadHideFrames(JNIEnv* env, jobject vthread, jboolean hide);
1155+
11531156
/*
11541157
* Core reflection support.
11551158
*/

src/hotspot/share/prims/jvm.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3882,6 +3882,8 @@ JVM_ENTRY(void, JVM_VirtualThreadMountBegin(JNIEnv* env, jobject vthread, jboole
38823882
assert(!JvmtiExport::can_support_virtual_threads(), "sanity check");
38833883
return;
38843884
}
3885+
assert(!thread->is_in_tmp_VTMS_transition(), "sanity check");
3886+
assert(!thread->is_in_VTMS_transition(), "sanity check");
38853887
JvmtiVTMSTransitionDisabler::start_VTMS_transition(vthread, /* is_mount */ true);
38863888
#else
38873889
fatal("Should only be called with JVMTI enabled");
@@ -3906,6 +3908,7 @@ JVM_ENTRY(void, JVM_VirtualThreadMountEnd(JNIEnv* env, jobject vthread, jboolean
39063908
}
39073909
}
39083910
assert(thread->is_in_VTMS_transition(), "sanity check");
3911+
assert(!thread->is_in_tmp_VTMS_transition(), "sanity check");
39093912
JvmtiVTMSTransitionDisabler::finish_VTMS_transition(vthread, /* is_mount */ true);
39103913
if (first_mount) {
39113914
// thread start
@@ -3954,7 +3957,7 @@ JVM_ENTRY(void, JVM_VirtualThreadUnmountBegin(JNIEnv* env, jobject vthread, jboo
39543957
}
39553958
}
39563959
}
3957-
3960+
assert(!thread->is_in_tmp_VTMS_transition(), "sanity check");
39583961
assert(!thread->is_in_VTMS_transition(), "sanity check");
39593962
JvmtiVTMSTransitionDisabler::start_VTMS_transition(vthread, /* is_mount */ false);
39603963

@@ -3977,12 +3980,27 @@ JVM_ENTRY(void, JVM_VirtualThreadUnmountEnd(JNIEnv* env, jobject vthread, jboole
39773980
return;
39783981
}
39793982
assert(thread->is_in_VTMS_transition(), "sanity check");
3983+
assert(!thread->is_in_tmp_VTMS_transition(), "sanity check");
39803984
JvmtiVTMSTransitionDisabler::finish_VTMS_transition(vthread, /* is_mount */ false);
39813985
#else
39823986
fatal("Should only be called with JVMTI enabled");
39833987
#endif
39843988
JVM_END
39853989

3990+
JVM_ENTRY(void, JVM_VirtualThreadHideFrames(JNIEnv* env, jobject vthread, jboolean hide))
3991+
#if INCLUDE_JVMTI
3992+
if (!DoJVMTIVirtualThreadTransitions) {
3993+
assert(!JvmtiExport::can_support_virtual_threads(), "sanity check");
3994+
return;
3995+
}
3996+
assert(!thread->is_in_VTMS_transition(), "sanity check");
3997+
assert(thread->is_in_tmp_VTMS_transition() != (bool)hide, "sanity check");
3998+
thread->toggle_is_in_tmp_VTMS_transition();
3999+
#else
4000+
fatal("Should only be called with JVMTI enabled");
4001+
#endif
4002+
JVM_END
4003+
39864004
/*
39874005
* Return the current class's class file version. The low order 16 bits of the
39884006
* returned jint contain the class's major version. The high order 16 bits

src/hotspot/share/prims/jvmtiEnvBase.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -703,10 +703,14 @@ JvmtiEnvBase::get_vthread_jvf(oop vthread) {
703703
javaVFrame*
704704
JvmtiEnvBase::get_cthread_last_java_vframe(JavaThread* jt, RegisterMap* reg_map_p) {
705705
// Strip vthread frames in case of carrier thread with mounted continuation.
706-
javaVFrame *jvf = JvmtiEnvBase::is_cthread_with_continuation(jt) ?
707-
jt->carrier_last_java_vframe(reg_map_p) :
708-
jt->last_java_vframe(reg_map_p);
709-
jvf = check_and_skip_hidden_frames(jt, jvf);
706+
bool cthread_with_cont = JvmtiEnvBase::is_cthread_with_continuation(jt);
707+
javaVFrame *jvf = cthread_with_cont ? jt->carrier_last_java_vframe(reg_map_p)
708+
: jt->last_java_vframe(reg_map_p);
709+
// Skip hidden frames only for carrier threads
710+
// which are in non-temporary VTMS transition.
711+
if (jt->is_in_VTMS_transition()) {
712+
jvf = check_and_skip_hidden_frames(jt, jvf);
713+
}
710714
return jvf;
711715
}
712716

src/hotspot/share/prims/jvmtiExport.cpp

Lines changed: 57 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -893,7 +893,7 @@ class JvmtiClassFileLoadHookPoster : public StackObj {
893893
_cached_class_file_ptr = cache_ptr;
894894
_has_been_modified = false;
895895

896-
assert(!_thread->is_in_VTMS_transition(), "CFLH events are not allowed in VTMS transition");
896+
assert(!_thread->is_in_any_VTMS_transition(), "CFLH events are not allowed in any VTMS transition");
897897
_state = _thread->jvmti_thread_state();
898898
if (_state != NULL) {
899899
_class_being_redefined = _state->get_class_being_redefined();
@@ -1050,6 +1050,9 @@ bool JvmtiExport::post_class_file_load_hook(Symbol* h_name,
10501050
if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {
10511051
return false;
10521052
}
1053+
if (JavaThread::current()->is_in_tmp_VTMS_transition()) {
1054+
return false; // skip CFLH events in tmp VTMS transition
1055+
}
10531056

10541057
JvmtiClassFileLoadHookPoster poster(h_name, class_loader,
10551058
h_protection_domain,
@@ -1184,8 +1187,8 @@ void JvmtiExport::post_raw_breakpoint(JavaThread *thread, Method* method, addres
11841187
if (state == NULL) {
11851188
return;
11861189
}
1187-
if (thread->is_in_VTMS_transition()) {
1188-
return; // no events should be posted if thread is in a VTMS transition
1190+
if (thread->is_in_any_VTMS_transition()) {
1191+
return; // no events should be posted if thread is in any VTMS transition
11891192
}
11901193

11911194
EVT_TRIG_TRACE(JVMTI_EVENT_BREAKPOINT, ("[%s] Trg Breakpoint triggered",
@@ -1340,7 +1343,10 @@ void JvmtiExport::post_class_load(JavaThread *thread, Klass* klass) {
13401343
if (state == NULL) {
13411344
return;
13421345
}
1343-
assert(!thread->is_in_VTMS_transition(), "class load events are not allowed in VTMS transition");
1346+
if (thread->is_in_tmp_VTMS_transition()) {
1347+
return; // skip ClassLoad events in tmp VTMS transition
1348+
}
1349+
assert(!thread->is_in_any_VTMS_transition(), "class load events are not allowed in any VTMS transition");
13441350

13451351
EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_LOAD, ("[%s] Trg Class Load triggered",
13461352
JvmtiTrace::safe_get_thread_name(thread)));
@@ -1375,7 +1381,10 @@ void JvmtiExport::post_class_prepare(JavaThread *thread, Klass* klass) {
13751381
if (state == NULL) {
13761382
return;
13771383
}
1378-
assert(!thread->is_in_VTMS_transition(), "class prepare events are not allowed in VTMS transition");
1384+
if (thread->is_in_tmp_VTMS_transition()) {
1385+
return; // skip ClassPrepare events in tmp VTMS transition
1386+
}
1387+
assert(!thread->is_in_any_VTMS_transition(), "class prepare events are not allowed in any VTMS transition");
13791388

13801389
EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_PREPARE, ("[%s] Trg Class Prepare triggered",
13811390
JvmtiTrace::safe_get_thread_name(thread)));
@@ -1694,8 +1703,8 @@ void JvmtiExport::post_object_free(JvmtiEnv* env, GrowableArray<jlong>* objects)
16941703
assert(objects != NULL, "Nothing to post");
16951704

16961705
JavaThread *javaThread = JavaThread::current();
1697-
if (javaThread->is_in_VTMS_transition()) {
1698-
return; // no events should be posted if thread is in a VTMS transition
1706+
if (javaThread->is_in_any_VTMS_transition()) {
1707+
return; // no events should be posted if thread is in any VTMS transition
16991708
}
17001709
if (!env->is_enabled(JVMTI_EVENT_OBJECT_FREE)) {
17011710
return; // the event type has been already disabled
@@ -1718,8 +1727,8 @@ void JvmtiExport::post_resource_exhausted(jint resource_exhausted_flags, const c
17181727

17191728
JavaThread *thread = JavaThread::current();
17201729

1721-
if (thread->is_in_VTMS_transition()) {
1722-
return; // no events should be posted if thread is in a VTMS transition
1730+
if (thread->is_in_any_VTMS_transition()) {
1731+
return; // no events should be posted if thread is in any VTMS transition
17231732
}
17241733

17251734
log_error(jvmti)("Posting Resource Exhausted event: %s",
@@ -1761,8 +1770,8 @@ void JvmtiExport::post_method_entry(JavaThread *thread, Method* method, frame cu
17611770
// for any thread that actually wants method entry, interp_only_mode is set
17621771
return;
17631772
}
1764-
if (mh->jvmti_mount_transition() || thread->is_in_VTMS_transition()) {
1765-
return; // no events should be posted if thread is in a VTMS transition
1773+
if (mh->jvmti_mount_transition() || thread->is_in_any_VTMS_transition()) {
1774+
return; // no events should be posted if thread is in any VTMS transition
17661775
}
17671776
EVT_TRIG_TRACE(JVMTI_EVENT_METHOD_ENTRY, ("[%s] Trg Method Entry triggered %s.%s",
17681777
JvmtiTrace::safe_get_thread_name(thread),
@@ -1845,8 +1854,8 @@ void JvmtiExport::post_method_exit_inner(JavaThread* thread,
18451854
bool exception_exit,
18461855
frame current_frame,
18471856
jvalue& value) {
1848-
if (mh->jvmti_mount_transition() || thread->is_in_VTMS_transition()) {
1849-
return; // no events should be posted if thread is in a VTMS transition
1857+
if (mh->jvmti_mount_transition() || thread->is_in_any_VTMS_transition()) {
1858+
return; // no events should be posted if thread is in any VTMS transition
18501859
}
18511860

18521861
EVT_TRIG_TRACE(JVMTI_EVENT_METHOD_EXIT, ("[%s] Trg Method Exit triggered %s.%s",
@@ -1921,8 +1930,8 @@ void JvmtiExport::post_single_step(JavaThread *thread, Method* method, address l
19211930
if (state == NULL) {
19221931
return;
19231932
}
1924-
if (mh->jvmti_mount_transition() || thread->is_in_VTMS_transition()) {
1925-
return; // no events should be posted if thread is in a VTMS transition
1933+
if (mh->jvmti_mount_transition() || thread->is_in_any_VTMS_transition()) {
1934+
return; // no events should be posted if thread is in any VTMS transition
19261935
}
19271936

19281937
JvmtiEnvThreadStateIterator it(state);
@@ -1958,8 +1967,8 @@ void JvmtiExport::post_exception_throw(JavaThread *thread, Method* method, addre
19581967
if (state == NULL) {
19591968
return;
19601969
}
1961-
if (thread->is_in_VTMS_transition()) {
1962-
return; // no events should be posted if thread is in a VTMS transition
1970+
if (thread->is_in_any_VTMS_transition()) {
1971+
return; // no events should be posted if thread is in any VTMS transition
19631972
}
19641973

19651974
EVT_TRIG_TRACE(JVMTI_EVENT_EXCEPTION, ("[%s] Trg Exception thrown triggered",
@@ -2080,8 +2089,8 @@ void JvmtiExport::notice_unwind_due_to_exception(JavaThread *thread, Method* met
20802089
assert(!state->is_exception_caught(), "exception must not be caught yet.");
20812090
state->set_exception_caught();
20822091

2083-
if (mh->jvmti_mount_transition() || thread->is_in_VTMS_transition()) {
2084-
return; // no events should be posted if thread is in a VTMS transition
2092+
if (mh->jvmti_mount_transition() || thread->is_in_any_VTMS_transition()) {
2093+
return; // no events should be posted if thread is in any VTMS transition
20852094
}
20862095
JvmtiEnvThreadStateIterator it(state);
20872096
for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
@@ -2126,8 +2135,8 @@ void JvmtiExport::post_field_access_by_jni(JavaThread *thread, oop obj,
21262135
// function don't make the call unless there is a Java context.
21272136
assert(thread->has_last_Java_frame(), "must be called with a Java context");
21282137

2129-
if (thread->is_in_VTMS_transition()) {
2130-
return; // no events should be posted if thread is in a VTMS transition
2138+
if (thread->is_in_any_VTMS_transition()) {
2139+
return; // no events should be posted if thread is in any VTMS transition
21312140
}
21322141

21332142
ResourceMark rm;
@@ -2162,8 +2171,8 @@ void JvmtiExport::post_field_access(JavaThread *thread, Method* method,
21622171
if (state == NULL) {
21632172
return;
21642173
}
2165-
if (thread->is_in_VTMS_transition()) {
2166-
return; // no events should be posted if thread is in a VTMS transition
2174+
if (thread->is_in_any_VTMS_transition()) {
2175+
return; // no events should be posted if thread is in any VTMS transition
21672176
}
21682177

21692178
EVT_TRIG_TRACE(JVMTI_EVENT_FIELD_ACCESS, ("[%s] Trg Field Access event triggered",
@@ -2212,8 +2221,8 @@ void JvmtiExport::post_field_modification_by_jni(JavaThread *thread, oop obj,
22122221
// function don't make the call unless there is a Java context.
22132222
assert(thread->has_last_Java_frame(), "must be called with Java context");
22142223

2215-
if (thread->is_in_VTMS_transition()) {
2216-
return; // no events should be posted if thread is in a VTMS transition
2224+
if (thread->is_in_any_VTMS_transition()) {
2225+
return; // no events should be posted if thread is in any VTMS transition
22172226
}
22182227

22192228
ResourceMark rm;
@@ -2243,8 +2252,8 @@ void JvmtiExport::post_raw_field_modification(JavaThread *thread, Method* method
22432252
address location, Klass* field_klass, Handle object, jfieldID field,
22442253
char sig_type, jvalue *value) {
22452254

2246-
if (thread->is_in_VTMS_transition()) {
2247-
return; // no events should be posted if thread is in a VTMS transition
2255+
if (thread->is_in_any_VTMS_transition()) {
2256+
return; // no events should be posted if thread is in any VTMS transition
22482257
}
22492258

22502259
if (sig_type == JVM_SIGNATURE_INT || sig_type == JVM_SIGNATURE_BOOLEAN ||
@@ -2318,8 +2327,8 @@ void JvmtiExport::post_field_modification(JavaThread *thread, Method* method,
23182327
if (state == NULL) {
23192328
return;
23202329
}
2321-
if (thread->is_in_VTMS_transition()) {
2322-
return; // no events should be posted if thread is in a VTMS transition
2330+
if (thread->is_in_any_VTMS_transition()) {
2331+
return; // no events should be posted if thread is in any VTMS transition
23232332
}
23242333

23252334
EVT_TRIG_TRACE(JVMTI_EVENT_FIELD_MODIFICATION,
@@ -2357,8 +2366,8 @@ void JvmtiExport::post_native_method_bind(Method* method, address* function_ptr)
23572366
HandleMark hm(thread);
23582367
methodHandle mh(thread, method);
23592368

2360-
if (thread->is_in_VTMS_transition()) {
2361-
return; // no events should be posted if thread is in a VTMS transition
2369+
if (thread->is_in_any_VTMS_transition()) {
2370+
return; // no events should be posted if thread is in any VTMS transition
23622371
}
23632372
EVT_TRIG_TRACE(JVMTI_EVENT_NATIVE_METHOD_BIND, ("[%s] Trg Native Method Bind event triggered",
23642373
JvmtiTrace::safe_get_thread_name(thread)));
@@ -2431,7 +2440,7 @@ void JvmtiExport::post_compiled_method_load(nmethod *nm) {
24312440
}
24322441
JavaThread* thread = JavaThread::current();
24332442

2434-
assert(!thread->is_in_VTMS_transition(), "compiled method load events are not allowed in VTMS transition");
2443+
assert(!thread->is_in_any_VTMS_transition(), "compiled method load events are not allowed in any VTMS transition");
24352444

24362445
EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
24372446
("[%s] method compile load event triggered",
@@ -2454,7 +2463,7 @@ void JvmtiExport::post_compiled_method_load(JvmtiEnv* env, nmethod *nm) {
24542463
}
24552464
JavaThread* thread = JavaThread::current();
24562465

2457-
assert(!thread->is_in_VTMS_transition(), "compiled method load events are not allowed in VTMS transition");
2466+
assert(!thread->is_in_any_VTMS_transition(), "compiled method load events are not allowed in any VTMS transition");
24582467

24592468
EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
24602469
("[%s] method compile load event sent %s.%s ",
@@ -2479,7 +2488,7 @@ void JvmtiExport::post_dynamic_code_generated_internal(const char *name, const v
24792488

24802489
JavaThread* thread = JavaThread::current();
24812490

2482-
assert(!thread->is_in_VTMS_transition(), "dynamic code generated events are not allowed in VTMS transition");
2491+
assert(!thread->is_in_any_VTMS_transition(), "dynamic code generated events are not allowed in any VTMS transition");
24832492

24842493
// In theory everyone coming thru here is in_vm but we need to be certain
24852494
// because a callee will do a vm->native transition
@@ -2527,7 +2536,7 @@ void JvmtiExport::post_dynamic_code_generated(JvmtiEnv* env, const char *name,
25272536
{
25282537
JavaThread* thread = JavaThread::current();
25292538

2530-
assert(!thread->is_in_VTMS_transition(), "dynamic code generated events are not allowed in VTMS transition");
2539+
assert(!thread->is_in_any_VTMS_transition(), "dynamic code generated events are not allowed in any VTMS transition");
25312540

25322541
EVT_TRIG_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED,
25332542
("[%s] dynamic code generated event triggered (by GenerateEvents)",
@@ -2551,7 +2560,7 @@ void JvmtiExport::post_dynamic_code_generated_while_holding_locks(const char* na
25512560
address code_begin, address code_end)
25522561
{
25532562
JavaThread* thread = JavaThread::current();
2554-
assert(!thread->is_in_VTMS_transition(), "dynamic code generated events are not allowed in VTMS transition");
2563+
assert(!thread->is_in_any_VTMS_transition(), "dynamic code generated events are not allowed in any VTMS transition");
25552564

25562565
// register the stub with the current dynamic code event collector
25572566
// Cannot take safepoint here so do not use state_for to get
@@ -2681,8 +2690,8 @@ void JvmtiExport::post_monitor_contended_enter(JavaThread *thread, ObjectMonitor
26812690
if (state == NULL) {
26822691
return;
26832692
}
2684-
if (thread->is_in_VTMS_transition()) {
2685-
return; // no events should be posted if thread is in a VTMS transition
2693+
if (thread->is_in_any_VTMS_transition()) {
2694+
return; // no events should be posted if thread is in any VTMS transition
26862695
}
26872696

26882697
HandleMark hm(thread);
@@ -2714,8 +2723,8 @@ void JvmtiExport::post_monitor_contended_entered(JavaThread *thread, ObjectMonit
27142723
if (state == NULL) {
27152724
return;
27162725
}
2717-
if (thread->is_in_VTMS_transition()) {
2718-
return; // no events should be posted if thread is in a VTMS transition
2726+
if (thread->is_in_any_VTMS_transition()) {
2727+
return; // no events should be posted if thread is in any VTMS transition
27192728
}
27202729

27212730
HandleMark hm(thread);
@@ -2748,8 +2757,8 @@ void JvmtiExport::post_monitor_wait(JavaThread *thread, oop object,
27482757
if (state == NULL) {
27492758
return;
27502759
}
2751-
if (thread->is_in_VTMS_transition()) {
2752-
return; // no events should be posted if thread is in a VTMS transition
2760+
if (thread->is_in_any_VTMS_transition()) {
2761+
return; // no events should be posted if thread is in any VTMS transition
27532762
}
27542763

27552764
HandleMark hm(thread);
@@ -2782,8 +2791,8 @@ void JvmtiExport::post_monitor_waited(JavaThread *thread, ObjectMonitor *obj_mnt
27822791
if (state == NULL) {
27832792
return;
27842793
}
2785-
if (thread->is_in_VTMS_transition()) {
2786-
return; // no events should be posted if thread is in a VTMS transition
2794+
if (thread->is_in_any_VTMS_transition()) {
2795+
return; // no events should be posted if thread is in any VTMS transition
27872796
}
27882797

27892798
HandleMark hm(thread);
@@ -2814,8 +2823,8 @@ void JvmtiExport::post_vm_object_alloc(JavaThread *thread, oop object) {
28142823
if (object == NULL) {
28152824
return;
28162825
}
2817-
if (thread->is_in_VTMS_transition()) {
2818-
return; // no events should be posted if thread is in a VTMS transition
2826+
if (thread->is_in_any_VTMS_transition()) {
2827+
return; // no events should be posted if thread is in any VTMS transition
28192828
}
28202829
HandleMark hm(thread);
28212830
Handle h(thread, object);
@@ -2848,8 +2857,8 @@ void JvmtiExport::post_sampled_object_alloc(JavaThread *thread, oop object) {
28482857
if (object == NULL) {
28492858
return;
28502859
}
2851-
if (thread->is_in_VTMS_transition()) {
2852-
return; // no events should be posted if thread is in a VTMS transition
2860+
if (thread->is_in_any_VTMS_transition()) {
2861+
return; // no events should be posted if thread is in any VTMS transition
28532862
}
28542863
HandleMark hm(thread);
28552864
Handle h(thread, object);

0 commit comments

Comments
 (0)