Summary
Degrade virtual thread support for JVMTI GetObjectMonitorUsage
and its JDWP/JDI counterparts:
- JDWP
ObjectReference.MonitorInfo
command - JDI
ObjectReference
methods:waitingThreads()
,owningThread()
andentryCount()
Problem
The object monitor implementation is being updated to allow virtual threads to be unmounted while owning monitors. It would add overhead to record monitor usage when freezing/unmounting, overhead that couldn't be tied to a JVMTI capability as the capability can be enabled at any time.
Solution
The proposed solution is to degrade virtual threads support for API's listed in the Summary, so that the information is not provided for virtual threads involved into the monitor locking mechanism.
Specification
1. The JVMTI GetObjecMonitorUsage spec changes are for the returned structure. The description of the fields in the jvmtiMonitorUsage
structure (the ObjectMonitor
usage info) are changed as below:
% git diff src/hotspot/share/prims/jvmti.xml
@@ -8247,41 +8247,46 @@
<synopsis>Get Object Monitor Usage</synopsis>
<typedef id="jvmtiMonitorUsage" label="Object monitor usage information">
<field id="owner">
<jthread/>
<description>
- The thread owning this monitor, or <code>nullptr</code> if unused
+ The platform thread owning this monitor, or <code>nullptr</code> if owned
+ by a virtual thread or not owned
</description>
</field>
<field id="entry_count">
<jint/>
<description>
- The number of times the owning thread has entered the monitor
+ The number of times the platform thread owning this monitor has entered it,
+ or <code>0</code> if owned by a virtual thread or not owned
</description>
</field>
<field id="waiter_count">
<jint/>
<description>
- The number of threads waiting to own this monitor
+ The number of platform threads waiting to own this monitor, or <code>0</code>
+ if only virtual threads are waiting or no threads are waiting
</description>
</field>
<field id="waiters">
<allocfieldbuf><jthread/></allocfieldbuf>
<description>
- The <code>waiter_count</code> waiting threads
+ The <code>waiter_count</code> waiting platform threads
</description>
</field>
<field id="notify_waiter_count">
<jint/>
<description>
- The number of threads waiting to be notified by this monitor
+ The number of platform threads waiting to own this monitor, or <code>0</code>
+ if only virtual threads are waiting to be notified or no threads are waiting
+ to be notified
</description>
</field>
<field id="notify_waiters">
<allocfieldbuf><jthread/></allocfieldbuf>
<description>
- The <code>notify_waiter_count</code> threads waiting to be notified
+ The <code>notify_waiter_count</code> platform threads waiting to be notified
</description>
</field>
</typedef>
<description>
Get information about the object's monitor.
@@ -8285,10 +8290,16 @@
</typedef>
<description>
Get information about the object's monitor.
The fields of the <functionlink id="jvmtiMonitorUsage"></functionlink> structure
are filled in with information about usage of the monitor.
+ <p/>
+ <b> This function does not support getting information about an object's monitor
+ when it is owned by a virtual thread. It also does not support returning a
+ reference to virtual threads that are waiting to own a monitor or waiting to
+ be notified.
+ </b>
<todo>
Decide and then clarify suspend requirements.
</todo>
</description>
<origin>jvmdi</origin>
2. The JDWP ObjectReference.MonitorInfo
command spec diff is:
% git diff src/java.se/share/data/jdwp/jdwp.spec
diff --git a/src/java.se/share/data/jdwp/jdwp.spec b/src/java.se/share/data/jdwp/jdwp.spec
index df23a602b13..347c118e234 100644
--- a/src/java.se/share/data/jdwp/jdwp.spec
+++ b/src/java.se/share/data/jdwp/jdwp.spec
@@ -1615,15 +1615,18 @@
"<a href=\"#JDWP_VirtualMachine_CapabilitiesNew\">CapabilitiesNew</a>."
(Out
(object object "The object ID")
)
(Reply
- (threadObject owner "The monitor owner, or null if it is not currently owned.")
- (int entryCount "The number of times the monitor has been entered.")
- (Repeat waiters "The total number of threads that are waiting to enter or re-enter "
- "the monitor, or waiting to be notified by the monitor."
- (threadObject thread "A thread waiting for this monitor.")
+ (threadObject owner "The platform thread owning this monitor, or null "
+ "if owned by a virtual thread or not owned.")
+ (int entryCount "The number of times the owning platform thread has entered the monitor, "
+ "or 0 if owned by a virtual thread or not owned.")
+ (Repeat waiters "The total number of platform threads that are waiting to enter or re-enter "
+ "the monitor, or waiting to be notified by the monitor, or 0 if "
+ "only virtual threads are waiting or no threads are waiting."
+ (threadObject thread "A platform thread waiting for this monitor.")
)
)
(ErrorSet
(Error INVALID_OBJECT)
(Error NOT_IMPLEMENTED)
3. The JDI ObjectReference
spec diff is:
% git diff src/jdk.jdi/share/classes/com/sun/jdi/ObjectReference.java
diff --git a/src/jdk.jdi/share/classes/com/sun/jdi/ObjectReference.java b/src/jdk.jdi/share/classes/com/sun/jdi/ObjectReference.java
index dbcf77d3e39..3f3490e84cd 100644
--- a/src/jdk.jdi/share/classes/com/sun/jdi/ObjectReference.java
+++ b/src/jdk.jdi/share/classes/com/sun/jdi/ObjectReference.java
@@ -343,11 +343,11 @@
*/
long uniqueID();
/**
* Returns a List containing a {@link ThreadReference} for
- * each thread currently waiting for this object's monitor.
+ * each platform thread currently waiting for this object's monitor.
* See {@link ThreadReference#currentContendedMonitor} for
* information about when a thread is considered to be waiting
* for a monitor.
* <p>
* Not all target VMs support this operation. See
@@ -353,11 +353,12 @@
* Not all target VMs support this operation. See
* {@link VirtualMachine#canGetMonitorInfo} to determine if the
* operation is supported.
*
* @return a List of {@link ThreadReference} objects. The list
- * has zero length if no threads are waiting for the monitor.
+ * has zero length if no threads are waiting for the monitor,
+ * or only virtual threads are waiting for the monitor.
* @throws java.lang.UnsupportedOperationException if the
* target VM does not support this operation.
* @throws IncompatibleThreadStateException if any
* waiting thread is not suspended
* in the target VM
@@ -364,11 +365,11 @@
*/
List<ThreadReference> waitingThreads()
throws IncompatibleThreadStateException;
/**
- * Returns an {@link ThreadReference} for the thread, if any,
+ * Returns an {@link ThreadReference} for the platform thread, if any,
* which currently owns this object's monitor.
* See {@link ThreadReference#ownedMonitors} for a definition
* of ownership.
* <p>
* Not all target VMs support this operation. See
@@ -373,12 +374,13 @@
* <p>
* Not all target VMs support this operation. See
* {@link VirtualMachine#canGetMonitorInfo} to determine if the
* operation is supported.
*
- * @return the {@link ThreadReference} which currently owns the
- * monitor, or null if it is unowned.
+ * @return the {@link ThreadReference} of the platform thread which
+ * currently owns the monitor, or null if the monitor is owned
+ * by a virtual thread or not owned.
*
* @throws java.lang.UnsupportedOperationException if the
* target VM does not support this operation.
* @throws IncompatibleThreadStateException if the owning thread is
* not suspended in the target VM
@@ -384,12 +386,13 @@
* not suspended in the target VM
*/
ThreadReference owningThread() throws IncompatibleThreadStateException;
/**
- * Returns the number times this object's monitor has been
- * entered by the current owning thread.
+ * Returns the number of times this object's monitor has been entered by
+ * the current owning thread if the owning thread is platform thread;
+ * Returns 0 if not owned by a platform thread.
* See {@link ThreadReference#ownedMonitors} for a definition
* of ownership.
* <p>
* Not all target VMs support this operation. See
* {@link VirtualMachine#canGetMonitorInfo} to determine if the
- csr of
-
JDK-8328083 degrade virtual thread support for GetObjectMonitorUsage
- Resolved