Skip to content

Commit 1c34f3c

Browse files
author
Serguei Spitsyn
committed
8352773: JVMTI should disable events during java upcalls
Reviewed-by: lmesnik, dholmes, cjplummer, coleenp
1 parent 7bb8b17 commit 1c34f3c

File tree

6 files changed

+39
-2
lines changed

6 files changed

+39
-2
lines changed

Diff for: src/hotspot/share/prims/jvmtiEnv.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -1212,7 +1212,7 @@ JvmtiEnv::StopThread(jthread thread, jobject exception) {
12121212
// thread - NOT protected by ThreadsListHandle and NOT pre-checked
12131213
jvmtiError
12141214
JvmtiEnv::InterruptThread(jthread thread) {
1215-
JavaThread* current_thread = JavaThread::current();
1215+
JavaThread* current_thread = JavaThread::current();
12161216
HandleMark hm(current_thread);
12171217

12181218
JvmtiVTMSTransitionDisabler disabler(thread);
@@ -1228,6 +1228,7 @@ JvmtiEnv::InterruptThread(jthread thread) {
12281228
if (java_lang_VirtualThread::is_instance(thread_obj)) {
12291229
// For virtual threads we have to call into Java to interrupt:
12301230
Handle obj(current_thread, thread_obj);
1231+
JvmtiJavaUpcallMark jjum(current_thread); // hide JVMTI events for Java upcall
12311232
JavaValue result(T_VOID);
12321233
JavaCalls::call_virtual(&result,
12331234
obj,

Diff for: src/hotspot/share/prims/jvmtiEnvBase.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,7 @@ JvmtiEnvBase::get_subgroups(JavaThread* current_thread, Handle group_hdl, jint *
864864

865865
// This call collects the strong and weak groups
866866
JavaThread* THREAD = current_thread;
867+
JvmtiJavaUpcallMark jjum(current_thread); // hide JVMTI events for Java upcall
867868
JavaValue result(T_OBJECT);
868869
JavaCalls::call_virtual(&result,
869870
group_hdl,

Diff for: src/hotspot/share/prims/jvmtiEnvBase.hpp

+21
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,27 @@ class JvmtiEnvIterator : public StackObj {
454454
JvmtiEnv* next(JvmtiEnvBase* env) { return env->next_environment(); }
455455
};
456456

457+
#if INCLUDE_JVMTI
458+
459+
// This helper class marks current thread as making a Java upcall.
460+
// It is needed to hide JVMTI events during JVMTI operation.
461+
class JvmtiJavaUpcallMark : public StackObj {
462+
private:
463+
JavaThread* _current;
464+
public:
465+
JvmtiJavaUpcallMark(JavaThread* current) {
466+
_current = current;
467+
assert(!_current->is_in_java_upcall(), "sanity check");
468+
_current->toggle_is_in_java_upcall();
469+
}
470+
471+
~JvmtiJavaUpcallMark() {
472+
assert(_current->is_in_java_upcall(), "sanity check");
473+
_current->toggle_is_in_java_upcall();
474+
}
475+
};
476+
#endif // INCLUDE_JVMTI
477+
457478
// Used in combination with the JvmtiHandshake class.
458479
// It is intended to support both platform and virtual threads.
459480
class JvmtiUnitedHandshakeClosure : public HandshakeClosure {

Diff for: src/hotspot/share/prims/jvmtiExport.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -1376,6 +1376,10 @@ void JvmtiExport::post_class_load(JavaThread *thread, Klass* klass) {
13761376
return;
13771377
}
13781378
if (thread->should_hide_jvmti_events()) {
1379+
// All events can be disabled if current thread is doing a Java upcall originated by JVMTI.
1380+
// ClassLoad events are important for JDWP agent but not expected during such upcalls.
1381+
// Catch if this invariant is broken.
1382+
assert(!thread->is_in_java_upcall(), "unexpected ClassLoad event during JVMTI upcall");
13791383
return;
13801384
}
13811385

@@ -1413,6 +1417,10 @@ void JvmtiExport::post_class_prepare(JavaThread *thread, Klass* klass) {
14131417
return;
14141418
}
14151419
if (thread->should_hide_jvmti_events()) {
1420+
// All events can be disabled if current thread is doing a Java upcall originated by JVMTI.
1421+
// ClassPrepare events are important for JDWP agent but not expected during such upcalls.
1422+
// Catch if this invariant is broken.
1423+
assert(!thread->is_in_java_upcall(), "unexpected ClassPrepare event during JVMTI upcall");
14161424
return;
14171425
}
14181426

Diff for: src/hotspot/share/runtime/javaThread.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,7 @@ JavaThread::JavaThread(MemTag mem_tag) :
450450
_carrier_thread_suspended(false),
451451
_is_in_VTMS_transition(false),
452452
_is_disable_suspend(false),
453+
_is_in_java_upcall(false),
453454
_VTMS_transition_mark(false),
454455
_on_monitor_waited_event(false),
455456
_contended_entered_monitor(nullptr),

Diff for: src/hotspot/share/runtime/javaThread.hpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ class JavaThread: public Thread {
331331
volatile bool _carrier_thread_suspended; // Carrier thread is externally suspended
332332
bool _is_in_VTMS_transition; // thread is in virtual thread mount state transition
333333
bool _is_disable_suspend; // JVMTI suspend is temporarily disabled; used on current thread only
334+
bool _is_in_java_upcall; // JVMTI is doing a Java upcall, so JVMTI events must be hidden
334335
bool _VTMS_transition_mark; // used for sync between VTMS transitions and disablers
335336
bool _on_monitor_waited_event; // Avoid callee arg processing for enterSpecial when posting waited event
336337
ObjectMonitor* _contended_entered_monitor; // Monitor for pending monitor_contended_entered callback
@@ -722,13 +723,17 @@ class JavaThread: public Thread {
722723
bool is_disable_suspend() const { return _is_disable_suspend; }
723724
void toggle_is_disable_suspend() { _is_disable_suspend = !_is_disable_suspend; };
724725

726+
bool is_in_java_upcall() const { return _is_in_java_upcall; }
727+
void toggle_is_in_java_upcall() { _is_in_java_upcall = !_is_in_java_upcall; };
728+
725729
bool VTMS_transition_mark() const { return Atomic::load(&_VTMS_transition_mark); }
726730
void set_VTMS_transition_mark(bool val) { Atomic::store(&_VTMS_transition_mark, val); }
727731

728732
// Temporarily skip posting JVMTI events for safety reasons when executions is in a critical section:
729733
// - is in a VTMS transition (_is_in_VTMS_transition)
730734
// - is in an interruptLock or similar critical section (_is_disable_suspend)
731-
bool should_hide_jvmti_events() const { return _is_in_VTMS_transition || _is_disable_suspend; }
735+
// - JVMTI is making a Java upcall (_is_in_java_upcall)
736+
bool should_hide_jvmti_events() const { return _is_in_VTMS_transition || _is_disable_suspend || _is_in_java_upcall; }
732737

733738
bool on_monitor_waited_event() { return _on_monitor_waited_event; }
734739
void set_on_monitor_waited_event(bool val) { _on_monitor_waited_event = val; }

0 commit comments

Comments
 (0)