Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8331422

degrade virtual thread support for GetObjectMonitorUsage

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 23
    • hotspot
    • None
    • behavioral
    • medium
    • Hide
      There is some compatibility risk involved. In JDK 19-22 virtual threads are supported by the JVM TI `GetObjectMonitorUsage`, JDWP `ObjectReferens.MonitorInfo` and ObjectReference methods: `waitingThreads()`, `owningThread()` and `entryCount()`. However, the `JetBrains` debugger does not depend on this functionality much and uses it for informational purpose only. This functionality was broken even before JVM TI was introduced and the tools developers never complained about it. There is a plan to deprecate this set of JPDA API's but it is for separate and later decision. A Release Note is planned.
      Show
      There is some compatibility risk involved. In JDK 19-22 virtual threads are supported by the JVM TI `GetObjectMonitorUsage`, JDWP `ObjectReferens.MonitorInfo` and ObjectReference methods: `waitingThreads()`, `owningThread()` and `entryCount()`. However, the `JetBrains` debugger does not depend on this functionality much and uses it for informational purpose only. This functionality was broken even before JVM TI was introduced and the tools developers never complained about it. There is a plan to deprecate this set of JPDA API's but it is for separate and later decision. A Release Note is planned.
    • Java API, Other
    • SE

      Summary

      Degrade virtual thread support for JVMTI GetObjectMonitorUsage and its JDWP/JDI counterparts:

      • JDWP ObjectReference.MonitorInfo command
      • JDI ObjectReference methods: waitingThreads(), owningThread() and entryCount()

      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

            sspitsyn Serguei Spitsyn
            alanb Alan Bateman
            Alan Bateman, Daniel Daugherty
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: