diff --git a/src/hotspot/share/prims/jvmti.xml b/src/hotspot/share/prims/jvmti.xml
index add7d43ad3e..3bcf15466d7 100644
--- a/src/hotspot/share/prims/jvmti.xml
+++ b/src/hotspot/share/prims/jvmti.xml
@@ -8249,37 +8249,42 @@ class C2 extends C1 implements I2 {
nullptr
if unused
+ The platform thread owning this monitor, or nullptr
if owned
+ by a virtual thread or not owned
0
if owned by a virtual thread or not owned
0
+ if only virtual threads are waiting or no threads are waiting
waiter_count
waiting threads
+ The waiter_count
waiting platform threads
0
+ if only virtual threads are waiting to be notified or no threads are waiting
+ to be notified
notify_waiter_count
threads waiting to be notified
+ The notify_waiter_count
platform threads waiting to be notified
diff --git a/test/hotspot/jtreg/serviceability/jvmti/ObjectMonitorUsage/ObjectMonitorUsage.java b/test/hotspot/jtreg/serviceability/jvmti/ObjectMonitorUsage/ObjectMonitorUsage.java index bc9a0c5cabc..0d136cadef7 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/ObjectMonitorUsage/ObjectMonitorUsage.java +++ b/test/hotspot/jtreg/serviceability/jvmti/ObjectMonitorUsage/ObjectMonitorUsage.java @@ -114,6 +114,13 @@ public class ObjectMonitorUsage { throw new Error("Unexpected " + e); } } + static Thread expOwnerThread() { + return Thread.currentThread().isVirtual() ? null : Thread.currentThread(); + } + + static int expEntryCount() { + return Thread.currentThread().isVirtual() ? 0 : 1; + } /* Scenario #0: * - owning: 0 @@ -127,14 +134,18 @@ public class ObjectMonitorUsage { setTestedMonitor(lockCheck); Thread[] wThreads = startWaitingThreads(isVirtual); + final int expWaitingCount = isVirtual ? 0 : NUMBER_OF_WAITING_THREADS; + // The numbers below describe the testing scenario, not the expected results. + // The expected numbers are different for virtual threads because + // they are not supported by JVMTI GetObjectMonitorUsage. // entry count: 0 // count of threads waiting to enter: 0 // count of threads waiting to re-enter: 0 // count of threads waiting to be notified: NUMBER_OF_WAITING_THREADS check(lockCheck, null, 0, // no owner thread 0, // count of threads waiting to enter: 0 - NUMBER_OF_WAITING_THREADS); + expWaitingCount); synchronized (lockCheck) { lockCheck.notifyAll(); @@ -158,20 +169,30 @@ public class ObjectMonitorUsage { Thread[] eThreads = null; synchronized (lockCheck) { + // Virtual threads are not supported by GetObjectMonitorUsage. + // Correct the expected values for the virtual thread case. + int expEnteringCount = isVirtual ? 0 : NUMBER_OF_ENTERING_THREADS; + + // The numbers below describe the testing scenario, not the expected results. + // The expected numbers are different for virtual threads because + // they are not supported by JVMTI GetObjectMonitorUsage. // entry count: 1 // count of threads waiting to enter: 0 // count of threads waiting to re-enter: 0 // count of threads waiting to be notified: 0 - check(lockCheck, Thread.currentThread(), 1, 0, 0); + check(lockCheck, expOwnerThread(), expEntryCount(), 0, 0); eThreads = startEnteringThreads(isVirtual); + // The numbers below describe the testing scenario, not the expected results. + // The expected numbers are different for virtual threads because + // they are not supported by JVMTI GetObjectMonitorUsage. // entry count: 1 // count of threads waiting to enter: NUMBER_OF_ENTERING_THREADS // count of threads waiting to re-enter: 0 // count of threads waiting to be notified: 0 - check(lockCheck, Thread.currentThread(), 1, - NUMBER_OF_ENTERING_THREADS, + check(lockCheck, expOwnerThread(), expEntryCount(), + expEnteringCount, 0 /* count of threads waiting to be notified: 0 */); } @@ -195,15 +216,23 @@ public class ObjectMonitorUsage { Thread[] eThreads = null; synchronized (lockCheck) { + // Virtual threads are not supported by the GetObjectMonitorUsage. + // Correct the expected values for the virtual thread case. + int expEnteringCount = isVirtual ? 0 : NUMBER_OF_ENTERING_THREADS; + int expWaitingCount = isVirtual ? 0 : NUMBER_OF_WAITING_THREADS; + eThreads = startEnteringThreads(isVirtual); + // The numbers below describe the testing scenario, not the expected results. + // The expected numbers are different for virtual threads because + // they are not supported by JVMTI GetObjectMonitorUsage. // entry count: 1 // count of threads waiting to enter: NUMBER_OF_ENTERING_THREADS // count of threads waiting to re-enter: 0 // count of threads waiting to be notified: NUMBER_OF_WAITING_THREADS - check(lockCheck, Thread.currentThread(), 1, - NUMBER_OF_ENTERING_THREADS, - NUMBER_OF_WAITING_THREADS); + check(lockCheck, expOwnerThread(), expEntryCount(), + expEnteringCount, + expWaitingCount); lockCheck.notifyAll(); } @@ -234,35 +263,51 @@ public class ObjectMonitorUsage { Thread[] eThreads = null; synchronized (lockCheck) { + // Virtual threads are not supported by GetObjectMonitorUsage. + // Correct the expected values for the virtual thread case. + int expEnteringCount = isVirtual ? 0 : NUMBER_OF_ENTERING_THREADS; + int expWaitingCount = isVirtual ? 0 : NUMBER_OF_WAITING_THREADS; + + // The numbers below describe the testing scenario, not the expected results. + // The expected numbers are different for virtual threads because + // they are not supported by JVMTI GetObjectMonitorUsage. // entry count: 1 // count of threads waiting to enter: 0 // count of threads waiting to re-enter: 0 // count of threads waiting to be notified: NUMBER_OF_WAITING_THREADS - check(lockCheck, Thread.currentThread(), 1, + check(lockCheck, expOwnerThread(), expEntryCount(), 0, // number of threads waiting to enter or re-enter - NUMBER_OF_WAITING_THREADS); + expWaitingCount); eThreads = startEnteringThreads(isVirtual); + // The numbers below describe the testing scenario, not the expected results. + // The expected numbers are different for virtual threads because + // they are not supported by JVMTI GetObjectMonitorUsage. // entry count: 1 // count of threads waiting to enter: NUMBER_OF_ENTERING_THREADS // count of threads waiting to re-enter: 0 // count of threads waiting to be notified: NUMBER_OF_WAITING_THREADS - check(lockCheck, Thread.currentThread(), 1, - NUMBER_OF_ENTERING_THREADS, - NUMBER_OF_WAITING_THREADS); + check(lockCheck, expOwnerThread(), expEntryCount(), + expEnteringCount, + expWaitingCount); for (int i = 0; i < NUMBER_OF_WAITING_THREADS; i++) { + expEnteringCount = isVirtual ? 0 : NUMBER_OF_ENTERING_THREADS + i + 1; + expWaitingCount = isVirtual ? 0 : NUMBER_OF_WAITING_THREADS - i - 1; lockCheck.notify(); // notify waiting threads one by one // now the notified WaitingTask has to be blocked on the lockCheck re-enter + // The numbers below describe the testing scenario, not the expected results. + // The expected numbers are different for virtual threads because + // they are not supported by JVMTI GetObjectMonitorUsage. // entry count: 1 // count of threads waiting to enter: NUMBER_OF_ENTERING_THREADS // count of threads waiting to re-enter: i + 1 // count of threads waiting to be notified: NUMBER_OF_WAITING_THREADS - i - 1 - check(lockCheck, Thread.currentThread(), 1, - NUMBER_OF_ENTERING_THREADS + i + 1, - NUMBER_OF_WAITING_THREADS - i - 1); + check(lockCheck, expOwnerThread(), expEntryCount(), + expEnteringCount, + expWaitingCount); } } joinThreads(wThreads); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/entryCount/entrycount002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/entryCount/entrycount002.java index 7736eae1d2b..e5e8f4e8d80 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/entryCount/entrycount002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/entryCount/entrycount002.java @@ -197,8 +197,11 @@ public class entrycount002 { display("Checking entryCount for iteration : " + i); try { + // The lockRef.entryCount() is expected to return 0 if the owner thread is virtual. + int expEntryCount = mainThread.isVirtual() ? 0 : i; int entryCount = lockRef.entryCount(); - if (entryCount != i) { + + if (entryCount != expEntryCount) { exitCode = Consts.TEST_FAILED; complain("entry count method returned unexpected value : " + entryCount + "\n\t expected one : " + i); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/owningThread/owningthread002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/owningThread/owningthread002.java index 89d1b703310..83e0bbb8c05 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/owningThread/owningthread002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/owningThread/owningthread002.java @@ -200,6 +200,15 @@ public class owningthread002 { try { ThreadReference thread = lockRef.owningThread(); + // The lockRef.owningThread() is expected to return null if tested threads are virtual. + if (eventThread.isVirtual()) { + if (thread == null) { + display("expected null is returned` by owningThread method on virtual thread: " + eventThread.name()); + } else { + complain("owningThread returned ThreadReference of virtual thread instead of null: " + thread.name()); + } + continue; + } if (thread.name().indexOf(owningthread002a.threadNamePrefix) < 0) { exitCode = Consts.TEST_FAILED; complain("owningThread returned ThreadReference with unexpected name: " + thread.name()); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/waitingThreads/waitingthreads002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/waitingThreads/waitingthreads002.java index 356f78876aa..74bc41a34eb 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/waitingThreads/waitingthreads002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ObjectReference/waitingThreads/waitingthreads002.java @@ -122,6 +122,9 @@ public class waitingthreads002 { if (thread.name().indexOf(waitingthreads002a.threadNamePrefix) >= 0 && thread.status() == ThreadReference.THREAD_STATUS_MONITOR ) { waitingCount++; + // Virtual threads are not present in result returned by objRef.waitingThreads(). + if (!thread.isVirtual()) { + } } } } @@ -159,7 +162,9 @@ public class waitingthreads002 { objRef = (ObjectReference) debuggeeClass.getValue(debuggeeClass.fieldByName(fieldName)); try { List waitingThreads = objRef.waitingThreads(); - if (waitingThreads.size() != waitingthreads002a.threadCount) { + final boolean vthreadMode = "Virtual".equals(System.getProperty("test.thread.factory")); + final int expWaitingCount = vthreadMode ? 0 : waitingthreads002a.threadCount; + if (waitingThreads.size() != expWaitingCount) { exitStatus = Consts.TEST_FAILED; complain("waitingThreads method returned list with unexpected size for " + fieldName + "\n\t expected value : " + waitingthreads002a.threadCount + "; got one : " + waitingThreads.size()); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetObjectMonitorUsage/objmonusage001.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetObjectMonitorUsage/objmonusage001.java index 1ae3bf79e1c..c3c3cb31ebd 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetObjectMonitorUsage/objmonusage001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetObjectMonitorUsage/objmonusage001.java @@ -61,8 +61,16 @@ public class objmonusage001 { syncObject[i] = new Object(); runn[i] = new objmonusage001a(mainThread, i, syncObject[i]); } + // Virtual threads are not supported by GetObjectMonitorUsage. + // Correct the expected values if the test is executed with + // JTREG_TEST_THREAD_FACTORY=Virtual. + Thread expOwner = mainThread.isVirtual() ? null : mainThread; + int expEntryCount = mainThread.isVirtual() ? 0 : 1; for (int i = 0; i < NUMBER_OF_THREADS; i++) { + Thread expNotifyWaiter = runn[i].isVirtual() ? null : runn[i]; + int expNotifyWaitingCount = runn[i].isVirtual() ? 0 : 1; + synchronized (syncObject[i]) { runn[i].start(); try { @@ -92,8 +100,8 @@ public class objmonusage001 { // This is a stable verification point because the worker thread is in wait() // and is not notified and the main thread is doing the verification. // - check(NUMBER_OF_THREADS + i, syncObject[i], mainThread, 1, - null, 0, runn[i], 1); + check(NUMBER_OF_THREADS + i, syncObject[i], expOwner, expEntryCount, + null, 0, expNotifyWaiter, expNotifyWaitingCount); } // Check #3: @@ -117,7 +125,7 @@ public class objmonusage001 { // and is not notified and the main thread is doing the verification. // check((NUMBER_OF_THREADS * 2) + i, syncObject[i], null, 0, - null, 0, runn[i], 1); + null, 0, expNotifyWaiter, expNotifyWaitingCount); } for (int i = 0; i < NUMBER_OF_THREADS; i++) { @@ -147,6 +155,14 @@ class objmonusage001a extends Thread { } public void run() { + // Virtual threads are not supported by GetObjectMonitorUsage. + // Correct the expected values if the test is executed with + // JTREG_TEST_THREAD_FACTORY=Virtual. + Thread expOwner = this.isVirtual() ? null : this; + Thread expNotifyWaiter = mainThread.isVirtual() ? null : mainThread; + int expEntryCount = this.isVirtual() ? 0 : 1; + int expNotifyWaitingCount = mainThread.isVirtual() ? 0 : 1; + synchronized (syncObject) { // Check #1: // - owner == this_thread: @@ -166,8 +182,8 @@ class objmonusage001a extends Thread { // This is a stable verification point because the main thread is in wait() // and is not notified and this worker thread is doing the verification. // - objmonusage001.check(index, syncObject, this, 1, - null, 0, mainThread, 1); + objmonusage001.check(index, syncObject, expOwner, expEntryCount, + null, 0, expNotifyWaiter, expNotifyWaitingCount); syncObject.notify(); try { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetObjectMonitorUsage/objmonusage004.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetObjectMonitorUsage/objmonusage004.java index 37addef82d6..8d79a6011f5 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetObjectMonitorUsage/objmonusage004.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetObjectMonitorUsage/objmonusage004.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, 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 @@ -60,11 +60,23 @@ public class objmonusage004 { Thread currThread = Thread.currentThread(); ContendThread thr[] = new ContendThread[NUMBER_OF_THREADS]; synchronized (lockCheck) { + // Virtual threads are not supported by GetObjectMonitorUsage. + // Correct the expected values if the test is executed with + // JTREG_TEST_THREAD_FACTORY=Virtual. + Thread expOwner = currThread.isVirtual() ? null : currThread; + int expEntryCount = currThread.isVirtual() ? 0 : 2; + synchronized (lockCheck) { - check(lockCheck, currThread, 2, 0); + check(lockCheck, expOwner, expEntryCount, 0); } + expEntryCount = currThread.isVirtual() ? 0 : 1; + int expWaiterCount = 0; + for (int i = 0; i < NUMBER_OF_THREADS; i++) { thr[i] = new ContendThread(); + if (!thr[i].isVirtual()) { + expWaiterCount++; + } synchronized (lockStart) { thr[i].start(); try { @@ -74,7 +86,7 @@ public class objmonusage004 { throw new Error("Unexpected " + e); } } - check(lockCheck, currThread, 1, i + 1); + check(lockCheck, expOwner, expEntryCount, expWaiterCount); } }