Skip to content
This repository was archived by the owner on Mar 19, 2024. It is now read-only.

Commit 865cf88

Browse files
author
Serguei Spitsyn
committed
8311218: fatal error: stuck in JvmtiVTMSTransitionDisabler::VTMS_transition_disable
Reviewed-by: alanb Backport-of: 0f8e4e0a81257c678e948c341a241dc0b810494f
1 parent 71cc879 commit 865cf88

File tree

15 files changed

+229
-33
lines changed

15 files changed

+229
-33
lines changed

make/data/hotspot-symbols/symbols-unix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ JVM_VirtualThreadEnd
223223
JVM_VirtualThreadMount
224224
JVM_VirtualThreadUnmount
225225
JVM_VirtualThreadHideFrames
226+
JVM_VirtualThreadDisableSuspend
226227

227228
# Scoped values
228229
JVM_EnsureMaterializedForStackWalk_func

src/hotspot/share/classfile/vmIntrinsics.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,7 @@ class methodHandle;
597597
do_intrinsic(_notifyJvmtiVThreadMount, java_lang_VirtualThread, notifyJvmtiMount_name, bool_void_signature, F_RN) \
598598
do_intrinsic(_notifyJvmtiVThreadUnmount, java_lang_VirtualThread, notifyJvmtiUnmount_name, bool_void_signature, F_RN) \
599599
do_intrinsic(_notifyJvmtiVThreadHideFrames, java_lang_VirtualThread, notifyJvmtiHideFrames_name, bool_void_signature, F_RN) \
600+
do_intrinsic(_notifyJvmtiVThreadDisableSuspend, java_lang_VirtualThread, notifyJvmtiDisableSuspend_name, bool_void_signature, F_RN) \
600601
\
601602
/* support for UnsafeConstants */ \
602603
do_class(jdk_internal_misc_UnsafeConstants, "jdk/internal/misc/UnsafeConstants") \

src/hotspot/share/classfile/vmSymbols.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ class SerializeClosure;
421421
template(notifyJvmtiMount_name, "notifyJvmtiMount") \
422422
template(notifyJvmtiUnmount_name, "notifyJvmtiUnmount") \
423423
template(notifyJvmtiHideFrames_name, "notifyJvmtiHideFrames") \
424+
template(notifyJvmtiDisableSuspend_name, "notifyJvmtiDisableSuspend") \
424425
template(doYield_name, "doYield") \
425426
template(enter_name, "enter") \
426427
template(enterSpecial_name, "enterSpecial") \

src/hotspot/share/include/jvm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,6 +1154,9 @@ JVM_VirtualThreadUnmount(JNIEnv* env, jobject vthread, jboolean hide);
11541154
JNIEXPORT void JNICALL
11551155
JVM_VirtualThreadHideFrames(JNIEnv* env, jobject vthread, jboolean hide);
11561156

1157+
JNIEXPORT void JNICALL
1158+
JVM_VirtualThreadDisableSuspend(JNIEnv* env, jobject vthread, jboolean enter);
1159+
11571160
/*
11581161
* Core reflection support.
11591162
*/

src/hotspot/share/jvmci/vmStructs_jvmci.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@
220220
nonstatic_field(JavaThread, _lock_stack, LockStack) \
221221
JVMTI_ONLY(nonstatic_field(JavaThread, _is_in_VTMS_transition, bool)) \
222222
JVMTI_ONLY(nonstatic_field(JavaThread, _is_in_tmp_VTMS_transition, bool)) \
223+
JVMTI_ONLY(nonstatic_field(JavaThread, _is_disable_suspend, bool)) \
223224
\
224225
nonstatic_field(LockStack, _top, uint32_t) \
225226
\

src/hotspot/share/opto/c2compiler.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,7 @@ bool C2Compiler::is_intrinsic_supported(vmIntrinsics::ID id) {
822822
case vmIntrinsics::_notifyJvmtiVThreadMount:
823823
case vmIntrinsics::_notifyJvmtiVThreadUnmount:
824824
case vmIntrinsics::_notifyJvmtiVThreadHideFrames:
825+
case vmIntrinsics::_notifyJvmtiVThreadDisableSuspend:
825826
#endif
826827
break;
827828

src/hotspot/share/opto/library_call.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,8 @@ bool LibraryCallKit::try_to_inline(int predicate) {
492492
"notifyJvmtiMount", false, false);
493493
case vmIntrinsics::_notifyJvmtiVThreadUnmount: return inline_native_notify_jvmti_funcs(CAST_FROM_FN_PTR(address, OptoRuntime::notify_jvmti_vthread_unmount()),
494494
"notifyJvmtiUnmount", false, false);
495-
case vmIntrinsics::_notifyJvmtiVThreadHideFrames: return inline_native_notify_jvmti_hide();
495+
case vmIntrinsics::_notifyJvmtiVThreadHideFrames: return inline_native_notify_jvmti_hide();
496+
case vmIntrinsics::_notifyJvmtiVThreadDisableSuspend: return inline_native_notify_jvmti_sync();
496497
#endif
497498

498499
#ifdef JFR_HAVE_INTRINSICS
@@ -2950,6 +2951,29 @@ bool LibraryCallKit::inline_native_notify_jvmti_hide() {
29502951
return true;
29512952
}
29522953

2954+
// Always update the is_disable_suspend bit.
2955+
bool LibraryCallKit::inline_native_notify_jvmti_sync() {
2956+
if (!DoJVMTIVirtualThreadTransitions) {
2957+
return true;
2958+
}
2959+
IdealKit ideal(this);
2960+
2961+
{
2962+
// unconditionally update the is_disable_suspend bit in current JavaThread
2963+
Node* thread = ideal.thread();
2964+
Node* arg = _gvn.transform(argument(1)); // argument for notification
2965+
Node* addr = basic_plus_adr(thread, in_bytes(JavaThread::is_disable_suspend_offset()));
2966+
const TypePtr *addr_type = _gvn.type(addr)->isa_ptr();
2967+
2968+
sync_kit(ideal);
2969+
access_store_at(nullptr, addr, addr_type, arg, _gvn.type(arg), T_BOOLEAN, IN_NATIVE | MO_UNORDERED);
2970+
ideal.sync_kit(this);
2971+
}
2972+
final_sync(ideal);
2973+
2974+
return true;
2975+
}
2976+
29532977
#endif // INCLUDE_JVMTI
29542978

29552979
#ifdef JFR_HAVE_INTRINSICS

src/hotspot/share/opto/library_call.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ class LibraryCallKit : public GraphKit {
245245
#if INCLUDE_JVMTI
246246
bool inline_native_notify_jvmti_funcs(address funcAddr, const char* funcName, bool is_start, bool is_end);
247247
bool inline_native_notify_jvmti_hide();
248+
bool inline_native_notify_jvmti_sync();
248249
#endif
249250

250251
#ifdef JFR_HAVE_INTRINSICS

src/hotspot/share/prims/jvm.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4008,6 +4008,22 @@ JVM_ENTRY(void, JVM_VirtualThreadHideFrames(JNIEnv* env, jobject vthread, jboole
40084008
#endif
40094009
JVM_END
40104010

4011+
// Notification from VirtualThread about disabling JVMTI Suspend in a sync critical section.
4012+
// Needed to avoid deadlocks with JVMTI suspend mechanism.
4013+
JVM_ENTRY(void, JVM_VirtualThreadDisableSuspend(JNIEnv* env, jobject vthread, jboolean enter))
4014+
#if INCLUDE_JVMTI
4015+
if (!DoJVMTIVirtualThreadTransitions) {
4016+
assert(!JvmtiExport::can_support_virtual_threads(), "sanity check");
4017+
return;
4018+
}
4019+
assert(thread->is_disable_suspend() != (bool)enter,
4020+
"nested or unbalanced monitor enter/exit is not allowed");
4021+
thread->toggle_is_disable_suspend();
4022+
#else
4023+
fatal("Should only be called with JVMTI enabled");
4024+
#endif
4025+
JVM_END
4026+
40114027
/*
40124028
* Return the current class's class file version. The low order 16 bits of the
40134029
* returned jint contain the class's major version. The high order 16 bits

src/hotspot/share/runtime/handshake.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,10 @@ HandshakeOperation* HandshakeState::get_op_for_self(bool allow_suspend, bool che
487487
assert(_handshakee == Thread::current(), "Must be called by self");
488488
assert(_lock.owned_by_self(), "Lock must be held");
489489
assert(allow_suspend || !check_async_exception, "invalid case");
490+
if (allow_suspend && _handshakee->is_disable_suspend()) {
491+
// filter out suspend operations while JavaThread is in disable_suspend mode
492+
allow_suspend = false;
493+
}
490494
if (!allow_suspend) {
491495
return _queue.peek(no_suspend_no_async_exception_filter);
492496
} else if (check_async_exception && !_async_exceptions_blocked) {

0 commit comments

Comments
 (0)