diff --git a/src/hotspot/share/prims/jvmti.xml b/src/hotspot/share/prims/jvmti.xml
index 67b49786b8e..152f72ff7a2 100644
--- a/src/hotspot/share/prims/jvmti.xml
+++ b/src/hotspot/share/prims/jvmti.xml
@@ -9697,6 +9697,7 @@ myInit() {
+
@@ -12249,6 +12250,8 @@ myInit() {
+
+
@@ -12937,16 +12940,10 @@ myInit() {
A thread start event is generated by a new thread before its initial
method executes.
- This event is generated by platform threads. It is also generated by
- virtual threads when the capability
-
- can_support_virtual_threads 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.
- If the capability can_support_virtual_threads is enabled then
- this event is not generated by virtual threads. Agents with support for
- virtual threads can enable
+ Agents with the can_support_virtual_threads capability
+ can enable the event
to be notified by newly started virtual threads.
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.
- This event is generated by platform threads. It is also generated by
- virtual threads when the capability
-
- can_support_virtual_threads 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.
- If the capability can_support_virtual_threads is enabled then
- this event is not generated by virtual threads. Agents with support for
- virtual threads can enable
+ Agents with the can_support_virtual_threads capability
+ can enable the event
to be notified by terminating virtual threads.
A platform thread may be listed in the array returned by
diff --git a/src/hotspot/share/prims/jvmtiExport.cpp b/src/hotspot/share/prims/jvmtiExport.cpp
index e4a0ccd8796..0dd00937d1b 100644
--- a/src/hotspot/share/prims/jvmtiExport.cpp
+++ b/src/hotspot/share/prims/jvmtiExport.cpp
@@ -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;
}
diff --git a/src/hotspot/share/prims/jvmtiThreadState.cpp b/src/hotspot/share/prims/jvmtiThreadState.cpp
index 40168637d79..651b65e2f33 100644
--- a/src/hotspot/share/prims/jvmtiThreadState.cpp
+++ b/src/hotspot/share/prims/jvmtiThreadState.cpp
@@ -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);
diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp
index 23eb62bf06d..a28f8bba62f 100644
--- a/src/hotspot/share/runtime/globals.hpp
+++ b/src/hotspot/share/runtime/globals.hpp
@@ -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)") \
diff --git a/test/hotspot/jtreg/serviceability/jvmti/vthread/VirtualThreadStartTest/VirtualThreadStartTest.java b/test/hotspot/jtreg/serviceability/jvmti/vthread/VirtualThreadStartTest/VirtualThreadStartTest.java
index 79a6187a15c..e571501eea6 100644
--- a/test/hotspot/jtreg/serviceability/jvmti/vthread/VirtualThreadStartTest/VirtualThreadStartTest.java
+++ b/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);
}
}
}
diff --git a/test/hotspot/jtreg/serviceability/jvmti/vthread/VirtualThreadStartTest/libVirtualThreadStartTest.cpp b/test/hotspot/jtreg/serviceability/jvmti/vthread/VirtualThreadStartTest/libVirtualThreadStartTest.cpp
index 73b122cb457..b4eefa992ef 100644
--- a/test/hotspot/jtreg/serviceability/jvmti/vthread/VirtualThreadStartTest/libVirtualThreadStartTest.cpp
+++ b/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) {