Skip to content

Commit 429daa0

Browse files
committed
[GR-48504] [GR-48899] [GR-47055] Clean up virtual threads code.
PullRequest: graal/15767
2 parents ff29052 + 2f9394e commit 429daa0

File tree

41 files changed

+627
-1333
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+627
-1333
lines changed

substratevm/mx.substratevm/suite.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,6 +1357,7 @@
13571357
"requiresConcealed": {
13581358
"jdk.internal.vm.ci": [
13591359
"jdk.vm.ci.meta",
1360+
"jdk.vm.ci.code",
13601361
"jdk.vm.ci.common",
13611362
]
13621363
},

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ThreadLocalAllocation.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
import com.oracle.svm.core.snippets.KnownIntrinsics;
6868
import com.oracle.svm.core.snippets.SubstrateForeignCallTarget;
6969
import com.oracle.svm.core.stack.StackOverflowCheck;
70-
import com.oracle.svm.core.thread.Continuation;
70+
import com.oracle.svm.core.thread.ContinuationSupport;
7171
import com.oracle.svm.core.thread.VMOperation;
7272
import com.oracle.svm.core.thread.VMThreads;
7373
import com.oracle.svm.core.threadlocal.FastThreadLocal;
@@ -375,7 +375,7 @@ private static Object allocateLargeArrayLikeObjectInNewTlab(DynamicHub hub, int
375375
@Uninterruptible(reason = "Holds uninitialized memory")
376376
private static Object formatArrayLikeObject(Pointer memory, DynamicHub hub, int length, boolean unaligned, FillContent fillContent, byte[] podReferenceMap) {
377377
Class<?> clazz = DynamicHub.toClass(hub);
378-
if (Continuation.isSupported() && clazz == StoredContinuation.class) {
378+
if (ContinuationSupport.isSupported() && clazz == StoredContinuation.class) {
379379
return FormatStoredContinuationNode.formatStoredContinuation(memory, clazz, length, false, unaligned, true);
380380
} else if (Pod.RuntimeSupport.isPresent() && podReferenceMap != null) {
381381
return FormatPodNode.formatPod(memory, clazz, length, podReferenceMap, false, unaligned, fillContent, true);

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/GenScavengeAllocationSnippets.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@
5858
import com.oracle.svm.core.heap.Pod;
5959
import com.oracle.svm.core.hub.DynamicHub;
6060
import com.oracle.svm.core.hub.LayoutEncoding;
61-
import com.oracle.svm.core.thread.Continuation;
6261
import com.oracle.svm.core.thread.ContinuationSupport;
6362

6463
import jdk.vm.ci.meta.JavaKind;
@@ -130,7 +129,7 @@ public Templates(OptionValues options, Providers providers, SubstrateAllocationS
130129
this.baseTemplates = baseTemplates;
131130
formatObject = snippet(providers, GenScavengeAllocationSnippets.class, "formatObjectSnippet");
132131
formatArray = snippet(providers, GenScavengeAllocationSnippets.class, "formatArraySnippet");
133-
formatStoredContinuation = Continuation.isSupported() ? snippet(providers, GenScavengeAllocationSnippets.class, "formatStoredContinuation") : null;
132+
formatStoredContinuation = ContinuationSupport.isSupported() ? snippet(providers, GenScavengeAllocationSnippets.class, "formatStoredContinuation") : null;
134133
formatPod = Pod.RuntimeSupport.isPresent() ? snippet(providers,
135134
GenScavengeAllocationSnippets.class,
136135
"formatPodSnippet",
@@ -141,7 +140,7 @@ public Templates(OptionValues options, Providers providers, SubstrateAllocationS
141140
public void registerLowering(Map<Class<? extends Node>, NodeLoweringProvider<?>> lowerings) {
142141
lowerings.put(FormatObjectNode.class, new FormatObjectLowering());
143142
lowerings.put(FormatArrayNode.class, new FormatArrayLowering());
144-
if (Continuation.isSupported()) {
143+
if (ContinuationSupport.isSupported()) {
145144
lowerings.put(FormatStoredContinuationNode.class, new FormatStoredContinuationLowering());
146145
}
147146
if (Pod.RuntimeSupport.isPresent()) {

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/GenScavengeAllocationSupport.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,19 @@
2424
*/
2525
package com.oracle.svm.core.genscavenge.graal;
2626

27-
import com.oracle.svm.core.heap.Pod;
28-
import com.oracle.svm.core.snippets.SnippetRuntime.SubstrateForeignCallDescriptor;
29-
import com.oracle.svm.core.thread.Continuation;
30-
import jdk.compiler.graal.core.common.spi.ForeignCallDescriptor;
31-
import jdk.compiler.graal.word.Word;
3227
import org.graalvm.word.UnsignedWord;
3328

3429
import com.oracle.svm.core.genscavenge.HeapParameters;
3530
import com.oracle.svm.core.genscavenge.ThreadLocalAllocation;
3631
import com.oracle.svm.core.graal.meta.SubstrateForeignCallsProvider;
3732
import com.oracle.svm.core.graal.snippets.GCAllocationSupport;
33+
import com.oracle.svm.core.heap.Pod;
3834
import com.oracle.svm.core.snippets.SnippetRuntime;
35+
import com.oracle.svm.core.snippets.SnippetRuntime.SubstrateForeignCallDescriptor;
36+
import com.oracle.svm.core.thread.ContinuationSupport;
37+
38+
import jdk.compiler.graal.core.common.spi.ForeignCallDescriptor;
39+
import jdk.compiler.graal.word.Word;
3940

4041
public class GenScavengeAllocationSupport implements GCAllocationSupport {
4142
private static final SubstrateForeignCallDescriptor SLOW_NEW_INSTANCE = SnippetRuntime.findForeignCall(ThreadLocalAllocation.class, "slowPathNewInstance", true);
@@ -46,7 +47,7 @@ public class GenScavengeAllocationSupport implements GCAllocationSupport {
4647

4748
public static void registerForeignCalls(SubstrateForeignCallsProvider foreignCalls) {
4849
foreignCalls.register(UNCONDITIONAL_FOREIGN_CALLS);
49-
if (Continuation.isSupported()) {
50+
if (ContinuationSupport.isSupported()) {
5051
foreignCalls.register(SLOW_NEW_STORED_CONTINUATION);
5152
}
5253
if (Pod.RuntimeSupport.isPresent()) {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/classinitialization/ClassInitializationInfo.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929

3030
import org.graalvm.nativeimage.CurrentIsolate;
3131
import org.graalvm.nativeimage.IsolateThread;
32-
import com.oracle.svm.core.hub.PredefinedClassesSupport;
3332
import org.graalvm.nativeimage.Platform;
3433
import org.graalvm.nativeimage.Platforms;
3534
import org.graalvm.nativeimage.c.function.CFunctionPointer;
@@ -38,10 +37,12 @@
3837
import com.oracle.svm.core.FunctionPointerHolder;
3938
import com.oracle.svm.core.c.InvokeJavaFunctionPointer;
4039
import com.oracle.svm.core.hub.DynamicHub;
40+
import com.oracle.svm.core.hub.PredefinedClassesSupport;
4141
import com.oracle.svm.core.jdk.InternalVMMethod;
4242
import com.oracle.svm.core.snippets.SubstrateForeignCallTarget;
43+
import com.oracle.svm.core.thread.ContinuationSupport;
4344
import com.oracle.svm.core.thread.JavaThreads;
44-
import com.oracle.svm.core.thread.VirtualThreads;
45+
import com.oracle.svm.core.thread.Target_jdk_internal_vm_Continuation;
4546
import com.oracle.svm.core.util.VMError;
4647

4748
import jdk.internal.misc.Unsafe;
@@ -263,16 +264,16 @@ private static void initialize(ClassInitializationInfo info, DynamicHub hub) {
263264
}
264265

265266
boolean pinned = false;
266-
if (VirtualThreads.isSupported() && JavaThreads.isCurrentThreadVirtual()) {
267+
if (ContinuationSupport.isSupported() && JavaThreads.isCurrentThreadVirtual()) {
267268
// See comment on field `initThread`
268-
VirtualThreads.singleton().pinCurrent();
269+
Target_jdk_internal_vm_Continuation.pin();
269270
pinned = true;
270271
}
271272
try {
272273
doInitialize(info, hub);
273274
} finally {
274275
if (pinned) {
275-
VirtualThreads.singleton().unpinCurrent();
276+
Target_jdk_internal_vm_Continuation.unpin();
276277
}
277278
}
278279
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/snippets/SubstrateAllocationSnippets.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@
102102
import com.oracle.svm.core.snippets.SnippetRuntime;
103103
import com.oracle.svm.core.snippets.SnippetRuntime.SubstrateForeignCallDescriptor;
104104
import com.oracle.svm.core.snippets.SubstrateForeignCallTarget;
105-
import com.oracle.svm.core.thread.Continuation;
106105
import com.oracle.svm.core.thread.ContinuationSupport;
107106
import com.oracle.svm.core.util.VMError;
108107

@@ -600,7 +599,7 @@ public Templates(OptionValues options, Providers providers, SubstrateAllocationS
600599
ALLOCATION_LOCATIONS);
601600

602601
SnippetInfo allocateStoredContinuationSnippet = null;
603-
if (Continuation.isSupported()) {
602+
if (ContinuationSupport.isSupported()) {
604603
allocateStoredContinuationSnippet = snippet(providers,
605604
SubstrateAllocationSnippets.class,
606605
"allocateStoredContinuation",
@@ -634,7 +633,7 @@ public void registerLowering(Map<Class<? extends Node>, NodeLoweringProvider<?>>
634633
lowerings.put(NewMultiArrayNode.class, new NewMultiArrayLowering());
635634
lowerings.put(ValidateNewInstanceClassNode.class, new ValidateNewInstanceClassLowering());
636635

637-
if (Continuation.isSupported()) {
636+
if (ContinuationSupport.isSupported()) {
638637
lowerings.put(NewStoredContinuationNode.class, new NewStoredContinuationLowering());
639638
}
640639
if (Pod.RuntimeSupport.isPresent()) {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/stackvalue/StackValueNode.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
import com.oracle.svm.core.FrameAccess;
4747
import com.oracle.svm.core.Uninterruptible;
4848
import com.oracle.svm.core.config.ConfigurationValues;
49-
import com.oracle.svm.core.thread.VirtualThreads;
5049

5150
import jdk.vm.ci.meta.ResolvedJavaMethod;
5251

@@ -153,7 +152,7 @@ public static StackValueNode create(int sizeInBytes, ResolvedJavaMethod method,
153152
* around in a caller, but these are difficult to ensure across multiple callers and
154153
* callees.
155154
*/
156-
boolean checkVirtualThread = disallowVirtualThread && VirtualThreads.isSupported() && !Uninterruptible.Utils.isUninterruptible(method);
155+
boolean checkVirtualThread = disallowVirtualThread && !Uninterruptible.Utils.isUninterruptible(method);
157156
return create(sizeInBytes, slotIdentity, checkVirtualThread);
158157
}
159158

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/StoredContinuationAccess.java

Lines changed: 11 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import jdk.compiler.graal.nodes.java.ArrayLengthNode;
3131
import jdk.compiler.graal.word.Word;
3232
import org.graalvm.nativeimage.ImageSingletons;
33-
import org.graalvm.nativeimage.IsolateThread;
3433
import org.graalvm.nativeimage.StackValue;
3534
import org.graalvm.nativeimage.c.function.CodePointer;
3635
import org.graalvm.nativeimage.c.struct.RawStructure;
@@ -39,9 +38,9 @@
3938
import org.graalvm.word.UnsignedWord;
4039
import org.graalvm.word.WordFactory;
4140

42-
import com.oracle.svm.core.UnmanagedMemoryUtil;
4341
import com.oracle.svm.core.AlwaysInline;
4442
import com.oracle.svm.core.Uninterruptible;
43+
import com.oracle.svm.core.UnmanagedMemoryUtil;
4544
import com.oracle.svm.core.c.NonmovableArray;
4645
import com.oracle.svm.core.code.CodeInfo;
4746
import com.oracle.svm.core.code.CodeInfoAccess;
@@ -58,9 +57,10 @@
5857
import com.oracle.svm.core.stack.JavaStackWalk;
5958
import com.oracle.svm.core.stack.JavaStackWalker;
6059
import com.oracle.svm.core.stack.StackFrameVisitor;
61-
import com.oracle.svm.core.thread.Continuation;
60+
import com.oracle.svm.core.thread.ContinuationInternals;
6261
import com.oracle.svm.core.thread.ContinuationSupport;
6362
import com.oracle.svm.core.thread.Safepoint;
63+
import com.oracle.svm.core.thread.Target_jdk_internal_vm_Continuation;
6464
import com.oracle.svm.core.util.UnsignedUtils;
6565
import com.oracle.svm.core.util.VMError;
6666

@@ -107,39 +107,14 @@ public static CodePointer getIP(StoredContinuation s) {
107107
return s.ip;
108108
}
109109

110-
public static int allocateToYield(Continuation c, Pointer baseSp, Pointer sp, CodePointer ip) {
111-
assert sp.isNonNull() && ip.isNonNull();
112-
return allocateFromStack(c, baseSp, sp, ip, WordFactory.nullPointer());
113-
}
114-
115-
public static int allocateToPreempt(Continuation c, Pointer baseSp, IsolateThread targetThread) {
116-
return allocateFromStack(c, baseSp, WordFactory.nullPointer(), WordFactory.nullPointer(), targetThread);
117-
}
118-
119-
private static int allocateFromStack(Continuation cont, Pointer baseSp, Pointer sp, CodePointer ip, IsolateThread targetThread) {
120-
boolean yield = sp.isNonNull();
121-
assert yield == ip.isNonNull() && yield == targetThread.isNull();
122-
assert baseSp.isNonNull();
123-
124-
Pointer startSp = sp;
125-
CodePointer startIp = ip;
126-
if (!yield) {
127-
PreemptVisitor visitor = new PreemptVisitor(baseSp);
128-
JavaStackWalker.walkThread(targetThread, visitor);
129-
if (visitor.preemptStatus != Continuation.FREEZE_OK) {
130-
return visitor.preemptStatus;
131-
}
132-
startSp = visitor.leafSP;
133-
startIp = visitor.leafIP;
134-
}
135-
136-
VMError.guarantee(startSp.isNonNull());
110+
public static int allocateToYield(Target_jdk_internal_vm_Continuation c, Pointer baseSp, Pointer sp, CodePointer ip) {
111+
assert baseSp.isNonNull() && sp.isNonNull() && ip.isNonNull();
137112

138-
int framesSize = UnsignedUtils.safeToInt(baseSp.subtract(startSp));
113+
int framesSize = UnsignedUtils.safeToInt(baseSp.subtract(sp));
139114
StoredContinuation instance = allocate(framesSize);
140-
fillUninterruptibly(instance, startIp, startSp, framesSize);
141-
cont.stored = instance;
142-
return Continuation.FREEZE_OK;
115+
fillUninterruptibly(instance, ip, sp, framesSize);
116+
ContinuationInternals.setStoredContinuation(c, instance);
117+
return ContinuationSupport.FREEZE_OK;
143118
}
144119

145120
@Uninterruptible(reason = "Prevent modifications to the stack while initializing instance and copying frames.")
@@ -300,7 +275,7 @@ private static final class PreemptVisitor extends StackFrameVisitor {
300275

301276
Pointer leafSP;
302277
CodePointer leafIP;
303-
int preemptStatus = Continuation.FREEZE_OK;
278+
int preemptStatus = ContinuationSupport.FREEZE_OK;
304279

305280
PreemptVisitor(Pointer endSP) {
306281
this.endSP = endSP;
@@ -315,7 +290,7 @@ protected boolean visitFrame(Pointer sp, CodePointer ip, CodeInfo codeInfo, Deop
315290
FrameInfoQueryResult frameInfo = CodeInfoTable.lookupCodeInfoQueryResult(codeInfo, ip).getFrameInfo();
316291
if (frameInfo.getSourceClass().equals(StoredContinuationAccess.class) && frameInfo.getSourceMethodName().equals("allocateToYield")) {
317292
// Continuation is already in the process of yielding, cancel preemption.
318-
preemptStatus = Continuation.YIELDING;
293+
preemptStatus = ContinuationSupport.FREEZE_YIELDING;
319294
return false;
320295
}
321296

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/InteriorObjRefWalker.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
import com.oracle.svm.core.heap.PodReferenceMapDecoder;
4444
import com.oracle.svm.core.heap.ReferenceAccess;
4545
import com.oracle.svm.core.heap.StoredContinuationAccess;
46-
import com.oracle.svm.core.thread.Continuation;
46+
import com.oracle.svm.core.thread.ContinuationSupport;
4747
import com.oracle.svm.core.util.VMError;
4848

4949
/**
@@ -130,7 +130,7 @@ private static boolean walkPod(Object obj, ObjectReferenceVisitor visitor, Dynam
130130
@AlwaysInline("Performance critical version")
131131
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
132132
private static boolean walkStoredContinuation(Object obj, ObjectReferenceVisitor visitor) {
133-
if (!Continuation.isSupported()) {
133+
if (!ContinuationSupport.isSupported()) {
134134
throw VMError.shouldNotReachHere("Stored continuation objects cannot be in the heap if the continuation support is disabled.");
135135
}
136136
return StoredContinuationAccess.walkReferences(obj, visitor);

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/image/DisallowedImageHeapObjects.java

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
import java.util.concurrent.ThreadLocalRandom;
3838

3939
import com.oracle.svm.core.SubstrateUtil;
40-
import com.oracle.svm.core.thread.VirtualThreads;
4140
import com.oracle.svm.core.util.VMError;
4241
import com.oracle.svm.util.ReflectionUtil;
4342

@@ -52,20 +51,12 @@ public interface DisallowedObjectReporter {
5251
RuntimeException raise(String msg, Object obj, String initializerAction);
5352
}
5453

55-
private static final Class<?> CANCELLABLE_CLASS;
56-
private static final Class<?> JDK_VIRTUAL_THREAD_CLASS;
57-
private static final Class<?> CONTINUATION_CLASS;
58-
private static final Method CONTINUATION_IS_STARTED_METHOD;
59-
private static final Class<?> CLEANER_CLEANABLE_CLASS;
60-
private static final Class<?> LEGACY_CLEANER_CLASS;
61-
static {
62-
CANCELLABLE_CLASS = ReflectionUtil.lookupClass(false, "sun.nio.fs.Cancellable");
63-
JDK_VIRTUAL_THREAD_CLASS = ReflectionUtil.lookupClass(true, "java.lang.VirtualThread");
64-
CONTINUATION_CLASS = ReflectionUtil.lookupClass(true, "jdk.internal.vm.Continuation");
65-
CONTINUATION_IS_STARTED_METHOD = (CONTINUATION_CLASS == null) ? null : ReflectionUtil.lookupMethod(CONTINUATION_CLASS, "isStarted");
66-
CLEANER_CLEANABLE_CLASS = ReflectionUtil.lookupClass(false, "jdk.internal.ref.CleanerImpl$CleanerCleanable");
67-
LEGACY_CLEANER_CLASS = ReflectionUtil.lookupClass(false, "jdk.internal.ref.Cleaner");
68-
}
54+
private static final Class<?> CANCELLABLE_CLASS = ReflectionUtil.lookupClass(false, "sun.nio.fs.Cancellable");
55+
private static final Class<?> VIRTUAL_THREAD_CLASS = ReflectionUtil.lookupClass(false, "java.lang.VirtualThread");
56+
private static final Class<?> CONTINUATION_CLASS = ReflectionUtil.lookupClass(false, "jdk.internal.vm.Continuation");
57+
private static final Method CONTINUATION_IS_STARTED_METHOD = ReflectionUtil.lookupMethod(CONTINUATION_CLASS, "isStarted");
58+
private static final Class<?> CLEANER_CLEANABLE_CLASS = ReflectionUtil.lookupClass(false, "jdk.internal.ref.CleanerImpl$CleanerCleanable");
59+
private static final Class<?> LEGACY_CLEANER_CLASS = ReflectionUtil.lookupClass(false, "jdk.internal.ref.Cleaner");
6960

7061
public static void check(Object obj, DisallowedObjectReporter reporter) {
7162
if (((obj instanceof Random) && !(obj instanceof ThreadLocalRandom)) || obj instanceof SplittableRandom) {
@@ -75,9 +66,8 @@ public static void check(Object obj, DisallowedObjectReporter reporter) {
7566
}
7667

7768
/* Started platform threads */
78-
if (obj instanceof Thread) {
79-
final Thread asThread = (Thread) obj;
80-
if (VirtualThreads.isSupported() && (VirtualThreads.singleton().isVirtual(asThread) || (JDK_VIRTUAL_THREAD_CLASS != null && JDK_VIRTUAL_THREAD_CLASS.isInstance(asThread)))) {
69+
if (obj instanceof Thread asThread) {
70+
if (VIRTUAL_THREAD_CLASS.isInstance(asThread)) {
8171
// allowed unless the thread is mounted, in which case it references its carrier
8272
// thread and fails
8373
} else if (asThread.getState() != Thread.State.NEW && asThread.getState() != Thread.State.TERMINATED) {
@@ -86,7 +76,7 @@ public static void check(Object obj, DisallowedObjectReporter reporter) {
8676
asThread, "Prevent threads from starting during image generation, or a started thread from being included in the image.");
8777
}
8878
}
89-
if (SubstrateUtil.HOSTED && CONTINUATION_CLASS != null && CONTINUATION_CLASS.isInstance(obj)) {
79+
if (SubstrateUtil.HOSTED && CONTINUATION_CLASS.isInstance(obj)) {
9080
boolean isStarted;
9181
try {
9282
isStarted = (Boolean) CONTINUATION_IS_STARTED_METHOD.invoke(obj);

0 commit comments

Comments
 (0)