Skip to content

Commit cc12225

Browse files
committed
[GR-39165] [GR-39648] More java.lang.Thread fixes for Native Image on JDK 19
PullRequest: graal/12184
2 parents 5e6514e + 17cdf24 commit cc12225

File tree

8 files changed

+99
-57
lines changed

8 files changed

+99
-57
lines changed

common.json

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,7 @@
2323
"labsjdk-ce-19-llvm": {"name": "labsjdk", "version": "ce-19+27-jvmci-22.3-b01-sulong", "platformspecific": true },
2424
"labsjdk-ee-19": {"name": "labsjdk", "version": "ee-19.0.1+0-jvmci-22.3-b01", "platformspecific": true },
2525
"labsjdk-ee-19Debug": {"name": "labsjdk", "version": "ee-19.0.1+0-jvmci-22.3-b01-debug", "platformspecific": true },
26-
"labsjdk-ee-19-llvm": {"name": "labsjdk", "version": "ee-19.0.1+0-jvmci-22.3-b01-sulong", "platformspecific": true },
27-
28-
"jdk-19-ea": {
29-
"build_id": "jdk-19+28",
30-
"name": "jpg-jdk",
31-
"version": "19",
32-
"extrabundles": [
33-
"static_libs"
34-
],
35-
"platformspecific": true
36-
}
26+
"labsjdk-ee-19-llvm": {"name": "labsjdk", "version": "ee-19.0.1+0-jvmci-22.3-b01-sulong", "platformspecific": true }
3727
},
3828

3929
"COMMENT.devkits" : "The devkits versions reflect those used to build the JVMCI JDKs (e.g., see devkit_platform_revisions in <jdk>/make/conf/jib-profiles.js)",

common.jsonnet

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,41 @@
1-
{
2-
local composable = (import "common-utils.libsonnet").composable,
1+
local composable = (import "common-utils.libsonnet").composable;
2+
3+
local mx_version = (import "graal-common.json").mx_version;
4+
local common_json = composable(import "common.json");
5+
local repo_config = import 'repo-configuration.libsonnet';
6+
local jdks = common_json.jdks;
7+
local deps = common_json.deps;
8+
local downloads = common_json.downloads;
9+
10+
# Finds the first integer in a string and returns it as an integer.
11+
local find_first_integer(versionString) =
12+
local charToInt(c) =
13+
std.codepoint(c) - std.codepoint("0");
14+
local firstNum(s, i) =
15+
assert std.length(s) > i : "No number found in string " + s;
16+
local n = charToInt(s[i]);
17+
if n >=0 && n < 10 then i else firstNum(s, i + 1);
18+
local lastNum(s, i) =
19+
if i >= std.length(s) then
20+
i
21+
else
22+
local n = charToInt(s[i]);
23+
if n < 0 || n > 9 then i else lastNum(s, i + 1);
24+
local versionIndexStart = firstNum(versionString, 0);
25+
local versionIndexEnd = lastNum(versionString, versionIndexStart);
26+
std.parseInt(versionString[versionIndexStart:versionIndexEnd])
27+
;
28+
# jdk_version is an hidden field that can be used to generate job names
29+
local add_jdk_version(name) =
30+
local jdk = jdks[name];
31+
// this assumes that the version is the first number in the jdk.version string
32+
local version = find_first_integer(jdk.version);
33+
// santity check that the parsed version is also included in the name
34+
assert std.length(std.findSubstr(std.toString(version), name)) == 1 : "Cannot find version %d in name %s" % [version, name];
35+
{ jdk_version:: version}
36+
;
337

4-
local mx_version = (import "graal-common.json").mx_version,
5-
local common_json = composable(import "common.json"),
6-
local repo_config = import 'repo-configuration.libsonnet',
7-
local jdks = common_json.jdks,
8-
local deps = common_json.deps,
9-
local downloads = common_json.downloads,
38+
{
1039

1140
mx:: {
1241
packages+: {
@@ -74,36 +103,17 @@
74103
}
75104
},
76105

106+
} + {
77107
// JDK definitions
78108
// ***************
79-
# jdk_version is an hidden field that can be used to generate job names
80-
local jdk11 = { jdk_version:: 11},
81-
local jdk17 = { jdk_version:: 17},
82-
local jdk19 = { jdk_version:: 19},
83-
84-
oraclejdk11:: jdk11 + { downloads+: { JAVA_HOME : jdks.oraclejdk11 }},
85-
oraclejdk17:: jdk17 + { downloads+: { JAVA_HOME : jdks.oraclejdk17 }},
86-
openjdk11:: jdk11 + { downloads+: { JAVA_HOME : jdks.openjdk11 }},
87-
88-
"labsjdk-ce-11":: jdk11 + { downloads+: { JAVA_HOME : jdks["labsjdk-ce-11"] }},
89-
"labsjdk-ee-11":: jdk11 + { downloads+: { JAVA_HOME : jdks["labsjdk-ee-11"] }},
90-
"labsjdk-ce-17":: jdk17 + { downloads+: { JAVA_HOME : jdks["labsjdk-ce-17"] }},
91-
"labsjdk-ee-17":: jdk17 + { downloads+: { JAVA_HOME : jdks["labsjdk-ee-17"] }},
92-
"labsjdk-ce-17Debug":: jdk17 + { downloads+: { JAVA_HOME : jdks["labsjdk-ce-17Debug"] }},
93-
"labsjdk-ee-17Debug":: jdk17 + { downloads+: { JAVA_HOME : jdks["labsjdk-ee-17Debug"] }},
94-
"labsjdk-ce-11-llvm":: jdk11 + { downloads+: { LLVM_JAVA_HOME : jdks["labsjdk-ce-11-llvm"] }},
95-
"labsjdk-ee-11-llvm":: jdk11 + { downloads+: { LLVM_JAVA_HOME : jdks["labsjdk-ee-11-llvm"] }},
96-
"labsjdk-ce-17-llvm":: jdk17 + { downloads+: { LLVM_JAVA_HOME : jdks["labsjdk-ce-17-llvm"] }},
97-
"labsjdk-ee-17-llvm":: jdk17 + { downloads+: { LLVM_JAVA_HOME : jdks["labsjdk-ee-17-llvm"] }},
98-
99-
"labsjdk-ce-19":: jdk19 + { downloads+: { JAVA_HOME : jdks["jdk-19-ea"] + { open: false} }},
100-
"labsjdk-ee-19":: jdk19 + { downloads+: { JAVA_HOME : jdks["jdk-19-ea"] + { open: false} }},
101-
109+
// this adds all jdks from common.json
110+
[name]: add_jdk_version(name) + { downloads+: { [if std.endsWith(name, "llvm") then "LLVM_JAVA_HOME" else "JAVA_HOME"] : jdks[name] }},
111+
for name in std.objectFieldsAll(jdks)
112+
} + {
102113
# Aliases to edition specific labsjdks
103114
labsjdk11:: self["labsjdk-" + repo_config.graalvm_edition + "-11"],
104115
labsjdk17:: self["labsjdk-" + repo_config.graalvm_edition + "-17"],
105116
labsjdk19:: self["labsjdk-" + repo_config.graalvm_edition + "-19"],
106-
labsjdk11Debug:: self["labsjdk-" + repo_config.graalvm_edition + "-11Debug"],
107117
labsjdk17Debug:: self["labsjdk-" + repo_config.graalvm_edition + "-17Debug"],
108118
labsjdk11LLVM:: self["labsjdk-" + repo_config.graalvm_edition + "-11-llvm"],
109119
labsjdk17LLVM:: self["labsjdk-" + repo_config.graalvm_edition + "-17-llvm"],

substratevm/ci.jsonnet

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,7 @@
8080
linux_amd64_jdk11 + gate("build-ce", "build,checkstubs,helloworld,test,nativeimagehelp,muslcbuild,debuginfotest") + maven + svm_unittest + t("35:00") + musl_toolchain + gdb("10.2"),
8181
linux_amd64_jdk11 + gate("modules-basic", "build,hellomodule,test") + maven + svm_unittest + t("30:00"),
8282
linux_amd64_jdk17 + gate("style-fullbuild", "style,fullbuild,helloworld,test,svmjunit,debuginfotest") + common.eclipse + common.jdt + maven + jsonschema + svm_unittest + t("50:00") + mx_build_exploded + gdb("10.2"),
83-
linux_amd64_jdk19 + gate("build-ce", "build") + {
84-
run: [
85-
# cannot yet use mx gate --tag build due to compile errors in /compiler
86-
["mx", "build"],
87-
# cannot yet use mx gate --tag hello world due to missing JFR support in JDK 19
88-
["mx", "helloworld"],
89-
]
90-
} + maven + svm_unittest + t("35:00"),
83+
linux_amd64_jdk19 + gate("build-ce", "build,helloworld") + maven + svm_unittest + t("35:00"),
9184
windows_jdk17 + gate("basics", "build,helloworld,test,svmjunit") + svm_unittest + t("1:30:00"),
9285
windows_jdk17 + gate("basics-quickbuild", "build,helloworld_quickbuild,test_quickbuild,svmjunit_quickbuild") + svm_unittest + t("1:30:00"),
9386
],

substratevm/mx.substratevm/mx_substratevm.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,9 @@ def image_demo_task(extra_image_args=None, flightrecorder=True):
322322
javac_command = ['--javac-command', ' '.join(javac_image_command(svmbuild_dir()))]
323323
helloworld(image_args + javac_command)
324324
helloworld(image_args + ['--shared']) # Build and run helloworld as shared library
325-
if not mx.is_windows() and flightrecorder:
325+
# JFR is currently not supported on JDK 19 [GR-39564] [GR-39642]
326+
is_jdk_version_supported = mx.get_jdk().version < mx.VersionSpec("19")
327+
if is_jdk_version_supported and not mx.is_windows() and flightrecorder:
326328
helloworld(image_args + ['-J-XX:StartFlightRecording=dumponexit=true']) # Build and run helloworld with FlightRecorder at image build time
327329
cinterfacetutorial(extra_image_args)
328330
clinittest([])

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrFeature.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.Collections;
2828
import java.util.List;
2929

30+
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
3031
import org.graalvm.nativeimage.ImageSingletons;
3132
import org.graalvm.nativeimage.Platform;
3233
import org.graalvm.nativeimage.hosted.Feature;
@@ -106,6 +107,11 @@ public boolean isInConfiguration(IsInConfigurationAccess access) {
106107
}
107108

108109
public static boolean isInConfiguration(boolean allowPrinting) {
110+
boolean javaVersionSupported = JavaVersionUtil.JAVA_SPEC < 19;
111+
if (HOSTED_ENABLED && !javaVersionSupported) {
112+
// [GR-39564] [GR-39642]
113+
throw UserError.abort("FlightRecorder is currently not supported in JDK 19.");
114+
}
109115
boolean systemSupported = osSupported();
110116
if (HOSTED_ENABLED && !systemSupported) {
111117
throw UserError.abort("FlightRecorder cannot be used to profile the image generator on this platform. " +
@@ -119,7 +125,7 @@ public static boolean isInConfiguration(boolean allowPrinting) {
119125
}
120126
runtimeEnabled = true;
121127
}
122-
return runtimeEnabled && systemSupported;
128+
return javaVersionSupported && runtimeEnabled && systemSupported;
123129
}
124130

125131
private static boolean osSupported() {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/PlatformThreads.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,12 @@ static Map<Thread, StackTraceElement[]> getAllStackTraces() {
750750
return vmOp.result;
751751
}
752752

753+
static Thread[] getAllThreads() {
754+
GetAllThreadsOperation vmOp = new GetAllThreadsOperation();
755+
vmOp.enqueue();
756+
return vmOp.result.toArray(new Thread[0]);
757+
}
758+
753759
@NeverInline("Starting a stack walk in the caller frame")
754760
private static StackTraceElement[] getStackTrace(IsolateThread thread) {
755761
if (thread == CurrentIsolate.getCurrentThread()) {
@@ -943,6 +949,22 @@ protected void operate() {
943949
}
944950
}
945951

952+
private static class GetAllThreadsOperation extends JavaVMOperation {
953+
private final ArrayList<Thread> result;
954+
955+
GetAllThreadsOperation() {
956+
super(VMOperationInfos.get(GetAllThreadsOperation.class, "Get all threads", SystemEffect.SAFEPOINT));
957+
result = new ArrayList<>();
958+
}
959+
960+
@Override
961+
protected void operate() {
962+
for (IsolateThread cur = VMThreads.firstThread(); cur.isNonNull(); cur = VMThreads.nextThread(cur)) {
963+
result.add(PlatformThreads.fromVMThread(cur));
964+
}
965+
}
966+
}
967+
946968
/**
947969
* Builds a list of all application threads. This must be done in a VM operation because only
948970
* there we are allowed to allocate Java memory while holding the {@link VMThreads#THREAD_MUTEX}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_Thread.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ static Thread currentVThread() {
291291

292292
@SuppressWarnings("static-method")
293293
@Substitute
294-
@TargetElement(onlyWith = LoomJDK.class)
294+
@TargetElement(onlyWith = JDK19OrLater.class)
295295
void setCurrentThread(Thread thread) {
296296
PlatformThreads.setCurrentThread(JavaThreads.fromTarget(this), thread);
297297
}
@@ -336,7 +336,14 @@ private Target_java_lang_Thread(
336336
// TODO: derive from characteristics bitset
337337
boolean inheritThreadLocals = false;
338338
/* Initialize the rest of the Thread object, ignoring `characteristics`. */
339-
JavaThreads.initializeNewThread(this, g, target, name, stackSize, acc, inheritThreadLocals);
339+
String nameLocal = (name != null) ? name : genThreadName();
340+
JavaThreads.initializeNewThread(this, g, target, nameLocal, stackSize, acc, inheritThreadLocals);
341+
}
342+
343+
@Substitute
344+
@TargetElement(onlyWith = JDK19OrLater.class)
345+
static String genThreadName() {
346+
return "Thread-" + JavaThreads.threadInitNumber.incrementAndGet();
340347
}
341348

342349
/**
@@ -558,6 +565,12 @@ private static Map<Thread, StackTraceElement[]> getAllStackTraces() {
558565
return PlatformThreads.getAllStackTraces();
559566
}
560567

568+
@Substitute
569+
@TargetElement(onlyWith = JDK19OrLater.class)
570+
private static Thread[] getAllThreads() {
571+
return PlatformThreads.getAllThreads();
572+
}
573+
561574
/**
562575
* In the JDK, this is a no-op except on Windows. The JDK resets the interrupt event used by
563576
* Process.waitFor ResetEvent((HANDLE) JVM_GetThreadInterruptEvent()); Our implementation in

vm/ci_includes/vm.jsonnet

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ local jdks = common_json.jdks;
2626

2727
vm_java_19:: graal_common.labsjdk19 + {
2828
environment+: {
29-
BASE_JDK_NAME: jdks['jdk-19-ea'].name,
30-
BASE_JDK_VERSION: jdks['jdk-19-ea'].version,
29+
BASE_JDK_NAME: jdks['labsjdk-ce-19'].name,
30+
BASE_JDK_VERSION: jdks['labsjdk-ce-19'].version,
3131
BASE_JDK_SHORT_VERSION: '19',
3232
},
3333
},
@@ -44,6 +44,12 @@ local jdks = common_json.jdks;
4444
},
4545
},
4646

47+
vm_java_19_llvm:: self.vm_java_19 + {
48+
downloads+: {
49+
LLVM_JAVA_HOME: jdks['labsjdk-ce-19-llvm'],
50+
},
51+
},
52+
4753
binaries_repository: 'lafo',
4854
svm_suite:: '/substratevm',
4955
libgraal_env: 'libgraal',

0 commit comments

Comments
 (0)