From 32b75fc71b4f2bf7866f97e85c422e0004bbaf6a Mon Sep 17 00:00:00 2001 From: Yasumasa Suenaga Date: Thu, 9 Oct 2025 23:05:09 +0900 Subject: [PATCH 01/11] 8369505: jhsdb jstack --mixed cannot handle continuation stub on Linux AMD64 --- .../share/runtime/continuationEntry.hpp | 1 + src/hotspot/share/runtime/vmStructs.cpp | 5 +- .../sun/jvm/hotspot/code/CodeBlob.java | 2 + .../hotspot/runtime/ContinuationEntry.java | 63 +++++++++++++++++++ .../sun/jvm/hotspot/runtime/JavaThread.java | 6 ++ .../sun/jvm/hotspot/runtime/x86/X86Frame.java | 18 +++++- 6 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ContinuationEntry.java diff --git a/src/hotspot/share/runtime/continuationEntry.hpp b/src/hotspot/share/runtime/continuationEntry.hpp index 8361f2f912be6..490293f5b118f 100644 --- a/src/hotspot/share/runtime/continuationEntry.hpp +++ b/src/hotspot/share/runtime/continuationEntry.hpp @@ -39,6 +39,7 @@ class RegisterMap; // Metadata stored in the continuation entry frame class ContinuationEntry { + friend class VMStructs; friend class JVMCIVMStructs; ContinuationEntryPD _pd; #ifdef ASSERT diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index dee0a5d4eb7d4..8dc4b660f9133 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -616,6 +616,7 @@ nonstatic_field(JavaThread, _active_handles, JNIHandleBlock*) \ nonstatic_field(JavaThread, _monitor_owner_id, int64_t) \ volatile_nonstatic_field(JavaThread, _terminated, JavaThread::TerminatedTypes) \ + nonstatic_field(JavaThread, _cont_entry, ContinuationEntry*) \ nonstatic_field(Thread, _osthread, OSThread*) \ \ /************/ \ @@ -796,7 +797,8 @@ nonstatic_field(Mutex, _name, const char*) \ static_field(Mutex, _mutex_array, Mutex**) \ static_field(Mutex, _num_mutex, int) \ - volatile_nonstatic_field(Mutex, _owner, Thread*) + volatile_nonstatic_field(Mutex, _owner, Thread*) \ + static_field(ContinuationEntry, _return_pc, address) //-------------------------------------------------------------------------------- // VM_TYPES @@ -1270,6 +1272,7 @@ declare_toplevel_type(FileMapHeader) \ declare_toplevel_type(CDSFileMapRegion) \ declare_toplevel_type(UpcallStub::FrameData) \ + declare_toplevel_type(ContinuationEntry) \ \ /************/ \ /* GC types */ \ diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/CodeBlob.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/CodeBlob.java index 20c5fabf8bc95..12469efc67e43 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/CodeBlob.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/CodeBlob.java @@ -180,6 +180,8 @@ public ImmutableOopMapSet getOopMaps() { public boolean isUpcallStub() { return getKind() == UpcallKind; } + public boolean isContinuationStub() { return getName().equals("StubRoutines (continuation stubs)"); } + public boolean isJavaMethod() { return false; } public boolean isNativeMethod() { return false; } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ContinuationEntry.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ContinuationEntry.java new file mode 100644 index 0000000000000..73152bdee8421 --- /dev/null +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ContinuationEntry.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, NTT DATA. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.runtime; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.types.*; + + +public class ContinuationEntry extends VMObject { + private static long size; + private static Address returnPC; + + static { + VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase())); + } + + private static synchronized void initialize(TypeDataBase db) throws WrongTypeException { + Type type = db.lookupType("ContinuationEntry"); + size = type.getSize(); + returnPC = type.getAddressField("_return_pc").getValue(); + } + + public ContinuationEntry(Address addr) { + super(addr); + } + + public Address getEntryPC() { + return returnPC; + } + + public Address getEntrySP(){ + return this.getAddress(); + } + + public Address getEntryFP(){ + return this.getAddress().addOffsetTo(size); + } + +} diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThread.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThread.java index d92f464f0d2f6..826b5cecfd568 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThread.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThread.java @@ -47,6 +47,7 @@ public class JavaThread extends Thread { private static AddressField stackBaseField; private static CIntegerField stackSizeField; private static CIntegerField terminatedField; + private static AddressField contEntryField; private static AddressField activeHandlesField; private static CIntegerField monitorOwnerIDField; private static long oopPtrSize; @@ -95,6 +96,7 @@ private static synchronized void initialize(TypeDataBase db) { stackBaseField = type.getAddressField("_stack_base"); stackSizeField = type.getCIntegerField("_stack_size"); terminatedField = type.getCIntegerField("_terminated"); + contEntryField = type.getAddressField("_cont_entry"); activeHandlesField = type.getAddressField("_active_handles"); monitorOwnerIDField = type.getCIntegerField("_monitor_owner_id"); @@ -340,6 +342,10 @@ public int getTerminated() { return (int) terminatedField.getValue(addr); } + public ContinuationEntry getContEntry() { + return VMObjectFactory.newObject(ContinuationEntry.class, contEntryField.getValue(addr)); + } + /** Gets the Java-side thread object for this JavaThread */ public Oop getThreadObj() { Oop obj = null; diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java index 3ee4f0a815892..bad828f9d47f0 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java @@ -270,7 +270,13 @@ public Frame sender(RegisterMap regMap, CodeBlob cb) { } if (cb != null) { - return cb.isUpcallStub() ? senderForUpcallStub(map, (UpcallStub)cb) : senderForCompiledFrame(map, cb); + if (cb.isUpcallStub()) { + senderForUpcallStub(map, (UpcallStub)cb); + } else if (cb.isContinuationStub()) { + return senderForContinuationStub(map, cb); + } else { + return senderForCompiledFrame(map, cb); + } } // Must be native-compiled frame, i.e. the marshaling code for native @@ -356,6 +362,16 @@ private void updateMapWithSavedLink(RegisterMap map, Address savedFPAddr) { map.setLocation(rbp, savedFPAddr); } + private Frame senderForContinuationStub(X86RegisterMap map, CodeBlob cb) { + var contEntry = map.getThread().getContEntry(); + + Address senderSP = contEntry.getEntrySP(); + Address senderPC = contEntry.getEntryPC(); + Address senderFP = contEntry.getEntryFP(); + + return new X86Frame(senderSP, senderFP, senderPC); + } + private Frame senderForCompiledFrame(X86RegisterMap map, CodeBlob cb) { if (DEBUG) { System.out.println("senderForCompiledFrame"); From d2a80f566318e1399e43ffdaf7d6aae6a4b4f3b2 Mon Sep 17 00:00:00 2001 From: Yasumasa Suenaga Date: Sat, 11 Oct 2025 12:19:49 +0900 Subject: [PATCH 02/11] Fix trivial bug --- .../share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java index bad828f9d47f0..2d972d3df176c 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java @@ -271,7 +271,7 @@ public Frame sender(RegisterMap regMap, CodeBlob cb) { if (cb != null) { if (cb.isUpcallStub()) { - senderForUpcallStub(map, (UpcallStub)cb); + return senderForUpcallStub(map, (UpcallStub)cb); } else if (cb.isContinuationStub()) { return senderForContinuationStub(map, cb); } else { From 2f3eee62775cf2086d37cc70d054c4c842afdef2 Mon Sep 17 00:00:00 2001 From: Yasumasa Suenaga Date: Sat, 11 Oct 2025 22:47:07 +0900 Subject: [PATCH 03/11] Fix for AArch64 --- .../hotspot/runtime/aarch64/AARCH64Frame.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/aarch64/AARCH64Frame.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/aarch64/AARCH64Frame.java index a5aa7ce440506..5ae4cb703b331 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/aarch64/AARCH64Frame.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/aarch64/AARCH64Frame.java @@ -270,7 +270,13 @@ public Frame sender(RegisterMap regMap, CodeBlob cb) { } if (cb != null) { - return cb.isUpcallStub() ? senderForUpcallStub(map, (UpcallStub)cb) : senderForCompiledFrame(map, cb); + if (cb.isUpcallStub()) { + return senderForUpcallStub(map, (UpcallStub)cb); + } else if (cb.isContinuationStub()) { + return senderForContinuationStub(map, cb); + } else { + return senderForCompiledFrame(map, cb); + } } // Must be native-compiled frame, i.e. the marshaling code for native @@ -356,6 +362,16 @@ private void updateMapWithSavedLink(RegisterMap map, Address savedFPAddr) { map.setLocation(fp, savedFPAddr); } + private Frame senderForContinuationStub(AARCH64RegisterMap map, CodeBlob cb) { + var contEntry = map.getThread().getContEntry(); + + Address senderSP = contEntry.getEntrySP(); + Address senderPC = contEntry.getEntryPC(); + Address senderFP = contEntry.getEntryFP(); + + return new AARCH64Frame(senderSP, senderFP, senderPC); + } + private Frame senderForCompiledFrame(AARCH64RegisterMap map, CodeBlob cb) { if (DEBUG) { System.out.println("senderForCompiledFrame"); From 915fca8d06cef2b6c10ebbc417733b07d0143fc5 Mon Sep 17 00:00:00 2001 From: Yasumasa Suenaga Date: Sat, 11 Oct 2025 23:52:47 +0900 Subject: [PATCH 04/11] Add testcase --- .../sa/LingeredAppWithVirtualThread.java | 74 ++++++++++++++++ ...TestJhsdbJstackMixedWithVirtualThread.java | 85 +++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 test/hotspot/jtreg/serviceability/sa/LingeredAppWithVirtualThread.java create mode 100644 test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixedWithVirtualThread.java diff --git a/test/hotspot/jtreg/serviceability/sa/LingeredAppWithVirtualThread.java b/test/hotspot/jtreg/serviceability/sa/LingeredAppWithVirtualThread.java new file mode 100644 index 0000000000000..0ac303ae7b2a6 --- /dev/null +++ b/test/hotspot/jtreg/serviceability/sa/LingeredAppWithVirtualThread.java @@ -0,0 +1,74 @@ + +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, NTT DATA + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.invoke.MethodHandle; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.Linker; +import java.lang.foreign.ValueLayout; +import java.util.concurrent.CountDownLatch; + +import jdk.test.lib.apps.LingeredApp; + +public class LingeredAppWithVirtualThread extends LingeredApp implements Runnable { + + private static final String THREAD_NAME = "target thread"; + + private static final MethodHandle hndSleep; + + private static final CountDownLatch signal = new CountDownLatch(1); + + static { + var linker = Linker.nativeLinker(); + var func = linker.defaultLookup() + .find("sleep") + .get(); + var desc = FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.JAVA_INT); + hndSleep = linker.downcallHandle(func, desc); + } + + @Override + public void run() { + signal.countDown(); + Thread.yield(); + try { + hndSleep.invoke(3600); + } catch(Throwable t) { + throw new RuntimeException(t); + } + } + + public static void main(String[] args) { + try { + Thread.ofVirtual() + .name(THREAD_NAME) + .start(new LingeredAppWithVirtualThread()); + + signal.await(); + LingeredApp.main(args); + } catch(Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixedWithVirtualThread.java b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixedWithVirtualThread.java new file mode 100644 index 0000000000000..2565fdf905643 --- /dev/null +++ b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixedWithVirtualThread.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, NTT DATA + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import jdk.test.lib.JDKToolLauncher; +import jdk.test.lib.SA.SATestUtils; +import jdk.test.lib.Utils; +import jdk.test.lib.apps.LingeredApp; +import jdk.test.lib.process.OutputAnalyzer; + +/** + * @test + * @bug 8369505 + * @requires (os.family == "linux") & (vm.hasSA) + * @requires (os.arch == "amd64" | os.arch == "aarch64") + * @library /test/lib + * @run driver TestJhsdbJstackMixedWithVirtualThread + */ +public class TestJhsdbJstackMixedWithVirtualThread { + + private static void runJstackMixed(LingeredApp app) throws Exception { + JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb"); + launcher.addVMArgs(Utils.getTestJavaOpts()); + launcher.addToolArg("jstack"); + launcher.addToolArg("--mixed"); + launcher.addToolArg("--pid"); + launcher.addToolArg(Long.toString(app.getPid())); + + ProcessBuilder pb = SATestUtils.createProcessBuilder(launcher); + Process jhsdb = pb.start(); + OutputAnalyzer out = new OutputAnalyzer(jhsdb); + + jhsdb.waitFor(); + + System.out.println(out.getStdout()); + System.err.println(out.getStderr()); + + out.stderrShouldBeEmptyIgnoreDeprecatedWarnings(); + out.shouldContain(""); + out.shouldNotContain(" return entry points"); + } + + public static void main(String... args) throws Exception { + SATestUtils.skipIfCannotAttach(); // throws SkippedException if attach not expected to work. + LingeredApp app = null; + + try { + app = new LingeredAppWithVirtualThread(); + LingeredApp.startApp(app); + System.out.println("Started LingeredApp with pid " + app.getPid()); + runJstackMixed(app); + System.out.println("Test Completed"); + } catch (Throwable e) { + e.printStackTrace(); + throw e; + } finally { + LingeredApp.stopApp(app); + } + } +} From 57294d7c1f85469a54f5ec6e0376fe9ebfd4334f Mon Sep 17 00:00:00 2001 From: Yasumasa Suenaga Date: Mon, 13 Oct 2025 12:03:30 +0900 Subject: [PATCH 05/11] Apply changes to RISC-V code --- .../hotspot/runtime/riscv64/RISCV64Frame.java | 18 +++++++++++++++++- .../TestJhsdbJstackMixedWithVirtualThread.java | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/riscv64/RISCV64Frame.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/riscv64/RISCV64Frame.java index e02e056f028cd..44c8f4c679ca8 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/riscv64/RISCV64Frame.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/riscv64/RISCV64Frame.java @@ -262,7 +262,13 @@ public Frame sender(RegisterMap regMap, CodeBlob cb) { } if (cb != null) { - return cb.isUpcallStub() ? senderForUpcallStub(map, (UpcallStub)cb) : senderForCompiledFrame(map, cb); + if (cb.isUpcallStub()) { + return senderForUpcallStub(map, (UpcallStub)cb); + } else if (cb.isContinuationStub()) { + return senderForContinuationStub(map, cb); + } else { + return senderForCompiledFrame(map, cb); + } } // Must be native-compiled frame, i.e. the marshaling code for native @@ -348,6 +354,16 @@ private void updateMapWithSavedLink(RegisterMap map, Address savedFPAddr) { map.setLocation(fp, savedFPAddr); } + private Frame senderForContinuationStub(RISCV64RegisterMap map, CodeBlob cb) { + var contEntry = map.getThread().getContEntry(); + + Address senderSP = contEntry.getEntrySP(); + Address senderPC = contEntry.getEntryPC(); + Address senderFP = contEntry.getEntryFP(); + + return new RISCV64Frame(senderSP, senderFP, senderPC); + } + private Frame senderForCompiledFrame(RISCV64RegisterMap map, CodeBlob cb) { if (DEBUG) { System.out.println("senderForCompiledFrame"); diff --git a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixedWithVirtualThread.java b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixedWithVirtualThread.java index 2565fdf905643..9b4fa067dc076 100644 --- a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixedWithVirtualThread.java +++ b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixedWithVirtualThread.java @@ -37,7 +37,7 @@ * @test * @bug 8369505 * @requires (os.family == "linux") & (vm.hasSA) - * @requires (os.arch == "amd64" | os.arch == "aarch64") + * @requires (os.arch == "amd64" | os.arch == "aarch64" | os.arch == "riscv64") * @library /test/lib * @run driver TestJhsdbJstackMixedWithVirtualThread */ From 25d883f7ef4ff7daaa77fbf1d5e73094eeff4e5a Mon Sep 17 00:00:00 2001 From: Yasumasa Suenaga Date: Mon, 13 Oct 2025 17:28:00 +0900 Subject: [PATCH 06/11] Update testcase --- .../sa/LingeredAppWithVirtualThread.java | 19 ++++++++++++++----- ...TestJhsdbJstackMixedWithVirtualThread.java | 5 +---- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/sa/LingeredAppWithVirtualThread.java b/test/hotspot/jtreg/serviceability/sa/LingeredAppWithVirtualThread.java index 0ac303ae7b2a6..771a94fac235c 100644 --- a/test/hotspot/jtreg/serviceability/sa/LingeredAppWithVirtualThread.java +++ b/test/hotspot/jtreg/serviceability/sa/LingeredAppWithVirtualThread.java @@ -24,8 +24,11 @@ */ import java.lang.invoke.MethodHandle; +import java.lang.foreign.Arena; import java.lang.foreign.FunctionDescriptor; import java.lang.foreign.Linker; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SymbolLookup; import java.lang.foreign.ValueLayout; import java.util.concurrent.CountDownLatch; @@ -40,12 +43,18 @@ public class LingeredAppWithVirtualThread extends LingeredApp implements Runnabl private static final CountDownLatch signal = new CountDownLatch(1); static { - var linker = Linker.nativeLinker(); - var func = linker.defaultLookup() - .find("sleep") - .get(); + MemorySegment func; + if (System.getProperty("os.name").startsWith("Windows")) { + func = SymbolLookup.libraryLookup("Kernel32", Arena.global()) + .findOrThrow("Sleep"); + } else { + func = Linker.nativeLinker() + .defaultLookup() + .findOrThrow("sleep"); + } + var desc = FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.JAVA_INT); - hndSleep = linker.downcallHandle(func, desc); + hndSleep = Linker.nativeLinker().downcallHandle(func, desc); } @Override diff --git a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixedWithVirtualThread.java b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixedWithVirtualThread.java index 9b4fa067dc076..798afa2d516aa 100644 --- a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixedWithVirtualThread.java +++ b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixedWithVirtualThread.java @@ -36,7 +36,7 @@ /** * @test * @bug 8369505 - * @requires (os.family == "linux") & (vm.hasSA) + * @requires vm.hasSA * @requires (os.arch == "amd64" | os.arch == "aarch64" | os.arch == "riscv64") * @library /test/lib * @run driver TestJhsdbJstackMixedWithVirtualThread @@ -47,7 +47,6 @@ private static void runJstackMixed(LingeredApp app) throws Exception { JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb"); launcher.addVMArgs(Utils.getTestJavaOpts()); launcher.addToolArg("jstack"); - launcher.addToolArg("--mixed"); launcher.addToolArg("--pid"); launcher.addToolArg(Long.toString(app.getPid())); @@ -61,8 +60,6 @@ private static void runJstackMixed(LingeredApp app) throws Exception { System.err.println(out.getStderr()); out.stderrShouldBeEmptyIgnoreDeprecatedWarnings(); - out.shouldContain(""); - out.shouldNotContain(" return entry points"); } public static void main(String... args) throws Exception { From 04d930993b64782bf7c1ae1dba815c0cb405e90d Mon Sep 17 00:00:00 2001 From: Yasumasa Suenaga Date: Tue, 14 Oct 2025 09:52:49 +0900 Subject: [PATCH 07/11] Update testcase --- ...alThread.java => TestJhsdbJstackWithVirtualThread.java} | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) rename test/hotspot/jtreg/serviceability/sa/{TestJhsdbJstackMixedWithVirtualThread.java => TestJhsdbJstackWithVirtualThread.java} (91%) diff --git a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixedWithVirtualThread.java b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackWithVirtualThread.java similarity index 91% rename from test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixedWithVirtualThread.java rename to test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackWithVirtualThread.java index 798afa2d516aa..0b2d5b983a8a8 100644 --- a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackMixedWithVirtualThread.java +++ b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackWithVirtualThread.java @@ -37,11 +37,11 @@ * @test * @bug 8369505 * @requires vm.hasSA - * @requires (os.arch == "amd64" | os.arch == "aarch64" | os.arch == "riscv64") + * @requires (os.arch == "amd64" | os.arch == "x86_64" | os.arch == "aarch64" | os.arch == "riscv64") * @library /test/lib - * @run driver TestJhsdbJstackMixedWithVirtualThread + * @run driver TestJhsdbJstackWithVirtualThread */ -public class TestJhsdbJstackMixedWithVirtualThread { +public class TestJhsdbJstackWithVirtualThread { private static void runJstackMixed(LingeredApp app) throws Exception { JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb"); @@ -60,6 +60,7 @@ private static void runJstackMixed(LingeredApp app) throws Exception { System.err.println(out.getStderr()); out.stderrShouldBeEmptyIgnoreDeprecatedWarnings(); + out.shouldNotContain("must have non-zero frame size"); } public static void main(String... args) throws Exception { From e8090fafd2087c6a3cf9d8a62935ee10a70f2154 Mon Sep 17 00:00:00 2001 From: Yasumasa Suenaga Date: Tue, 14 Oct 2025 10:58:11 +0900 Subject: [PATCH 08/11] Switch argument of s(S)leep between Windows API and POSIX function --- .../serviceability/sa/LingeredAppWithVirtualThread.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/serviceability/sa/LingeredAppWithVirtualThread.java b/test/hotspot/jtreg/serviceability/sa/LingeredAppWithVirtualThread.java index 771a94fac235c..44cc8c4d3716a 100644 --- a/test/hotspot/jtreg/serviceability/sa/LingeredAppWithVirtualThread.java +++ b/test/hotspot/jtreg/serviceability/sa/LingeredAppWithVirtualThread.java @@ -40,6 +40,8 @@ public class LingeredAppWithVirtualThread extends LingeredApp implements Runnabl private static final MethodHandle hndSleep; + private static final int sleepArg; + private static final CountDownLatch signal = new CountDownLatch(1); static { @@ -47,10 +49,12 @@ public class LingeredAppWithVirtualThread extends LingeredApp implements Runnabl if (System.getProperty("os.name").startsWith("Windows")) { func = SymbolLookup.libraryLookup("Kernel32", Arena.global()) .findOrThrow("Sleep"); + sleepArg = 3600_000; // 1h in milliseconds } else { func = Linker.nativeLinker() .defaultLookup() .findOrThrow("sleep"); + sleepArg = 3600; // 1h in seconds } var desc = FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.JAVA_INT); @@ -62,7 +66,7 @@ public void run() { signal.countDown(); Thread.yield(); try { - hndSleep.invoke(3600); + hndSleep.invoke(sleepArg); } catch(Throwable t) { throw new RuntimeException(t); } From b82bb9aaf2f68936da2aafe2cb391c18b9fd0dca Mon Sep 17 00:00:00 2001 From: Yasumasa Suenaga Date: Tue, 14 Oct 2025 14:24:25 +0900 Subject: [PATCH 09/11] Update TestJhsdbJstackWithVirtualThread.java --- .../serviceability/sa/TestJhsdbJstackWithVirtualThread.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackWithVirtualThread.java b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackWithVirtualThread.java index 0b2d5b983a8a8..fce9906ca94ef 100644 --- a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackWithVirtualThread.java +++ b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackWithVirtualThread.java @@ -43,7 +43,7 @@ */ public class TestJhsdbJstackWithVirtualThread { - private static void runJstackMixed(LingeredApp app) throws Exception { + private static void runJstack(LingeredApp app) throws Exception { JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb"); launcher.addVMArgs(Utils.getTestJavaOpts()); launcher.addToolArg("jstack"); @@ -71,7 +71,7 @@ public static void main(String... args) throws Exception { app = new LingeredAppWithVirtualThread(); LingeredApp.startApp(app); System.out.println("Started LingeredApp with pid " + app.getPid()); - runJstackMixed(app); + runJstack(app); System.out.println("Test Completed"); } catch (Throwable e) { e.printStackTrace(); From e64d696b250aa560528de9b6c0afee1b2657db51 Mon Sep 17 00:00:00 2001 From: Yasumasa Suenaga Date: Wed, 15 Oct 2025 09:58:44 +0900 Subject: [PATCH 10/11] Move Thread.yield() --- .../jtreg/serviceability/sa/LingeredAppWithVirtualThread.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/serviceability/sa/LingeredAppWithVirtualThread.java b/test/hotspot/jtreg/serviceability/sa/LingeredAppWithVirtualThread.java index 44cc8c4d3716a..a6b97d21d0c23 100644 --- a/test/hotspot/jtreg/serviceability/sa/LingeredAppWithVirtualThread.java +++ b/test/hotspot/jtreg/serviceability/sa/LingeredAppWithVirtualThread.java @@ -63,8 +63,8 @@ public class LingeredAppWithVirtualThread extends LingeredApp implements Runnabl @Override public void run() { - signal.countDown(); Thread.yield(); + signal.countDown(); try { hndSleep.invoke(sleepArg); } catch(Throwable t) { From a8e3f4f440975375ced65d1e76f45ccfb9a2f504 Mon Sep 17 00:00:00 2001 From: Yasumasa Suenaga Date: Wed, 15 Oct 2025 19:22:30 +0900 Subject: [PATCH 11/11] Cosmetic change --- .../jtreg/serviceability/sa/LingeredAppWithVirtualThread.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/sa/LingeredAppWithVirtualThread.java b/test/hotspot/jtreg/serviceability/sa/LingeredAppWithVirtualThread.java index a6b97d21d0c23..ca98506e13381 100644 --- a/test/hotspot/jtreg/serviceability/sa/LingeredAppWithVirtualThread.java +++ b/test/hotspot/jtreg/serviceability/sa/LingeredAppWithVirtualThread.java @@ -67,7 +67,7 @@ public void run() { signal.countDown(); try { hndSleep.invoke(sleepArg); - } catch(Throwable t) { + } catch (Throwable t) { throw new RuntimeException(t); } } @@ -80,7 +80,7 @@ public static void main(String[] args) { signal.await(); LingeredApp.main(args); - } catch(Exception e) { + } catch (Exception e) { throw new RuntimeException(e); } }