Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions substratevm/mx.substratevm/suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,20 @@
},


"com.oracle.svm.core.jdk19": {
"subDir": "src",
"sourceDirs": ["src"],
"dependencies": ["com.oracle.svm.core"],
"requiresConcealed" : {
"java.base" : [
],
},
"javaCompliance": "19+",
"checkstyle": "com.oracle.svm.core",
"workingSets": "SVM",
},


"com.oracle.svm.core.genscavenge": {
"subDir": "src",
"sourceDirs": [
Expand Down Expand Up @@ -1086,6 +1100,7 @@
"com.oracle.svm.hosted.jdk17",
"com.oracle.svm.core",
"com.oracle.svm.core.jdk17",
"com.oracle.svm.core.jdk19",
"com.oracle.svm.core.graal.amd64",
"com.oracle.svm.core.graal.aarch64",
"com.oracle.svm.core.posix",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.svm.core.thread;
package com.oracle.svm.core.jdk19;

import static java.util.concurrent.TimeUnit.MILLISECONDS;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadFactory;

import com.oracle.svm.core.thread.Target_java_lang_Thread;
import com.oracle.svm.core.thread.Target_java_lang_VirtualThread;
import com.oracle.svm.core.thread.VirtualThreads;
import org.graalvm.nativeimage.Platforms;

import com.oracle.svm.core.SubstrateUtil;
Expand All @@ -49,7 +52,7 @@ private static Target_java_lang_VirtualThread cast(Thread thread) {

@Override
public ThreadFactory createFactory() {
throw VMError.unimplemented();
return Thread.ofVirtual().factory();
}

@Override
Expand All @@ -61,7 +64,7 @@ public boolean isVirtual(Thread thread) {
public void join(Thread thread, long millis) throws InterruptedException {
if (thread.isAlive()) {
long nanos = MILLISECONDS.toNanos(millis);
cast(thread).joinNanos(nanos);
// cast(thread).joinNanos(nanos);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import org.graalvm.compiler.options.OptionStability;
import org.graalvm.compiler.options.OptionType;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
import org.graalvm.nativeimage.ImageInfo;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.Platform;
Expand Down Expand Up @@ -134,11 +135,12 @@ protected void onValueUpdate(EconomicMap<OptionKey<?>, Object> values, Boolean o
@Option(help = "Support continuations (without requiring a Project Loom JDK)") //
public static final HostedOptionKey<Boolean> SupportContinuations = new HostedOptionKey<>(false);

@Option(help = "Build with Project Loom JDK") //
@Option(help = "Support continuations via Virtual Threads") //
public static final HostedOptionKey<Boolean> UseLoom = new HostedOptionKey<>(false) {
@Override
protected void onValueUpdate(EconomicMap<OptionKey<?>, Object> values, Boolean oldValue, Boolean newValue) {
if (newValue) {
assert JavaVersionUtil.JAVA_SPEC >= 19;
SupportContinuations.update(values, true);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,14 @@ public interface CPUFeatures extends PointerBase {
@AllowNarrowingCast
@CField
boolean fDMB_ATOMICS();

@AllowNarrowingCast
@CField
boolean fPACA();

@AllowNarrowingCast
@CField
boolean fSVEBITPERM();
}
// Checkstyle: resume
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,27 @@ public void afterRegistration(AfterRegistrationAccess access) {
if (Continuation.isSupported()) {
VirtualThreads impl;
if (LoomSupport.isEnabled()) {
impl = new LoomVirtualThreads();
try {
impl = (VirtualThreads) Class.forName("com.oracle.svm.core.jdk19.LoomVirtualThreads").getDeclaredConstructor().newInstance();
} catch (Exception e) {
throw UserError.abort(e, "Error initializing LoomVirtualThreads");
}
} else {
/*
* GR-37518: ForkJoinPool on 11 syncs on a String which doesn't have its own monitor
* field, and unparking a virtual thread in additionalMonitorsLock.unlock causes a
* deadlock between carrier thread and virtual thread. 17 uses a ReentrantLock.
*/
UserError.guarantee(JavaVersionUtil.JAVA_SPEC >= 17, "Continuations (%s) are currently supported only on JDK 17 and later.",
SubstrateOptionsParser.commandArgument(SubstrateOptions.SupportContinuations, "+"));
SubstrateOptionsParser.commandArgument(SubstrateOptions.SupportContinuations, "+"));

impl = new SubstrateVirtualThreads();
}
ImageSingletons.add(VirtualThreads.class, impl);
} else {
UserError.guarantee(!SubstrateOptions.UseLoom.getValue(), "%s cannot be enabled without option %s.",
SubstrateOptionsParser.commandArgument(SubstrateOptions.UseLoom, "+"),
SubstrateOptionsParser.commandArgument(SubstrateOptions.SupportContinuations, "+"));
SubstrateOptionsParser.commandArgument(SubstrateOptions.UseLoom, "+"),
SubstrateOptionsParser.commandArgument(SubstrateOptions.SupportContinuations, "+"));
}
}

Expand All @@ -77,7 +81,7 @@ public void beforeAnalysis(BeforeAnalysisAccess access) {
}

access.registerReachabilityHandler(a -> access.registerAsInHeap(StoredContinuation.class),
ReflectionUtil.lookupMethod(StoredContinuationAccess.class, "allocate", int.class));
ReflectionUtil.lookupMethod(StoredContinuationAccess.class, "allocate", int.class));

if (LoomSupport.isEnabled()) {
RuntimeReflection.register(ReflectionUtil.lookupMethod(ForkJoinPool.class, "compensatedBlock", ForkJoinPool.ManagedBlocker.class));
Expand All @@ -90,8 +94,8 @@ public void beforeAnalysis(BeforeAnalysisAccess access) {
static void abortIfUnsupported() {
if (!Continuation.isSupported()) {
throw UserError.abort("Continuation support is used, but not enabled. Use options %s or %s.",
SubstrateOptionsParser.commandArgument(SubstrateOptions.SupportContinuations, "+"),
SubstrateOptionsParser.commandArgument(SubstrateOptions.UseLoom, "+"));
SubstrateOptionsParser.commandArgument(SubstrateOptions.SupportContinuations, "+"),
SubstrateOptionsParser.commandArgument(SubstrateOptions.UseLoom, "+"));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ public final class JavaThreads {
static final AtomicLong threadSeqNumber = new AtomicLong();
/** For Thread.nextThreadNum(). */
static final AtomicInteger threadInitNumber = new AtomicInteger();
/** For Thread.ThreadNumbering.next() after JDK 19. */
static final AtomicInteger threadNumber = new AtomicInteger();

private JavaThreads() {
}
Expand All @@ -95,6 +97,14 @@ public static void setThreadStatus(Thread thread, int threadStatus) {
LoomSupport.CompatibilityUtil.setThreadStatus(toTarget(thread), threadStatus);
}

public static Target_sun_nio_ch_Interruptible getBlocker(Thread thread) {
if (JavaVersionUtil.JAVA_SPEC >= 19) {
return toTarget(thread).nioBlocker;
} else {
return toTarget(thread).blocker;
}
}

/** Safe method to get a thread's internal state since {@link Thread#getState} is not final. */
static Thread.State getThreadState(Thread thread) {
return Target_jdk_internal_misc_VM.toThreadState(getThreadStatus(thread));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -433,10 +433,11 @@ boolean joinNanos(long nanos) throws InterruptedException {
}

private Object interruptLock() {
if (JavaVersionUtil.JAVA_SPEC >= 19) {
throw VMError.unsupportedFeature("Loom is not yet supported on JDK 19");
if (JavaVersionUtil.JAVA_SPEC < 19) {
return JavaThreads.toTarget(this).blockerLock;
} else {
return JavaThreads.toTarget(this).interruptLock;
}
return JavaThreads.toTarget(this).blockerLock;
}

/** @see #releaseInterruptLockAndSwitchBack */
Expand Down Expand Up @@ -478,7 +479,7 @@ public void interrupt() {
Object token = switchToCarrierAndAcquireInterruptLock();
try {
JavaThreads.writeInterruptedFlag(this, true);
Target_sun_nio_ch_Interruptible b = JavaThreads.toTarget(this).blocker;
Target_sun_nio_ch_Interruptible b = JavaThreads.getBlocker(this);
if (b != null) {
b.interrupt(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ public final class Target_java_lang_Thread {

@Alias @TargetElement(onlyWith = JDK17OrEarlier.class) //
volatile Target_sun_nio_ch_Interruptible blocker;
@Alias @TargetElement(onlyWith = JDK19OrLater.class) //
volatile Target_sun_nio_ch_Interruptible nioBlocker;

/** @see JavaThreads#setCurrentThreadLockHelper */
@Inject @TargetElement(onlyWith = ContinuationsSupported.class) //
Expand Down Expand Up @@ -206,10 +208,10 @@ private static int nextThreadNum() {
null, 0,
Thread.NORM_PRIORITY, asDaemon, ThreadStatus.RUNNABLE);

if (LoomSupport.isEnabled() || JavaVersionUtil.JAVA_SPEC >= 19) {
tid = Target_java_lang_Thread_ThreadIdentifiers.next();
tid = nextThreadID();
if (JavaVersionUtil.JAVA_SPEC >= 19) {
interruptLock = new Object();
} else {
tid = nextThreadID();
blockerLock = new Object();
}
name = (withName != null) ? withName : ("System-" + nextThreadNum());
Expand Down Expand Up @@ -258,15 +260,6 @@ static Thread currentThread() {
return thread;
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
@Substitute
@TargetElement(onlyWith = LoomJDK.class)
private static Thread currentThread0() {
Thread thread = PlatformThreads.currentThread.get();
assert thread != null : "Thread has not been set yet";
return thread;
}

@Substitute
@TargetElement(onlyWith = JDK19OrLater.class)
static Thread currentCarrierThread() {
Expand Down Expand Up @@ -346,22 +339,7 @@ static String genThreadName() {
return "Thread-" + JavaThreads.threadInitNumber.incrementAndGet();
}

/**
* This constructor is only called by `VirtualThread#VirtualThread(Executor, String, int,
* Runnable)`.
*/
@Substitute
@TargetElement(onlyWith = LoomJDK.class)
private Target_java_lang_Thread(String name, int characteristics) {
/* Non-0 instance field initialization. */
this.interruptLock = new Object();

this.name = (name != null) ? name : "<unnamed>";
this.tid = Target_java_lang_Thread_ThreadIdentifiers.next();
this.contextClassLoader = Thread.currentThread().getContextClassLoader();
}

@SuppressWarnings("hiding")
@SuppressWarnings({"hiding", "deprecation"})
@Substitute
private void start0() {
if (!SubstrateOptions.MultiThreaded.getValue()) {
Expand Down Expand Up @@ -594,15 +572,9 @@ private static Thread[] getAllThreads() {
private static native void clearInterruptEvent();

@Substitute
@TargetElement(onlyWith = LoomJDK.class)
static Object[] scopedCache() {
throw VMError.unimplemented();
}

@Substitute
@TargetElement(onlyWith = LoomJDK.class)
static void setScopedCache(Object[] cache) {
throw VMError.unimplemented();
@TargetElement(onlyWith = JDK19OrLater.class)
boolean getAndClearInterrupt() {
return JavaThreads.getAndClearInterruptedFlag(JavaThreads.fromTarget(this));
}

@Alias @TargetElement(onlyWith = LoomJDK.class) //
Expand All @@ -616,6 +588,10 @@ static void setScopedCache(Object[] cache) {
@TargetElement(onlyWith = LoomJDK.class)
public static native Thread startVirtualThread(Runnable task);

@Alias
@TargetElement(onlyWith = JDK19OrLater.class)
static native String genThreadName();

}

@TargetClass(value = Thread.class, innerClass = "FieldHolder", onlyWith = JDK19OrLater.class)
Expand Down Expand Up @@ -658,6 +634,15 @@ static long next() {
}
}

@Substitute//
@TargetClass(value = Thread.class, innerClass = "ThreadNumbering", onlyWith = JDK19OrLater.class)
final class Target_java_lang_Thread_ThreadNumbering {
@Substitute//
static int next() {
return JavaThreads.threadNumber.incrementAndGet();
}
}

@TargetClass(value = Thread.class, innerClass = "VirtualThreads", onlyWith = {LoomJDK.class, JDK17OrEarlier.class})
final class Target_java_lang_Thread_VirtualThreads {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,6 @@ typedef struct {
char fSTXR_PREFETCH;
char fA53MAC;
char fDMB_ATOMICS;
char fPACA;
char fSVEBITPERM;
} CPUFeatures;
10 changes: 10 additions & 0 deletions substratevm/src/com.oracle.svm.native.libchelper/src/cpuid.c
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,8 @@ void determineCPUFeatures(CPUFeatures* features) {
features->fSTXR_PREFETCH = 0;
features->fA53MAC = 0;
features->fDMB_ATOMICS = 0;
features->fPACA = 0;
features->fSVEBITPERM = 0;
}

/*
Expand Down Expand Up @@ -674,9 +676,15 @@ void determineCPUFeatures(CPUFeatures* features) {
#ifndef HWCAP_SVE
#define HWCAP_SVE (1L << 22)
#endif
#ifndef HWCAP_PACA
#define HWCAP_PACA (1L << 30)
#endif
#ifndef HWCAP2_SVE2
#define HWCAP2_SVE2 (1L << 1)
#endif
#ifndef HWCAP2_SVEBITPERM
#define HWCAP2_SVEBITPERM (1L << 4)
#endif

#define CPU_ARM 'A'
#define CPU_CAVIUM 'C'
Expand Down Expand Up @@ -706,6 +714,8 @@ void determineCPUFeatures(CPUFeatures* features) {
features->fSTXR_PREFETCH = 0;
features->fA53MAC = 0;
features->fDMB_ATOMICS = 0;
features->fPACA = !!(auxv & HWCAP_PACA);
features->fSVEBITPERM = !!(auxv2 & HWCAP2_SVEBITPERM);

//checking for features signaled in another way

Expand Down