Skip to content

Commit 39ea681

Browse files
committed
remove org.graalvm.nativeimage dependency from jdk.graal.compiler
1 parent 07564f5 commit 39ea681

File tree

62 files changed

+509
-391
lines changed

Some content is hidden

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

62 files changed

+509
-391
lines changed

compiler/mx.compiler/suite.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,6 @@
170170
"dependencies" : [
171171
"sdk:WORD",
172172
"sdk:COLLECTIONS",
173-
"sdk:NATIVEIMAGE",
174173
"truffle:TRUFFLE_COMPILER",
175174
],
176175
"requires" : [
@@ -643,7 +642,6 @@
643642
"distDependencies" : [
644643
"sdk:COLLECTIONS",
645644
"sdk:WORD",
646-
"sdk:NATIVEIMAGE",
647645
"truffle:TRUFFLE_COMPILER",
648646
],
649647
"allowsJavadocWarnings": True,
@@ -680,6 +678,7 @@
680678
"jdk.graal.compiler.libgraal.loader"
681679
],
682680
"distDependencies" : [
681+
"sdk:NATIVEIMAGE",
683682
"sdk:NATIVEIMAGE_LIBGRAAL",
684683
"GRAAL",
685684
],
@@ -699,10 +698,12 @@
699698
"distDependencies": [
700699
"GRAAL",
701700
"GRAAL_MANAGEMENT",
701+
"sdk:NATIVEIMAGE",
702702
"sdk:NATIVEIMAGE_LIBGRAAL",
703+
"sdk:COLLECTIONS",
703704
"sdk:JNIUTILS",
704-
"sdk:NATIVEIMAGE",
705-
"sdk:NATIVEBRIDGE"
705+
"sdk:NATIVEBRIDGE",
706+
"truffle:TRUFFLE_COMPILER"
706707
],
707708
"maven": False,
708709
},

compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/LibGraalFeature.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,11 @@
4747
import java.util.function.Consumer;
4848
import java.util.stream.Collectors;
4949

50+
import jdk.graal.compiler.core.common.NativeImageSupport;
5051
import jdk.graal.compiler.hotspot.CompilerConfig;
5152
import org.graalvm.collections.EconomicMap;
5253
import org.graalvm.jniutils.NativeBridgeSupport;
54+
import org.graalvm.nativeimage.ImageInfo;
5355
import org.graalvm.nativeimage.ImageSingletons;
5456
import org.graalvm.nativeimage.Platform;
5557
import org.graalvm.nativeimage.Platforms;
@@ -60,6 +62,7 @@
6062
import org.graalvm.nativeimage.libgraal.LibGraalLoader;
6163

6264
import jdk.graal.compiler.core.common.Fields;
65+
import jdk.graal.compiler.core.common.LibGraalSupport.HostedOnly;
6366
import jdk.graal.compiler.core.common.spi.ForeignCallSignature;
6467
import jdk.graal.compiler.debug.GraalError;
6568
import jdk.graal.compiler.graph.Edges;
@@ -146,6 +149,12 @@ private static Path readLibgraalJavaHome(ClassLoader cl) {
146149

147150
@Override
148151
public void afterRegistration(AfterRegistrationAccess access) {
152+
// Check that NativeImageSupport.inBuildtimeCode() and ImageInfo.inImageBuildtimeCode()
153+
// agree on the system property key and value they rely on.
154+
GraalError.guarantee(ImageInfo.PROPERTY_IMAGE_CODE_KEY.equals("org.graalvm.nativeimage.imagecode") &&
155+
ImageInfo.PROPERTY_IMAGE_CODE_VALUE_BUILDTIME.equals("buildtime"),
156+
"%s is out of sync with %s", NativeImageSupport.class, ImageInfo.class);
157+
149158
ImageSingletons.add(NativeBridgeSupport.class, new LibGraalNativeBridgeSupport());
150159

151160
// All qualified exports to libgraal modules need to be further exported to
@@ -290,7 +299,7 @@ private Map.Entry<long[], Long> computeReplacement(Object receiver) {
290299
}
291300

292301
/**
293-
* List of reached elements annotated by {@link LibGraalSupport.HostedOnly}.
302+
* List of reached elements annotated by {@link HostedOnly}.
294303
*/
295304
private final List<Object> reachedHostedOnlyElements = new ArrayList<>();
296305

@@ -303,7 +312,7 @@ public void accept(DuringAnalysisAccess duringAnalysisAccess) {
303312

304313
private void registerHostedOnlyElements(BeforeAnalysisAccess access, AnnotatedElement... elements) {
305314
for (AnnotatedElement element : elements) {
306-
if (element.getAnnotation(LibGraalSupport.HostedOnly.class) != null) {
315+
if (element.getAnnotation(HostedOnly.class) != null) {
307316
access.registerReachabilityHandler(new HostedOnlyElementCallback(element, reachedHostedOnlyElements), element);
308317
}
309318
}
@@ -446,12 +455,9 @@ public void afterAnalysis(AfterAnalysisAccess access) {
446455
suggestions.computeIfAbsent(name, k -> new TreeSet<>()).add(value);
447456
}
448457
var sep = System.lineSeparator() + " ";
449-
var s = suggestions.entrySet().stream()
450-
.map(e -> e.getValue().stream()
451-
.map(v -> "-H:AbortOn" + e.getKey() + "Reachable" + "=" + v)
452-
.collect(Collectors.joining(sep)))
453-
.collect(Collectors.joining(sep));
454-
String anno = LibGraalSupport.HostedOnly.class.getSimpleName();
458+
var s = suggestions.entrySet().stream().map(e -> e.getValue().stream().map(v -> "-H:AbortOn" + e.getKey() + "Reachable" + "=" + v).collect(Collectors.joining(sep))).collect(
459+
Collectors.joining(sep));
460+
String anno = HostedOnly.class.getSimpleName();
455461
throw new IllegalArgumentException("@" + anno + " annotated elements reached. Add following Native Image flags to see why they are reachable:" + sep + s);
456462
}
457463
}

compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/VerifyLibGraalContextChecks.java

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -26,29 +26,17 @@
2626

2727
import java.util.List;
2828

29-
import jdk.graal.compiler.hotspot.HotSpotGraalCompilerFactory;
3029
import jdk.graal.compiler.nodes.StructuredGraph;
3130
import jdk.graal.compiler.nodes.java.LoadFieldNode;
3231
import jdk.graal.compiler.nodes.spi.CoreProviders;
3332
import jdk.graal.compiler.phases.VerifyPhase;
3433
import jdk.graal.compiler.serviceprovider.GraalServices;
3534
import jdk.vm.ci.meta.ResolvedJavaField;
36-
import jdk.vm.ci.meta.ResolvedJavaMethod;
3735
import jdk.vm.ci.meta.ResolvedJavaType;
3836
import jdk.vm.ci.services.Services;
39-
import org.graalvm.nativeimage.ImageInfo;
4037

4138
/**
42-
* Ensures that the only code directly accessing
43-
* {@link jdk.vm.ci.services.Services#IS_IN_NATIVE_IMAGE} is in
44-
* {@link jdk.graal.compiler.serviceprovider.GraalServices}. All other code must use one of the
45-
* following methods:
46-
* <ul>
47-
* <li>{@link GraalServices#isInLibgraal()}</li>
48-
* <li>{@link ImageInfo#inImageCode()}</li>
49-
* <li>{@link ImageInfo#inImageBuildtimeCode()}</li>
50-
* <li>{@link ImageInfo#inImageRuntimeCode()}</li>
51-
* </ul>
39+
* Ensures that no code accesses {@link jdk.vm.ci.services.Services#IS_IN_NATIVE_IMAGE}.
5240
*/
5341
public class VerifyLibGraalContextChecks extends VerifyPhase<CoreProviders> {
5442

@@ -57,16 +45,6 @@ public boolean checkContract() {
5745
return false;
5846
}
5947

60-
static boolean isAllowedToAccess(ResolvedJavaMethod method) {
61-
if (method.getDeclaringClass().toJavaName().equals(GraalServices.class.getName())) {
62-
return method.getName().equals("isBuildingLibgraal") || method.getName().equals("isInLibgraal");
63-
}
64-
if (method.getDeclaringClass().toJavaName().equals(HotSpotGraalCompilerFactory.class.getName())) {
65-
return method.getName().equals("createCompiler");
66-
}
67-
return false;
68-
}
69-
7048
@Override
7149
protected void verify(StructuredGraph graph, CoreProviders context) {
7250

@@ -78,13 +56,11 @@ protected void verify(StructuredGraph graph, CoreProviders context) {
7856
ResolvedJavaField field = load.field();
7957
if (field.getDeclaringClass().toJavaName().equals(Services.class.getName())) {
8058
if (field.getName().equals("IS_IN_NATIVE_IMAGE")) {
81-
if (!isAllowedToAccess(graph.method())) {
82-
throw new VerificationError("reading %s in %s is prohibited - use %s.isInLibgraal() instead",
83-
field.format("%H.%n"),
84-
graph.method().format("%H.%n(%p)"),
85-
GraalServices.class.getName());
59+
throw new VerificationError("reading %s in %s is prohibited - use %s.isInLibgraal() instead",
60+
field.format("%H.%n"),
61+
graph.method().format("%H.%n(%p)"),
62+
GraalServices.class.getName());
8663

87-
}
8864
}
8965
}
9066
}

compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/VerifySystemPropertyUsage.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
*/
2525
package jdk.graal.compiler.core.test;
2626

27+
import jdk.graal.compiler.core.common.NativeImageSupport;
2728
import jdk.graal.compiler.nodes.StructuredGraph;
2829
import jdk.graal.compiler.nodes.java.MethodCallTargetNode;
2930
import jdk.graal.compiler.nodes.spi.CoreProviders;
@@ -89,6 +90,9 @@ protected void verify(StructuredGraph graph, CoreProviders context) {
8990
} else if (holderQualified.equals("jdk.graal.compiler.hotspot.HotSpotReplacementsImpl") && caller.getName().equals("registerSnippet")) {
9091
// We allow opening snippet registration in jargraal unit tests.
9192
return;
93+
} else if (holderQualified.equals(NativeImageSupport.class.getName())) {
94+
// Called as part of initializing GraalServices
95+
return;
9296
}
9397
for (MethodCallTargetNode t : graph.getNodes(MethodCallTargetNode.TYPE)) {
9498
ResolvedJavaMethod callee = t.targetMethod();
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package jdk.graal.compiler.hotspot.test;
26+
27+
import java.io.IOException;
28+
import java.nio.file.Files;
29+
import java.nio.file.Path;
30+
import java.util.List;
31+
import java.util.Set;
32+
import java.util.regex.Pattern;
33+
import java.util.stream.Collectors;
34+
35+
import org.graalvm.nativeimage.ImageInfo;
36+
import org.junit.Test;
37+
38+
import jdk.graal.compiler.core.GraalCompiler;
39+
import jdk.graal.compiler.core.test.GraalCompilerTest;
40+
import jdk.graal.compiler.debug.GraalError;
41+
import jdk.graal.compiler.serviceprovider.GraalServices;
42+
import jdk.graal.compiler.test.SubprocessUtil;
43+
import jdk.graal.compiler.test.SubprocessUtil.Subprocess;
44+
45+
/**
46+
* Tests that {@code jdk.graal.compiler} does not have unwanted dependencies such as
47+
* {@code org.graalvm.nativeimage}.
48+
*/
49+
public class GraalModuleDependenciesTest extends GraalCompilerTest {
50+
51+
static Path getJavaExe() {
52+
Path javaHome = Path.of(System.getProperty("java.home"));
53+
boolean isWindows = GraalServices.getSavedProperty("os.name").contains("Windows");
54+
Path javaExe = javaHome.resolve(Path.of("bin", isWindows ? "java.exe" : "java"));
55+
if (!Files.isExecutable(javaExe)) {
56+
throw new GraalError("Java launcher %s does not exist or is not executable", javaExe);
57+
}
58+
return javaExe;
59+
}
60+
61+
private static Subprocess run(String... command) throws InterruptedException, IOException {
62+
Subprocess proc = SubprocessUtil.java(List.of(command));
63+
if (proc.exitCode != 0) {
64+
fail("Non-zero exit code:%n%s", proc.preserveArgfile());
65+
}
66+
return proc;
67+
}
68+
69+
private static String removeVersionSuffix(String moduleName) {
70+
int at = moduleName.indexOf('@');
71+
if (at == -1) {
72+
return moduleName;
73+
}
74+
return moduleName.substring(0, at);
75+
}
76+
77+
@Test
78+
public void test() throws InterruptedException, IOException {
79+
String javaExe = getJavaExe().toString();
80+
Subprocess proc = run(javaExe,
81+
"--limit-modules=jdk.graal.compiler",
82+
"--list-modules");
83+
84+
String graal = GraalCompiler.class.getModule().getName();
85+
String nativeImage = ImageInfo.class.getModule().getName();
86+
Set<String> moduleNames = proc.output.stream().map(GraalModuleDependenciesTest::removeVersionSuffix).collect(Collectors.toSet());
87+
if (!moduleNames.contains(graal)) {
88+
fail("Missing Graal (%s):%n%s", graal, proc.preserveArgfile());
89+
}
90+
if (moduleNames.contains(nativeImage)) {
91+
fail("Native Image API (%s) should not be a dependency of Graal (%s):%n%s", nativeImage, graal, proc.preserveArgfile());
92+
}
93+
94+
proc = run(javaExe,
95+
"--limit-modules=jdk.graal.compiler",
96+
"-XX:+EagerJVMCI",
97+
"-Djdk.graal.ShowConfiguration=info",
98+
"--version");
99+
Pattern expect = Pattern.compile("^Using .* loaded from class files");
100+
if (proc.output.stream().noneMatch(line -> expect.matcher(line).find())) {
101+
fail("Did not find line matching %s%n%s", expect, proc.preserveArgfile());
102+
}
103+
}
104+
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/CompilationWatchDog.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,8 @@
3131
import java.util.concurrent.ThreadFactory;
3232
import java.util.concurrent.TimeUnit;
3333

34-
import org.graalvm.nativeimage.ImageInfo;
35-
3634
import jdk.graal.compiler.core.common.CompilationIdentifier;
35+
import jdk.graal.compiler.core.common.NativeImageSupport;
3736
import jdk.graal.compiler.core.common.util.Util;
3837
import jdk.graal.compiler.debug.TTY;
3938
import jdk.graal.compiler.options.Option;
@@ -336,7 +335,7 @@ private static ScheduledExecutorService createExecutor(ThreadFactory factory) {
336335
public static CompilationWatchDog watch(CompilationIdentifier compilation, OptionValues options,
337336
boolean singleShotExecutor, EventHandler eventHandler, ThreadFactory factory) {
338337
int delay = Options.CompilationWatchDogStartDelay.getValue(options);
339-
if (ImageInfo.inImageBuildtimeCode() && !Options.CompilationWatchDogStartDelay.hasBeenSet(options)) {
338+
if (NativeImageSupport.inBuildtimeCode() && !Options.CompilationWatchDogStartDelay.hasBeenSet(options)) {
340339
// Disable watch dog by default when building a native image
341340
delay = 0;
342341
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/LibGraalSupport.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525
package jdk.graal.compiler.core.common;
2626

2727
import org.graalvm.collections.EconomicMap;
28-
import org.graalvm.nativeimage.Platform;
29-
import org.graalvm.nativeimage.Platforms;
3028

3129
import java.io.PrintStream;
3230
import java.lang.annotation.ElementType;
@@ -51,11 +49,11 @@ public interface LibGraalSupport {
5149
/**
5250
* Denotes that the annotated element (type, method, or field) is only visible when running
5351
* hosted on HotSpot (i.e., jargraal or while building libgraal) but not cannot be used at
54-
* libgraal run time.
52+
* libgraal run time. This annotation is ignored when building a non-libgraal native image.
5553
*/
5654
@Retention(RetentionPolicy.RUNTIME)
5755
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD})
58-
public @interface HostedOnly {
56+
@interface HostedOnly {
5957
}
6058

6159
/**
@@ -84,7 +82,7 @@ public interface LibGraalSupport {
8482
* @param initialValue the initial value of the off-heap word
8583
* @return a supplier of the address of the off-heap word
8684
*/
87-
@Platforms(Platform.HOSTED_ONLY.class)
85+
@LibGraalSupport.HostedOnly
8886
Supplier<Long> createGlobal(long initialValue);
8987

9088
/**
@@ -109,7 +107,7 @@ public interface LibGraalSupport {
109107
/**
110108
* Enqueues pending {@link Reference}s into their corresponding {@link ReferenceQueue}s and
111109
* executes pending cleaners.
112-
*
110+
* <p>
113111
* If automatic reference handling is enabled, this method is a no-op.
114112
*/
115113
void processReferences();
@@ -156,19 +154,21 @@ public interface LibGraalSupport {
156154
void shutdown(String callbackClassName, String callbackMethodName);
157155

158156
/**
159-
* Non-null iff accessed in the context of the libgraal class loader or if executing in the
157+
* Returns true if the current runtime is in the libgraal native image (i.e. SVM).
158+
*/
159+
static boolean inLibGraalRuntime() {
160+
return false;
161+
}
162+
163+
/**
164+
* Non-null iff accessed in the context of the libgraal class loader or executing in the
160165
* libgraal runtime.
161166
*/
162167
LibGraalSupport INSTANCE = Init.init();
163168

164169
/**
165-
* @return true iff called from classes loaded by the libgraal class loader or if executing in
166-
* the libgraal runtime
170+
* Initializaton support for {@link LibGraalSupport#INSTANCE}.
167171
*/
168-
static boolean inLibGraal() {
169-
return INSTANCE != null;
170-
}
171-
172172
class Init {
173173
@SuppressWarnings("try")
174174
static LibGraalSupport init() {

0 commit comments

Comments
 (0)