On Wed, 1 May 2024 10:20:52 GMT, Serguei Spitsyn <sspit...@openjdk.org> wrote:

> The fix is to degrade virtual threads support in the JVM TI 
> `GetObjectMonitorUsage` function so that it is specified to only return an 
> owner when the owner is a platform thread. Also, virtual threads are not 
> listed in the both `waiters` and `notify_waiters` lists returned in the 
> `jvmtiMonitorUsage` structure. Java 19 re-specified a number of JVMTI 
> functions and events for virtual threads, we missed this one.
> 
> The main motivation for degrading it now is that the object monitor 
> implementation is being updated to allow virtual threads unmount while owning 
> monitors. It would add overhead to record monitor usage when 
> freezing/unmount, overhead that couldn't be tied to a JVMTI capability as the 
> capability can be enabled at any time.
> 
> `GetObjectMonitorUsage` was broken for 20+ years 
> ([8247972](https://bugs.openjdk.org/browse/JDK-8247972)) without bug reports 
> so it seems unlikely that the function is widely used. Degrading it to only 
> return an owner when the owner is a platform thread has no compatibility 
> impact for tooling that uses it in conjunction with `HotSpot` thread dumps or 
> `ThreadMXBean`.
> 
> One other point about `GetObjectMonitorUsage` is that it pre-dates 
> j.u.concurrent in Java 5 so it can't be used to get a full picture of the 
> lock usage in a program.
> 
> The specs of the impacted `JDWP ObjectReference.MonitorInfo` command and the 
> JDI `ObjectReference` `ownerThread()`, `waitingThreads()` and `entryCount()` 
> methods are updated to match the JVM TI spec.
> 
> Also, please, review the related CSR and Release Note:
> - CSR: [8331422](https://bugs.openjdk.org/browse/JDK-8331422): degrade 
> virtual thread support for GetObjectMonitorUsage
> - RN: [8331465](https://bugs.openjdk.org/browse/JDK-8331465): Release Note: 
> degrade virtual thread support for GetObjectMonitorUsage
> 
> Testing:
>  - tested impacted and updated tests locally
>  - tested with mach5 tiers 1-6

I've only looked at specs and tests so far. Still need to review the JVMTI code 
changes. I looked at the CSR too, but thought it best to just comment on the 
spec changes here.

src/hotspot/share/prims/jvmti.xml line 8259:

> 8257:           <jint/>
> 8258:           <description>
> 8259:             The number of times the owning platform thread has entered 
> the monitor

"the owning platform thread" doesn't really make sense if the monitor is owned 
by a virtual thread. You might want structure it more like the "owner" 
description above:


The number of times the platform thread owning this monitor has has entered it, 
or <code>0</code> if owned by a virtual thread or not owned

src/hotspot/share/prims/jvmti.xml line 8266:

> 8264:           <description>
> 8265:             The number of platform threads waiting to own this monitor,
> 8266:             or <code>0</code> if the monitor is owned by a virtual 
> thread or not owned

Be consistent with above descriptions. They don't say "if the monitor is owned 
by". They say "if owned by".

src/hotspot/share/prims/jvmti.xml line 8279:

> 8277:           <description>
> 8278:             The number of platform threads waiting to be notified by 
> this monitor,
> 8279:             or <code>0</code> if the monitor is owned by a virtual 
> thread or not owned

Same consistency issue as with `waiter_count`

src/java.se/share/data/jdwp/jdwp.spec line 1620:

> 1618:         )
> 1619:         (Reply
> 1620:             (threadObject owner "The platform thread owning this 
> monitor, or <code>nullptr</code> "

I don't think we should be introducing `<code>nullptr</code>` for just this one 
location. Please stick with `null` for now.

src/java.se/share/data/jdwp/jdwp.spec line 1621:

> 1619:         (Reply
> 1620:             (threadObject owner "The platform thread owning this 
> monitor, or <code>nullptr</code> "
> 1621:                                 "if owned` by a virtual thread or not 
> owned.")

You have a dangling back quote after "owned". This is showing up in the CSR too.

src/java.se/share/data/jdwp/jdwp.spec line 1622:

> 1620:             (threadObject owner "The platform thread owning this 
> monitor, or <code>nullptr</code> "
> 1621:                                 "if owned` by a virtual thread or not 
> owned.")
> 1622:             (int entryCount "The number of times the owning platform 
> thread has entered the monitor.")

See the comment I left for the JVMTI spec. We should be more complete in the 
explanation here, explaining how it is 0 for virtual threads.

src/jdk.jdi/share/classes/com/sun/jdi/ObjectReference.java line 348:

> 346:     /**
> 347:      * Returns a List containing a {@link ThreadReference} for
> 348:      * each platform thread currently waiting for this object's monitor.

You need to add "platform" a little below in the `@return` section.

src/jdk.jdi/share/classes/com/sun/jdi/ObjectReference.java line 369:

> 367: 
> 368:     /**
> 369:      * Returns an {@link ThreadReference} for the platform thread, if 
> any,

Pre-existing issue: It should be "a" not "an", but then in the `@return` 
section we are using "the", so maybe we should use similar wording here: 
`...the {@link ThreadReference} of the platform thread...`

test/hotspot/jtreg/serviceability/jvmti/ObjectMonitorUsage/ObjectMonitorUsage.java
 line 257:

> 255:             // Correct the expected values for the virtual thread case.
> 256:             int expEnteringCount = isVirtual ? 0 : 
> NUMBER_OF_ENTERING_THREADS;
> 257:             int expWaitingCount  = isVirtual ? 0 : 
> NUMBER_OF_WAITING_THREADS;

There are comments below that still reference NUMBER_OF_ENTERING_THREADS  and 
NUMBER_OF_WAITING_THREADS.

test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/waitingThreads/waitingthreads002.java
 line 167:

> 165:                     try {
> 166:                         List waitingThreads = objRef.waitingThreads();
> 167:                         if (waitingThreads.size() != expWaitingCount) {

I don't see the need for the expWaitingCount bookkeeping. Can't we just verify 
that size() is zero if we are using virtual threads? I guess maybe the reason 
you took this approach is because you don't know if the threads are going to be 
virtual or not until you check them. There is a way to find out, but it's not 
that pretty either:

    static final boolean vthreadMode = 
"Virtual".equals(System.getProperty("test.thread.factory"));

test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetObjectMonitorUsage/objmonusage001.java
 line 65:

> 63:         }
> 64:         // Virtual threads are not supported by the 
> GetObjectMonitorUsage. Correct
> 65:         // the expected values if the test is executed with 
> MainWrapper=virtual.

"MainWrapper" is not the proper terminology any more.  It's "Test Thread 
Factory" (JTREG_TEST_THREAD_FACTORY=Virtual).

test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetObjectMonitorUsage/objmonusage001.java
 line 158:

> 156:     public void run() {
> 157:         // Virtual threads are not supported by the 
> GetObjectMonitorUsage. Correct
> 158:         // the expected values if the test is executed with 
> MainWrapper=virtual.

"MainWrapper" again.

test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetObjectMonitorUsage/objmonusage004.java
 line 64:

> 62:         synchronized (lockCheck) {
> 63:             // Virtual threads are not supported by the 
> GetObjectMonitorUsage. Correct
> 64:             // the expected values if the test is executed with 
> MainWrapper=virtual.

"MainWrappe" again.

-------------

PR Review: https://git.openjdk.org/jdk/pull/19030#pullrequestreview-2034390826
PR Review Comment: https://git.openjdk.org/jdk/pull/19030#discussion_r1586784250
PR Review Comment: https://git.openjdk.org/jdk/pull/19030#discussion_r1586784280
PR Review Comment: https://git.openjdk.org/jdk/pull/19030#discussion_r1586792380
PR Review Comment: https://git.openjdk.org/jdk/pull/19030#discussion_r1586800777
PR Review Comment: https://git.openjdk.org/jdk/pull/19030#discussion_r1586802318
PR Review Comment: https://git.openjdk.org/jdk/pull/19030#discussion_r1586803324
PR Review Comment: https://git.openjdk.org/jdk/pull/19030#discussion_r1586806802
PR Review Comment: https://git.openjdk.org/jdk/pull/19030#discussion_r1586809854
PR Review Comment: https://git.openjdk.org/jdk/pull/19030#discussion_r1586833617
PR Review Comment: https://git.openjdk.org/jdk/pull/19030#discussion_r1586821719
PR Review Comment: https://git.openjdk.org/jdk/pull/19030#discussion_r1586824426
PR Review Comment: https://git.openjdk.org/jdk/pull/19030#discussion_r1586827714
PR Review Comment: https://git.openjdk.org/jdk/pull/19030#discussion_r1586829010

Reply via email to