From 66fefb0a08a2534aeb048f8cd8dcd3a01dd64448 Mon Sep 17 00:00:00 2001 From: Josef Eisl Date: Tue, 26 Sep 2023 08:40:34 +0200 Subject: [PATCH 1/4] svm: adopt "JDK-8312498 Thread::getState and JVM TI GetThreadState should return TIMED_WAITING virtual thread is timed parked" [GR-48899] (cherry picked from commit 421ff9926f7d6177f188cb698eaab1e27dbd980d) --- .../thread/Target_java_lang_VirtualThread.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_VirtualThread.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_VirtualThread.java index 9d9935dd0be6..803ae2d01c01 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_VirtualThread.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_VirtualThread.java @@ -30,6 +30,8 @@ import java.util.Locale; import java.util.concurrent.Executor; +import org.graalvm.compiler.serviceprovider.JavaVersionUtil; + import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.Uninterruptible; import com.oracle.svm.core.annotate.Alias; @@ -43,6 +45,7 @@ import com.oracle.svm.core.jdk.JDK20OrEarlier; import com.oracle.svm.core.jdk.JDK20OrLater; import com.oracle.svm.core.jdk.JDK21OrLater; +import com.oracle.svm.core.jdk.JDK21OrEarlier; import com.oracle.svm.core.jdk.LoomJDK; import com.oracle.svm.core.jfr.HasJfrSupport; import com.oracle.svm.core.jfr.SubstrateJVM; @@ -62,8 +65,12 @@ public final class Target_java_lang_VirtualThread { @Alias static int PINNED; @Alias static int YIELDING; @Alias static int TERMINATED; - @Alias static int RUNNABLE_SUSPENDED; - @Alias static int PARKED_SUSPENDED; + @Alias // + @TargetElement(onlyWith = JDK21OrEarlier.class) // + static int RUNNABLE_SUSPENDED; + @Alias // + @TargetElement(onlyWith = JDK21OrEarlier.class) // + static int PARKED_SUSPENDED; @Alias static Target_jdk_internal_vm_ContinuationScope VTHREAD_SCOPE; // Checkstyle: resume @@ -164,7 +171,7 @@ Thread.State threadState() { } else { return Thread.State.RUNNABLE; } - } else if (state == RUNNABLE || state == RUNNABLE_SUSPENDED) { + } else if (state == RUNNABLE || (JavaVersionUtil.JAVA_SPEC <= 21 && state == RUNNABLE_SUSPENDED)) { return Thread.State.RUNNABLE; } else if (state == RUNNING) { Object token = VirtualThreadHelper.acquireInterruptLockMaybeSwitch(this); @@ -179,7 +186,7 @@ Thread.State threadState() { return Thread.State.RUNNABLE; } else if (state == PARKING || state == YIELDING) { return Thread.State.RUNNABLE; - } else if (state == PARKED || state == PARKED_SUSPENDED || state == PINNED) { + } else if (state == PARKED || (JavaVersionUtil.JAVA_SPEC <= 21 && state == PARKED_SUSPENDED) || state == PINNED) { int parkedThreadStatus = MonitorSupport.singleton().getParkedThreadStatus(asThread(this), false); switch (parkedThreadStatus) { case ThreadStatus.BLOCKED_ON_MONITOR_ENTER: From 9bed798815887234992fe6d9be43fa14aebe1a9b Mon Sep 17 00:00:00 2001 From: Peter Hofer Date: Fri, 6 Oct 2023 19:19:22 +0200 Subject: [PATCH 2/4] [GR-48899] Support TIMED_WAITING for virtual threads. (cherry picked from commit 4fad6c2661356dfd51afe82d88009b549bfdbedb) --- .../Target_java_lang_VirtualThread.java | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_VirtualThread.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_VirtualThread.java index 803ae2d01c01..a630d3160819 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_VirtualThread.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_VirtualThread.java @@ -46,6 +46,7 @@ import com.oracle.svm.core.jdk.JDK20OrLater; import com.oracle.svm.core.jdk.JDK21OrLater; import com.oracle.svm.core.jdk.JDK21OrEarlier; +import com.oracle.svm.core.jdk.JDK22OrLater; import com.oracle.svm.core.jdk.LoomJDK; import com.oracle.svm.core.jfr.HasJfrSupport; import com.oracle.svm.core.jfr.SubstrateJVM; @@ -65,12 +66,10 @@ public final class Target_java_lang_VirtualThread { @Alias static int PINNED; @Alias static int YIELDING; @Alias static int TERMINATED; - @Alias // - @TargetElement(onlyWith = JDK21OrEarlier.class) // - static int RUNNABLE_SUSPENDED; - @Alias // - @TargetElement(onlyWith = JDK21OrEarlier.class) // - static int PARKED_SUSPENDED; + @Alias static int SUSPENDED; + @TargetElement(onlyWith = JDK22OrLater.class) @Alias static int TIMED_PARKING; + @TargetElement(onlyWith = JDK22OrLater.class) @Alias static int TIMED_PARKED; + @TargetElement(onlyWith = JDK22OrLater.class) @Alias static int TIMED_PINNED; @Alias static Target_jdk_internal_vm_ContinuationScope VTHREAD_SCOPE; // Checkstyle: resume @@ -162,7 +161,7 @@ void unmount() { @Substitute Thread.State threadState() { - int state = state(); + int state = state() & ~SUSPENDED; if (state == NEW) { return Thread.State.NEW; } else if (state == STARTED) { @@ -171,7 +170,7 @@ Thread.State threadState() { } else { return Thread.State.RUNNABLE; } - } else if (state == RUNNABLE || (JavaVersionUtil.JAVA_SPEC <= 21 && state == RUNNABLE_SUSPENDED)) { + } else if (state == RUNNABLE) { return Thread.State.RUNNABLE; } else if (state == RUNNING) { Object token = VirtualThreadHelper.acquireInterruptLockMaybeSwitch(this); @@ -186,7 +185,7 @@ Thread.State threadState() { return Thread.State.RUNNABLE; } else if (state == PARKING || state == YIELDING) { return Thread.State.RUNNABLE; - } else if (state == PARKED || (JavaVersionUtil.JAVA_SPEC <= 21 && state == PARKED_SUSPENDED) || state == PINNED) { + } else if (state == PARKED || state == PINNED) { int parkedThreadStatus = MonitorSupport.singleton().getParkedThreadStatus(asThread(this), false); switch (parkedThreadStatus) { case ThreadStatus.BLOCKED_ON_MONITOR_ENTER: @@ -199,6 +198,12 @@ Thread.State threadState() { } } else if (state == TERMINATED) { return Thread.State.TERMINATED; + } else if (JavaVersionUtil.JAVA_SPEC >= 22) { + if (state == TIMED_PARKING) { + return Thread.State.RUNNABLE; + } else if (state == TIMED_PARKED || state == TIMED_PINNED) { + return Thread.State.TIMED_WAITING; + } } throw new InternalError(); } From 5e6c071bbeca42c3daaa7f7508a2e00bcb5d92ff Mon Sep 17 00:00:00 2001 From: Josef Eisl Date: Sat, 9 Dec 2023 15:50:52 +0100 Subject: [PATCH 3/4] svm: adopt "JDK-8321270: Virtual Thread.yield consumes parking permit" [GR-50851] https://github.com/openjdk/jdk/commit/29d7a22348e43cba253d0483c4c05922368f6b8a (cherry picked from commit 595ac63036c8888330cc1f4eb4e381f5c70629f3) --- .../svm/core/thread/Target_java_lang_VirtualThread.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_VirtualThread.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_VirtualThread.java index a630d3160819..01cb0c540876 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_VirtualThread.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_VirtualThread.java @@ -59,17 +59,20 @@ public final class Target_java_lang_VirtualThread { // Checkstyle: stop @Alias static int NEW; @Alias static int STARTED; - @Alias static int RUNNABLE; + @Alias // + @TargetElement(onlyWith = JDK21OrEarlier.class) static int RUNNABLE; @Alias static int RUNNING; @Alias static int PARKING; @Alias static int PARKED; @Alias static int PINNED; @Alias static int YIELDING; + @TargetElement(onlyWith = JDK22OrLater.class) @Alias static int YIELDED; @Alias static int TERMINATED; @Alias static int SUSPENDED; @TargetElement(onlyWith = JDK22OrLater.class) @Alias static int TIMED_PARKING; @TargetElement(onlyWith = JDK22OrLater.class) @Alias static int TIMED_PARKED; @TargetElement(onlyWith = JDK22OrLater.class) @Alias static int TIMED_PINNED; + @TargetElement(onlyWith = JDK22OrLater.class) @Alias static int UNPARKED; @Alias static Target_jdk_internal_vm_ContinuationScope VTHREAD_SCOPE; // Checkstyle: resume @@ -170,7 +173,9 @@ Thread.State threadState() { } else { return Thread.State.RUNNABLE; } - } else if (state == RUNNABLE) { + } else if (JavaVersionUtil.JAVA_SPEC < 22 && state == RUNNABLE) { + return Thread.State.RUNNABLE; + } else if (JavaVersionUtil.JAVA_SPEC >= 22 && (state == UNPARKED || state == YIELDED)) { return Thread.State.RUNNABLE; } else if (state == RUNNING) { Object token = VirtualThreadHelper.acquireInterruptLockMaybeSwitch(this); From 885530a86770891ed64ac5e26d48bf66c404b650 Mon Sep 17 00:00:00 2001 From: Volker Simonis Date: Wed, 13 Mar 2024 10:44:41 +0100 Subject: [PATCH 4/4] svm: fix for JDK 21.0.4 after the downport of "8315373: Change VirtualThread to unmount after freezing, re-mount before thawing" and dependnet changes https://git.openjdk.org/jdk21u-dev/commit/3eb5517b73b58bee4985ae6c20a6e613e35d426c --- .../oracle/svm/core/jdk/JDK21u3OrEarlier.java | 40 +++++++++++++++++++ .../oracle/svm/core/jdk/JDK21u4OrLater.java | 40 +++++++++++++++++++ .../Target_java_lang_VirtualThread.java | 24 +++++------ 3 files changed, 91 insertions(+), 13 deletions(-) create mode 100644 substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JDK21u3OrEarlier.java create mode 100644 substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JDK21u4OrLater.java diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JDK21u3OrEarlier.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JDK21u3OrEarlier.java new file mode 100644 index 000000000000..972e645957ae --- /dev/null +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JDK21u3OrEarlier.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 com.oracle.svm.core.jdk; + +import java.util.function.BooleanSupplier; + +import org.graalvm.compiler.serviceprovider.JavaVersionUtil; + +public class JDK21u3OrEarlier implements BooleanSupplier { + + public static final boolean jdk21u3OrEarlier = JavaVersionUtil.JAVA_SPEC < 21 || + (JavaVersionUtil.JAVA_SPEC == 21 && Runtime.version().update() <= 3); + + @Override + public boolean getAsBoolean() { + return jdk21u3OrEarlier; + } +} diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JDK21u4OrLater.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JDK21u4OrLater.java new file mode 100644 index 000000000000..cae248622c82 --- /dev/null +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JDK21u4OrLater.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 com.oracle.svm.core.jdk; + +import java.util.function.BooleanSupplier; + +import org.graalvm.compiler.serviceprovider.JavaVersionUtil; + +public class JDK21u4OrLater implements BooleanSupplier { + + public static final boolean jdk21u4OrLater = JavaVersionUtil.JAVA_SPEC > 21 || + (JavaVersionUtil.JAVA_SPEC == 21 && Runtime.version().update() >= 4); + + @Override + public boolean getAsBoolean() { + return jdk21u4OrLater; + } +} diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_VirtualThread.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_VirtualThread.java index 01cb0c540876..6fe180ddb54d 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_VirtualThread.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_VirtualThread.java @@ -30,8 +30,6 @@ import java.util.Locale; import java.util.concurrent.Executor; -import org.graalvm.compiler.serviceprovider.JavaVersionUtil; - import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.Uninterruptible; import com.oracle.svm.core.annotate.Alias; @@ -45,8 +43,8 @@ import com.oracle.svm.core.jdk.JDK20OrEarlier; import com.oracle.svm.core.jdk.JDK20OrLater; import com.oracle.svm.core.jdk.JDK21OrLater; -import com.oracle.svm.core.jdk.JDK21OrEarlier; -import com.oracle.svm.core.jdk.JDK22OrLater; +import com.oracle.svm.core.jdk.JDK21u3OrEarlier; +import com.oracle.svm.core.jdk.JDK21u4OrLater; import com.oracle.svm.core.jdk.LoomJDK; import com.oracle.svm.core.jfr.HasJfrSupport; import com.oracle.svm.core.jfr.SubstrateJVM; @@ -60,19 +58,19 @@ public final class Target_java_lang_VirtualThread { @Alias static int NEW; @Alias static int STARTED; @Alias // - @TargetElement(onlyWith = JDK21OrEarlier.class) static int RUNNABLE; + @TargetElement(onlyWith = JDK21u3OrEarlier.class) static int RUNNABLE; @Alias static int RUNNING; @Alias static int PARKING; @Alias static int PARKED; @Alias static int PINNED; @Alias static int YIELDING; - @TargetElement(onlyWith = JDK22OrLater.class) @Alias static int YIELDED; + @TargetElement(onlyWith = JDK21u4OrLater.class) @Alias static int YIELDED; @Alias static int TERMINATED; @Alias static int SUSPENDED; - @TargetElement(onlyWith = JDK22OrLater.class) @Alias static int TIMED_PARKING; - @TargetElement(onlyWith = JDK22OrLater.class) @Alias static int TIMED_PARKED; - @TargetElement(onlyWith = JDK22OrLater.class) @Alias static int TIMED_PINNED; - @TargetElement(onlyWith = JDK22OrLater.class) @Alias static int UNPARKED; + @TargetElement(onlyWith = JDK21u4OrLater.class) @Alias static int TIMED_PARKING; + @TargetElement(onlyWith = JDK21u4OrLater.class) @Alias static int TIMED_PARKED; + @TargetElement(onlyWith = JDK21u4OrLater.class) @Alias static int TIMED_PINNED; + @TargetElement(onlyWith = JDK21u4OrLater.class) @Alias static int UNPARKED; @Alias static Target_jdk_internal_vm_ContinuationScope VTHREAD_SCOPE; // Checkstyle: resume @@ -173,9 +171,9 @@ Thread.State threadState() { } else { return Thread.State.RUNNABLE; } - } else if (JavaVersionUtil.JAVA_SPEC < 22 && state == RUNNABLE) { + } else if (JDK21u3OrEarlier.jdk21u3OrEarlier && state == RUNNABLE) { return Thread.State.RUNNABLE; - } else if (JavaVersionUtil.JAVA_SPEC >= 22 && (state == UNPARKED || state == YIELDED)) { + } else if (JDK21u4OrLater.jdk21u4OrLater && (state == UNPARKED || state == YIELDED)) { return Thread.State.RUNNABLE; } else if (state == RUNNING) { Object token = VirtualThreadHelper.acquireInterruptLockMaybeSwitch(this); @@ -203,7 +201,7 @@ Thread.State threadState() { } } else if (state == TERMINATED) { return Thread.State.TERMINATED; - } else if (JavaVersionUtil.JAVA_SPEC >= 22) { + } else if (JDK21u4OrLater.jdk21u4OrLater) { if (state == TIMED_PARKING) { return Thread.State.RUNNABLE; } else if (state == TIMED_PARKED || state == TIMED_PINNED) {