8307399: get rid of compatibility ThreadStart/ThreadEnd events for virtual threads
Reviewed-by: alanb, pchilanomate, cjplummer
This commit is contained in:
parent
f5a6b7f7c0
commit
2be1f10fec
src/hotspot/share
test/hotspot/jtreg/serviceability/jvmti/vthread/VirtualThreadStartTest
@ -9697,6 +9697,7 @@ myInit() {
|
||||
<li><eventlink id="VMStart"></eventlink></li>
|
||||
<li><eventlink id="VMDeath"></eventlink></li>
|
||||
<li><eventlink id="ThreadStart"></eventlink></li>
|
||||
<li><eventlink id="VirtualThreadStart"></eventlink></li>
|
||||
<li><eventlink id="CompiledMethodLoad"></eventlink></li>
|
||||
<li><eventlink id="CompiledMethodUnload"></eventlink></li>
|
||||
<li><eventlink id="DynamicCodeGenerated"></eventlink></li>
|
||||
@ -12249,6 +12250,8 @@ myInit() {
|
||||
<li><eventlink id="VMDeath"></eventlink></li>
|
||||
<li><eventlink id="ThreadStart"></eventlink></li>
|
||||
<li><eventlink id="ThreadEnd"></eventlink></li>
|
||||
<li><eventlink id="VirtualThreadStart"></eventlink></li>
|
||||
<li><eventlink id="VirtualThreadEnd"></eventlink></li>
|
||||
<li><eventlink id="ClassLoad"></eventlink></li>
|
||||
<li><eventlink id="ClassPrepare"></eventlink></li>
|
||||
</ul>
|
||||
@ -12937,16 +12940,10 @@ myInit() {
|
||||
A thread start event is generated by a new thread before its initial
|
||||
method executes.
|
||||
<p/>
|
||||
This event is generated by platform threads. It is also generated by
|
||||
virtual threads when the capability
|
||||
<internallink id="jvmtiCapabilities.can_support_virtual_threads">
|
||||
<code>can_support_virtual_threads</code></internallink> is not enabled.
|
||||
Agents without support for virtual threads that enable this event will
|
||||
therefore be notified by all newly started threads.
|
||||
This event is generated by platform thread. It is not generated by virtual threads.
|
||||
<p/>
|
||||
If the capability <code>can_support_virtual_threads</code> is enabled then
|
||||
this event is not generated by virtual threads. Agents with support for
|
||||
virtual threads can enable <eventlink id="VirtualThreadStart"></eventlink>
|
||||
Agents with the <code>can_support_virtual_threads</code> capability
|
||||
can enable the <eventlink id="VirtualThreadStart"></eventlink> event
|
||||
to be notified by newly started virtual threads.
|
||||
<p/>
|
||||
A platform thread may be listed in the array returned by
|
||||
@ -12984,16 +12981,10 @@ myInit() {
|
||||
A thread end event is generated by a terminating thread after its
|
||||
initial method has finished execution.
|
||||
<p/>
|
||||
This event is generated by platform threads. It is also generated by
|
||||
virtual threads when the capability
|
||||
<internallink id="jvmtiCapabilities.can_support_virtual_threads">
|
||||
<code>can_support_virtual_threads</code></internallink> is not enabled.
|
||||
Agents without support for virtual threads that enable this event for
|
||||
all threads will therefore be notified by all terminating threads.
|
||||
This event is generated by platform thread. It is not generated by virtual threads.
|
||||
<p/>
|
||||
If the capability <code>can_support_virtual_threads</code> is enabled then
|
||||
this event is not generated by virtual threads. Agents with support for
|
||||
virtual threads can enable <eventlink id="VirtualThreadEnd"></eventlink>
|
||||
Agents with the <code>can_support_virtual_threads</code> capability
|
||||
can enable the <eventlink id="VirtualThreadEnd"></eventlink> event
|
||||
to be notified by terminating virtual threads.
|
||||
<p/>
|
||||
A platform thread may be listed in the array returned by
|
||||
|
@ -1476,11 +1476,13 @@ void JvmtiExport::post_thread_start(JavaThread *thread) {
|
||||
// do JVMTI thread initialization (if needed)
|
||||
JvmtiEventController::thread_started(thread);
|
||||
|
||||
if (JvmtiExport::can_support_virtual_threads() && thread->threadObj()->is_a(vmClasses::BoundVirtualThread_klass())) {
|
||||
// Check for VirtualThreadStart event instead.
|
||||
HandleMark hm(thread);
|
||||
Handle vthread(thread, thread->threadObj());
|
||||
JvmtiExport::post_vthread_start((jthread)vthread.raw_value());
|
||||
if (thread->threadObj()->is_a(vmClasses::BoundVirtualThread_klass())) {
|
||||
if (JvmtiExport::can_support_virtual_threads()) {
|
||||
// Check for VirtualThreadStart event instead.
|
||||
HandleMark hm(thread);
|
||||
Handle vthread(thread, thread->threadObj());
|
||||
JvmtiExport::post_vthread_start((jthread)vthread.raw_value());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1520,11 +1522,13 @@ void JvmtiExport::post_thread_end(JavaThread *thread) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (JvmtiExport::can_support_virtual_threads() && thread->threadObj()->is_a(vmClasses::BoundVirtualThread_klass())) {
|
||||
// Check for VirtualThreadEnd event instead.
|
||||
HandleMark hm(thread);
|
||||
Handle vthread(thread, thread->threadObj());
|
||||
JvmtiExport::post_vthread_end((jthread)vthread.raw_value());
|
||||
if (thread->threadObj()->is_a(vmClasses::BoundVirtualThread_klass())) {
|
||||
if (JvmtiExport::can_support_virtual_threads()) {
|
||||
// Check for VirtualThreadEnd event instead.
|
||||
HandleMark hm(thread);
|
||||
Handle vthread(thread, thread->threadObj());
|
||||
JvmtiExport::post_vthread_end((jthread)vthread.raw_value());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -526,17 +526,11 @@ JvmtiVTMSTransitionDisabler::VTMS_vthread_start(jobject vthread) {
|
||||
assert(!thread->is_in_VTMS_transition(), "sanity check");
|
||||
assert(!thread->is_in_tmp_VTMS_transition(), "sanity check");
|
||||
|
||||
JvmtiEventController::thread_started(thread);
|
||||
if (JvmtiExport::can_support_virtual_threads()) {
|
||||
JvmtiEventController::thread_started(thread);
|
||||
if (JvmtiExport::should_post_vthread_start()) {
|
||||
JvmtiExport::post_vthread_start(vthread);
|
||||
}
|
||||
} else { // compatibility for vthread unaware agents: legacy thread_start
|
||||
if (PostVirtualThreadCompatibleLifecycleEvents &&
|
||||
JvmtiExport::should_post_thread_life()) {
|
||||
// JvmtiEventController::thread_started is called here
|
||||
JvmtiExport::post_thread_start(thread);
|
||||
}
|
||||
}
|
||||
// post VirtualThreadMount event after VirtualThreadStart
|
||||
if (JvmtiExport::should_post_vthread_mount()) {
|
||||
@ -559,11 +553,6 @@ JvmtiVTMSTransitionDisabler::VTMS_vthread_end(jobject vthread) {
|
||||
if (JvmtiExport::should_post_vthread_end()) {
|
||||
JvmtiExport::post_vthread_end(vthread);
|
||||
}
|
||||
} else { // compatibility for vthread unaware agents: legacy thread_end
|
||||
if (PostVirtualThreadCompatibleLifecycleEvents &&
|
||||
JvmtiExport::should_post_thread_life()) {
|
||||
JvmtiExport::post_thread_end(thread);
|
||||
}
|
||||
}
|
||||
if (thread->jvmti_thread_state() != nullptr) {
|
||||
JvmtiExport::cleanup_thread(thread);
|
||||
|
@ -698,10 +698,6 @@ const int ObjectAlignmentInBytes = 8;
|
||||
"Disable the use of stack guard pages if the JVM is loaded " \
|
||||
"on the primordial process thread") \
|
||||
\
|
||||
product(bool, PostVirtualThreadCompatibleLifecycleEvents, true, EXPERIMENTAL, \
|
||||
"Post virtual thread ThreadStart and ThreadEnd events for " \
|
||||
"virtual thread unaware agents") \
|
||||
\
|
||||
product(bool, DoJVMTIVirtualThreadTransitions, true, EXPERIMENTAL, \
|
||||
"Do JVMTI virtual thread mount/unmount transitions " \
|
||||
"(disabling this flag implies no JVMTI events are posted)") \
|
||||
|
13
test/hotspot/jtreg/serviceability/jvmti/vthread/VirtualThreadStartTest/VirtualThreadStartTest.java
13
test/hotspot/jtreg/serviceability/jvmti/vthread/VirtualThreadStartTest/VirtualThreadStartTest.java
@ -46,6 +46,7 @@ public class VirtualThreadStartTest {
|
||||
private static final String AGENT_LIB = "VirtualThreadStartTest";
|
||||
private static final int THREAD_CNT = 10;
|
||||
|
||||
private static native boolean canSupportVirtualThreads();
|
||||
private static native int getAndResetStartedThreads();
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
@ -55,8 +56,6 @@ public class VirtualThreadStartTest {
|
||||
String arg = args.length == 2 ? args[1] : "";
|
||||
VirtualMachine vm = VirtualMachine.attach(String.valueOf(ProcessHandle.current().pid()));
|
||||
vm.loadAgentLibrary(AGENT_LIB, arg);
|
||||
} else {
|
||||
System.loadLibrary(AGENT_LIB);
|
||||
}
|
||||
getAndResetStartedThreads();
|
||||
|
||||
@ -64,11 +63,15 @@ public class VirtualThreadStartTest {
|
||||
Thread.ofVirtual().name("Tested-VT-" + i).start(() -> {}).join();
|
||||
}
|
||||
|
||||
// No VirtualThreadStart events are expected if can_support_virtual_threads is disabled.
|
||||
int expStartedThreads = canSupportVirtualThreads() ? THREAD_CNT : 0;
|
||||
int startedThreads = getAndResetStartedThreads();
|
||||
System.out.println("ThreadStart event count: " + startedThreads + ", expected: " + THREAD_CNT);
|
||||
if (startedThreads != THREAD_CNT) {
|
||||
|
||||
System.out.println("ThreadStart event count: " + startedThreads + ", expected: " + expStartedThreads);
|
||||
|
||||
if (startedThreads != expStartedThreads) {
|
||||
throw new RuntimeException("Failed: wrong ThreadStart count: " +
|
||||
startedThreads + " expected: " + THREAD_CNT);
|
||||
startedThreads + " expected: " + expStartedThreads);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
13
test/hotspot/jtreg/serviceability/jvmti/vthread/VirtualThreadStartTest/libVirtualThreadStartTest.cpp
13
test/hotspot/jtreg/serviceability/jvmti/vthread/VirtualThreadStartTest/libVirtualThreadStartTest.cpp
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -67,12 +67,18 @@ void JNICALL VirtualThreadStart(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread) {
|
||||
if (!can_support_vt_enabled) {
|
||||
fatal(jni, "Failed: expected ThreadStart instead of VirtualThreadStart event");
|
||||
}
|
||||
printf("VirtualThreadStart event: %s\n", tname);
|
||||
LOG("VirtualThreadStart event: %s\n", tname);
|
||||
started_thread_cnt++;
|
||||
}
|
||||
deallocate(jvmti, jni, (void*)tname);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_VirtualThreadStartTest_canSupportVirtualThreads(JNIEnv* jni, jclass clazz) {
|
||||
LOG("can_support_virtual_threads: %d\n", can_support_vt_enabled);
|
||||
return can_support_vt_enabled ? JNI_TRUE : JNI_FALSE;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_VirtualThreadStartTest_getAndResetStartedThreads(JNIEnv* jni, jclass clazz) {
|
||||
RawMonitorLocker agent_start_locker(jvmti, jni, agent_event_lock);
|
||||
@ -116,8 +122,7 @@ jint agent_init(JavaVM *jvm, char *options, void *reserved) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
}
|
||||
printf("agent_init: can_support_virtual_threads capability: %d\n",
|
||||
caps.can_support_virtual_threads);
|
||||
LOG("agent_init: can_support_virtual_threads: %d\n", caps.can_support_virtual_threads);
|
||||
|
||||
err = jvmti->SetEventCallbacks(&callbacks, (jint)sizeof(callbacks));
|
||||
if (err != JVMTI_ERROR_NONE) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user