From 4dfdd8e5a232332ede1fdaafcd98d09b4c8eee28 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Mon, 4 Nov 2024 16:49:55 +0100 Subject: [PATCH 01/31] use class literals where possible --- substratevm/mx.substratevm/suite.py | 3 +- .../hotspot/libgraal/LibGraalFeature.java | 45 ++++++++++++------- .../LibGraalFieldsOffsetsFeature.java | 7 +-- .../libgraal/LibGraalSubstitutions.java | 30 ++++++------- 4 files changed, 50 insertions(+), 35 deletions(-) diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py index c1076f561a03..c2801a9fe4dd 100644 --- a/substratevm/mx.substratevm/suite.py +++ b/substratevm/mx.substratevm/suite.py @@ -1407,7 +1407,8 @@ "jdk.internal.vm.ci" : [ "jdk.vm.ci.services", "jdk.vm.ci.runtime", - "jdk.vm.ci.code" + "jdk.vm.ci.code", + "jdk.vm.ci.hotspot" ], }, "annotationProcessors": [ diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java index 6ddc9b091704..2e3b23750891 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java @@ -43,6 +43,10 @@ import java.util.function.Function; import java.util.regex.Pattern; +import jdk.graal.compiler.lir.phases.LIRPhase; +import jdk.graal.compiler.phases.BasePhase; +import jdk.graal.compiler.serviceprovider.GlobalAtomicLong; +import jdk.vm.ci.hotspot.HotSpotModifiers; import org.graalvm.collections.EconomicMap; import org.graalvm.jniutils.NativeBridgeSupport; import org.graalvm.nativeimage.ImageSingletons; @@ -135,12 +139,20 @@ public List> getRequiredFeatures() { private Function, Object> newLIRPhaseStatistics; - MethodHandle handleGlobalAtomicLongGetInitialValue; + /** + * Handle to {@link GlobalAtomicLong#getInitialValue()} in the guest. + */ + MethodHandle globalAtomicLongGetInitialValue; public ClassLoader getLoader() { return loader; } + /** + * Loads the class {@code c} in the libgraal class loader. + * + * @throws Error if loading fails + */ public Class loadClassOrFail(Class c) { if (c.getClassLoader() == loader) { return c; @@ -151,6 +163,13 @@ public Class loadClassOrFail(Class c) { return loadClassOrFail(c.getName()); } + /** + * Loads the class named {@code name} in the libgraal class loader. The + * {@link #loadClassOrFail(Class)} method should be used instead if the relevant class literal + * is accessible. + * + * @throws Error if loading fails + */ public Class loadClassOrFail(String name) { try { return loader.loadClass(name); @@ -189,18 +208,14 @@ public void afterRegistration(AfterRegistrationAccess access) { loader = libGraalClassLoader.getClassLoader(); ImageSingletons.lookup(ClassForNameSupport.class).setLibGraalLoader(loader); - buildTimeClass = loadClassOrFail("jdk.graal.compiler.hotspot.libgraal.BuildTime"); + buildTimeClass = loadClassOrFail(BuildTime.class); // Guest JVMCI and Graal need access to some JDK internal packages String[] basePackages = {"jdk.internal.misc", "jdk.internal.util", "jdk.internal.vm"}; ModuleSupport.accessPackagesToClass(ModuleSupport.Access.EXPORT, null, false, "java.base", basePackages); try { - /* - * Get GlobalAtomicLong.getInitialValue() method from LibGraalClassLoader for - * LibGraalGraalSubstitutions.GlobalAtomicLongAddressProvider FieldValueTransformer - */ - handleGlobalAtomicLongGetInitialValue = mhl.findVirtual(loadClassOrFail("jdk.graal.compiler.serviceprovider.GlobalAtomicLong"), + globalAtomicLongGetInitialValue = mhl.findVirtual(loadClassOrFail(GlobalAtomicLong.class), "getInitialValue", methodType(long.class)); } catch (Throwable e) { @@ -238,16 +253,16 @@ public void duringSetup(DuringSetupAccess access) { access.registerObjectReplacer(obj -> obj == loader ? customRuntimeLoader : obj); try { - var basePhaseStatisticsClass = loadClassOrFail("jdk.graal.compiler.phases.BasePhase$BasePhaseStatistics"); - var lirPhaseStatisticsClass = loadClassOrFail("jdk.graal.compiler.lir.phases.LIRPhase$LIRPhaseStatistics"); + var basePhaseStatisticsClass = loadClassOrFail(BasePhase.BasePhaseStatistics.class); + var lirPhaseStatisticsClass = loadClassOrFail(LIRPhase.LIRPhaseStatistics.class); MethodType statisticsCTorType = methodType(void.class, Class.class); var basePhaseStatisticsCTor = mhl.findConstructor(basePhaseStatisticsClass, statisticsCTorType); var lirPhaseStatisticsCTor = mhl.findConstructor(lirPhaseStatisticsClass, statisticsCTorType); newBasePhaseStatistics = new StatisticsCreator(basePhaseStatisticsCTor)::create; newLIRPhaseStatistics = new StatisticsCreator(lirPhaseStatisticsCTor)::create; - basePhaseClass = loadClassOrFail("jdk.graal.compiler.phases.BasePhase"); - lirPhaseClass = loadClassOrFail("jdk.graal.compiler.lir.phases.LIRPhase"); + basePhaseClass = loadClassOrFail(BasePhase.class); + lirPhaseClass = loadClassOrFail(LIRPhase.class); ImageSingletons.add(LibGraalCompilerSupport.class, new LibGraalCompilerSupport()); } catch (Throwable e) { @@ -258,7 +273,7 @@ public void duringSetup(DuringSetupAccess access) { accessImpl.registerClassReachabilityListener(this::registerPhaseStatistics); optionCollector = new OptionCollector(LibGraalEntryPoints.vmOptionDescriptors); access.registerObjectReachabilityHandler(optionCollector::accept, OptionKey.class); - access.registerObjectReachabilityHandler(optionCollector::accept, loadClassOrFail(OptionKey.class.getName())); + access.registerObjectReachabilityHandler(optionCollector::accept, loadClassOrFail(OptionKey.class)); GetJNIConfig.register(loader); } @@ -376,11 +391,11 @@ public void beforeAnalysis(BeforeAnalysisAccess baa) { var bb = impl.getBigBang(); /* Contains static fields that depend on HotSpotJVMCIRuntime */ - RuntimeClassInitialization.initializeAtRunTime(loadClassOrFail("jdk.vm.ci.hotspot.HotSpotModifiers")); + RuntimeClassInitialization.initializeAtRunTime(loadClassOrFail(HotSpotModifiers.class)); RuntimeClassInitialization.initializeAtRunTime(loadClassOrFail("jdk.vm.ci.hotspot.HotSpotCompiledCodeStream")); RuntimeClassInitialization.initializeAtRunTime(loadClassOrFail("jdk.vm.ci.hotspot.HotSpotCompiledCodeStream$Tag")); /* ThreadLocal in static field jdk.graal.compiler.debug.DebugContext.activated */ - RuntimeClassInitialization.initializeAtRunTime(loadClassOrFail("jdk.graal.compiler.debug.DebugContext")); + RuntimeClassInitialization.initializeAtRunTime(loadClassOrFail(DebugContext.class)); /* Needed for runtime calls to BoxingSnippets.Templates.getCacheClass(JavaKind) */ RuntimeReflection.registerAllDeclaredClasses(Character.class); @@ -406,7 +421,7 @@ public void beforeAnalysis(BeforeAnalysisAccess baa) { List> guestServiceClasses = new ArrayList<>(); List> serviceClasses = impl.getImageClassLoader().findAnnotatedClasses(LibGraalService.class, false); - serviceClasses.stream().map(c -> loadClassOrFail(c.getName())).forEach(guestServiceClasses::add); + serviceClasses.stream().map(this::loadClassOrFail).forEach(guestServiceClasses::add); // Transfer libgraal qualifier (e.g. "PGO optimized") from host to guest. String nativeImageLocationQualifier = CompilerConfigurationFactory.getNativeImageLocationQualifier(); diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFieldsOffsetsFeature.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFieldsOffsetsFeature.java index a5474369f3e0..2fb3c50021ce 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFieldsOffsetsFeature.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFieldsOffsetsFeature.java @@ -33,6 +33,7 @@ import java.util.Map; import java.util.function.Function; +import jdk.graal.compiler.hotspot.libgraal.BuildTime; import org.graalvm.collections.EconomicMap; import org.graalvm.nativeimage.ImageSingletons; @@ -105,8 +106,8 @@ protected FieldsOffsetsReplacement(Object fields) { } static class FieldsOffsetsReplacements { - protected final Map replacements = new IdentityHashMap<>(); - protected boolean sealed; + private final Map replacements = new IdentityHashMap<>(); + private boolean sealed; } private static Map getReplacements() { @@ -165,7 +166,7 @@ public void duringSetup(DuringSetupAccess a) { public void beforeAnalysis(BeforeAnalysisAccess access) { MethodHandle getInputEdgesOffsets; MethodHandle getSuccessorEdgesOffsets; - var buildTimeClass = libGraalFeature.loadClassOrFail("jdk.graal.compiler.hotspot.libgraal.BuildTime"); + var buildTimeClass = libGraalFeature.loadClassOrFail(BuildTime.class); try { MethodType offsetAccessorSignature = MethodType.methodType(long[].class, Object.class); getInputEdgesOffsets = mhl.findStatic(buildTimeClass, "getInputEdgesOffsets", offsetAccessorSignature); diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalSubstitutions.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalSubstitutions.java index 14b29ffd7afd..082d10a69729 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalSubstitutions.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalSubstitutions.java @@ -30,7 +30,7 @@ import java.util.Map; import java.util.function.Supplier; -import jdk.graal.compiler.word.Word; +import jdk.graal.compiler.libgraal.LibGraalFeature; import org.graalvm.jniutils.JNI; import org.graalvm.jniutils.JNIExceptionWrapper; import org.graalvm.jniutils.JNIMethodScope; @@ -63,6 +63,9 @@ import com.oracle.svm.core.util.VMError; import com.oracle.svm.graal.hotspot.LibGraalJNIMethodScope; +import jdk.graal.compiler.serviceprovider.GlobalAtomicLong; +import jdk.graal.compiler.word.Word; + class LibGraalJVMCISubstitutions { @TargetClass(className = "jdk.vm.ci.services.Services", classLoader = LibGraalClassLoaderSupplier.class, onlyWith = LibGraalFeature.IsEnabled.class) @@ -168,20 +171,16 @@ static final class Target_jdk_graal_compiler_serviceprovider_GlobalAtomicLong { @Delete private long address; - /* - * Graal class GlobalAtomicLong uses a java.lang.ref.Cleaner in static field - * GlobalAtomicLong.cleaner to ensure all native memory allocated by GlobalAtomicLong - * instances get freed when the instances are garbage collected. - * - * Native image does not support java.lang.ref.Cleaner. Instead, we can use a - * CGlobalData per GlobalAtomicLong instance if we can guarantee that no instances - * are created at libgraal-runtime. I.e. all GlobalAtomicLongs in the libgraal-image are - * image-heap objects. + /** + * {@link GlobalAtomicLong} in jargraal uses a {@link Cleaner} to ensure all native memory + * allocated by {@link GlobalAtomicLong} instances is freed when the instances are garbage + * collected. In libgraal, no {@link GlobalAtomicLong} instances are created at runtime so + * no cleaner is needed. */ @Delete private static Cleaner cleaner; /** - * Delete the constructor to ensure instances of {@code GlobalAtomicLong} cannot be created + * Delete the constructor to ensure instances of {@link GlobalAtomicLong} cannot be created * at runtime. */ @Substitute @@ -197,10 +196,9 @@ private long getAddress() { } } - /* - * The challenge with using CGlobalData for GlobalAtomicLongs is that we do have to - * make sure they get initialized with the correct initialValue for a given GlobalAtomicLong - * instance at image build-time. This FieldValueTransformer ensures that. + /** + * A field value transformer for the {@code addressSupplier} field injected into a + * {@link GlobalAtomicLong} that copies the build-time {@code initialValue}. */ @Platforms(HOSTED_ONLY.class) private static final class GlobalAtomicLongAddressProvider implements FieldValueTransformer { @@ -208,7 +206,7 @@ private static final class GlobalAtomicLongAddressProvider implements FieldValue public Object transform(Object receiver, Object originalValue) { long initialValue; try { - initialValue = (long) ImageSingletons.lookup(LibGraalFeature.class).handleGlobalAtomicLongGetInitialValue.invoke(receiver); + initialValue = (long) ImageSingletons.lookup(LibGraalFeature.class).globalAtomicLongGetInitialValue.invoke(receiver); } catch (Throwable e) { throw VMError.shouldNotReachHere(e); } From 4e980592c4351f827dfc123f3bbdbdad05ff9bc9 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Fri, 8 Nov 2024 15:20:37 +0100 Subject: [PATCH 02/31] remove LibGraal dependency on java.management and some SVM internals --- .../hotspot/libgraal/LibGraalClassLoader.java | 13 ++++- .../compiler/hotspot/libgraal/BuildTime.java | 6 +-- .../compiler/hotspot/libgraal/RunTime.java | 14 +++-- .../hotspot/libgraal/LibGraalEntryPoints.java | 9 +--- .../hotspot/libgraal/LibGraalFeature.java | 52 +++++++++++++------ 5 files changed, 56 insertions(+), 38 deletions(-) diff --git a/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/hotspot/libgraal/LibGraalClassLoader.java b/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/hotspot/libgraal/LibGraalClassLoader.java index aaf39c51dd3b..6e8eb5a6d337 100644 --- a/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/hotspot/libgraal/LibGraalClassLoader.java +++ b/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/hotspot/libgraal/LibGraalClassLoader.java @@ -46,13 +46,14 @@ import java.util.Objects; import java.util.Set; +import jdk.graal.compiler.serviceprovider.LibGraalService; +import jdk.internal.jimage.BasicImageReader; +import jdk.internal.jimage.ImageLocation; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; import org.graalvm.nativeimage.hosted.Feature; import jdk.graal.compiler.debug.GraalError; -import jdk.internal.jimage.BasicImageReader; -import jdk.internal.jimage.ImageLocation; import jdk.internal.module.Modules; /** @@ -103,6 +104,14 @@ final class HostedLibGraalClassLoader extends ClassLoader implements LibGraalCla "org.graalvm.truffle.compiler", "com.oracle.graal.graal_enterprise"); + /** + * Modules containing classes that can be annotated by {@link LibGraalService}. + */ + private static final Set LIBGRAAL_SERVICES_MODULES = Set.of( + "jdk.graal.compiler", + "org.graalvm.truffle.compiler", + "com.oracle.graal.graal_enterprise"); + static { ClassLoader.registerAsParallelCapable(); } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/BuildTime.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/BuildTime.java index bad8cbed8d48..3d65885b7b22 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/BuildTime.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/BuildTime.java @@ -37,7 +37,6 @@ import java.util.ServiceLoader; import java.util.function.BiConsumer; import java.util.function.Consumer; -import java.util.function.Supplier; import org.graalvm.collections.EconomicMap; @@ -146,7 +145,8 @@ private static void addProviders(Map, List> services, String arch, C * @param arch a value compatible with {@link ArchitectureSpecific#getArchitecture()} */ @SuppressWarnings({"try", "unused", "unchecked"}) - public static void configureGraalForLibGraal(String arch, + public static void configureGraalForLibGraal( + String arch, List> guestServiceClasses, Consumer> registerAsInHeap, Consumer>> hostedGraalSetFoldNodePluginClasses, @@ -211,7 +211,7 @@ public static Map getRuntimeHandles() { methodType(long.class, long.class, boolean.class, boolean.class, boolean.class, boolean.class, long.class, int.class, int.class, - String.class, BiConsumer.class, Supplier.class)), + String.class, BiConsumer.class)), "hashConstantOopFields", MHL.findStatic(RunTime.class, "hashConstantOopFields", methodType(long.class, long.class, boolean.class, int.class, int.class, boolean.class, Runnable.class)), diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/RunTime.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/RunTime.java index d8fa6c3419bc..7d7eb7e9f040 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/RunTime.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/RunTime.java @@ -27,7 +27,6 @@ import java.util.Arrays; import java.util.Map; import java.util.function.BiConsumer; -import java.util.function.Supplier; import org.graalvm.collections.EconomicMap; @@ -58,6 +57,9 @@ import jdk.vm.ci.runtime.JVMCIBackend; import jdk.vm.ci.runtime.JVMCICompiler; +import static jdk.graal.compiler.serviceprovider.GraalServices.getCurrentThreadAllocatedBytes; +import static jdk.graal.compiler.serviceprovider.GraalServices.isThreadAllocatedMemorySupported; + /** * This class provides implementations for {@code @CEntryPoint}s that libgraal has to provide as a * JVM JIT compiler as well as handles (created by {@link BuildTime#getRuntimeHandles}) to other @@ -103,16 +105,12 @@ private static OptionValues decodeOptions(long address, int size, int hash) { * * @param profileLoadPath value of the {@code Options#LoadProfiles} option or null * @param timeAndMemConsumer allows caller to get info about compile time and memory consumption - * @param currentThreadAllocatedBytes gives access to - * {@code com.sun.management.ThreadMXBean#getCurrentThreadAllocatedBytes()} needed to - * compute memory consumption during compilation */ @SuppressWarnings("try") public static long compileMethod(long methodHandle, boolean useProfilingInfo, boolean installAsDefault, boolean printMetrics, boolean eagerResolving, long optionsAddress, int optionsSize, int optionsHash, - String profileLoadPath, BiConsumer timeAndMemConsumer, - Supplier currentThreadAllocatedBytes) { + String profileLoadPath, BiConsumer timeAndMemConsumer) { HotSpotJVMCIRuntime runtime = HotSpotJVMCIRuntime.runtime(); HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) runtime.getCompiler(); @@ -128,7 +126,7 @@ public static long compileMethod(long methodHandle, boolean useProfilingInfo, long allocatedBytesBefore = 0; long timeBefore = 0; if (timeAndMemConsumer != null) { - allocatedBytesBefore = currentThreadAllocatedBytes.get(); + allocatedBytesBefore = isThreadAllocatedMemorySupported() ? getCurrentThreadAllocatedBytes() : -1; timeBefore = System.nanoTime(); } OptionValues options = decodeOptions(optionsAddress, optionsSize, optionsHash); @@ -137,7 +135,7 @@ public static long compileMethod(long methodHandle, boolean useProfilingInfo, } task.runCompilation(options); if (timeAndMemConsumer != null) { - long allocatedBytesAfter = currentThreadAllocatedBytes.get(); + long allocatedBytesAfter = allocatedBytesBefore == -1 ? -1 : getCurrentThreadAllocatedBytes(); long bytesAllocated = allocatedBytesAfter - allocatedBytesBefore; long timeAfter = System.nanoTime(); long timeSpent = timeAfter - timeBefore; diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java index c4b3ca421d73..ef4c59d60bf7 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java @@ -28,7 +28,6 @@ import java.io.PrintStream; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles.Lookup; -import java.lang.management.ManagementFactory; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -39,7 +38,6 @@ import java.util.Objects; import java.util.Set; import java.util.function.BiConsumer; -import java.util.function.Supplier; import java.util.stream.Collectors; import com.oracle.svm.core.heap.UnknownObjectField; @@ -89,7 +87,6 @@ import org.graalvm.word.PointerBase; import com.oracle.svm.core.heap.Heap; -import com.sun.management.ThreadMXBean; import jdk.internal.misc.Unsafe; @@ -255,23 +252,19 @@ private static long compileMethod(JNIEnv jniEnv, profileLoadPath = null; } BiConsumer timeAndMemConsumer; - Supplier currentThreadAllocatedBytes; if (timeAndMemBufferAddress != 0) { timeAndMemConsumer = (timeSpent, bytesAllocated) -> { Unsafe.getUnsafe().putLong(timeAndMemBufferAddress, bytesAllocated); Unsafe.getUnsafe().putLong(timeAndMemBufferAddress + 8, timeSpent); }; - ThreadMXBean threadMXBean = (ThreadMXBean) ManagementFactory.getThreadMXBean(); - currentThreadAllocatedBytes = () -> threadMXBean.getCurrentThreadAllocatedBytes(); } else { timeAndMemConsumer = null; - currentThreadAllocatedBytes = null; } return (long) singleton().compileMethod.invoke(methodHandle, useProfilingInfo, installAsDefault, printMetrics, eagerResolving, optionsAddress, optionsSize, optionsHash, - profileLoadPath, timeAndMemConsumer, currentThreadAllocatedBytes); + profileLoadPath, timeAndMemConsumer); } catch (Throwable t) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); t.printStackTrace(new PrintStream(baos)); diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java index 2e3b23750891..847281b7eade 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java @@ -26,6 +26,7 @@ import static java.lang.invoke.MethodType.methodType; +import java.lang.annotation.Annotation; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; @@ -43,10 +44,6 @@ import java.util.function.Function; import java.util.regex.Pattern; -import jdk.graal.compiler.lir.phases.LIRPhase; -import jdk.graal.compiler.phases.BasePhase; -import jdk.graal.compiler.serviceprovider.GlobalAtomicLong; -import jdk.vm.ci.hotspot.HotSpotModifiers; import org.graalvm.collections.EconomicMap; import org.graalvm.jniutils.NativeBridgeSupport; import org.graalvm.nativeimage.ImageSingletons; @@ -59,7 +56,6 @@ import com.oracle.graal.pointsto.BigBang; import com.oracle.graal.pointsto.meta.AnalysisType; import com.oracle.graal.pointsto.reports.CallTreePrinter; -import com.oracle.svm.core.SubstrateTargetDescription; import com.oracle.svm.core.hub.ClassForNameSupport; import com.oracle.svm.core.util.VMError; import com.oracle.svm.graal.hotspot.GetCompilerConfig; @@ -76,11 +72,16 @@ import jdk.graal.compiler.hotspot.CompilerConfigurationFactory; import jdk.graal.compiler.hotspot.libgraal.BuildTime; import jdk.graal.compiler.hotspot.libgraal.LibGraalClassLoaderBase; +import jdk.graal.compiler.lir.phases.LIRPhase; import jdk.graal.compiler.nodes.graphbuilderconf.GeneratedInvocationPlugin; import jdk.graal.compiler.options.OptionDescriptor; import jdk.graal.compiler.options.OptionKey; +import jdk.graal.compiler.phases.BasePhase; +import jdk.graal.compiler.serviceprovider.GlobalAtomicLong; import jdk.graal.compiler.serviceprovider.LibGraalService; -import jdk.vm.ci.code.TargetDescription; +import jdk.vm.ci.code.Architecture; +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; +import jdk.vm.ci.hotspot.HotSpotModifiers; /** * This feature builds the libgraal shared library (e.g., libjvmcicompiler.so on linux). @@ -178,6 +179,14 @@ public Class loadClassOrFail(String name) { } } + public Class loadClassOrNull(String name) { + try { + return loader.loadClass(name); + } catch (Throwable e) { + return null; + } + } + /** * Performs tasks once this feature is registered. *
    @@ -385,6 +394,22 @@ private void registerPhaseStatistics(DuringAnalysisAccess a, Class newlyReach } } + @SuppressWarnings("unchecked") + public List> findLibGraalServices() { + Set libgraalServicesModules = ReflectionUtil.invokeMethod(ReflectionUtil.lookupMethod(loader.getClass(), "getLibgraalServicesModules"), loader); + Map modules = ReflectionUtil.invokeMethod(ReflectionUtil.lookupMethod(loader.getClass(), "getModules"), loader); + + Class service = (Class) loadClassOrFail(LibGraalService.class); + List> libgraalServices = new ArrayList<>(); + modules.entrySet().stream()// + .filter(e -> libgraalServicesModules.contains(e.getValue())) + .map(Map.Entry::getKey)// + .map(this::loadClassOrNull)// + .filter(c -> c != null && c.getAnnotation(service) != null)// + .forEach(libgraalServices::add); + return libgraalServices; + } + @Override public void beforeAnalysis(BeforeAnalysisAccess baa) { BeforeAnalysisAccessImpl impl = (BeforeAnalysisAccessImpl) baa; @@ -411,17 +436,11 @@ public void beforeAnalysis(BeforeAnalysisAccess baa) { /* Configure static state of Graal. */ try { - TargetDescription targetDescription = ImageSingletons.lookup(SubstrateTargetDescription.class); - String arch = targetDescription.arch.getName(); - - Consumer> registerAsInHeap = nodeClass -> impl.getMetaAccess().lookupJavaType(nodeClass) - .registerAsInstantiated("All NodeClass classes are marked as instantiated eagerly."); + Consumer> registerAsInHeap = baa::registerAsInHeap; Consumer>> hostedGraalSetFoldNodePluginClasses = GeneratedInvocationPlugin::setFoldNodePluginClasses; - List> guestServiceClasses = new ArrayList<>(); - List> serviceClasses = impl.getImageClassLoader().findAnnotatedClasses(LibGraalService.class, false); - serviceClasses.stream().map(this::loadClassOrFail).forEach(guestServiceClasses::add); + List> guestServiceClasses = findLibGraalServices(); // Transfer libgraal qualifier (e.g. "PGO optimized") from host to guest. String nativeImageLocationQualifier = CompilerConfigurationFactory.getNativeImageLocationQualifier(); @@ -444,9 +463,8 @@ public void beforeAnalysis(BeforeAnalysisAccess baa) { } } - ModuleSupport.accessPackagesToClass(ModuleSupport.Access.OPEN, buildTimeClass, false, "org.graalvm.word", "org.graalvm.word.impl"); - - configureGraalForLibGraal.invoke(arch, + Architecture arch = HotSpotJVMCIRuntime.runtime().getHostJVMCIBackend().getTarget().arch; + configureGraalForLibGraal.invoke(arch.getName(), guestServiceClasses, registerAsInHeap, hostedGraalSetFoldNodePluginClasses, From d927ed584b54fa88b8daedbf1c74b97eb0100e6d Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Mon, 4 Nov 2024 20:14:42 +0100 Subject: [PATCH 03/31] added jdk.graal.nativeimage module --- compiler/mx.compiler/mx_compiler.py | 1 + compiler/mx.compiler/suite.py | 40 +- .../loader/HostedLibGraalClassLoader.java} | 69 +-- .../libgraal/loader/LibGraalClassLoader.java | 35 ++ .../graal/compiler/core/common/Fields.java | 81 ++- .../graal/compiler/core/phases/BaseTier.java | 15 +- .../src/jdk/graal/compiler/graph/Edges.java | 45 ++ .../jdk/graal/compiler/graph/NodeClass.java | 105 ++-- .../compiler/hotspot/CompilationTask.java | 21 +- .../compiler/hotspot/libgraal/BuildTime.java | 5 + .../graal/compiler/java/BytecodeParser.java | 2 +- .../compiler/lir/phases/LIRPhaseSuite.java | 14 +- .../serviceprovider/GraalServices.java | 30 -- .../compiler/serviceprovider/IsolateUtil.java | 14 +- .../compiler/serviceprovider/VMSupport.java | 21 - .../jdk.graal.nativeimage/snapshot.sigtest | 33 ++ .../nativeimage/LibGraalFeatureComponent.java | 35 ++ .../graal/nativeimage/LibGraalLoader.java} | 28 +- .../graal/nativeimage/LibGraalRuntime.java | 80 +++ .../impl/LibGraalRuntimeSupport.java | 34 ++ .../jdk/graal/nativeimage/package-info.java | 35 ++ .../org.graalvm.nativeimage/snapshot.sigtest | 1 + .../hosted/FieldValueTransformer.java | 9 + substratevm/mx.substratevm/suite.py | 1 + ...FieldValueTransformerWithAvailability.java | 1 + .../oracle/svm/core/jdk/RuntimeSupport.java | 23 +- .../libgraal/LibGraalCompilerSupport.java | 63 --- .../hotspot/libgraal/LibGraalEntryPoints.java | 13 +- .../hotspot/libgraal/LibGraalFeature.java | 269 +++++----- .../LibGraalFieldsOffsetsFeature.java | 482 ------------------ .../libgraal/LibGraalNativeBridgeSupport.java | 6 +- .../libgraal/LibGraalReflectionUtil.java | 240 +++++++++ .../libgraal/LibGraalSubstitutions.java | 104 +--- .../svm/graal/hotspot/GetCompilerConfig.java | 29 +- .../graal/hosted/FieldsOffsetsFeature.java | 49 +- .../graal/hosted/GraalCompilerFeature.java | 2 +- .../GraalGraphObjectReplacer.java | 4 - .../substitutions/GraalSubstitutions.java | 24 +- .../oracle/svm/hosted/ClassLoaderFeature.java | 4 +- .../hosted/ImageSingletonsSupportImpl.java | 11 +- .../hosted/NativeImageClassLoaderSupport.java | 49 +- .../hosted/NativeImageGeneratorRunner.java | 1 + .../ameta/FieldValueInterceptionSupport.java | 6 +- .../ClassInitializationFeature.java | 1 + .../com/oracle/svm/util/ModuleSupport.java | 13 +- 45 files changed, 1029 insertions(+), 1119 deletions(-) rename compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/{hotspot/libgraal/LibGraalClassLoader.java => libgraal/loader/HostedLibGraalClassLoader.java} (87%) create mode 100644 compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/LibGraalClassLoader.java create mode 100644 compiler/src/jdk.graal.nativeimage/snapshot.sigtest create mode 100644 compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalFeatureComponent.java rename compiler/src/{jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/LibGraalClassLoaderBase.java => jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalLoader.java} (68%) create mode 100644 compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java create mode 100644 compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/impl/LibGraalRuntimeSupport.java create mode 100644 compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/package-info.java delete mode 100644 substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalCompilerSupport.java delete mode 100644 substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFieldsOffsetsFeature.java create mode 100644 substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalReflectionUtil.java diff --git a/compiler/mx.compiler/mx_compiler.py b/compiler/mx.compiler/mx_compiler.py index e721174e0251..982852a0e74b 100644 --- a/compiler/mx.compiler/mx_compiler.py +++ b/compiler/mx.compiler/mx_compiler.py @@ -1483,6 +1483,7 @@ def _jvmci_jars(): return [ 'compiler:GRAAL', 'compiler:GRAAL_MANAGEMENT', + 'compiler:GRAAL_NATIVEIMAGE', ] # The community compiler component diff --git a/compiler/mx.compiler/suite.py b/compiler/mx.compiler/suite.py index 44e3d98e945d..4e22a4d7d1eb 100644 --- a/compiler/mx.compiler/suite.py +++ b/compiler/mx.compiler/suite.py @@ -164,10 +164,22 @@ # ------------- Graal ------------- + # Native Image API extensions for libgraal. + "jdk.graal.nativeimage" : { + "subDir" : "src", + "sourceDirs" : ["src"], + "dependencies" : [ + "sdk:NATIVEIMAGE" + ], + "checkstyle" : "jdk.graal.compiler", + "javaCompliance" : "21+" + }, + "jdk.graal.compiler" : { "subDir" : "src", "sourceDirs" : ["src"], "dependencies" : [ + "GRAAL_NATIVEIMAGE", "sdk:WORD", "sdk:COLLECTIONS", "sdk:NATIVEIMAGE", @@ -478,7 +490,7 @@ "workingSets" : "Graal", "javaCompliance" : "21+", "dependencies" : [ - "jdk.graal.compiler", + "jdk.graal.nativeimage", ], "requiresConcealed" : { "java.base" : [ @@ -552,6 +564,31 @@ "maven": False, }, + "GRAAL_NATIVEIMAGE" : { + "subDir" : "src", + "dependencies" : [ + "jdk.graal.nativeimage", + ], + "distDependencies" : ["sdk:NATIVEIMAGE"], + "javadocType": "api", + "moduleInfo" : { + "name" : "jdk.graal.nativeimage", + "requires" : [ + "transitive org.graalvm.nativeimage", + ], + "exports" : [ + "jdk.graal.nativeimage", + """jdk.graal.nativeimage.impl to org.graalvm.nativeimage.builder""", + ], + "uses" : [], + "opens" : [], + }, + "description" : "Native Image API extensions for libgraal.", + "maven": { + "tag": ["default", "public"], + }, + }, + "GRAAL" : { # This distribution defines a module. "moduleInfo" : { @@ -603,6 +640,7 @@ "GRAAL_VERSION", ], "distDependencies" : [ + "GRAAL_NATIVEIMAGE", "sdk:COLLECTIONS", "sdk:WORD", "sdk:NATIVEIMAGE", diff --git a/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/hotspot/libgraal/LibGraalClassLoader.java b/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/HostedLibGraalClassLoader.java similarity index 87% rename from compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/hotspot/libgraal/LibGraalClassLoader.java rename to compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/HostedLibGraalClassLoader.java index 6e8eb5a6d337..6410bb2dc25d 100644 --- a/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/hotspot/libgraal/LibGraalClassLoader.java +++ b/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/HostedLibGraalClassLoader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -22,7 +22,15 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.hotspot.libgraal; +package jdk.graal.compiler.libgraal.loader; + +import jdk.graal.nativeimage.LibGraalLoader; +import jdk.internal.jimage.BasicImageReader; +import jdk.internal.jimage.ImageLocation; +import jdk.internal.module.Modules; +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; +import org.graalvm.nativeimage.hosted.Feature; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -46,22 +54,11 @@ import java.util.Objects; import java.util.Set; -import jdk.graal.compiler.serviceprovider.LibGraalService; -import jdk.internal.jimage.BasicImageReader; -import jdk.internal.jimage.ImageLocation; -import org.graalvm.nativeimage.Platform; -import org.graalvm.nativeimage.Platforms; -import org.graalvm.nativeimage.hosted.Feature; - -import jdk.graal.compiler.debug.GraalError; -import jdk.internal.module.Modules; - /** * A classloader, that reads class files and resources from a jimage file at image build time. */ -@SuppressWarnings("unused") @Platforms(Platform.HOSTED_ONLY.class) -final class HostedLibGraalClassLoader extends ClassLoader implements LibGraalClassLoaderBase { +public final class HostedLibGraalClassLoader extends ClassLoader implements LibGraalLoader { private static final String JAVA_HOME_PROPERTY_KEY = "jdk.graal.internal.libgraal.javahome"; private static final String JAVA_HOME_PROPERTY_VALUE = System.getProperty(JAVA_HOME_PROPERTY_KEY, System.getProperty("java.home")); @@ -76,12 +73,6 @@ final class HostedLibGraalClassLoader extends ClassLoader implements LibGraalCla */ private final Map resources = new HashMap<>(); - /** - * Map from the {@linkplain Class#forName(String) name} of a class to the image path of its - * class file. - */ - private final Map classes; - /** * Map from a service name to a list of providers. */ @@ -105,7 +96,7 @@ final class HostedLibGraalClassLoader extends ClassLoader implements LibGraalCla "com.oracle.graal.graal_enterprise"); /** - * Modules containing classes that can be annotated by {@link LibGraalService}. + * Modules containing classes that can be annotated by {@code LibGraalService}. */ private static final Set LIBGRAAL_SERVICES_MODULES = Set.of( "jdk.graal.compiler", @@ -118,6 +109,7 @@ final class HostedLibGraalClassLoader extends ClassLoader implements LibGraalCla public final Path libGraalJavaHome; + @SuppressWarnings("unused") public HostedLibGraalClassLoader() { super(LibGraalClassLoader.LOADER_NAME, Feature.class.getClassLoader()); libGraalJavaHome = Path.of(JAVA_HOME_PROPERTY_VALUE); @@ -138,7 +130,6 @@ public HostedLibGraalClassLoader() { Modules.addExports(javaBaseModule, "jdk.internal.misc", unnamedModuleOfThisLoader); Map modulesMap = new HashMap<>(); - Map classesMap = new HashMap<>(); Path imagePath = libGraalJavaHome.resolve(Path.of("lib", "modules")); this.imageReader = BasicImageReader.open(imagePath); @@ -157,7 +148,6 @@ public HostedLibGraalClassLoader() { services.computeIfAbsent(p.service(), k -> new ArrayList<>()).addAll(p.providers()); } } else { - classesMap.put(className, entry); modulesMap.put(className, module); } } @@ -166,28 +156,29 @@ public HostedLibGraalClassLoader() { } modules = Map.copyOf(modulesMap); - classes = Map.copyOf(classesMap); } catch (IOException e) { - throw GraalError.shouldNotReachHere(e); + throw new RuntimeException(e); } } + /** + * Gets an unmodifiable map from the {@linkplain Class#forName(String) name} of a class to the + * name of its enclosing module. + */ @Override - public Map getModules() { + public Map getModuleMap() { return modules; } - /* Allow image builder to perform registration action on each class this loader provides. */ - @Override - public Set getAllClassNames() { - return classes.keySet(); + public Set getServicesModules() { + return LIBGRAAL_SERVICES_MODULES; } @Override protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - if (!classes.containsKey(name)) { + if (!modules.containsKey(name)) { return super.loadClass(name, resolve); } synchronized (getClassLoadingLock(name)) { @@ -270,7 +261,7 @@ protected Enumeration findResources(String name) throws IOException { /** * A {@link URLStreamHandler} for use with URLs returned by - * {@link HostedLibGraalClassLoader#findResource(java.lang.String)}. + * {@link HostedLibGraalClassLoader#findResource(String)}. */ private class ImageURLStreamHandler extends URLStreamHandler { @Override @@ -327,22 +318,12 @@ public String getContentType() { } @Override - public HostedLibGraalClassLoader getClassLoader() { + public ClassLoader getClassLoader() { return this; } @Override - public LibGraalClassLoader getRuntimeClassLoader() { + public ClassLoader getRuntimeClassLoader() { return LibGraalClassLoader.singleton; } } - -public final class LibGraalClassLoader extends ClassLoader { - - static final String LOADER_NAME = "LibGraalClassLoader"; - static final LibGraalClassLoader singleton = new LibGraalClassLoader(); - - private LibGraalClassLoader() { - super(LOADER_NAME, null); - } -} diff --git a/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/LibGraalClassLoader.java b/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/LibGraalClassLoader.java new file mode 100644 index 000000000000..1c34e1d3d0ff --- /dev/null +++ b/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/LibGraalClassLoader.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 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 jdk.graal.compiler.libgraal.loader; + +public final class LibGraalClassLoader extends ClassLoader { + + static final String LOADER_NAME = "LibGraalClassLoader"; + static final LibGraalClassLoader singleton = new LibGraalClassLoader(); + + private LibGraalClassLoader() { + super(LOADER_NAME, null); + } +} diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/Fields.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/Fields.java index 0b8dd2fa3ef9..cc4edb45c51a 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/Fields.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/Fields.java @@ -24,18 +24,24 @@ */ package jdk.graal.compiler.core.common; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Map; import jdk.graal.compiler.debug.GraalError; +import jdk.graal.compiler.options.ExcludeFromJacocoGeneratedReport; +import jdk.graal.nativeimage.LibGraalFeatureComponent; import jdk.internal.misc.Unsafe; +import org.graalvm.nativeimage.hosted.Feature; /** * Describes fields in a class, primarily for access via {@link Unsafe}. */ -public class Fields { +public class Fields implements LibGraalFeatureComponent { private static final Unsafe UNSAFE = Unsafe.getUnsafe(); private static final Fields EMPTY_FIELDS = new Fields(Collections.emptyList()); @@ -57,6 +63,25 @@ public class Fields { private final Class[] declaringClasses; + @ExcludeFromJacocoGeneratedReport("only called when building libgraal") + public static void setLibGraalFeatureComponents(Collection components) { + GraalError.guarantee(libGraalFeatureComponents == null, "already initialized"); + Fields.libGraalFeatureComponents = components; + } + + /** + * Registers {@code c} if in a context where a registry + * {@linkplain #setLibGraalFeatureComponents exists}. + */ + public static void addLibGraalFeatureComponents(LibGraalFeatureComponent c) { + if (libGraalFeatureComponents != null) { + libGraalFeatureComponents.add(c); + } + } + + private static Collection libGraalFeatureComponents; + + @SuppressWarnings("this-escape") protected Fields(List fields) { Collections.sort(fields); this.offsets = new long[fields.size()]; @@ -71,10 +96,39 @@ protected Fields(List fields) { declaringClasses[index] = f.declaringClass; index++; } + if (libGraalFeatureComponents != null) { + libGraalFeatureComponents.add(this); + } + } + + private Field getField(int i) { + try { + return getDeclaringClass(i).getDeclaredField(getName(i)); + } catch (NoSuchFieldException e) { + throw GraalError.shouldNotReachHere(e); + } + } + + public Map.Entry recomputeOffsetsAndIterationMask(Feature.BeforeCompilationAccess access) { + long[] newOffsets = new long[offsets.length]; + for (int i = 0; i < offsets.length; i++) { + Field field = getField(i); + long newOffset = access.objectFieldOffset(field); + newOffsets[i] = newOffset; + } + return Map.entry(newOffsets, 0L); + } + + @Override + public void duringAnalysis(Feature.DuringAnalysisAccess access) { + for (int i = 0; i < offsets.length; i++) { + Field field = getField(i); + access.registerAsUnsafeAccessed(field); + } } public static Fields create(ArrayList fields) { - if (fields.size() == 0) { + if (fields.isEmpty()) { return EMPTY_FIELDS; } return new Fields(fields); @@ -93,15 +147,6 @@ public static void translateInto(Fields fields, ArrayList extends PhaseSuite { @@ -50,10 +51,16 @@ public LoopPolicies createLoopPolicies(@SuppressWarnings("unused") OptionValues @Override protected void run(StructuredGraph graph, C context) { for (BasePhase phase : getPhases()) { - // Notify the runtime that most objects allocated in previous HIR phase are dead and can - // be reclaimed. This will lower the chance of allocation failure in the next HIR phase. - try (DebugCloseable timer = HIRHintedGC.start(graph.getDebug())) { - GraalServices.notifyLowMemoryPoint(); + if (GraalServices.isInLibgraal()) { + /* + * Notify the runtime that most objects allocated in previous HIR phase are dead and + * can be reclaimed. This will lower the chance of allocation failure in the next + * HIR phase. + */ + try (DebugCloseable timer = HIRHintedGC.start(graph.getDebug())) { + LibGraalRuntime.notifyLowMemoryPoint(false); + LibGraalRuntime.processReferences(); + } } phase.apply(graph, context); } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graph/Edges.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graph/Edges.java index 2bea2c5a7c96..0553d368f2ad 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graph/Edges.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graph/Edges.java @@ -29,11 +29,15 @@ import java.util.ArrayList; import java.util.Iterator; +import java.util.Map; import jdk.graal.compiler.core.common.Fields; import jdk.graal.compiler.core.common.FieldsScanner; +import jdk.graal.compiler.debug.Assertions; +import jdk.graal.compiler.debug.GraalError; import jdk.graal.compiler.graph.NodeClass.EdgeInfo; import jdk.internal.misc.Unsafe; +import org.graalvm.nativeimage.hosted.Feature; /** * Describes {@link Node} fields representing the set of inputs for the node or the set of the @@ -41,8 +45,35 @@ */ public abstract class Edges extends Fields { + private static final long MAX_EDGES = 8; + private static final long MAX_LIST_EDGES = 6; + static final long OFFSET_MASK = 0xFC; + static final long LIST_MASK = 0x01; + static final long NEXT_EDGE = 0x08; + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); + public static long computeIterationMask(Type type, int directCount, long[] offsets) { + long mask = 0; + if (offsets.length > MAX_EDGES) { + throw new GraalError("Exceeded maximum of %d edges (%s)", MAX_EDGES, type); + } + if (offsets.length - directCount > MAX_LIST_EDGES) { + throw new GraalError("Exceeded maximum of %d list edges (%s)", MAX_LIST_EDGES, type); + } + + for (int i = offsets.length - 1; i >= 0; i--) { + long offset = offsets[i]; + assert ((offset & OFFSET_MASK) == offset) : Assertions.errorMessageContext("field offset too large or has low bits set", offset); + mask <<= NEXT_EDGE; + mask |= offset; + if (i >= directCount) { + mask |= 0x3; + } + } + return mask; + } + /** * Constants denoting whether a set of edges are inputs or successors. */ @@ -53,11 +84,21 @@ public enum Type { private final int directCount; private final Type type; + private final long iterationMask; + @SuppressWarnings("this-escape") public Edges(Type type, int directCount, ArrayList edges) { super(edges); this.type = type; this.directCount = directCount; + this.iterationMask = computeIterationMask(type, directCount, getOffsets()); + } + + @Override + public Map.Entry recomputeOffsetsAndIterationMask(Feature.BeforeCompilationAccess access) { + Map.Entry e = super.recomputeOffsetsAndIterationMask(access); + long[] newOffsets = e.getKey(); + return Map.entry(newOffsets, computeIterationMask(type, directCount, newOffsets)); } public static void translateInto(Edges edges, ArrayList infos) { @@ -66,6 +107,10 @@ public static void translateInto(Edges edges, ArrayList infos) { } } + public long getIterationMask() { + return iterationMask; + } + public static Node getNodeUnsafe(Node node, long offset) { return (Node) UNSAFE.getReference(node, offset); } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graph/NodeClass.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graph/NodeClass.java index 90261a55a445..9e3a201c2160 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graph/NodeClass.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graph/NodeClass.java @@ -28,6 +28,9 @@ import static jdk.graal.compiler.debug.GraalError.shouldNotReachHere; import static jdk.graal.compiler.debug.GraalError.shouldNotReachHereUnexpectedValue; import static jdk.graal.compiler.graph.Edges.translateInto; +import static jdk.graal.compiler.graph.Edges.NEXT_EDGE; +import static jdk.graal.compiler.graph.Edges.LIST_MASK; +import static jdk.graal.compiler.graph.Edges.OFFSET_MASK; import static jdk.graal.compiler.graph.Graph.isNodeModificationCountsEnabled; import static jdk.graal.compiler.graph.InputEdges.translateInto; import static jdk.graal.compiler.graph.Node.WithAllEdges; @@ -44,6 +47,8 @@ import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; +import jdk.graal.compiler.serviceprovider.GraalServices; +import jdk.graal.nativeimage.LibGraalFeatureComponent; import org.graalvm.collections.EconomicMap; import org.graalvm.collections.Equivalence; @@ -73,6 +78,7 @@ import jdk.internal.misc.Unsafe; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; +import org.graalvm.nativeimage.hosted.Feature; /** * Metadata for every {@link Node} type. The metadata includes: @@ -82,7 +88,7 @@ *
  • The identifier for an {@link IterableNodeType} class.
  • *
*/ -public final class NodeClass extends FieldIntrospection { +public final class NodeClass extends FieldIntrospection implements LibGraalFeatureComponent { private static final Unsafe UNSAFE = Unsafe.getUnsafe(); // Timers for creation of a NodeClass instance @@ -94,11 +100,6 @@ public final class NodeClass extends FieldIntrospection { private static final TimerKey Init_AllowedUsages = DebugContext.timer("NodeClass.Init.AllowedUsages"); private static final TimerKey Init_IterableIds = DebugContext.timer("NodeClass.Init.IterableIds"); - public static final long MAX_EDGES = 8; - public static final long MAX_LIST_EDGES = 6; - public static final long OFFSET_MASK = 0xFC; - public static final long LIST_MASK = 0x01; - public static final long NEXT_EDGE = 0x08; private static final int SHORT_INPUT_LIST_THRESHOLD = 3; @SuppressWarnings("try") @@ -160,8 +161,6 @@ public static NodeClass get(Class clazz) { private final int iterableId; private final EnumSet allowedUsageTypes; private int[] iterableIds; - private final long inputsIteration; - private final long successorIteration; private static final CounterKey ITERABLE_NODE_TYPES = DebugContext.counter("IterableNodeTypes"); @@ -200,9 +199,7 @@ private NodeClass(Class clazz, NodeClass superNodeClass, FieldsSca try (DebugCloseable t1 = Init_Edges.start(debug)) { successors = new SuccessorEdges(fs.directSuccessors, fs.successors); - successorIteration = computeIterationMask(successors.type(), successors.getDirectCount(), successors.getOffsets()); inputs = new InputEdges(fs.directInputs, fs.inputs); - inputsIteration = computeIterationMask(inputs.type(), inputs.getDirectCount(), inputs.getOffsets()); } try (DebugCloseable t1 = Init_Data.start(debug)) { data = Fields.create(fs.data); @@ -220,6 +217,7 @@ private NodeClass(Class clazz, NodeClass superNodeClass, FieldsSca NodeInfo info = getAnnotationTimed(clazz, NodeInfo.class, debug); assert info != null : "Missing NodeInfo annotation on " + clazz; + shortName = computeShortName(info); if (!info.nameTemplate().isEmpty()) { this.nameTemplate = info.nameTemplate(); } else if (!info.shortName().isEmpty()) { @@ -285,6 +283,11 @@ private NodeClass(Class clazz, NodeClass superNodeClass, FieldsSca debug.log("Node cost for node of type __| %s |_, cycles:%s,size:%s", clazz, cycles, size); } assert verifyMemoryEdgeInvariant(fs) : "Nodes participating in the memory graph should have at most 1 optional memory input."; + + Fields.addLibGraalFeatureComponents(this); + + // All NodeClass instances must be constructed at libgraal build time + GraalError.guarantee(!GraalServices.isInLibgraal(), getClazz().getName()); } private static boolean verifyMemoryEdgeInvariant(NodeFieldsScanner fs) { @@ -308,27 +311,6 @@ public NodeSize size() { return size; } - public static long computeIterationMask(Edges.Type type, int directCount, long[] offsets) { - long mask = 0; - if (offsets.length > NodeClass.MAX_EDGES) { - throw new GraalError("Exceeded maximum of %d edges (%s)", NodeClass.MAX_EDGES, type); - } - if (offsets.length - directCount > NodeClass.MAX_LIST_EDGES) { - throw new GraalError("Exceeded maximum of %d list edges (%s)", NodeClass.MAX_LIST_EDGES, type); - } - - for (int i = offsets.length - 1; i >= 0; i--) { - long offset = offsets[i]; - assert ((offset & OFFSET_MASK) == offset) : Assertions.errorMessageContext("field offset too large or has low bits set", offset); - mask <<= NodeClass.NEXT_EDGE; - mask |= offset; - if (i >= directCount) { - mask |= 0x3; - } - } - return mask; - } - private synchronized void addIterableId(int newIterableId) { assert !containsId(newIterableId, iterableIds); int[] copy = Arrays.copyOf(iterableIds, iterableIds.length + 1); @@ -354,23 +336,23 @@ private static boolean containsId(int iterableId, int[] iterableIds) { return false; } - private String shortName; + private final String shortName; public String shortName() { - if (shortName == null) { - NodeInfo info = getClazz().getAnnotation(NodeInfo.class); - if (!info.shortName().isEmpty()) { - shortName = info.shortName(); + return shortName; + } + + private String computeShortName(NodeInfo info) { + if (!info.shortName().isEmpty()) { + return info.shortName(); + } else { + String localShortName = getClazz().getSimpleName(); + if (localShortName.endsWith("Node") && !localShortName.equals("StartNode") && !localShortName.equals("EndNode")) { + return localShortName.substring(0, localShortName.length() - 4); } else { - String localShortName = getClazz().getSimpleName(); - if (localShortName.endsWith("Node") && !localShortName.equals("StartNode") && !localShortName.equals("EndNode")) { - shortName = localShortName.substring(0, localShortName.length() - 4); - } else { - shortName = localShortName; - } + return localShortName; } } - return shortName; } @Override @@ -419,6 +401,14 @@ public EnumSet getAllowedUsageTypes() { return allowedUsageTypes; } + @Override + public void duringAnalysis(Feature.DuringAnalysisAccess access) { + if (!Modifier.isAbstract(getClazz().getModifiers())) { + /* Support for NodeClass.allocateInstance. */ + access.registerAsUnsafeAllocated(getClazz()); + } + } + /** * Describes a field representing an input or successor edge in a node. */ @@ -1075,7 +1065,7 @@ public final long advanceInput() { int size = nodeList.size(); if (size != 0) { // Set pointer to upper most index of node list. - return ((mask >>> NEXT_EDGE) << 24) | (mask & 0xFD) | ((size - 1) << NEXT_EDGE); + return ((mask >>> NEXT_EDGE) << 24) | (mask & 0xFD) | ((long) (size - 1) << NEXT_EDGE); } } // Node list is empty or null => skip. @@ -1146,7 +1136,7 @@ public Position nextPosition() { } public NodeIterable getSuccessorIterable(final Node node) { - long mask = this.successorIteration; + long mask = this.successors.getIterationMask(); return new NodeIterable<>() { @Override @@ -1180,7 +1170,7 @@ public String toString() { } public NodeIterable getInputIterable(final Node node) { - long mask = this.inputsIteration; + long mask = this.inputs.getIterationMask(); return new NodeIterable<>() { @Override @@ -1214,11 +1204,11 @@ public String toString() { } public boolean equalSuccessors(Node node, Node other) { - return equalEdges(node, other, successorIteration); + return equalEdges(node, other, successors.getIterationMask()); } public boolean equalInputs(Node node, Node other) { - return equalEdges(node, other, inputsIteration); + return equalEdges(node, other, inputs.getIterationMask()); } private boolean equalEdges(Node node, Node other, long mask) { @@ -1245,7 +1235,7 @@ private boolean equalEdges(Node node, Node other, long mask) { } public void pushInputs(Node node, NodeStack stack) { - long myMask = this.inputsIteration; + long myMask = this.inputs.getIterationMask(); while (myMask != 0) { long offset = (myMask & OFFSET_MASK); if ((myMask & LIST_MASK) == 0) { @@ -1273,11 +1263,11 @@ private static void pushAllHelper(NodeStack stack, Node node, long offset) { } public void applySuccessors(Node node, EdgeVisitor consumer) { - applyEdges(node, consumer, this.successorIteration, successors); + applyEdges(node, consumer, this.successors.getIterationMask(), successors); } public void applyInputs(Node node, EdgeVisitor consumer) { - applyEdges(node, consumer, this.inputsIteration, inputs); + applyEdges(node, consumer, this.inputs.getIterationMask(), inputs); } private static void applyEdges(Node node, EdgeVisitor consumer, long mask, Edges edges) { @@ -1317,7 +1307,7 @@ private static void applyHelper(Node node, EdgeVisitor consumer, long offset) { } public void unregisterAtSuccessorsAsPredecessor(Node node) { - long myMask = this.successorIteration; + long myMask = this.successors.getIterationMask(); while (myMask != 0) { long offset = (myMask & OFFSET_MASK); if ((myMask & LIST_MASK) == 0) { @@ -1347,7 +1337,7 @@ private static void unregisterAtSuccessorsAsPredecessorHelper(Node node, long of } public void registerAtSuccessorsAsPredecessor(Node node) { - long myMask = this.successorIteration; + long myMask = this.successors.getIterationMask(); while (myMask != 0) { long offset = (myMask & OFFSET_MASK); if ((myMask & LIST_MASK) == 0) { @@ -1386,7 +1376,7 @@ private static void registerAtSuccessorsAsPredecessorHelper(Node node, long offs */ public boolean replaceFirstInput(Node node, Node key, Node replacement) { assert node.getNodeClass() == this : Assertions.errorMessageContext("node", node, "this", this); - return replaceFirstEdge(node, key, replacement, this.inputsIteration, inputs); + return replaceFirstEdge(node, key, replacement, this.inputs.getIterationMask(), inputs); } /** @@ -1399,7 +1389,7 @@ public boolean replaceFirstInput(Node node, Node key, Node replacement) { */ public boolean replaceFirstSuccessor(Node node, Node key, Node replacement) { assert node.getNodeClass() == this : Assertions.errorMessageContext("node", node, "this", this); - return replaceFirstEdge(node, key, replacement, this.successorIteration, successors); + return replaceFirstEdge(node, key, replacement, this.successors.getIterationMask(), successors); } private static boolean replaceFirstEdge(Node node, Node key, Node replacement, long mask, Edges edges) { @@ -1426,7 +1416,8 @@ private static boolean replaceFirstEdge(Node node, Node key, Node replacement, l } void registerAtInputsAsUsage(Node node) { - long myMask = this.inputsIteration; + // GraalError.guarantee(this.inputsIteration != null, this.getClazz().getName()); + long myMask = this.inputs.getIterationMask(); while (myMask != 0) { long offset = (myMask & OFFSET_MASK); if ((myMask & LIST_MASK) == 0) { @@ -1456,7 +1447,7 @@ private static void registerAtInputsAsUsageHelper(Node node, long offset) { } public void unregisterAtInputsAsUsage(Node node) { - long myMask = this.inputsIteration; + long myMask = this.inputs.getIterationMask(); while (myMask != 0) { long offset = (myMask & OFFSET_MASK); if ((myMask & LIST_MASK) == 0) { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/CompilationTask.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/CompilationTask.java index f0417153d8f8..5aa4e2f47a71 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/CompilationTask.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/CompilationTask.java @@ -34,6 +34,7 @@ import java.io.PrintStream; +import jdk.graal.nativeimage.LibGraalRuntime; import org.graalvm.collections.EconomicMap; import jdk.graal.compiler.api.replacements.SnippetReflectionProvider; @@ -56,9 +57,7 @@ import jdk.graal.compiler.nodes.StructuredGraph; import jdk.graal.compiler.nodes.spi.StableProfileProvider; import jdk.graal.compiler.nodes.spi.StableProfileProvider.TypeFilter; -import jdk.graal.compiler.options.Option; import jdk.graal.compiler.options.OptionKey; -import jdk.graal.compiler.options.OptionType; import jdk.graal.compiler.options.OptionValues; import jdk.graal.compiler.options.OptionsParser; import jdk.graal.compiler.printer.GraalDebugHandlersFactory; @@ -77,12 +76,6 @@ public class CompilationTask implements CompilationWatchDog.EventHandler { - static class Options { - @Option(help = "Perform a full GC of the libgraal heap after every compile to reduce idle heap and reclaim " + - "references to the HotSpot heap. This flag has no effect in the context of jargraal.", type = OptionType.Debug)// - public static final OptionKey FullGCAfterCompile = new OptionKey<>(false); - } - @Override public void onStuckCompilation(CompilationWatchDog watchDog, Thread watched, CompilationIdentifier compilation, StackTraceElement[] stackTrace, long stuckTime) { CompilationWatchDog.EventHandler.super.onStuckCompilation(watchDog, watched, compilation, stackTrace, stuckTime); @@ -435,11 +428,13 @@ public HotSpotCompilationRequestResult runCompilation(OptionValues initialOption public HotSpotCompilationRequestResult runCompilation(DebugContext debug) { try (DebugCloseable a = CompilationTime.start(debug)) { HotSpotCompilationRequestResult result = runCompilation(debug, new HotSpotCompilationWrapper()); - - // Notify the runtime that most objects allocated in the current compilation - // are dead and can be reclaimed. - try (DebugCloseable timer = HintedFullGC.start(debug)) { - GraalServices.notifyLowMemoryPoint(Options.FullGCAfterCompile.getValue(debug.getOptions())); + if (GraalServices.isInLibgraal()) { + // Notify the runtime that most objects allocated in the current compilation + // are dead and can be reclaimed. + try (DebugCloseable timer = HintedFullGC.start(debug)) { + LibGraalRuntime.notifyLowMemoryPoint(true); + LibGraalRuntime.processReferences(); + } } return result; } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/BuildTime.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/BuildTime.java index 3d65885b7b22..c9e9754c0db7 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/BuildTime.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/BuildTime.java @@ -31,6 +31,7 @@ import java.lang.invoke.MethodHandles.Lookup; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -38,6 +39,8 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; +import jdk.graal.compiler.core.common.Fields; +import jdk.graal.nativeimage.LibGraalFeatureComponent; import org.graalvm.collections.EconomicMap; import jdk.graal.compiler.core.ArchitectureSpecific; @@ -147,6 +150,7 @@ private static void addProviders(Map, List> services, String arch, C @SuppressWarnings({"try", "unused", "unchecked"}) public static void configureGraalForLibGraal( String arch, + Collection libGraalFeatureComponents, List> guestServiceClasses, Consumer> registerAsInHeap, Consumer>> hostedGraalSetFoldNodePluginClasses, @@ -155,6 +159,7 @@ public static void configureGraalForLibGraal( GraalError.guarantee(VALID_LOADER_NAME.equals(LOADER.getName()), "Only call this method from classloader " + VALID_LOADER_NAME); + Fields.setLibGraalFeatureComponents(libGraalFeatureComponents); Map, List> services = new HashMap<>(); guestServiceClasses.forEach(c -> addProviders(services, arch, c)); GraalServices.setLibgraalServices(services); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/java/BytecodeParser.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/java/BytecodeParser.java index 2ada474b6cbf..ecfa176ad5a0 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/java/BytecodeParser.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/java/BytecodeParser.java @@ -2411,7 +2411,7 @@ boolean checkNodeConsistency(boolean pluginResult) { @Override public void replacePlugin(GeneratedInvocationPlugin plugin, ResolvedJavaMethod targetMethod, ValueNode[] args, PluginReplacementNode.ReplacementFunction replacementFunction) { - assert replacementFunction != null; + GraalError.guarantee(replacementFunction != null, "%s", targetMethod); JavaType returnType = maybeEagerlyResolve(targetMethod.getSignature().getReturnType(method.getDeclaringClass()), targetMethod.getDeclaringClass()); StampPair returnStamp = getReplacements().getGraphBuilderPlugins().getOverridingStamp(this, returnType, false); if (returnStamp == null) { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/phases/LIRPhaseSuite.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/phases/LIRPhaseSuite.java index 83c1d2c1d5da..c2e15a554168 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/phases/LIRPhaseSuite.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/phases/LIRPhaseSuite.java @@ -35,6 +35,7 @@ import jdk.graal.compiler.debug.TimerKey; import jdk.graal.compiler.lir.gen.LIRGenerationResult; import jdk.graal.compiler.serviceprovider.GraalServices; +import jdk.graal.nativeimage.LibGraalRuntime; import jdk.vm.ci.code.TargetDescription; public class LIRPhaseSuite extends LIRPhase implements PhasePlan> { @@ -105,10 +106,15 @@ public static boolean findNextPhase(ListIterator> it, Class phase : phases) { - // Notify the runtime that most objects allocated in previous LIR phase are dead and can - // be reclaimed. This will lower the chance of allocation failure in the next LIR phase. - try (DebugCloseable timer = LIRHintedGC.start(lirGenRes.getLIR().getDebug())) { - GraalServices.notifyLowMemoryPoint(); + if (GraalServices.isInLibgraal()) { + // Notify the runtime that most objects allocated in previous LIR phase are dead and + // can + // be reclaimed. This will lower the chance of allocation failure in the next LIR + // phase. + try (DebugCloseable timer = LIRHintedGC.start(lirGenRes.getLIR().getDebug())) { + LibGraalRuntime.notifyLowMemoryPoint(false); + LibGraalRuntime.processReferences(); + } } phase.apply(target, lirGenRes, context); } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java index 1465a850b4be..780c13035b0f 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java @@ -458,34 +458,4 @@ public static double fma(double a, double b, double c) { public static int getJavaUpdateVersion() { return Runtime.version().update(); } - - /** - * Notifies that the compiler is at a point where memory usage is expected to be minimal like - * after the completion of compilation. - * - * @param forceFullGC controls whether to explicitly perform a full GC - */ - public static void notifyLowMemoryPoint(boolean forceFullGC) { - notifyLowMemoryPoint(true, forceFullGC); - } - - /** - * Notifies that the compiler is at a point where memory usage is might have dropped - * significantly like after some major phase execution. - */ - public static void notifyLowMemoryPoint() { - notifyLowMemoryPoint(false, false); - } - - /** - * Notifies that the compiler is at a point where memory usage is expected to be relatively low - * (e.g., just before/after a compilation). The garbage collector might be able to make use of - * such a hint to optimize its performance. - * - * @param hintFullGC controls whether the hinted GC should be a full GC. - * @param forceFullGC controls whether to explicitly perform a full GC - */ - private static void notifyLowMemoryPoint(boolean hintFullGC, boolean forceFullGC) { - VMSupport.notifyLowMemoryPoint(hintFullGC, forceFullGC); - } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/IsolateUtil.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/IsolateUtil.java index 769b59941ac3..854b40dec5c7 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/IsolateUtil.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/IsolateUtil.java @@ -24,6 +24,10 @@ */ package jdk.graal.compiler.serviceprovider; +import jdk.graal.nativeimage.LibGraalRuntime; +import org.graalvm.nativeimage.CurrentIsolate; +import org.graalvm.nativeimage.ImageInfo; + /** * Utility methods that provide access to isolate details. */ @@ -33,7 +37,10 @@ public final class IsolateUtil { * Gets the address of the current isolate or 0 if this not an isolate-aware runtime. */ public static long getIsolateAddress() { - return VMSupport.getIsolateAddress(); + if (ImageInfo.inImageRuntimeCode()) { + return CurrentIsolate.getIsolate().rawValue(); + } + return 0L; } /** @@ -42,7 +49,10 @@ public static long getIsolateAddress() { * process. */ public static long getIsolateID() { - return VMSupport.getIsolateID(); + if (ImageInfo.inImageRuntimeCode()) { + return LibGraalRuntime.getIsolateID(); + } + return 0L; } /** diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/VMSupport.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/VMSupport.java index a84195a2932c..7cde1693cb7d 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/VMSupport.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/VMSupport.java @@ -30,19 +30,6 @@ * The methods of this class are substituted by the libgraal implementation. */ public final class VMSupport { - /** - * @see IsolateUtil#getIsolateAddress - */ - public static long getIsolateAddress() { - return 0L; - } - - /** - * @see IsolateUtil#getIsolateID - */ - public static long getIsolateID() { - return 0L; - } /** * Gets a scope that performs setup/cleanup actions around a libgraal compilation. @@ -79,12 +66,4 @@ public static void shutdownLibGraal() { */ public static void invokeShutdownCallback(String cbClassName, String cbMethodName) { } - - /** - * @param hintFullGC controls whether the hinted GC should be a full GC. - * @param forceFullGC controls whether to explicitly perform a full GC - * @see GraalServices#notifyLowMemoryPoint() - */ - public static void notifyLowMemoryPoint(boolean hintFullGC, boolean forceFullGC) { - } } diff --git a/compiler/src/jdk.graal.nativeimage/snapshot.sigtest b/compiler/src/jdk.graal.nativeimage/snapshot.sigtest new file mode 100644 index 000000000000..e1f38ad4eb2a --- /dev/null +++ b/compiler/src/jdk.graal.nativeimage/snapshot.sigtest @@ -0,0 +1,33 @@ +#Signature file v4.1 +#Version + +CLSS public abstract interface jdk.graal.nativeimage.LibGraalFeatureComponent +meth public abstract void duringAnalysis(org.graalvm.nativeimage.hosted.Feature$DuringAnalysisAccess) + +CLSS public abstract interface jdk.graal.nativeimage.LibGraalLoader +meth public abstract java.util.Set getServicesModules() +meth public abstract java.lang.ClassLoader getRuntimeClassLoader() +meth public abstract java.util.Map getModuleMap() +meth public abstract java.lang.ClassLoader getClassLoader() +meth public java.util.Set getAllClassNames() + +CLSS public final jdk.graal.nativeimage.LibGraalRuntime +meth public static long getIsolateID() +meth public static void notifyLowMemoryPoint(boolean) +meth public static void processReferences() +supr java.lang.Object + +CLSS public java.lang.Object +cons public init() +meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException +meth protected void finalize() throws java.lang.Throwable + anno 0 java.lang.Deprecated(boolean forRemoval=true, java.lang.String since="9") +meth public boolean equals(java.lang.Object) +meth public final java.lang.Class getClass() +meth public final void notify() +meth public final void notifyAll() +meth public final void wait() throws java.lang.InterruptedException +meth public final void wait(long) throws java.lang.InterruptedException +meth public final void wait(long,int) throws java.lang.InterruptedException +meth public int hashCode() +meth public java.lang.String toString() diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalFeatureComponent.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalFeatureComponent.java new file mode 100644 index 000000000000..a3561b91b974 --- /dev/null +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalFeatureComponent.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 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 jdk.graal.nativeimage; + +import org.graalvm.nativeimage.hosted.Feature; + +/** + * A subset of {@link Feature} interception points specific to building LibGraal. + */ +public interface LibGraalFeatureComponent { + + void duringAnalysis(Feature.DuringAnalysisAccess access); +} diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/LibGraalClassLoaderBase.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalLoader.java similarity index 68% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/LibGraalClassLoaderBase.java rename to compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalLoader.java index 0fb49d052f7d..e7cc443afe3d 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/LibGraalClassLoaderBase.java +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalLoader.java @@ -22,22 +22,24 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ - -package jdk.graal.compiler.hotspot.libgraal; +package jdk.graal.nativeimage; import java.util.Map; import java.util.Set; -public interface LibGraalClassLoaderBase { - +/** + * The class loader used to load the Graal and JVMCI classes compiled into libgraal implements this + * interface to provide extra information about the libgraal classes. + */ +public interface LibGraalLoader { /** - * @return instance of ClassLoader that implements this interface. + * @return ClassLoader that implements this interface. */ ClassLoader getClassLoader(); /** - * @return instance of ClassLoader that should be seen at image-runtime if a class was loaded at - * image-buildtime by this classloader. + * @return loader that should be seen at image-runtime if a class was loaded at image-buildtime + * by {@link #getClassLoader()} */ ClassLoader getRuntimeClassLoader(); @@ -45,10 +47,18 @@ public interface LibGraalClassLoaderBase { * Gets an unmodifiable map from the {@linkplain Class#forName(String) name} of a class to the * name of its enclosing module. */ - Map getModules(); + Map getModuleMap(); + + /** + * Gets the names of the modules containing classes that can be annotated by + * {@code LibGraalService}. + */ + Set getServicesModules(); /** * Get unmodifiable set of fully qualified names of all classes this loader can load. */ - Set getAllClassNames(); + default Set getAllClassNames() { + return getModuleMap().keySet(); + } } diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java new file mode 100644 index 000000000000..39d30cb2a94c --- /dev/null +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 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 jdk.graal.nativeimage; + +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; + +import org.graalvm.nativeimage.ImageSingletons; + +import jdk.graal.nativeimage.impl.LibGraalRuntimeSupport; + +/** + * LibGraal specific extensions to {@link org.graalvm.nativeimage}. + * + * @since 24.2 + */ +public final class LibGraalRuntime { + + /** + * Enqueues pending {@link Reference}s into their corresponding {@link ReferenceQueue}s and + * executes pending cleaners. + * + * If automatic reference handling is enabled, this method is a no-op. + * + * @since 24.2 + */ + public static void processReferences() { + ImageSingletons.lookup(LibGraalRuntimeSupport.class).processReferences(); + } + + /** + * Notifies the runtime that the caller is at a point where the live set of objects is expected + * to just have decreased significantly and now is a good time for a partial or full collection. + * + * @param suggestFullGC if a GC is performed, then suggests a full GC is done. This is true when + * the caller believes the heap occupancy is close to the minimal set of live objects + * for Graal (e.g. after a compilation). + * + * @since 24.2 + */ + public static void notifyLowMemoryPoint(boolean suggestFullGC) { + ImageSingletons.lookup(LibGraalRuntimeSupport.class).notifyLowMemoryPoint(suggestFullGC); + } + + /** + * Gets an identifier for the current isolate that is guaranteed to be unique for the first + * {@code 2^64 - 1} isolates in the process. + * + * @return a non-zero value + * @since 24.2 + */ + public static long getIsolateID() { + return ImageSingletons.lookup(LibGraalRuntimeSupport.class).getIsolateID(); + } + + private LibGraalRuntime() { + } +} diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/impl/LibGraalRuntimeSupport.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/impl/LibGraalRuntimeSupport.java new file mode 100644 index 000000000000..c9cf75e57eae --- /dev/null +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/impl/LibGraalRuntimeSupport.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 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 jdk.graal.nativeimage.impl; + +public interface LibGraalRuntimeSupport { + + void processReferences(); + + void notifyLowMemoryPoint(boolean suggestFullGC); + + long getIsolateID(); +} diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/package-info.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/package-info.java new file mode 100644 index 000000000000..f13c28e44cd5 --- /dev/null +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 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. + */ +/* + @ApiInfo( + group="Native Image LibGraal extensions" + ) + */ +/** + * Extensions to the GraalVM SDK Native Image API to customize building libgraal. + * + * @since 24.2 + */ +package jdk.graal.nativeimage; diff --git a/sdk/src/org.graalvm.nativeimage/snapshot.sigtest b/sdk/src/org.graalvm.nativeimage/snapshot.sigtest index ddb5a9414cd4..84a50d03b131 100644 --- a/sdk/src/org.graalvm.nativeimage/snapshot.sigtest +++ b/sdk/src/org.graalvm.nativeimage/snapshot.sigtest @@ -1079,6 +1079,7 @@ meth public abstract java.util.Set reachableMethod CLSS public abstract interface org.graalvm.nativeimage.hosted.FieldValueTransformer meth public abstract java.lang.Object transform(java.lang.Object,java.lang.Object) +meth public boolean isAvailable() CLSS public final org.graalvm.nativeimage.hosted.RuntimeClassInitialization meth public !varargs static void initializeAtBuildTime(java.lang.Class[]) diff --git a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/FieldValueTransformer.java b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/FieldValueTransformer.java index 04afbd762e9e..a05d2b3c59a6 100644 --- a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/FieldValueTransformer.java +++ b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/FieldValueTransformer.java @@ -83,4 +83,13 @@ public interface FieldValueTransformer { * @since 22.3 */ Object transform(Object receiver, Object originalValue); + + /** + * Returns true when the value for this custom computation is available. + * + * @since 24.2 + */ + default boolean isAvailable() { + return true; + } } diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py index c2801a9fe4dd..66546c067a30 100644 --- a/substratevm/mx.substratevm/suite.py +++ b/substratevm/mx.substratevm/suite.py @@ -1738,6 +1738,7 @@ "transitive org.graalvm.nativeimage.pointsto", "org.graalvm.collections", "org.graalvm.truffle.compiler", + "jdk.graal.nativeimage" ], "uses" : [ "org.graalvm.nativeimage.Platform", diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/fieldvaluetransformer/FieldValueTransformerWithAvailability.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/fieldvaluetransformer/FieldValueTransformerWithAvailability.java index 2beb2e5b7fb3..3f6390d7920e 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/fieldvaluetransformer/FieldValueTransformerWithAvailability.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/fieldvaluetransformer/FieldValueTransformerWithAvailability.java @@ -38,6 +38,7 @@ public interface FieldValueTransformerWithAvailability extends FieldValueTransfo /** * Returns true when the value for this custom computation is available. */ + @Override boolean isAvailable(); /** diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RuntimeSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RuntimeSupport.java index bc95bf523cba..2a2df3be11da 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RuntimeSupport.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RuntimeSupport.java @@ -28,10 +28,13 @@ import java.util.Objects; import java.util.concurrent.atomic.AtomicReference; +import com.oracle.svm.core.heap.Heap; +import jdk.graal.nativeimage.impl.LibGraalRuntimeSupport; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; import org.graalvm.nativeimage.VMRuntime; +import org.graalvm.nativeimage.impl.IsolateSupport; import org.graalvm.nativeimage.impl.VMRuntimeSupport; import com.oracle.svm.core.IsolateArgumentParser; @@ -42,8 +45,24 @@ import jdk.graal.compiler.api.replacements.Fold; -@AutomaticallyRegisteredImageSingleton({VMRuntimeSupport.class, RuntimeSupport.class}) -public final class RuntimeSupport implements VMRuntimeSupport { +@AutomaticallyRegisteredImageSingleton({VMRuntimeSupport.class, RuntimeSupport.class, LibGraalRuntimeSupport.class}) +public final class RuntimeSupport implements VMRuntimeSupport, LibGraalRuntimeSupport { + + @Override + public void processReferences() { + Heap.getHeap().doReferenceHandling(); + } + + @Override + public void notifyLowMemoryPoint(boolean suggestFullGC) { + Heap.getHeap().getGC().collectionHint(suggestFullGC); + } + + @Override + public long getIsolateID() { + return ImageSingletons.lookup(IsolateSupport.class).getIsolateID(); + } + @FunctionalInterface public interface Hook { void execute(boolean isFirstIsolate); diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalCompilerSupport.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalCompilerSupport.java deleted file mode 100644 index d2985195e875..000000000000 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalCompilerSupport.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2024, 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.graal.hotspot.libgraal; - -import org.graalvm.collections.EconomicMap; -import org.graalvm.nativeimage.ImageSingletons; -import org.graalvm.nativeimage.Platform; -import org.graalvm.nativeimage.Platforms; - -import com.oracle.svm.core.util.ImageHeapMap; - -/** - * Holds data that is pre-computed during native image generation and accessed at run time during a - * Graal compilation. - */ -public class LibGraalCompilerSupport { - - public final EconomicMap, Object> nodeClasses = ImageHeapMap.create(); - public final EconomicMap, Object> instructionClasses = ImageHeapMap.create(); - - protected EconomicMap, Object> basePhaseStatistics = ImageHeapMap.create(); - protected EconomicMap, Object> lirPhaseStatistics = ImageHeapMap.create(); - - @Platforms(Platform.HOSTED_ONLY.class) - static void registerStatistics(Class phaseSubClass, EconomicMap, Object> cache, Object newStatistics) { - assert !cache.containsKey(phaseSubClass); - cache.put(phaseSubClass, newStatistics); - } - - public static LibGraalCompilerSupport get() { - return ImageSingletons.lookup(LibGraalCompilerSupport.class); - } - - public EconomicMap, Object> getBasePhaseStatistics() { - return basePhaseStatistics; - } - - public EconomicMap, Object> getLirPhaseStatistics() { - return lirPhaseStatistics; - } -} diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java index ef4c59d60bf7..db68c0871cf1 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java @@ -58,7 +58,9 @@ import jdk.graal.compiler.options.OptionValues; import jdk.graal.compiler.options.OptionsParser; import jdk.graal.compiler.word.Word; +import jdk.graal.compiler.serviceprovider.IsolateUtil; import org.graalvm.collections.EconomicMap; +import jdk.graal.nativeimage.LibGraalRuntime; import org.graalvm.jniutils.HSObject; import org.graalvm.jniutils.JNI; import org.graalvm.jniutils.JNI.JByteArray; @@ -83,11 +85,8 @@ import org.graalvm.nativeimage.c.function.CEntryPoint.IsolateThreadContext; import org.graalvm.nativeimage.c.type.CLongPointer; import org.graalvm.nativeimage.c.type.CTypeConversion; -import org.graalvm.nativeimage.impl.IsolateSupport; import org.graalvm.word.PointerBase; -import com.oracle.svm.core.heap.Heap; - import jdk.internal.misc.Unsafe; /** @@ -306,7 +305,7 @@ private static long hashConstantOopFields(JNIEnv jniEnv, * any code which is expecting to process a reference queue to let it clean up. */ static void doReferenceHandling() { - Heap.getHeap().doReferenceHandling(); + LibGraalRuntime.processReferences(); synchronized (LibGraalJVMCISubstitutions.Target_jdk_vm_ci_hotspot_Cleaner.class) { LibGraalJVMCISubstitutions.Target_jdk_vm_ci_hotspot_Cleaner.clean(); } @@ -368,7 +367,7 @@ final class LibGraalScopeEntryPoints { @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_LibGraalScope_getIsolateId") @SuppressWarnings("unused") public static long getIsolateId(PointerBase env, PointerBase jclass, @IsolateThreadContext long isolateThreadId) { - return ImageSingletons.lookup(IsolateSupport.class).getIsolateID(); + return IsolateUtil.getIsolateID(); } } @@ -588,8 +587,8 @@ public static void doCompile(JNIEnv env, try { singleton().doCompile.invoke(compiler, taskHsHandle, compilableHsHandle, listenerHsHandle); } finally { - Heap.getHeap().doReferenceHandling(); - Heap.getHeap().getGC().collectionHint(true); + LibGraalRuntime.processReferences(); + LibGraalRuntime.notifyLowMemoryPoint(true); } } catch (Throwable t) { JNIExceptionWrapper.throwInHotSpot(env, t); diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java index 847281b7eade..9cdd34f15654 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java @@ -31,17 +31,19 @@ import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.MethodType; -import java.lang.reflect.Modifier; +import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.nio.file.Path; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; +import java.util.IdentityHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.BooleanSupplier; import java.util.function.Consumer; -import java.util.function.Function; import java.util.regex.Pattern; import org.graalvm.collections.EconomicMap; @@ -50,6 +52,7 @@ import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; import org.graalvm.nativeimage.hosted.Feature; +import org.graalvm.nativeimage.hosted.FieldValueTransformer; import org.graalvm.nativeimage.hosted.RuntimeClassInitialization; import org.graalvm.nativeimage.hosted.RuntimeReflection; @@ -57,28 +60,25 @@ import com.oracle.graal.pointsto.meta.AnalysisType; import com.oracle.graal.pointsto.reports.CallTreePrinter; import com.oracle.svm.core.hub.ClassForNameSupport; -import com.oracle.svm.core.util.VMError; import com.oracle.svm.graal.hotspot.GetCompilerConfig; import com.oracle.svm.graal.hotspot.GetJNIConfig; import com.oracle.svm.hosted.FeatureImpl.AfterAnalysisAccessImpl; -import com.oracle.svm.hosted.FeatureImpl.BeforeAnalysisAccessImpl; -import com.oracle.svm.hosted.FeatureImpl.DuringAnalysisAccessImpl; -import com.oracle.svm.hosted.FeatureImpl.DuringSetupAccessImpl; import com.oracle.svm.util.ModuleSupport; import com.oracle.svm.util.ModuleSupport.Access; -import com.oracle.svm.util.ReflectionUtil; +import jdk.graal.compiler.core.common.Fields; import jdk.graal.compiler.debug.DebugContext; +import jdk.graal.compiler.debug.GraalError; +import jdk.graal.compiler.graph.Edges; import jdk.graal.compiler.hotspot.CompilerConfigurationFactory; import jdk.graal.compiler.hotspot.libgraal.BuildTime; -import jdk.graal.compiler.hotspot.libgraal.LibGraalClassLoaderBase; -import jdk.graal.compiler.lir.phases.LIRPhase; import jdk.graal.compiler.nodes.graphbuilderconf.GeneratedInvocationPlugin; import jdk.graal.compiler.options.OptionDescriptor; import jdk.graal.compiler.options.OptionKey; -import jdk.graal.compiler.phases.BasePhase; import jdk.graal.compiler.serviceprovider.GlobalAtomicLong; import jdk.graal.compiler.serviceprovider.LibGraalService; +import jdk.graal.nativeimage.LibGraalFeatureComponent; +import jdk.graal.nativeimage.LibGraalLoader; import jdk.vm.ci.code.Architecture; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; import jdk.vm.ci.hotspot.HotSpotModifiers; @@ -89,13 +89,6 @@ * With use of {@code -Djdk.graal.internal.libgraal.javahome=path}, the Graal and JVMCI classes from * which libgraal is built can be from a "guest" JDK that may be different from the JDK on which * Native Image is running. - *

- * This feature is composed of these key classes: - *

    - *
  • {@code HostedLibGraalClassLoader}
  • - *
  • {@link LibGraalEntryPoints}
  • - *
  • {@link LibGraalSubstitutions}
  • - *
*/ @Platforms(Platform.HOSTED_ONLY.class) public final class LibGraalFeature implements Feature { @@ -107,14 +100,9 @@ public boolean getAsBoolean() { } } - @Override - public List> getRequiredFeatures() { - return List.of(LibGraalFieldsOffsetsFeature.class); - } - final MethodHandles.Lookup mhl = MethodHandles.lookup(); - LibGraalClassLoaderBase libGraalClassLoader; + LibGraalLoader libgraalLoader; /** * Loader used for loading classes from the guest GraalVM. @@ -127,18 +115,9 @@ public List> getRequiredFeatures() { Class buildTimeClass; /** - * Handle to {@link jdk.graal.compiler.phases.BasePhase} in the guest. - */ - private Class basePhaseClass; - - private Function, Object> newBasePhaseStatistics; - - /** - * Handle to {@link jdk.graal.compiler.lir.phases.LIRPhase} in the guest. + * Set of {@link LibGraalFeatureComponent}s created during analysis. */ - private Class lirPhaseClass; - - private Function, Object> newLIRPhaseStatistics; + private final Set libGraalFeatureComponents = ConcurrentHashMap.newKeySet(); /** * Handle to {@link GlobalAtomicLong#getInitialValue()} in the guest. @@ -199,22 +178,18 @@ public Class loadClassOrNull(String name) { @Override public void afterRegistration(AfterRegistrationAccess access) { // LibGraalEntryPoints uses a number of classes in org.graalvm.nativeimage.builder - accessModulesToClass(ModuleSupport.Access.EXPORT, LibGraalFeature.class, - "org.graalvm.nativeimage.builder"); + exportModulesToLibGraal("org.graalvm.nativeimage.builder"); // LibGraalFeature accesses a few Graal classes (see import statements above) - accessModulesToClass(ModuleSupport.Access.EXPORT, LibGraalFeature.class, "jdk.graal.compiler"); + exportModulesToLibGraal("jdk.graal.compiler"); // LibGraalTruffleToLibGraalEntryPoints access TruffleToLibGraal.Id - accessModulesToClass(ModuleSupport.Access.EXPORT, LibGraalFeature.class, "org.graalvm.truffle.compiler"); + exportModulesToLibGraal("org.graalvm.truffle.compiler"); ImageSingletons.add(NativeBridgeSupport.class, new LibGraalNativeBridgeSupport()); - // Target_jdk_graal_compiler_serviceprovider_VMSupport.getIsolateID needs access to - // org.graalvm.nativeimage.impl.IsolateSupport - accessModulesToClass(ModuleSupport.Access.EXPORT, LibGraalFeature.class, "org.graalvm.nativeimage"); - libGraalClassLoader = createHostedLibGraalClassLoader(access); - loader = libGraalClassLoader.getClassLoader(); + libgraalLoader = createHostedLibGraalClassLoader(access); + loader = libgraalLoader.getClassLoader(); ImageSingletons.lookup(ClassForNameSupport.class).setLibGraalLoader(loader); buildTimeClass = loadClassOrFail(BuildTime.class); @@ -226,17 +201,20 @@ public void afterRegistration(AfterRegistrationAccess access) { try { globalAtomicLongGetInitialValue = mhl.findVirtual(loadClassOrFail(GlobalAtomicLong.class), "getInitialValue", methodType(long.class)); - } catch (Throwable e) { - VMError.shouldNotReachHere(e); + GraalError.shouldNotReachHere(e); } } @SuppressWarnings("unchecked") - private static LibGraalClassLoaderBase createHostedLibGraalClassLoader(AfterRegistrationAccess access) { - var hostedLibGraalClassLoaderClass = access.findClassByName("jdk.graal.compiler.hotspot.libgraal.HostedLibGraalClassLoader"); + private static LibGraalLoader createHostedLibGraalClassLoader(AfterRegistrationAccess access) { + var hostedLibGraalClassLoaderClass = access.findClassByName("jdk.graal.compiler.libgraal.loader.HostedLibGraalClassLoader"); ModuleSupport.accessPackagesToClass(Access.EXPORT, hostedLibGraalClassLoaderClass, false, "java.base", "jdk.internal.module"); - return ReflectionUtil.newInstance((Class) hostedLibGraalClassLoaderClass); + return LibGraalReflectionUtil.newInstance((Class) hostedLibGraalClassLoaderClass); + } + + private static void exportModulesToLibGraal(String... moduleNames) { + accessModulesToClass(Access.EXPORT, LibGraalFeature.class, moduleNames); } private static void accessModulesToClass(ModuleSupport.Access access, Class accessingClass, String... moduleNames) { @@ -253,33 +231,9 @@ static Module getBootModule(String moduleName) { @Override public void duringSetup(DuringSetupAccess access) { + ClassLoader runtimeLoader = libgraalLoader.getRuntimeClassLoader(); + access.registerObjectReplacer(obj -> obj == loader ? runtimeLoader : obj); - /* - * HostedLibGraalClassLoader provides runtime-replacement loader instance. Make sure - * HostedLibGraalClassLoader gets replaced by customRuntimeLoader instance in image. - */ - ClassLoader customRuntimeLoader = libGraalClassLoader.getRuntimeClassLoader(); - access.registerObjectReplacer(obj -> obj == loader ? customRuntimeLoader : obj); - - try { - var basePhaseStatisticsClass = loadClassOrFail(BasePhase.BasePhaseStatistics.class); - var lirPhaseStatisticsClass = loadClassOrFail(LIRPhase.LIRPhaseStatistics.class); - MethodType statisticsCTorType = methodType(void.class, Class.class); - var basePhaseStatisticsCTor = mhl.findConstructor(basePhaseStatisticsClass, statisticsCTorType); - var lirPhaseStatisticsCTor = mhl.findConstructor(lirPhaseStatisticsClass, statisticsCTorType); - newBasePhaseStatistics = new StatisticsCreator(basePhaseStatisticsCTor)::create; - newLIRPhaseStatistics = new StatisticsCreator(lirPhaseStatisticsCTor)::create; - - basePhaseClass = loadClassOrFail(BasePhase.class); - lirPhaseClass = loadClassOrFail(LIRPhase.class); - - ImageSingletons.add(LibGraalCompilerSupport.class, new LibGraalCompilerSupport()); - } catch (Throwable e) { - throw VMError.shouldNotReachHere("Failed to invoke jdk.graal.compiler.hotspot.libgraal.BuildTime methods", e); - } - - DuringSetupAccessImpl accessImpl = (DuringSetupAccessImpl) access; - accessImpl.registerClassReachabilityListener(this::registerPhaseStatistics); optionCollector = new OptionCollector(LibGraalEntryPoints.vmOptionDescriptors); access.registerObjectReachabilityHandler(optionCollector::accept, OptionKey.class); access.registerObjectReachabilityHandler(optionCollector::accept, loadClassOrFail(OptionKey.class)); @@ -317,14 +271,14 @@ private class OptionCollector implements Consumer { MethodHandle mh = mhl.findStatic(buildTimeClass, "initLibgraalOptions", mt); compilerOptionsInfo = mh.invoke(); } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); + throw GraalError.shouldNotReachHere(e); } } @Override public void accept(Object option) { if (sealed) { - VMError.guarantee(options.contains(option), "All options must have been discovered during static analysis: %s", option); + GraalError.guarantee(options.contains(option), "All options must have been discovered during static analysis: %s", option); } else { options.add(option); } @@ -338,66 +292,36 @@ void afterAnalysis(AfterAnalysisAccess access) { if (option instanceof OptionKey optionKey) { OptionDescriptor descriptor = optionKey.getDescriptor(); if (descriptor.isServiceLoaded()) { - VMError.guarantee(access.isReachable(option.getClass()), "%s", option.getClass()); - VMError.guarantee(access.isReachable(descriptor.getClass()), "%s", descriptor.getClass()); + GraalError.guarantee(access.isReachable(option.getClass()), "%s", option.getClass()); + GraalError.guarantee(access.isReachable(descriptor.getClass()), "%s", descriptor.getClass()); vmOptionDescriptors.put(optionKey.getName(), descriptor); } } else { ClassLoader optionCL = option.getClass().getClassLoader(); - VMError.guarantee(optionCL == loader, "unexpected option loader: %s", optionCL); + GraalError.guarantee(optionCL == loader, "unexpected option loader: %s", optionCL); compilerOptions.add(option); } } try { MethodType mt = methodType(Iterable.class, List.class, Object.class, Map.class); MethodHandle mh = mhl.findStatic(buildTimeClass, "finalizeLibgraalOptions", mt); - Map modules = ReflectionUtil.invokeMethod(ReflectionUtil.lookupMethod(loader.getClass(), "getModules"), loader); + LibGraalLoader manifest = (LibGraalLoader) loader; + Map modules = manifest.getModuleMap(); Iterable values = (Iterable) mh.invoke(compilerOptions, compilerOptionsInfo, modules); for (Object descriptor : values) { - VMError.guarantee(access.isReachable(descriptor.getClass()), "%s", descriptor.getClass()); + GraalError.guarantee(access.isReachable(descriptor.getClass()), "%s", descriptor.getClass()); } } catch (Throwable e) { - VMError.shouldNotReachHere(e); - } - } - } - - private record StatisticsCreator(MethodHandle ctorHandle) { - Object create(Class clazz) { - try { - return ctorHandle.invoke(clazz); - } catch (Throwable e) { - throw VMError.shouldNotReachHere("Failed to create new instance of Statistics clazz with MethodHandle " + ctorHandle, e); - } - } - } - - private void registerPhaseStatistics(DuringAnalysisAccess a, Class newlyReachableClass) { - DuringAnalysisAccessImpl access = (DuringAnalysisAccessImpl) a; - - if (!Modifier.isAbstract(newlyReachableClass.getModifiers())) { - boolean requireAnalysisIteration = true; - if (basePhaseClass.isAssignableFrom(newlyReachableClass)) { - LibGraalCompilerSupport.registerStatistics(newlyReachableClass, LibGraalCompilerSupport.get().basePhaseStatistics, - newBasePhaseStatistics.apply(newlyReachableClass)); - - } else if (lirPhaseClass.isAssignableFrom(newlyReachableClass)) { - LibGraalCompilerSupport.registerStatistics(newlyReachableClass, LibGraalCompilerSupport.get().lirPhaseStatistics, - newLIRPhaseStatistics.apply(newlyReachableClass)); - } else { - requireAnalysisIteration = false; - } - - if (requireAnalysisIteration) { - access.requireAnalysisIteration(); + throw GraalError.shouldNotReachHere(e); } } } @SuppressWarnings("unchecked") public List> findLibGraalServices() { - Set libgraalServicesModules = ReflectionUtil.invokeMethod(ReflectionUtil.lookupMethod(loader.getClass(), "getLibgraalServicesModules"), loader); - Map modules = ReflectionUtil.invokeMethod(ReflectionUtil.lookupMethod(loader.getClass(), "getModules"), loader); + LibGraalLoader manifest = (LibGraalLoader) loader; + Set libgraalServicesModules = manifest.getServicesModules(); + Map modules = manifest.getModuleMap(); Class service = (Class) loadClassOrFail(LibGraalService.class); List> libgraalServices = new ArrayList<>(); @@ -410,10 +334,72 @@ public List> findLibGraalServices() { return libgraalServices; } + private BeforeCompilationAccess beforeCompilationAccess; + + /** + * Transformer for {@code Fields.offsets} and {@code Edges.iterationMask} which need to be + * recomputed to use SVM field offsets instead of HotSpot field offsets. + */ + class FieldOffsetsTransformer implements FieldValueTransformer { + /** + * Map from {@link Fields} objects to a (newOffsets, newIterationMask) tuple represented as + * a {@link java.util.Map.Entry} value. + */ + private final Map> replacements = new IdentityHashMap<>(); + + final Class edgesClass; + final Class fieldsClass; + final Field fieldsOffsetsField; + final Field edgesIterationMaskField; + final Method recomputeOffsetsAndIterationMaskMethod; + + FieldOffsetsTransformer() { + edgesClass = loadClassOrFail(Edges.class.getName()); + fieldsClass = loadClassOrFail(Fields.class.getName()); + fieldsOffsetsField = LibGraalReflectionUtil.lookupField(fieldsClass, "offsets"); + edgesIterationMaskField = LibGraalReflectionUtil.lookupField(edgesClass, "iterationMask"); + recomputeOffsetsAndIterationMaskMethod = LibGraalReflectionUtil.lookupMethod(fieldsClass, "recomputeOffsetsAndIterationMask", BeforeCompilationAccess.class); + } + + void register(BeforeAnalysisAccess access) { + access.registerFieldValueTransformer(fieldsOffsetsField, this); + access.registerFieldValueTransformer(edgesIterationMaskField, this); + } + + @Override + public boolean isAvailable() { + return beforeCompilationAccess != null; + } + + @Override + public Object transform(Object receiver, Object originalValue) { + Map.Entry repl = getReplacement(receiver); + if (originalValue instanceof long[]) { + return repl.getKey(); + } + return repl.getValue(); + } + + private Map.Entry getReplacement(Object receiver) { + synchronized (replacements) { + return replacements.computeIfAbsent(receiver, this::computeReplacement); + } + } + + @SuppressWarnings("unchecked") + private Map.Entry computeReplacement(Object receiver) { + try { + return (Map.Entry) recomputeOffsetsAndIterationMaskMethod.invoke(receiver, beforeCompilationAccess); + } catch (Throwable e) { + throw GraalError.shouldNotReachHere(e); + } + } + } + @Override - public void beforeAnalysis(BeforeAnalysisAccess baa) { - BeforeAnalysisAccessImpl impl = (BeforeAnalysisAccessImpl) baa; - var bb = impl.getBigBang(); + public void beforeAnalysis(BeforeAnalysisAccess access) { + + new FieldOffsetsTransformer().register(access); /* Contains static fields that depend on HotSpotJVMCIRuntime */ RuntimeClassInitialization.initializeAtRunTime(loadClassOrFail(HotSpotModifiers.class)); @@ -424,19 +410,19 @@ public void beforeAnalysis(BeforeAnalysisAccess baa) { /* Needed for runtime calls to BoxingSnippets.Templates.getCacheClass(JavaKind) */ RuntimeReflection.registerAllDeclaredClasses(Character.class); - RuntimeReflection.register(ReflectionUtil.lookupField(ReflectionUtil.lookupClass("java.lang.Character$CharacterCache"), "cache")); + RuntimeReflection.register(LibGraalReflectionUtil.lookupField(LibGraalReflectionUtil.lookupClass("java.lang.Character$CharacterCache"), "cache")); RuntimeReflection.registerAllDeclaredClasses(Byte.class); - RuntimeReflection.register(ReflectionUtil.lookupField(ReflectionUtil.lookupClass("java.lang.Byte$ByteCache"), "cache")); + RuntimeReflection.register(LibGraalReflectionUtil.lookupField(LibGraalReflectionUtil.lookupClass("java.lang.Byte$ByteCache"), "cache")); RuntimeReflection.registerAllDeclaredClasses(Short.class); - RuntimeReflection.register(ReflectionUtil.lookupField(ReflectionUtil.lookupClass("java.lang.Short$ShortCache"), "cache")); + RuntimeReflection.register(LibGraalReflectionUtil.lookupField(LibGraalReflectionUtil.lookupClass("java.lang.Short$ShortCache"), "cache")); RuntimeReflection.registerAllDeclaredClasses(Integer.class); - RuntimeReflection.register(ReflectionUtil.lookupField(ReflectionUtil.lookupClass("java.lang.Integer$IntegerCache"), "cache")); + RuntimeReflection.register(LibGraalReflectionUtil.lookupField(LibGraalReflectionUtil.lookupClass("java.lang.Integer$IntegerCache"), "cache")); RuntimeReflection.registerAllDeclaredClasses(Long.class); - RuntimeReflection.register(ReflectionUtil.lookupField(ReflectionUtil.lookupClass("java.lang.Long$LongCache"), "cache")); + RuntimeReflection.register(LibGraalReflectionUtil.lookupField(LibGraalReflectionUtil.lookupClass("java.lang.Long$LongCache"), "cache")); /* Configure static state of Graal. */ try { - Consumer> registerAsInHeap = baa::registerAsInHeap; + Consumer> registerAsInHeap = access::registerAsInHeap; Consumer>> hostedGraalSetFoldNodePluginClasses = GeneratedInvocationPlugin::setFoldNodePluginClasses; @@ -449,14 +435,15 @@ public void beforeAnalysis(BeforeAnalysisAccess baa) { "configureGraalForLibGraal", methodType(void.class, String.class, // arch + Collection.class, // libGraalFeatureComponents List.class, // guestServiceClasses Consumer.class, // registerAsInHeap Consumer.class, // hostedGraalSetFoldNodePluginClasses String.class, // nativeImageLocationQualifier byte[].class // encodedGuestObjects )); - Path libGraalJavaHome = ReflectionUtil.readField(loader.getClass(), "libGraalJavaHome", loader); - GetCompilerConfig.Result configResult = GetCompilerConfig.from(libGraalJavaHome, bb.getOptions()); + Path libGraalJavaHome = LibGraalReflectionUtil.readField(loader.getClass(), "libGraalJavaHome", loader); + GetCompilerConfig.Result configResult = GetCompilerConfig.from(libGraalJavaHome); for (var e : configResult.opens().entrySet()) { for (String source : e.getValue()) { ModuleSupport.accessPackagesToClass(ModuleSupport.Access.OPEN, buildTimeClass, false, e.getKey(), source); @@ -465,6 +452,7 @@ public void beforeAnalysis(BeforeAnalysisAccess baa) { Architecture arch = HotSpotJVMCIRuntime.runtime().getHostJVMCIBackend().getTarget().arch; configureGraalForLibGraal.invoke(arch.getName(), + libGraalFeatureComponents, guestServiceClasses, registerAsInHeap, hostedGraalSetFoldNodePluginClasses, @@ -474,7 +462,14 @@ public void beforeAnalysis(BeforeAnalysisAccess baa) { initGraalRuntimeHandles(mhl.findStatic(buildTimeClass, "getRuntimeHandles", methodType(Map.class))); initializeTruffle(); } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); + throw GraalError.shouldNotReachHere(e); + } + } + + @Override + public void duringAnalysis(DuringAnalysisAccess access) { + for (var c : libGraalFeatureComponents) { + c.duringAnalysis(access); } } @@ -493,9 +488,14 @@ private void initializeTruffle() throws Throwable { truffleConfigureGraalForLibGraal.invoke(); } - @SuppressWarnings("try") @Override public void afterAnalysis(AfterAnalysisAccess access) { + checkForbiddenTypes((AfterAnalysisAccessImpl) access); + optionCollector.afterAnalysis(access); + } + + @SuppressWarnings("try") + private void checkForbiddenTypes(AfterAnalysisAccessImpl access) { /* * Verify we only have JVMCI & Graal classes reachable that are coming from * LibGraalClassLoader except for hosted JVMCI & Graal classes that are legitimately used by @@ -529,8 +529,7 @@ public void afterAnalysis(AfterAnalysisAccess access) { Set forbiddenHostedModules = Set.of("jdk.internal.vm.ci", "org.graalvm.collections", "org.graalvm.word", "jdk.graal.compiler"); - AfterAnalysisAccessImpl accessImpl = (AfterAnalysisAccessImpl) access; - BigBang bigBang = accessImpl.getBigBang(); + BigBang bigBang = access.getBigBang(); CallTreePrinter callTreePrinter = new CallTreePrinter(bigBang); callTreePrinter.buildCallTree(); @@ -555,12 +554,16 @@ public void afterAnalysis(AfterAnalysisAccess access) { } if (!forbiddenReachableTypes.isEmpty()) { CallTreePrinter.print(bigBang, "reports", "report"); - VMError.shouldNotReachHere("LibGraalEntryPoints build found forbidden hosted types as reachable: %s", String.join(", ", forbiddenReachableTypes)); + throw new GraalError("LibGraalEntryPoints build found forbidden hosted types as reachable: %s", String.join(", ", forbiddenReachableTypes)); } - optionCollector.afterAnalysis(access); } private static Pattern classesPattern(String packageName, String... regexes) { return Pattern.compile("%s(%s)".formatted(Pattern.quote(packageName + '.'), String.join("|", regexes))); } + + @Override + public void beforeCompilation(BeforeCompilationAccess access) { + beforeCompilationAccess = access; + } } diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFieldsOffsetsFeature.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFieldsOffsetsFeature.java deleted file mode 100644 index 2fb3c50021ce..000000000000 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFieldsOffsetsFeature.java +++ /dev/null @@ -1,482 +0,0 @@ -/* - * Copyright (c) 2024, 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.graal.hotspot.libgraal; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.IdentityHashMap; -import java.util.Map; -import java.util.function.Function; - -import jdk.graal.compiler.hotspot.libgraal.BuildTime; -import org.graalvm.collections.EconomicMap; -import org.graalvm.nativeimage.ImageSingletons; - -import com.oracle.graal.pointsto.meta.AnalysisField; -import com.oracle.graal.pointsto.meta.AnalysisType; -import com.oracle.svm.core.BuildPhaseProvider; -import com.oracle.svm.core.feature.InternalFeature; -import com.oracle.svm.core.fieldvaluetransformer.FieldValueTransformerWithAvailability; -import com.oracle.svm.core.util.VMError; -import com.oracle.svm.hosted.FeatureImpl.BeforeAnalysisAccessImpl; -import com.oracle.svm.hosted.FeatureImpl.CompilationAccessImpl; -import com.oracle.svm.hosted.FeatureImpl.DuringAnalysisAccessImpl; -import com.oracle.svm.hosted.FeatureImpl.DuringSetupAccessImpl; -import com.oracle.svm.hosted.meta.HostedMetaAccess; -import com.oracle.svm.util.ModuleSupport; -import com.oracle.svm.util.ReflectionUtil; - -import jdk.internal.misc.Unsafe; - -/** - * Graal uses unsafe memory accesses to access {@code Node}s and {@code LIRInstruction}s. The - * offsets for these accesses are maintained in {@code Fields}, which are accessible from - * meta-classes such as {@code NodeClass} and {@code LIRInstructionClass}. We do not want to replace - * the whole meta-classes. Instead, we just replace the {@code long[]} arrays that hold the actual - * offsets. - */ -public final class LibGraalFieldsOffsetsFeature implements InternalFeature { - - private final MethodHandles.Lookup mhl = MethodHandles.lookup(); - private LibGraalFeature libGraalFeature; - - private Class fieldsClass; - private Class edgesClass; - private Class edgesTypeClass; - private MethodHandle fieldsClassGetOffsetsMethod; - private MethodHandle fieldsClassGetCountMethod; - private MethodHandle fieldsClassGetDeclaringClassMethod; - private MethodHandle fieldsClassGetNameMethod; - - private MethodHandle edgesClassTypeMethod; - private MethodHandle edgesClassGetDirectCountMethod; - - private Class nodeClass; - private Class nodeClassClass; - private Class inputEdgesClass; - private Class successorEdgesClass; - private MethodHandle nodeClassClassGetMethod; - private MethodHandle nodeClassClassGetInputEdgesMethod; - private MethodHandle nodeClassClassGetSuccessorEdgesMethod; - private MethodHandle nodeClassClassGetShortNameMethod; - private MethodHandle nodeClassClassComputeIterationMaskMethod; - - private Class fieldIntrospectionClass; - private MethodHandle fieldIntrospectionClassGetDataMethod; - private MethodHandle fieldIntrospectionClassGetAllFieldsMethod; - private MethodHandle fieldIntrospectionClassGetClazzMethod; - private Class lirInstructionClass; - private Class lirInstructionClassClass; - private MethodHandle lirInstructionClassClassGetMethod; - - private static class FieldsOffsetsReplacement { - protected final Object fields; - protected boolean newValuesAvailable; - protected long[] newOffsets; - protected long newIterationInitMask; - - protected FieldsOffsetsReplacement(Object fields) { - this.fields = fields; - } - } - - static class FieldsOffsetsReplacements { - private final Map replacements = new IdentityHashMap<>(); - private boolean sealed; - } - - private static Map getReplacements() { - return ImageSingletons.lookup(FieldsOffsetsReplacements.class).replacements; - } - - @Override - public void duringSetup(DuringSetupAccess a) { - DuringSetupAccessImpl access = (DuringSetupAccessImpl) a; - libGraalFeature = ImageSingletons.lookup(LibGraalFeature.class); - - fieldsClass = libGraalFeature.loadClassOrFail("jdk.graal.compiler.core.common.Fields"); - edgesClass = libGraalFeature.loadClassOrFail("jdk.graal.compiler.graph.Edges"); - edgesTypeClass = libGraalFeature.loadClassOrFail("jdk.graal.compiler.graph.Edges$Type"); - nodeClass = libGraalFeature.loadClassOrFail("jdk.graal.compiler.graph.Node"); - nodeClassClass = libGraalFeature.loadClassOrFail("jdk.graal.compiler.graph.NodeClass"); - lirInstructionClass = libGraalFeature.loadClassOrFail("jdk.graal.compiler.lir.LIRInstruction"); - lirInstructionClassClass = libGraalFeature.loadClassOrFail("jdk.graal.compiler.lir.LIRInstructionClass"); - fieldIntrospectionClass = libGraalFeature.loadClassOrFail("jdk.graal.compiler.core.common.FieldIntrospection"); - inputEdgesClass = libGraalFeature.loadClassOrFail("jdk.graal.compiler.graph.InputEdges"); - successorEdgesClass = libGraalFeature.loadClassOrFail("jdk.graal.compiler.graph.SuccessorEdges"); - - try { - fieldsClassGetOffsetsMethod = mhl.findVirtual(fieldsClass, "getOffsets", MethodType.methodType(long[].class)); - fieldsClassGetCountMethod = mhl.findVirtual(fieldsClass, "getCount", MethodType.methodType(int.class)); - fieldsClassGetDeclaringClassMethod = mhl.findVirtual(fieldsClass, "getDeclaringClass", MethodType.methodType(Class.class, int.class)); - fieldsClassGetNameMethod = mhl.findVirtual(fieldsClass, "getName", MethodType.methodType(String.class, int.class)); - - edgesClassTypeMethod = mhl.findVirtual(edgesClass, "type", MethodType.methodType(edgesTypeClass)); - edgesClassGetDirectCountMethod = mhl.findVirtual(edgesClass, "getDirectCount", MethodType.methodType(int.class)); - - nodeClassClassGetMethod = mhl.findStatic(nodeClassClass, "get", MethodType.methodType(nodeClassClass, Class.class)); - nodeClassClassGetInputEdgesMethod = mhl.findVirtual(nodeClassClass, "getInputEdges", MethodType.methodType(inputEdgesClass)); - nodeClassClassGetSuccessorEdgesMethod = mhl.findVirtual(nodeClassClass, "getSuccessorEdges", MethodType.methodType(successorEdgesClass)); - nodeClassClassGetShortNameMethod = mhl.findVirtual(nodeClassClass, "shortName", MethodType.methodType(String.class)); - nodeClassClassGetShortNameMethod = mhl.findVirtual(nodeClassClass, "shortName", MethodType.methodType(String.class)); - nodeClassClassComputeIterationMaskMethod = mhl.findStatic(nodeClassClass, "computeIterationMask", MethodType.methodType(long.class, edgesTypeClass, int.class, long[].class)); - - lirInstructionClassClassGetMethod = mhl.findStatic(lirInstructionClassClass, "get", MethodType.methodType(lirInstructionClassClass, Class.class)); - - fieldIntrospectionClassGetDataMethod = mhl.findVirtual(fieldIntrospectionClass, "getData", MethodType.methodType(fieldsClass)); - fieldIntrospectionClassGetAllFieldsMethod = mhl.findVirtual(fieldIntrospectionClass, "getAllFields", MethodType.methodType(fieldsClass.arrayType())); - fieldIntrospectionClassGetClazzMethod = mhl.findVirtual(fieldIntrospectionClass, "getClazz", MethodType.methodType(Class.class)); - - } catch (ReflectiveOperationException e) { - throw VMError.shouldNotReachHere(e); - } - - ModuleSupport.accessModuleByClass(ModuleSupport.Access.EXPORT, LibGraalFieldsOffsetsFeature.class, InternalFeature.class); - ImageSingletons.add(FieldsOffsetsReplacements.class, new FieldsOffsetsReplacements()); - access.registerObjectReplacer(this::replaceFieldsOffsets); - access.registerClassReachabilityListener(this::classReachabilityListener); - } - - @Override - public void beforeAnalysis(BeforeAnalysisAccess access) { - MethodHandle getInputEdgesOffsets; - MethodHandle getSuccessorEdgesOffsets; - var buildTimeClass = libGraalFeature.loadClassOrFail(BuildTime.class); - try { - MethodType offsetAccessorSignature = MethodType.methodType(long[].class, Object.class); - getInputEdgesOffsets = mhl.findStatic(buildTimeClass, "getInputEdgesOffsets", offsetAccessorSignature); - getSuccessorEdgesOffsets = mhl.findStatic(buildTimeClass, "getSuccessorEdgesOffsets", offsetAccessorSignature); - } catch (ReflectiveOperationException e) { - throw VMError.shouldNotReachHere(e); - } - - access.registerFieldValueTransformer(ReflectionUtil.lookupField(nodeClassClass, "inputsIteration"), - new IterationMaskRecomputation(getInputEdgesOffsets)); - access.registerFieldValueTransformer(ReflectionUtil.lookupField(nodeClassClass, "successorIteration"), - new IterationMaskRecomputation(getSuccessorEdgesOffsets)); - } - - private static class IterationMaskRecomputation implements FieldValueTransformerWithAvailability { - - private final MethodHandle offsetsFromReceiver; - - IterationMaskRecomputation(MethodHandle offsetsFromReceiver) { - this.offsetsFromReceiver = offsetsFromReceiver; - } - - @Override - public boolean isAvailable() { - return BuildPhaseProvider.isHostedUniverseBuilt(); - } - - @Override - public Object transform(Object receiver, Object originalValue) { - FieldsOffsetsReplacement replacement; - try { - long[] offsetsFromEdges = (long[]) offsetsFromReceiver.invoke(receiver); - replacement = LibGraalFieldsOffsetsFeature.getReplacements().get(offsetsFromEdges); - } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); - } - assert replacement.newValuesAvailable : "Cannot access iteration mask before field offsets are assigned"; - return replacement.newIterationInitMask; - } - } - - private Object replaceFieldsOffsets(Object source) { - if (fieldsClass.isInstance(source)) { - /* - * All instances of Fields must have been registered before, otherwise we miss the - * substitution of its offsets array. - */ - assert !ImageSingletons.lookup(FieldsOffsetsReplacements.class).sealed || getReplacements().containsKey(getOffsetsFromFields(source)) : source; - - } else if (source instanceof long[]) { - FieldsOffsetsReplacement replacement = getReplacements().get(source); - if (replacement != null) { - assert source == getOffsetsFromFields(replacement.fields); - - /* - * We can only compute the new offsets after static analysis, i.e., after the object - * layout is done and run-time field offsets are available. Until then, we return - * the hosted offsets so that we have a return value. The actual offsets do not - * matter at this point. - */ - if (replacement.newValuesAvailable) { - return replacement.newOffsets; - } - } - } - return source; - } - - /* Invoked once for every class that is reachable in the native image. */ - private void classReachabilityListener(DuringAnalysisAccess a, Class newlyReachableClass) { - DuringAnalysisAccessImpl access = (DuringAnalysisAccessImpl) a; - if (BuildPhaseProvider.isAnalysisFinished()) { - throw VMError.shouldNotReachHere("New class reachable after analysis: " + newlyReachableClass); - } - - if (!newlyReachableClass.equals(nodeClass) && nodeClass.isAssignableFrom(newlyReachableClass)) { - registerClass(newlyReachableClass, LibGraalCompilerSupport.get().nodeClasses, this::getNodeClassFromNode, false, access); - } else if (!newlyReachableClass.equals(lirInstructionClass) && lirInstructionClass.isAssignableFrom(newlyReachableClass)) { - registerClass(newlyReachableClass, LibGraalCompilerSupport.get().instructionClasses, this::getLIRInstructionClassFromLIRInstruction, true, access); - } - } - - private void registerClass(Class clazz, EconomicMap, Object> registry, - Function, Object> lookup, boolean excludeAbstract, DuringAnalysisAccessImpl access) { - assert !registry.containsKey(clazz); - - if (!excludeAbstract || !Modifier.isAbstract(clazz.getModifiers())) { - Object nodeClazz = lookup.apply(clazz); - registry.put(clazz, nodeClazz); - registerFields(nodeClazz, access); - - access.requireAnalysisIteration(); - } - } - - private void registerFields(Object introspection, BeforeAnalysisAccessImpl config) { - if (nodeClassClass.isInstance(introspection)) { - - /* The partial evaluator allocates Node classes via Unsafe. */ - AnalysisType nodeType = config.getMetaAccess().lookupJavaType(getClazzFromFieldIntrospection(introspection)); - nodeType.registerInstantiatedCallback(unused -> nodeType.registerAsUnsafeAllocated("Graal node class")); - - Object dataFields = getDataFromFieldIntrospection(introspection); - registerFields(dataFields, config, "Graal node data field"); - - Object inputEdges = getInputEdgesFromNodeClass(introspection); - registerFields(inputEdges, config, "Graal node input edge"); - - Object successorEdges = getSuccessorEdgesFromNodeClass(introspection); - registerFields(successorEdges, config, "Graal node successor edge"); - - /* Ensure field shortName is initialized, so that the instance is immutable. */ - invokeShortName(introspection); - - } else { - assert fieldIntrospectionClass.isInstance(introspection); - for (Object fields : getAllFieldsFromFieldIntrospection(introspection)) { - registerFields(fields, config, "Graal field"); - } - } - } - - private void registerFields(Object fields, BeforeAnalysisAccessImpl config, Object reason) { - getReplacements().put(getOffsetsFromFields(fields), new FieldsOffsetsReplacement(fields)); - - for (int i = 0; i < getCountFromFields(fields); i++) { - AnalysisField aField = config.getMetaAccess().lookupJavaField(findField(fields, i)); - aField.getType().registerAsReachable(aField); - config.registerAsUnsafeAccessed(aField, reason); - } - } - - private Field findField(Object fields, int index) { - try { - return getDeclaringClassFromFields(fields, index).getDeclaredField(getNameFromFields(fields, index)); - } catch (NoSuchFieldException ex) { - throw VMError.shouldNotReachHere(ex); - } - } - - @Override - public void beforeCompilation(BeforeCompilationAccess a) { - CompilationAccessImpl config = (CompilationAccessImpl) a; - HostedMetaAccess hMetaAccess = config.getMetaAccess(); - - getReplacements().forEach((originalOffsets, replacement) -> { - Object fields = replacement.fields; - long[] newOffsets = new long[getCountFromFields(fields)]; - for (int i = 0; i < newOffsets.length; i++) { - Field field = findField(fields, i); - assert Unsafe.getUnsafe().objectFieldOffset(field) == originalOffsets[i]; - newOffsets[i] = hMetaAccess.lookupJavaField(field).getLocation(); - } - replacement.newOffsets = newOffsets; - - if (edgesClass.isInstance(fields)) { - Object edges = edgesClass.cast(fields); - replacement.newIterationInitMask = nodeClassComputeIterationMask(typeFromEdges(edges), getDirectCountFromEdges(edges), newOffsets); - } - - replacement.newValuesAvailable = true; - }); - - ImageSingletons.lookup(FieldsOffsetsReplacements.class).sealed = true; - } - - @Override - public void afterCompilation(AfterCompilationAccess access) { - access.registerAsImmutable(LibGraalCompilerSupport.get().nodeClasses.getValues(), o -> true); - access.registerAsImmutable(LibGraalCompilerSupport.get().instructionClasses.getValues(), o -> true); - } - - private long[] getOffsetsFromFields(Object fields) { - try { - return (long[]) fieldsClassGetOffsetsMethod.invoke(fields); - } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); - } - } - - private int getCountFromFields(Object fields) { - try { - return (int) fieldsClassGetCountMethod.invoke(fields); - } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); - } - } - - private Class getDeclaringClassFromFields(Object fields, int index) { - try { - return (Class) fieldsClassGetDeclaringClassMethod.invoke(fields, index); - } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); - } - } - - private String getNameFromFields(Object fields, int index) { - try { - return (String) fieldsClassGetNameMethod.invoke(fields, index); - } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); - } - } - - private Object typeFromEdges(Object edges) { - try { - assert edgesClass.isInstance(edges); - Object edgesType = edgesClassTypeMethod.invoke(edges); - return edgesTypeClass.cast(edgesType); - } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); - } - } - - private int getDirectCountFromEdges(Object edges) { - try { - assert edgesClass.isInstance(edges); - return (int) edgesClassGetDirectCountMethod.invoke(edges); - } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); - } - } - - private Object getDataFromFieldIntrospection(Object fieldIntrospection) { - try { - assert fieldIntrospectionClass.isInstance(fieldIntrospection); - Object fields = fieldIntrospectionClassGetDataMethod.invoke(fieldIntrospection); - return fieldsClass.cast(fields); - } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); - } - } - - private Class getClazzFromFieldIntrospection(Object fieldIntrospection) { - try { - assert fieldIntrospectionClass.isInstance(fieldIntrospection); - Object clazz = fieldIntrospectionClassGetClazzMethod.invoke(fieldIntrospection); - return (Class) clazz; - } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); - } - } - - private Object[] getAllFieldsFromFieldIntrospection(Object fieldIntrospection) { - try { - assert fieldIntrospectionClass.isInstance(fieldIntrospection); - Object allFields = fieldIntrospectionClassGetAllFieldsMethod.invoke(fieldIntrospection); - return (Object[]) fieldsClass.arrayType().cast(allFields); - } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); - } - } - - private Object getNodeClassFromNode(Class clazz) { - try { - assert nodeClass.isAssignableFrom(clazz); - Object nodeClassInstance = nodeClassClassGetMethod.invoke(clazz); - assert nodeClassClass.isInstance(nodeClassInstance); - return nodeClassInstance; - } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); - } - } - - private Object getInputEdgesFromNodeClass(Object nodeClazz) { - try { - assert nodeClassClass.isInstance(nodeClazz); - Object inputEdges = nodeClassClassGetInputEdgesMethod.invoke(nodeClazz); - return inputEdgesClass.cast(inputEdges); - } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); - } - } - - private Object getSuccessorEdgesFromNodeClass(Object nodeClazz) { - try { - assert nodeClassClass.isInstance(nodeClazz); - Object successorEdges = nodeClassClassGetSuccessorEdgesMethod.invoke(nodeClazz); - return successorEdgesClass.cast(successorEdges); - } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); - } - } - - private void invokeShortName(Object nodeClazz) { - try { - assert nodeClassClass.isInstance(nodeClazz); - nodeClassClassGetShortNameMethod.invoke(nodeClazz); - } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); - } - } - - private long nodeClassComputeIterationMask(Object edgesType, int directCount, long[] offsets) { - try { - assert edgesTypeClass.isInstance(edgesType); - return (long) nodeClassClassComputeIterationMaskMethod.invoke(edgesType, directCount, offsets); - } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); - } - } - - private Object getLIRInstructionClassFromLIRInstruction(Class clazz) { - try { - assert lirInstructionClass.isAssignableFrom(clazz); - Object nodeClassInstance = lirInstructionClassClassGetMethod.invoke(clazz); - assert lirInstructionClassClass.isInstance(nodeClassInstance); - return nodeClassInstance; - } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); - } - } -} diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalNativeBridgeSupport.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalNativeBridgeSupport.java index b1167d39a63a..444efca1372b 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalNativeBridgeSupport.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalNativeBridgeSupport.java @@ -26,12 +26,10 @@ import java.util.concurrent.atomic.AtomicInteger; +import jdk.graal.compiler.serviceprovider.IsolateUtil; import org.graalvm.jniutils.JNIMethodScope; import org.graalvm.jniutils.NativeBridgeSupport; -import org.graalvm.nativeimage.ImageSingletons; -import org.graalvm.nativeimage.impl.IsolateSupport; - public final class LibGraalNativeBridgeSupport implements NativeBridgeSupport { private static final String JNI_LIBGRAAL_TRACE_LEVEL_PROPERTY_NAME = "JNI_LIBGRAAL_TRACE_LEVEL"; @@ -63,7 +61,7 @@ public void trace(String message) { inTrace.set(true); try { StringBuilder sb = new StringBuilder(); - long isolateID = ImageSingletons.lookup(IsolateSupport.class).getIsolateID(); + long isolateID = IsolateUtil.getIsolateID(); sb.append('[').append(isolateID).append(':').append(Thread.currentThread().getName()).append(']'); JNIMethodScope scope = JNIMethodScope.scopeOrNull(); if (scope != null) { diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalReflectionUtil.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalReflectionUtil.java new file mode 100644 index 000000000000..c8394a1b6d87 --- /dev/null +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalReflectionUtil.java @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2019, 2019, 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.graal.hotspot.libgraal; + +import java.lang.invoke.MethodHandles; +import java.lang.invoke.VarHandle; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import com.oracle.svm.util.ModuleSupport; + +/** + * This is a copy of {@code com.oracle.svm.util.ReflectionUtil}. + */ +public final class LibGraalReflectionUtil { + + @SuppressWarnings("serial") + public static final class ReflectionUtilError extends Error { + private ReflectionUtilError(Throwable cause) { + super(cause); + } + } + + private LibGraalReflectionUtil() { + } + + /** + * Ensure that this class is allowed to call setAccessible for an element of the provided + * declaring class. + */ + private static void openModule(Class declaringClass) { + ModuleSupport.accessModuleByClass(ModuleSupport.Access.OPEN, LibGraalReflectionUtil.class, declaringClass); + } + + public static Class lookupClass(String className) { + return lookupClass(false, className); + } + + public static Class lookupClass(boolean optional, String className) { + return lookupClass(optional, className, LibGraalReflectionUtil.class.getClassLoader()); + } + + public static Class lookupClass(boolean optional, String className, ClassLoader loader) { + try { + return Class.forName(className, false, loader); + } catch (ClassNotFoundException ex) { + if (optional) { + return null; + } + throw new ReflectionUtilError(ex); + } + } + + public static Method lookupMethod(Class declaringClass, String methodName, Class... parameterTypes) { + return lookupMethod(false, declaringClass, methodName, parameterTypes); + } + + public static Method lookupMethod(boolean optional, Class declaringClass, String methodName, Class... parameterTypes) { + try { + Method result = declaringClass.getDeclaredMethod(methodName, parameterTypes); + openModule(declaringClass); + result.setAccessible(true); + return result; + } catch (ReflectiveOperationException ex) { + if (optional) { + return null; + } + throw new ReflectionUtilError(ex); + } + } + + public static Method lookupPublicMethodInClassHierarchy(Class clazz, String methodName, Class... parameterTypes) { + return lookupPublicMethodInClassHierarchy(false, clazz, methodName, parameterTypes); + } + + public static Method lookupPublicMethodInClassHierarchy(boolean optional, Class clazz, String methodName, Class... parameterTypes) { + try { + Method result = clazz.getMethod(methodName, parameterTypes); + openModule(result.getDeclaringClass()); + result.setAccessible(true); + return result; + } catch (ReflectiveOperationException ex) { + if (optional) { + return null; + } + throw new ReflectionUtilError(ex); + } + } + + public static Constructor lookupConstructor(Class declaringClass, Class... parameterTypes) { + return lookupConstructor(false, declaringClass, parameterTypes); + } + + public static Constructor lookupConstructor(boolean optional, Class declaringClass, Class... parameterTypes) { + try { + Constructor result = declaringClass.getDeclaredConstructor(parameterTypes); + openModule(declaringClass); + result.setAccessible(true); + return result; + } catch (ReflectiveOperationException ex) { + if (optional) { + return null; + } + throw new ReflectionUtilError(ex); + } + } + + /** + * Invokes the provided method, and unwraps a possible {@link InvocationTargetException} so that + * it appears as if the method had been invoked directly without the use of reflection. + */ + @SuppressWarnings("unchecked") + public static T invokeMethod(Method method, Object receiver, Object... arguments) { + try { + method.setAccessible(true); + return (T) method.invoke(receiver, arguments); + } catch (InvocationTargetException ex) { + Throwable cause = ex.getCause(); + if (cause != null) { + throw rethrow(cause); + } + throw new ReflectionUtilError(ex); + } catch (ReflectiveOperationException ex) { + throw new ReflectionUtilError(ex); + } + } + + @SuppressWarnings("unchecked") + private static RuntimeException rethrow(Throwable ex) throws E { + throw (E) ex; + } + + public static T newInstance(Class declaringClass) { + try { + return lookupConstructor(declaringClass).newInstance(); + } catch (ReflectiveOperationException ex) { + throw new ReflectionUtilError(ex); + } + } + + public static T newInstance(Constructor constructor, Object... initArgs) { + try { + return constructor.newInstance(initArgs); + } catch (ReflectiveOperationException ex) { + throw new ReflectionUtilError(ex); + } + } + + public static VarHandle unreflectField(Class declaringClass, String fieldName, MethodHandles.Lookup lookup) { + try { + Field field = LibGraalReflectionUtil.lookupField(declaringClass, fieldName); + MethodHandles.Lookup privateLookup = MethodHandles.privateLookupIn(declaringClass, lookup); + return privateLookup.unreflectVarHandle(field); + } catch (IllegalAccessException ex) { + throw new ReflectionUtilError(ex); + } + } + + public static Field lookupField(Class declaringClass, String fieldName) { + return lookupField(false, declaringClass, fieldName); + } + + private static final Method fieldGetDeclaredFields0 = LibGraalReflectionUtil.lookupMethod(Class.class, "getDeclaredFields0", boolean.class); + + public static Field lookupField(boolean optional, Class declaringClass, String fieldName) { + try { + Field result = declaringClass.getDeclaredField(fieldName); + openModule(declaringClass); + result.setAccessible(true); + return result; + } catch (ReflectiveOperationException ex) { + /* Try to get hidden field */ + try { + Field[] allFields = (Field[]) fieldGetDeclaredFields0.invoke(declaringClass, false); + for (Field field : allFields) { + if (field.getName().equals(fieldName)) { + openModule(declaringClass); + field.setAccessible(true); + return field; + } + } + } catch (ReflectiveOperationException e) { + // ignore + } + if (optional) { + return null; + } + throw new ReflectionUtilError(ex); + } + } + + @SuppressWarnings("unchecked") + public static T readField(Class declaringClass, String fieldName, Object receiver) { + try { + return (T) lookupField(declaringClass, fieldName).get(receiver); + } catch (ReflectiveOperationException ex) { + throw new ReflectionUtilError(ex); + } + } + + public static T readStaticField(Class declaringClass, String fieldName) { + return readField(declaringClass, fieldName, null); + } + + public static void writeField(Class declaringClass, String fieldName, Object receiver, Object value) { + try { + lookupField(declaringClass, fieldName).set(receiver, value); + } catch (ReflectiveOperationException ex) { + throw new ReflectionUtilError(ex); + } + } + + public static void writeStaticField(Class declaringClass, String fieldName, Object value) { + writeField(declaringClass, fieldName, null, value); + } +} diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalSubstitutions.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalSubstitutions.java index 082d10a69729..90c63214f48c 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalSubstitutions.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalSubstitutions.java @@ -30,12 +30,10 @@ import java.util.Map; import java.util.function.Supplier; -import jdk.graal.compiler.libgraal.LibGraalFeature; import org.graalvm.jniutils.JNI; import org.graalvm.jniutils.JNIExceptionWrapper; import org.graalvm.jniutils.JNIMethodScope; import org.graalvm.jniutils.JNIUtil; -import org.graalvm.nativeimage.CurrentIsolate; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.LogHandler; import org.graalvm.nativeimage.Platform.HOSTED_ONLY; @@ -43,10 +41,8 @@ import org.graalvm.nativeimage.StackValue; import org.graalvm.nativeimage.VMRuntime; import org.graalvm.nativeimage.hosted.FieldValueTransformer; -import org.graalvm.nativeimage.impl.IsolateSupport; import org.graalvm.word.Pointer; -import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.annotate.Alias; import com.oracle.svm.core.annotate.Delete; import com.oracle.svm.core.annotate.Inject; @@ -56,13 +52,12 @@ import com.oracle.svm.core.annotate.TargetElement; import com.oracle.svm.core.c.CGlobalData; import com.oracle.svm.core.c.CGlobalDataFactory; -import com.oracle.svm.core.heap.GCCause; -import com.oracle.svm.core.heap.Heap; import com.oracle.svm.core.jdk.JDKLatest; import com.oracle.svm.core.log.FunctionPointerLogHandler; -import com.oracle.svm.core.util.VMError; import com.oracle.svm.graal.hotspot.LibGraalJNIMethodScope; +import jdk.graal.compiler.debug.GraalError; +import jdk.graal.compiler.libgraal.LibGraalFeature; import jdk.graal.compiler.serviceprovider.GlobalAtomicLong; import jdk.graal.compiler.word.Word; @@ -159,6 +154,14 @@ static final class Target_jdk_vm_ci_hotspot_HotSpotResolvedObjectTypeImpl { } public class LibGraalSubstitutions { + /** + * Used to avoid complaints by javac about casts that appear to violate the Java type system + * rules but are safe in the context of SVM substitutions. + */ + @SuppressWarnings({"unused", "unchecked"}) + public static T cast(Object obj, Class toType) { + return (T) obj; + } private static final String GLOBAL_ATOMIC_LONG = "jdk.graal.compiler.serviceprovider.GlobalAtomicLong"; @@ -187,7 +190,7 @@ static final class Target_jdk_graal_compiler_serviceprovider_GlobalAtomicLong { @TargetElement(name = TargetElement.CONSTRUCTOR_NAME) @SuppressWarnings({"unused", "static-method"}) public void constructor(long initialValue) { - throw VMError.unsupportedFeature("Cannot create " + GLOBAL_ATOMIC_LONG + " objects in native image runtime"); + throw GraalError.shouldNotReachHere("Cannot create " + GLOBAL_ATOMIC_LONG + " objects in native image runtime"); } @Substitute @@ -208,7 +211,7 @@ public Object transform(Object receiver, Object originalValue) { try { initialValue = (long) ImageSingletons.lookup(LibGraalFeature.class).globalAtomicLongGetInitialValue.invoke(receiver); } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); + throw GraalError.shouldNotReachHere(e); } return CGlobalDataFactory.createWord(Word.unsigned(initialValue), null, true); } @@ -217,16 +220,6 @@ public Object transform(Object receiver, Object originalValue) { @TargetClass(className = "jdk.graal.compiler.serviceprovider.VMSupport", classLoader = LibGraalClassLoaderSupplier.class, onlyWith = LibGraalFeature.IsEnabled.class) static final class Target_jdk_graal_compiler_serviceprovider_VMSupport { - @Substitute - public static long getIsolateAddress() { - return CurrentIsolate.getIsolate().rawValue(); - } - - @Substitute - public static long getIsolateID() { - return ImageSingletons.lookup(IsolateSupport.class).getIsolateID(); - } - /** * Performs the following actions around a libgraal compilation: *
    @@ -280,7 +273,7 @@ public static void fatalError(String message, int delayMS) { } catch (InterruptedException e) { // ignore } - VMError.shouldNotReachHere(message); + GraalError.shouldNotReachHere(message); } } @@ -303,73 +296,6 @@ public static void invokeShutdownCallback(String cbClassName, String cbMethodNam env.getFunctions().getCallStaticVoidMethodA().call(env, cbClass, cbMethod, StackValue.get(0)); JNIExceptionWrapper.wrapAndThrowPendingJNIException(env); } - - @Substitute - public static void notifyLowMemoryPoint(boolean hintFullGC, boolean forceFullGC) { - if (forceFullGC) { - Heap.getHeap().getGC().collectCompletely(GCCause.JavaLangSystemGC); - } else { - Heap.getHeap().getGC().collectionHint(hintFullGC); - } - LibGraalEntryPoints.doReferenceHandling(); - } - } - - @TargetClass(className = "jdk.graal.compiler.phases.BasePhase", classLoader = LibGraalClassLoaderSupplier.class, onlyWith = LibGraalFeature.IsEnabled.class) - static final class Target_jdk_graal_compiler_phases_BasePhase { - - /* - * Redirect method to image build-time pre-computed statistics in LibGraalCompilerSupport. - */ - @Substitute - static Target_jdk_graal_compiler_phases_BasePhase_BasePhaseStatistics getBasePhaseStatistics(Class clazz) { - Object result = LibGraalCompilerSupport.get().getBasePhaseStatistics().get(clazz); - if (result == null) { - throw VMError.shouldNotReachHere(String.format("Missing statistics for phase class: %s%n", clazz.getName())); - } - return SubstrateUtil.cast(result, Target_jdk_graal_compiler_phases_BasePhase_BasePhaseStatistics.class); - } - } - - @TargetClass(className = "jdk.graal.compiler.phases.BasePhase", innerClass = "BasePhaseStatistics", classLoader = LibGraalClassLoaderSupplier.class, onlyWith = LibGraalFeature.IsEnabled.class) - static final class Target_jdk_graal_compiler_phases_BasePhase_BasePhaseStatistics { - } - - @TargetClass(className = "jdk.graal.compiler.lir.phases.LIRPhase", classLoader = LibGraalClassLoaderSupplier.class, onlyWith = LibGraalFeature.IsEnabled.class) - static final class Target_jdk_graal_compiler_lir_phases_LIRPhase { - - /* - * Redirect method to image build-time pre-computed statistics in LibGraalCompilerSupport. - */ - @Substitute - static Target_jdk_graal_compiler_lir_phases_LIRPhase_LIRPhaseStatistics getLIRPhaseStatistics(Class clazz) { - Object result = LibGraalCompilerSupport.get().getLirPhaseStatistics().get(clazz); - if (result == null) { - throw VMError.shouldNotReachHere(String.format("Missing statistics for phase class: %s%n", clazz.getName())); - } - return SubstrateUtil.cast(result, Target_jdk_graal_compiler_lir_phases_LIRPhase_LIRPhaseStatistics.class); - } - } - - @TargetClass(className = "jdk.graal.compiler.lir.phases.LIRPhase", innerClass = "LIRPhaseStatistics", classLoader = LibGraalClassLoaderSupplier.class, onlyWith = LibGraalFeature.IsEnabled.class) - static final class Target_jdk_graal_compiler_lir_phases_LIRPhase_LIRPhaseStatistics { - } - - @TargetClass(className = "jdk.graal.compiler.graph.NodeClass", classLoader = LibGraalClassLoaderSupplier.class, onlyWith = LibGraalFeature.IsEnabled.class) - static final class Target_jdk_graal_compiler_graph_NodeClass { - - @Alias // - private String shortName; - - /* - * All node-classes in libgraal are in the image-heap and were already fully initialized at - * build-time. The shortName accessor method can be reduced to a simple field access. - */ - @Substitute - public String shortName() { - assert shortName != null; - return shortName; - } } @TargetClass(className = "jdk.graal.compiler.hotspot.HotSpotGraalOptionValues", classLoader = LibGraalClassLoaderSupplier.class, onlyWith = LibGraalFeature.IsEnabled.class) @@ -390,7 +316,7 @@ private static void printLibgraalProperties(PrintStream out, String prefix) { static final class Target_jdk_graal_compiler_core_GraalServiceThread { @Substitute() void beforeRun() { - Thread thread = SubstrateUtil.cast(this, Thread.class); + Thread thread = cast(this, Thread.class); if (!LibGraalEntryPoints.attachCurrentThread(thread.isDaemon(), null)) { throw new InternalError("Couldn't attach to HotSpot runtime"); } @@ -413,7 +339,7 @@ class LibGraalClassLoaderSupplier implements Supplier { @Override public ClassLoader get() { ClassLoader loader = ImageSingletons.lookup(LibGraalFeature.class).loader; - VMError.guarantee(loader != null); + GraalError.guarantee(loader != null, "NPE"); return loader; } } diff --git a/substratevm/src/com.oracle.svm.graal.hotspot/src/com/oracle/svm/graal/hotspot/GetCompilerConfig.java b/substratevm/src/com.oracle.svm.graal.hotspot/src/com/oracle/svm/graal/hotspot/GetCompilerConfig.java index ad11fc4f03d3..302d219f380a 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot/src/com/oracle/svm/graal/hotspot/GetCompilerConfig.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot/src/com/oracle/svm/graal/hotspot/GetCompilerConfig.java @@ -35,18 +35,8 @@ import java.util.Set; import java.util.stream.Collectors; -import org.graalvm.collections.UnmodifiableEconomicMap; -import org.graalvm.collections.UnmodifiableMapCursor; - -import com.oracle.graal.pointsto.api.PointstoOptions; -import com.oracle.svm.core.option.HostedOptionKey; -import com.oracle.svm.core.option.RuntimeOptionKey; - import jdk.graal.compiler.debug.GraalError; -import jdk.graal.compiler.hotspot.HotSpotGraalOptionValues; import jdk.graal.compiler.hotspot.libgraal.CompilerConfig; -import jdk.graal.compiler.options.OptionKey; -import jdk.graal.compiler.options.OptionValues; import jdk.graal.compiler.util.ObjectCopier; import org.graalvm.nativeimage.ImageInfo; @@ -102,12 +92,9 @@ private static boolean isInBootLayer(Path javaExe, String module) { * * @param javaHome the value of the {@code java.home} system property reported by a Java * installation directory that includes the Graal classes in its runtime image - * @param options the options passed to native-image */ - public static Result from(Path javaHome, OptionValues options) { + public static Result from(Path javaHome) { Path javaExe = GetJNIConfig.getJavaExe(javaHome); - UnmodifiableEconomicMap, Object> optionsMap = options.getMap(); - UnmodifiableMapCursor, Object> entries = optionsMap.getEntries(); Map> opens = Map.of( // Needed to reflect fields like // java.util.ImmutableCollections.EMPTY @@ -137,20 +124,6 @@ public static Result from(Path javaHome, OptionValues options) { } } - // Propagate compiler options - while (entries.advance()) { - OptionKey key = entries.getKey(); - if (key instanceof RuntimeOptionKey || key instanceof HostedOptionKey) { - // Ignore Native Image options - continue; - } - if (key.getDescriptor().getDeclaringClass().getModule().equals(PointstoOptions.class.getModule())) { - // Ignore points-to analysis options - continue; - } - command.add("-D%s%s=%s".formatted(HotSpotGraalOptionValues.GRAAL_OPTION_PROPERTY_PREFIX, key.getName(), entries.getValue())); - } - command.add(CompilerConfig.class.getName()); Path encodedConfigPath = Path.of(GetCompilerConfig.class.getSimpleName() + "_" + ProcessHandle.current().pid() + ".txt").toAbsolutePath(); command.add(encodedConfigPath.toString()); diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/FieldsOffsetsFeature.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/FieldsOffsetsFeature.java index dea96dff84b1..bb2e20200d05 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/FieldsOffsetsFeature.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/FieldsOffsetsFeature.java @@ -41,10 +41,8 @@ import com.oracle.svm.core.util.VMError; import com.oracle.svm.graal.GraalCompilerSupport; import com.oracle.svm.hosted.FeatureImpl.BeforeAnalysisAccessImpl; -import com.oracle.svm.hosted.FeatureImpl.CompilationAccessImpl; import com.oracle.svm.hosted.FeatureImpl.DuringAnalysisAccessImpl; import com.oracle.svm.hosted.FeatureImpl.DuringSetupAccessImpl; -import com.oracle.svm.hosted.meta.HostedMetaAccess; import jdk.graal.compiler.core.common.FieldIntrospection; import jdk.graal.compiler.core.common.Fields; @@ -53,7 +51,6 @@ import jdk.graal.compiler.graph.NodeClass; import jdk.graal.compiler.lir.LIRInstruction; import jdk.graal.compiler.lir.LIRInstructionClass; -import jdk.internal.misc.Unsafe; /** * Graal uses unsafe memory accesses to access {@link Node}s and {@link LIRInstruction}s. The @@ -64,7 +61,7 @@ */ public class FieldsOffsetsFeature implements Feature { - abstract static class IterationMaskRecomputation implements FieldValueTransformerWithAvailability { + public static class IterationMaskRecomputation implements FieldValueTransformerWithAvailability { @Override public boolean isAvailable() { return BuildPhaseProvider.isHostedUniverseBuilt(); @@ -72,33 +69,16 @@ public boolean isAvailable() { @Override public Object transform(Object receiver, Object originalValue) { - Edges edges = getEdges((NodeClass) receiver); + Edges edges = (Edges) receiver; FieldsOffsetsReplacement replacement = FieldsOffsetsFeature.getReplacements().get(edges.getOffsets()); assert replacement.fields == edges; - assert replacement.newValuesAvailable : "Cannot access iteration mask before field offsets are assigned"; + assert replacement.newOffsets != null : "Cannot access iteration mask before field offsets are assigned"; return replacement.newIterationInitMask; } - - protected abstract Edges getEdges(NodeClass nodeClass); - } - - public static class InputsIterationMaskRecomputation extends IterationMaskRecomputation { - @Override - protected Edges getEdges(NodeClass nodeClass) { - return nodeClass.getInputEdges(); - } - } - - public static class SuccessorsIterationMaskRecomputation extends IterationMaskRecomputation { - @Override - protected Edges getEdges(NodeClass nodeClass) { - return nodeClass.getSuccessorEdges(); - } } static class FieldsOffsetsReplacement { protected final Fields fields; - protected boolean newValuesAvailable; protected long[] newOffsets; protected long newIterationInitMask; @@ -144,7 +124,7 @@ private static Object replaceFieldsOffsets(Object source) { * the hosted offsets so that we have a return value. The actual offsets do not * matter at this point. */ - if (replacement.newValuesAvailable) { + if (replacement.newOffsets != null) { return replacement.newOffsets; } } @@ -228,25 +208,10 @@ private static Field findField(Fields fields, int index) { @Override public void beforeCompilation(BeforeCompilationAccess a) { - CompilationAccessImpl config = (CompilationAccessImpl) a; - HostedMetaAccess hMetaAccess = config.getMetaAccess(); - for (FieldsOffsetsReplacement replacement : getReplacements().values()) { - Fields fields = replacement.fields; - long[] newOffsets = new long[fields.getCount()]; - for (int i = 0; i < newOffsets.length; i++) { - Field field = findField(fields, i); - assert Unsafe.getUnsafe().objectFieldOffset(field) == fields.getOffsets()[i]; - newOffsets[i] = hMetaAccess.lookupJavaField(field).getLocation(); - } - replacement.newOffsets = newOffsets; - - if (fields instanceof Edges) { - Edges edges = (Edges) fields; - replacement.newIterationInitMask = NodeClass.computeIterationMask(edges.type(), edges.getDirectCount(), newOffsets); - } - - replacement.newValuesAvailable = true; + Map.Entry e = replacement.fields.recomputeOffsetsAndIterationMask(a); + replacement.newOffsets = e.getKey(); + replacement.newIterationInitMask = e.getValue(); } ImageSingletons.lookup(FieldsOffsetsReplacements.class).newValuesAvailable = true; } diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/GraalCompilerFeature.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/GraalCompilerFeature.java index 5ed05c456eef..0c5b390de35c 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/GraalCompilerFeature.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/GraalCompilerFeature.java @@ -42,7 +42,7 @@ /** * This feature is used to contain functionality needed when a Graal compiler is included in a - * native-image. This is used by RuntimeCompilation and LibGraal. + * native-image. This is used by RuntimeCompilation but not LibGraalFeature. */ public class GraalCompilerFeature implements InternalFeature { diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/runtimecompilation/GraalGraphObjectReplacer.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/runtimecompilation/GraalGraphObjectReplacer.java index fdf914682b3c..a715e594f9b9 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/runtimecompilation/GraalGraphObjectReplacer.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/runtimecompilation/GraalGraphObjectReplacer.java @@ -76,7 +76,6 @@ import jdk.graal.compiler.api.runtime.GraalRuntime; import jdk.graal.compiler.core.common.spi.ForeignCallsProvider; import jdk.graal.compiler.debug.MetricKey; -import jdk.graal.compiler.graph.NodeClass; import jdk.graal.compiler.hotspot.GraalHotSpotVMConfig; import jdk.graal.compiler.hotspot.HotSpotBackendFactory; import jdk.graal.compiler.hotspot.SnippetResolvedJavaMethod; @@ -190,9 +189,6 @@ public Object apply(Object source) { } else if (source instanceof MetricKey) { /* Ensure lazily initialized name fields are computed. */ ((MetricKey) source).getName(); - } else if (source instanceof NodeClass) { - /* Ensure lazily initialized shortName field is computed. */ - ((NodeClass) source).shortName(); } else if (source instanceof ResolvedJavaMethod) { if (source instanceof OriginalMethodProvider) { diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/substitutions/GraalSubstitutions.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/substitutions/GraalSubstitutions.java index 670bc0cf9f0e..9302712207de 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/substitutions/GraalSubstitutions.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/substitutions/GraalSubstitutions.java @@ -35,6 +35,7 @@ import java.util.concurrent.ConcurrentHashMap; import jdk.graal.compiler.word.Word; +import jdk.graal.compiler.graph.Edges; import org.graalvm.collections.EconomicMap; import org.graalvm.collections.EconomicSet; import org.graalvm.collections.Equivalence; @@ -79,7 +80,6 @@ import jdk.graal.compiler.debug.TTY; import jdk.graal.compiler.debug.TimeSource; import jdk.graal.compiler.graph.Node; -import jdk.graal.compiler.graph.NodeClass; import jdk.graal.compiler.lir.gen.ArithmeticLIRGeneratorTool; import jdk.graal.compiler.lir.phases.LIRPhase; import jdk.graal.compiler.nodes.Invoke; @@ -348,25 +348,11 @@ static LIRPhase.LIRPhaseStatistics getLIRPhaseStatistics(Class clazz) { } } -@TargetClass(value = NodeClass.class, onlyWith = GraalCompilerFeature.IsEnabled.class) -final class Target_jdk_graal_compiler_graph_NodeClass { - - @Alias// - @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Custom, declClass = FieldsOffsetsFeature.InputsIterationMaskRecomputation.class)// - private long inputsIteration; - +@TargetClass(value = Edges.class, onlyWith = GraalCompilerFeature.IsEnabled.class) +final class Target_jdk_graal_compiler_graph_Edges { @Alias// - @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Custom, declClass = FieldsOffsetsFeature.SuccessorsIterationMaskRecomputation.class)// - private long successorIteration; - - @Alias // - private String shortName; - - @Substitute - public String shortName() { - assert shortName != null; - return shortName; - } + @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Custom, declClass = FieldsOffsetsFeature.IterationMaskRecomputation.class)// + private long iterationMask; } @TargetClass(value = NoDeadCodeVerifyHandler.class) diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ClassLoaderFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ClassLoaderFeature.java index 78ae580dd4b4..e2c786004a52 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ClassLoaderFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ClassLoaderFeature.java @@ -41,7 +41,7 @@ import com.oracle.svm.hosted.jdk.HostedClassLoaderPackageManagement; import com.oracle.svm.util.ReflectionUtil; -import jdk.graal.compiler.hotspot.libgraal.LibGraalClassLoaderBase; +import jdk.graal.nativeimage.LibGraalLoader; import jdk.internal.loader.ClassLoaders; import jdk.vm.ci.meta.JavaConstant; @@ -121,7 +121,7 @@ public void duringSetup(DuringSetupAccess access) { var config = (FeatureImpl.DuringSetupAccessImpl) access; if (ImageLayerBuildingSupport.firstImageBuild()) { - LibGraalClassLoaderBase libGraalLoader = ((DuringSetupAccessImpl) access).imageClassLoader.classLoaderSupport.getLibGraalLoader(); + LibGraalLoader libGraalLoader = ((DuringSetupAccessImpl) access).imageClassLoader.classLoaderSupport.getLibGraalLoader(); if (libGraalLoader != null) { ClassLoader libGraalClassLoader = libGraalLoader.getClassLoader(); ClassForNameSupport.singleton().setLibGraalLoader(libGraalClassLoader); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ImageSingletonsSupportImpl.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ImageSingletonsSupportImpl.java index 2cb9a59b6476..12db6e834157 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ImageSingletonsSupportImpl.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ImageSingletonsSupportImpl.java @@ -253,7 +253,16 @@ T doLookup(Class key, boolean stripRuntimeOnly) { checkKey(key); Object result = configObjects.get(key); if (result == null) { - throw UserError.abort("ImageSingletons do not contain key %s", key.getTypeName()); + var others = configObjects.keySet().stream()// + .filter(c -> c.getName().equals(key.getName()))// + .map(c -> c.getClassLoader().getName() + "/" + c.getTypeName())// + .toList(); + if (others.isEmpty()) { + throw UserError.abort("ImageSingletons do not contain key %s", key.getTypeName()); + } + throw UserError.abort("ImageSingletons do not contain key %s/%s but does contain the following key(s): %s", + key.getClassLoader().getName(), key.getTypeName(), + String.join(", ", others)); } else if (result == SINGLETON_INSTALLATION_FORBIDDEN) { throw UserError.abort("A LayeredImageSingleton was installed in a prior layer which forbids creating the singleton in a subsequent layer. Key %s", key.getTypeName()); } else if (result instanceof RuntimeOnlyWrapper wrapper) { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageClassLoaderSupport.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageClassLoaderSupport.java index e21b23e82c76..442cd92e9fca 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageClassLoaderSupport.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageClassLoaderSupport.java @@ -75,6 +75,9 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import com.oracle.svm.core.SubstrateUtil; +import com.oracle.svm.util.ModuleSupport; +import jdk.graal.nativeimage.LibGraalLoader; import org.graalvm.collections.EconomicMap; import org.graalvm.collections.EconomicSet; import org.graalvm.collections.MapCursor; @@ -82,7 +85,6 @@ import com.oracle.svm.core.NativeImageClassLoaderOptions; import com.oracle.svm.core.SubstrateOptions; -import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.option.AccumulatingLocatableMultiOptionValue; import com.oracle.svm.core.option.HostedOptionKey; import com.oracle.svm.core.option.LocatableMultiOptionValue.ValueWithOrigin; @@ -97,12 +99,9 @@ import com.oracle.svm.hosted.option.HostedOptionParser; import com.oracle.svm.util.ClassUtil; import com.oracle.svm.util.LogUtils; -import com.oracle.svm.util.ModuleSupport; -import com.oracle.svm.util.ModuleSupport.Access; import com.oracle.svm.util.ReflectionUtil; import jdk.graal.compiler.debug.GraalError; -import jdk.graal.compiler.hotspot.libgraal.LibGraalClassLoaderBase; import jdk.graal.compiler.options.OptionKey; import jdk.graal.compiler.options.OptionValues; import jdk.internal.module.Modules; @@ -134,7 +133,7 @@ public final class NativeImageClassLoaderSupport { private Set javaPathsToInclude; private boolean includeAllFromClassPath; - private Optional libGraalLoader; + private Optional libGraalLoader; private List classLoaders; private final Set> classesToIncludeUnconditionally = ConcurrentHashMap.newKeySet(); @@ -232,7 +231,7 @@ public NativeImageClassLoader getClassLoader() { return classLoader; } - public LibGraalClassLoaderBase getLibGraalLoader() { + public LibGraalLoader getLibGraalLoader() { VMError.guarantee(libGraalLoader != null, "Invalid access to libGraalLoader before getting set up"); return libGraalLoader.orElse(null); } @@ -272,15 +271,15 @@ public void loadAllClasses(ForkJoinPool executor, ImageClassLoader imageClassLoa new LoadClassHandler(executor, imageClassLoader).run(); - LibGraalClassLoaderBase graalLoader = getLibGraalLoader(); - if (graalLoader != null) { - /* If we have a customLoader, register its classes to the image builder */ - for (String fqn : graalLoader.getAllClassNames()) { + LibGraalLoader loader = getLibGraalLoader(); + if (loader != null) { + /* If we have a LibGraalLoader, register its classes to the image builder */ + for (String fqn : loader.getAllClassNames()) { try { - var clazz = graalLoader.getClassLoader().loadClass(fqn); + var clazz = loader.getClassLoader().loadClass(fqn); imageClassLoader.handleClass(clazz); } catch (ClassNotFoundException e) { - throw GraalError.shouldNotReachHere(e, graalLoader + " could not load class " + fqn); + throw GraalError.shouldNotReachHere(e, loader + " could not load class " + fqn); } } } @@ -572,22 +571,20 @@ private Stream processOption(OptionKey loaderClass = Class.forName(libGraalClassLoaderFQN, true, classLoader); - LibGraalClassLoaderBase loaderInstance = (LibGraalClassLoaderBase) ReflectionUtil.newInstance(loaderClass); - libGraalLoader = Optional.of(loaderInstance); - classLoaders = List.of(loaderInstance.getClassLoader(), getClassLoader()); + Class loaderClass = Class.forName(className, true, classLoader); + if (!LibGraalLoader.class.isAssignableFrom(loaderClass)) { + throw VMError.shouldNotReachHere("Class named by " + nameOption + " does not implement " + LibGraalLoader.class + '.'); + } + libGraalLoader = Optional.of((LibGraalLoader) ReflectionUtil.newInstance(loaderClass)); + classLoaders = List.of(libGraalLoader.get().getClassLoader(), getClassLoader()); } catch (ClassNotFoundException e) { - throw VMError.shouldNotReachHere("LibGraalClassLoader " + libGraalClassLoaderFQN + - " set via " + SubstrateOptionsParser.commandArgument(NativeImageOptions.LibGraalClassLoader, libGraalClassLoaderFQN) + - " could not be found.", e); - } catch (ClassCastException e) { - throw VMError.shouldNotReachHere("LibGraalClassLoader " + libGraalClassLoaderFQN + - " set via " + SubstrateOptionsParser.commandArgument(NativeImageOptions.LibGraalClassLoader, libGraalClassLoaderFQN) + - " does not extend class " + LibGraalClassLoaderBase.class.getName() + '.', e); + throw VMError.shouldNotReachHere("Class named by " + nameOption + " could not be found.", e); } } else { libGraalLoader = Optional.empty(); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGeneratorRunner.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGeneratorRunner.java index 57c05a2ed19a..4fddd3534d25 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGeneratorRunner.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGeneratorRunner.java @@ -239,6 +239,7 @@ private static void transitiveRequires(boolean verbose, Module requiringModule, /* graal */ potentialNeedModule.getName().startsWith("org.graalvm.") || potentialNeedModule.getName().startsWith("jdk.graal.compiler") || + potentialNeedModule.getName().startsWith("jdk.graal.nativeimage") || /* enterprise graal */ potentialNeedModule.getName().startsWith("com.oracle.graal.") || /* exclude all truffle modules */ diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ameta/FieldValueInterceptionSupport.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ameta/FieldValueInterceptionSupport.java index c7d20ec4d54c..86da81cdb6ad 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ameta/FieldValueInterceptionSupport.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ameta/FieldValueInterceptionSupport.java @@ -209,10 +209,8 @@ private Object computeAndCacheFieldValueInterceptor(AnalysisField field) { public boolean isValueAvailable(AnalysisField field) { var interceptor = lookupFieldValueInterceptor(field); if (interceptor instanceof FieldValueTransformation transformation) { - if (transformation.getFieldValueTransformer() instanceof FieldValueTransformerWithAvailability transformerWithAvailability) { - if (!transformerWithAvailability.isAvailable()) { - return false; - } + if (!transformation.getFieldValueTransformer().isAvailable()) { + return false; } } else if (interceptor instanceof FieldValueComputer computer) { if (!computer.isAvailable()) { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationFeature.java index 94698eb2b6c6..e418fce47499 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationFeature.java @@ -128,6 +128,7 @@ private static void initializeNativeImagePackagesAtBuildTime(ClassInitialization initializationSupport.initializeAtBuildTime("org.graalvm.collections", NATIVE_IMAGE_CLASS_REASON); initializationSupport.initializeAtBuildTime("jdk.graal.compiler", NATIVE_IMAGE_CLASS_REASON); + initializationSupport.initializeAtBuildTime("jdk.graal.nativeimage", NATIVE_IMAGE_CLASS_REASON); initializationSupport.initializeAtBuildTime("org.graalvm.word", NATIVE_IMAGE_CLASS_REASON); initializationSupport.initializeAtBuildTime("org.graalvm.nativeimage", NATIVE_IMAGE_CLASS_REASON); initializationSupport.initializeAtBuildTime("org.graalvm.nativebridge", NATIVE_IMAGE_CLASS_REASON); diff --git a/substratevm/src/com.oracle.svm.util/src/com/oracle/svm/util/ModuleSupport.java b/substratevm/src/com.oracle.svm.util/src/com/oracle/svm/util/ModuleSupport.java index 0445979610fb..3682d4704b16 100644 --- a/substratevm/src/com.oracle.svm.util/src/com/oracle/svm/util/ModuleSupport.java +++ b/substratevm/src/com.oracle.svm.util/src/com/oracle/svm/util/ModuleSupport.java @@ -48,8 +48,17 @@ public final class ModuleSupport { public static final String PROPERTY_IMAGE_EXPLICITLY_LIMITED_MODULES = "org.graalvm.nativeimage.module.limitmods"; public static final boolean modulePathBuild = isModulePathBuild(); - public static final Set SYSTEM_MODULES = Set.of("org.graalvm.nativeimage.builder", "org.graalvm.nativeimage", "org.graalvm.nativeimage.base", "com.oracle.svm.svm_enterprise", - "org.graalvm.word", "jdk.internal.vm.ci", "jdk.graal.compiler", "com.oracle.graal.graal_enterprise"); + public static final Set SYSTEM_MODULES = Set.of( + "com.oracle.graal.graal_enterprise", + "com.oracle.svm.svm_enterprise", + "jdk.graal.compiler", + "jdk.graal.nativeimage", + "jdk.internal.vm.ci", + "org.graalvm.nativeimage", + "org.graalvm.nativeimage.base", + "org.graalvm.nativeimage.builder", + "org.graalvm.truffle.compiler", + "org.graalvm.word"); private ModuleSupport() { } From 4464f5a73d300a593998aca5f0abc4fb08c57c53 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Mon, 4 Nov 2024 16:49:55 +0100 Subject: [PATCH 04/31] added GlobalData API and re-implemented GlobalAtomicLong on it --- compiler/mx.compiler/suite.py | 3 +- .../compiler/core/CompilationWrapper.java | 6 +- .../hotspot/CompilerConfigurationFactory.java | 2 +- .../hotspot/HotSpotForeignCallLinkage.java | 4 +- .../hotspot/HotSpotGraalCompiler.java | 2 +- .../hotspot/HotSpotGraalOptionValues.java | 2 +- .../hotspot/HotSpotTTYStreamProvider.java | 2 +- .../LibGraalTruffleHostEnvironmentLookup.java | 2 +- .../graphbuilderconf/InvocationPlugins.java | 2 +- .../serviceprovider/GlobalAtomicLong.java | 55 +++++++++++----- .../serviceprovider/GraalServices.java | 2 +- .../jdk.graal.nativeimage/snapshot.sigtest | 4 ++ .../graal/nativeimage/hosted/GlobalData.java | 52 +++++++++++++++ .../nativeimage/hosted/package-info.java | 35 +++++++++++ .../nativeimage/impl/GlobalDataSupport.java | 32 ++++++++++ .../oracle/svm/core/c/GlobalLongSupplier.java | 47 ++++++++++++++ .../hotspot/libgraal/LibGraalFeature.java | 48 +++++++++----- .../libgraal/LibGraalSubstitutions.java | 63 ------------------- .../graal/hosted/GraalCompilerFeature.java | 17 +++++ .../substitutions/GraalSubstitutions.java | 44 ------------- .../svm/hosted/GlobalDataSupportImpl.java | 40 ++++++++++++ 21 files changed, 313 insertions(+), 151 deletions(-) create mode 100644 compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/hosted/GlobalData.java create mode 100644 compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/hosted/package-info.java create mode 100644 compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/impl/GlobalDataSupport.java create mode 100644 substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/c/GlobalLongSupplier.java create mode 100644 substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/GlobalDataSupportImpl.java diff --git a/compiler/mx.compiler/suite.py b/compiler/mx.compiler/suite.py index 4e22a4d7d1eb..3f7bf49dfbcf 100644 --- a/compiler/mx.compiler/suite.py +++ b/compiler/mx.compiler/suite.py @@ -578,7 +578,8 @@ ], "exports" : [ "jdk.graal.nativeimage", - """jdk.graal.nativeimage.impl to org.graalvm.nativeimage.builder""", + "jdk.graal.nativeimage.hosted", + "jdk.graal.nativeimage.impl to org.graalvm.nativeimage.builder", ], "uses" : [], "opens" : [], diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/CompilationWrapper.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/CompilationWrapper.java index 768886081f39..3f9e20b9708b 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/CompilationWrapper.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/CompilationWrapper.java @@ -428,9 +428,9 @@ private void maybeExitVM(ExceptionAction action) { // Global counters used to measure compilation failure rate over a // period of COMPILATION_FAILURE_DETECTION_PERIOD_MS - private static final GlobalAtomicLong totalCompilations = new GlobalAtomicLong(0L); - private static final GlobalAtomicLong failedCompilations = new GlobalAtomicLong(0L); - private static final GlobalAtomicLong compilationPeriodStart = new GlobalAtomicLong(0L); + private static final GlobalAtomicLong totalCompilations = new GlobalAtomicLong("TOTAL_COMPILATIONS", 0L); + private static final GlobalAtomicLong failedCompilations = new GlobalAtomicLong("FAILED_COMPILATIONS", 0L); + private static final GlobalAtomicLong compilationPeriodStart = new GlobalAtomicLong("COMPILATION_PERIOD_START", 0L); private static final long COMPILATION_FAILURE_DETECTION_PERIOD_NS = TimeUnit.SECONDS.toNanos(2); private static final int MIN_COMPILATIONS_FOR_FAILURE_DETECTION = 25; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/CompilerConfigurationFactory.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/CompilerConfigurationFactory.java index a46c237bc88d..c8375e6f980a 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/CompilerConfigurationFactory.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/CompilerConfigurationFactory.java @@ -203,7 +203,7 @@ private static List getAllCandidates() { } // Ensures ShowConfiguration output is printed once per VM process. - private static final GlobalAtomicLong shownConfiguration = new GlobalAtomicLong(0L); + private static final GlobalAtomicLong shownConfiguration = new GlobalAtomicLong("SHOWN_CONFIGURATION", 0L); /** * Selects and instantiates a {@link CompilerConfigurationFactory}. The selection algorithm is diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotForeignCallLinkage.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotForeignCallLinkage.java index 5f000ac77bd6..122efa543d07 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotForeignCallLinkage.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotForeignCallLinkage.java @@ -372,7 +372,7 @@ private static GlobalAtomicLong getStubData(ForeignCallSignature sig) { synchronized (STUBS) { data = STUBS.get(sig); if (data == null) { - data = new GlobalAtomicLong(0L); + data = new GlobalAtomicLong("STUB_" + sig.getName(), 0L); STUBS.put(sig, data); } } @@ -401,7 +401,7 @@ public static void initStubs(List sigs) { */ public static boolean initStub(ForeignCallSignature sig) { if (!STUBS.containsKey(sig)) { - STUBS.put(sig, new GlobalAtomicLong(0L)); + STUBS.put(sig, new GlobalAtomicLong("STUB_" + sig.getName(), 0L)); return true; } return false; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalCompiler.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalCompiler.java index 55495b020b46..d4be1177024d 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalCompiler.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalCompiler.java @@ -368,7 +368,7 @@ public boolean isGCSupported(int gcIdentifier) { } // Support for CrashAtThrowsOOME - private static final GlobalAtomicLong OOME_CRASH_DONE = new GlobalAtomicLong(0); + private static final GlobalAtomicLong OOME_CRASH_DONE = new GlobalAtomicLong("OOME_CRASH_DONE", 0); @Override public boolean notifyCrash(OptionValues options, String crashMessage) { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalOptionValues.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalOptionValues.java index 5fe1a4b4a3be..8ffad619f1a5 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalOptionValues.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalOptionValues.java @@ -73,7 +73,7 @@ public class HotSpotGraalOptionValues { /** * Guard for issuing warning about deprecated Graal option prefix at most once. */ - private static final GlobalAtomicLong LEGACY_OPTION_DEPRECATION_WARNED = new GlobalAtomicLong(0L); + private static final GlobalAtomicLong LEGACY_OPTION_DEPRECATION_WARNED = new GlobalAtomicLong("LEGACY_OPTION_DEPRECATION_WARNED", 0L); /** * Gets the system property assignment that would set the current value for a given option. diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotTTYStreamProvider.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotTTYStreamProvider.java index 1b66967ff3fd..44a325fec502 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotTTYStreamProvider.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotTTYStreamProvider.java @@ -74,7 +74,7 @@ public PrintStream getStream() { /** * Gets a pointer to a global word initialized to 0. */ - private static final GlobalAtomicLong BARRIER = new GlobalAtomicLong(0L); + private static final GlobalAtomicLong BARRIER = new GlobalAtomicLong("BARRIER", 0L); /** * Executes {@code action}. {@link #BARRIER} is used to ensure the action is executed exactly diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleHostEnvironmentLookup.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleHostEnvironmentLookup.java index be7781e34e08..bc5f5e185814 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleHostEnvironmentLookup.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleHostEnvironmentLookup.java @@ -47,7 +47,7 @@ public final class LibGraalTruffleHostEnvironmentLookup implements TruffleHostEnvironment.Lookup { private static final int NO_TRUFFLE_REGISTERED = 0; - private static final GlobalAtomicLong WEAK_TRUFFLE_RUNTIME_INSTANCE = new GlobalAtomicLong(NO_TRUFFLE_REGISTERED); + private static final GlobalAtomicLong WEAK_TRUFFLE_RUNTIME_INSTANCE = new GlobalAtomicLong("WEAK_TRUFFLE_RUNTIME_INSTANCE", NO_TRUFFLE_REGISTERED); @NativeImageReinitialize private TruffleHostEnvironment previousRuntime; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/InvocationPlugins.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/InvocationPlugins.java index 5ded5f9bcc23..256b0c69b9da 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/InvocationPlugins.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/InvocationPlugins.java @@ -977,7 +977,7 @@ public String toString() { /** * The id of the single isolate to emit output for {@link Options#PrintIntrinsics}. */ - private static final GlobalAtomicLong PRINTING_ISOLATE = new GlobalAtomicLong(0L); + private static final GlobalAtomicLong PRINTING_ISOLATE = new GlobalAtomicLong("PRINTING_ISOLATE", 0L); /** * The intrinsic methods (in {@link Options#DisableIntrinsics} format) that have been printed by diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GlobalAtomicLong.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GlobalAtomicLong.java index c323d818c3d0..4ee016fccf54 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GlobalAtomicLong.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GlobalAtomicLong.java @@ -26,8 +26,12 @@ import java.lang.ref.Cleaner; import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Supplier; +import jdk.graal.compiler.debug.GraalError; +import jdk.graal.nativeimage.hosted.GlobalData; import jdk.internal.misc.Unsafe; +import org.graalvm.nativeimage.ImageInfo; /** * A shareable long value in the JVM process that is updated atomically. The long value is stored in @@ -46,11 +50,23 @@ public class GlobalAtomicLong { */ private static Cleaner cleaner; + /** + * Name of the global. This is only used for {@link #toString()} and is not guaranteed to be + * unique. + */ + private final String name; + /** * Address of native memory storing the long value. */ private volatile long address; + /** + * Supplies the address of the global memory storing the global value. This field is transformed + * during native image building into a supplier backed by {@link GlobalData} + */ + private final Supplier addressSupplier; + /** * Value to which the value will be initialized. */ @@ -61,8 +77,27 @@ public class GlobalAtomicLong { * * @param initialValue initial value to which the long is set when its memory is allocated */ - public GlobalAtomicLong(long initialValue) { + public GlobalAtomicLong(String name, long initialValue) { + this.name = name; this.initialValue = initialValue; + if (ImageInfo.inImageRuntimeCode()) { + throw GraalError.shouldNotReachHere("Cannot create " + getClass().getName() + " objects in native image runtime"); + } else { + addressSupplier = () -> { + if (ImageInfo.inImageRuntimeCode()) { + throw GraalError.shouldNotReachHere("The addressSupplier field value should have been replaced at image build time"); + } + long addr = UNSAFE.allocateMemory(Long.BYTES); + synchronized (GlobalAtomicLong.class) { + if (cleaner == null) { + cleaner = Cleaner.create(); + } + cleaner.register(GlobalAtomicLong.this, () -> UNSAFE.freeMemory(addr)); + } + UNSAFE.putLongVolatile(null, addr, initialValue); + return addr; + }; + } } public long getInitialValue() { @@ -71,28 +106,18 @@ public long getInitialValue() { @Override public String toString() { - long addr = getAddress(); - if (addr == 0L) { - return String.valueOf(initialValue); + if (address == 0L) { + return name + ":" + initialValue; } else { - return String.format("%d (@0x%x)", get(), addr); + return String.format("%s:%d(@0x%x)", name, get(), address); } } - // Substituted by Target_jdk_graal_compiler_serviceprovider_GlobalAtomicLong private long getAddress() { if (address == 0L) { synchronized (this) { if (address == 0L) { - long addr = UNSAFE.allocateMemory(Long.BYTES); - synchronized (GlobalAtomicLong.class) { - if (cleaner == null) { - cleaner = Cleaner.create(); - } - cleaner.register(this, () -> UNSAFE.freeMemory(addr)); - } - UNSAFE.putLongVolatile(null, addr, initialValue); - address = addr; + address = addressSupplier.get(); } } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java index 780c13035b0f..070960219a11 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java @@ -284,7 +284,7 @@ public static String getExecutionID() { return Long.toString(ProcessHandle.current().pid()); } - private static final GlobalAtomicLong globalTimeStamp = new GlobalAtomicLong(0L); + private static final GlobalAtomicLong globalTimeStamp = new GlobalAtomicLong("GLOBAL_TIME_STAMP", 0L); /** * Gets a time stamp for the current process. This method will always return the same value for diff --git a/compiler/src/jdk.graal.nativeimage/snapshot.sigtest b/compiler/src/jdk.graal.nativeimage/snapshot.sigtest index e1f38ad4eb2a..af2e39279757 100644 --- a/compiler/src/jdk.graal.nativeimage/snapshot.sigtest +++ b/compiler/src/jdk.graal.nativeimage/snapshot.sigtest @@ -17,6 +17,10 @@ meth public static void notifyLowMemoryPoint(boolean) meth public static void processReferences() supr java.lang.Object +CLSS public final jdk.graal.nativeimage.hosted.GlobalData +meth public static java.util.function.Supplier createGlobal(long) +supr java.lang.Object + CLSS public java.lang.Object cons public init() meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/hosted/GlobalData.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/hosted/GlobalData.java new file mode 100644 index 000000000000..3fd6c9d045c7 --- /dev/null +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/hosted/GlobalData.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 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 jdk.graal.nativeimage.hosted; + +import jdk.graal.nativeimage.impl.GlobalDataSupport; +import org.graalvm.nativeimage.ImageSingletons; +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; + +import java.util.function.Supplier; + +/** + * Methods for creating initialized, off-heap data that is shared across all isolates in a process. + */ +@Platforms(Platform.HOSTED_ONLY.class) +public final class GlobalData { + + /** + * Creates a pre-allocated and pre-initialized word that is off-heap. + * + * @param initialValue the initial value of the off-heap word + * @return a supplier of the address of the off-heap word + */ + public static Supplier createGlobal(long initialValue) { + return ImageSingletons.lookup(GlobalDataSupport.class).createGlobal(initialValue); + } + + private GlobalData() { + } +} diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/hosted/package-info.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/hosted/package-info.java new file mode 100644 index 000000000000..f345ee5c7e58 --- /dev/null +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/hosted/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 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. + */ +/* + @ApiInfo( + group="Native Image LibGraal extensions" + ) + */ +/** + * Extensions to the GraalVM SDK Native Image API to customize building libgraal. + * + * @since 24.2 + */ +package jdk.graal.nativeimage.hosted; diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/impl/GlobalDataSupport.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/impl/GlobalDataSupport.java new file mode 100644 index 000000000000..00feb22b662d --- /dev/null +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/impl/GlobalDataSupport.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 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 jdk.graal.nativeimage.impl; + +import java.util.function.Supplier; + +public interface GlobalDataSupport { + + Supplier createGlobal(long initialValue); +} diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/c/GlobalLongSupplier.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/c/GlobalLongSupplier.java new file mode 100644 index 000000000000..9bd5c8922e8e --- /dev/null +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/c/GlobalLongSupplier.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024, 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.c; + +import jdk.graal.compiler.word.Word; +import jdk.graal.nativeimage.hosted.GlobalData; +import org.graalvm.word.PointerBase; + +import java.util.function.Supplier; + +/** + * @see GlobalData#createGlobal(long) + */ +public class GlobalLongSupplier implements Supplier { + private final CGlobalData data; + + public GlobalLongSupplier(long initialValue) { + this.data = CGlobalDataFactory.createWord(Word.unsigned(initialValue), null, true); + } + + @Override + public Long get() { + return data.get().rawValue(); + } +} diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java index 9cdd34f15654..f5fc047c6b68 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java @@ -79,6 +79,7 @@ import jdk.graal.compiler.serviceprovider.LibGraalService; import jdk.graal.nativeimage.LibGraalFeatureComponent; import jdk.graal.nativeimage.LibGraalLoader; +import jdk.graal.nativeimage.hosted.GlobalData; import jdk.vm.ci.code.Architecture; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; import jdk.vm.ci.hotspot.HotSpotModifiers; @@ -119,15 +120,6 @@ public boolean getAsBoolean() { */ private final Set libGraalFeatureComponents = ConcurrentHashMap.newKeySet(); - /** - * Handle to {@link GlobalAtomicLong#getInitialValue()} in the guest. - */ - MethodHandle globalAtomicLongGetInitialValue; - - public ClassLoader getLoader() { - return loader; - } - /** * Loads the class {@code c} in the libgraal class loader. * @@ -197,13 +189,6 @@ public void afterRegistration(AfterRegistrationAccess access) { // Guest JVMCI and Graal need access to some JDK internal packages String[] basePackages = {"jdk.internal.misc", "jdk.internal.util", "jdk.internal.vm"}; ModuleSupport.accessPackagesToClass(ModuleSupport.Access.EXPORT, null, false, "java.base", basePackages); - - try { - globalAtomicLongGetInitialValue = mhl.findVirtual(loadClassOrFail(GlobalAtomicLong.class), - "getInitialValue", methodType(long.class)); - } catch (Throwable e) { - GraalError.shouldNotReachHere(e); - } } @SuppressWarnings("unchecked") @@ -396,10 +381,41 @@ private Map.Entry computeReplacement(Object receiver) { } } + /** + * Transforms {@code GlobalAtomicLong.addressSupplier} by replacing it with a {@link GlobalData} + * backed address supplier. + */ + class GlobalAtomicLongTransformer implements FieldValueTransformer { + private MethodHandle globalAtomicLongGetInitialValue; + + void register(BeforeAnalysisAccess access) { + Class globalAtomicLongClass = loadClassOrFail(GlobalAtomicLong.class.getName()); + Field addressSupplierField = LibGraalReflectionUtil.lookupField(globalAtomicLongClass, "addressSupplier"); + access.registerFieldValueTransformer(addressSupplierField, this); + try { + globalAtomicLongGetInitialValue = mhl.findVirtual(globalAtomicLongClass, "getInitialValue", methodType(long.class)); + } catch (Throwable e) { + GraalError.shouldNotReachHere(e); + } + } + + @Override + public Object transform(Object receiver, Object originalValue) { + long initialValue; + try { + initialValue = (long) globalAtomicLongGetInitialValue.invoke(receiver); + } catch (Throwable e) { + throw GraalError.shouldNotReachHere(e); + } + return GlobalData.createGlobal(initialValue); + } + } + @Override public void beforeAnalysis(BeforeAnalysisAccess access) { new FieldOffsetsTransformer().register(access); + new GlobalAtomicLongTransformer().register(access); /* Contains static fields that depend on HotSpotJVMCIRuntime */ RuntimeClassInitialization.initializeAtRunTime(loadClassOrFail(HotSpotModifiers.class)); diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalSubstitutions.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalSubstitutions.java index 90c63214f48c..06d03bcdd22f 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalSubstitutions.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalSubstitutions.java @@ -25,7 +25,6 @@ package com.oracle.svm.graal.hotspot.libgraal; import java.io.PrintStream; -import java.lang.ref.Cleaner; import java.lang.ref.ReferenceQueue; import java.util.Map; import java.util.function.Supplier; @@ -41,25 +40,17 @@ import org.graalvm.nativeimage.StackValue; import org.graalvm.nativeimage.VMRuntime; import org.graalvm.nativeimage.hosted.FieldValueTransformer; -import org.graalvm.word.Pointer; import com.oracle.svm.core.annotate.Alias; -import com.oracle.svm.core.annotate.Delete; -import com.oracle.svm.core.annotate.Inject; import com.oracle.svm.core.annotate.RecomputeFieldValue; import com.oracle.svm.core.annotate.Substitute; import com.oracle.svm.core.annotate.TargetClass; -import com.oracle.svm.core.annotate.TargetElement; -import com.oracle.svm.core.c.CGlobalData; -import com.oracle.svm.core.c.CGlobalDataFactory; import com.oracle.svm.core.jdk.JDKLatest; import com.oracle.svm.core.log.FunctionPointerLogHandler; import com.oracle.svm.graal.hotspot.LibGraalJNIMethodScope; import jdk.graal.compiler.debug.GraalError; import jdk.graal.compiler.libgraal.LibGraalFeature; -import jdk.graal.compiler.serviceprovider.GlobalAtomicLong; -import jdk.graal.compiler.word.Word; class LibGraalJVMCISubstitutions { @@ -163,60 +154,6 @@ public static T cast(Object obj, Class toType) { return (T) obj; } - private static final String GLOBAL_ATOMIC_LONG = "jdk.graal.compiler.serviceprovider.GlobalAtomicLong"; - - @TargetClass(className = GLOBAL_ATOMIC_LONG, classLoader = LibGraalClassLoaderSupplier.class, onlyWith = LibGraalFeature.IsEnabled.class) - static final class Target_jdk_graal_compiler_serviceprovider_GlobalAtomicLong { - - @Inject// - @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Custom, declClass = GlobalAtomicLongAddressProvider.class) // - private CGlobalData addressSupplier; - - @Delete private long address; - - /** - * {@link GlobalAtomicLong} in jargraal uses a {@link Cleaner} to ensure all native memory - * allocated by {@link GlobalAtomicLong} instances is freed when the instances are garbage - * collected. In libgraal, no {@link GlobalAtomicLong} instances are created at runtime so - * no cleaner is needed. - */ - @Delete private static Cleaner cleaner; - - /** - * Delete the constructor to ensure instances of {@link GlobalAtomicLong} cannot be created - * at runtime. - */ - @Substitute - @TargetElement(name = TargetElement.CONSTRUCTOR_NAME) - @SuppressWarnings({"unused", "static-method"}) - public void constructor(long initialValue) { - throw GraalError.shouldNotReachHere("Cannot create " + GLOBAL_ATOMIC_LONG + " objects in native image runtime"); - } - - @Substitute - private long getAddress() { - return addressSupplier.get().rawValue(); - } - } - - /** - * A field value transformer for the {@code addressSupplier} field injected into a - * {@link GlobalAtomicLong} that copies the build-time {@code initialValue}. - */ - @Platforms(HOSTED_ONLY.class) - private static final class GlobalAtomicLongAddressProvider implements FieldValueTransformer { - @Override - public Object transform(Object receiver, Object originalValue) { - long initialValue; - try { - initialValue = (long) ImageSingletons.lookup(LibGraalFeature.class).globalAtomicLongGetInitialValue.invoke(receiver); - } catch (Throwable e) { - throw GraalError.shouldNotReachHere(e); - } - return CGlobalDataFactory.createWord(Word.unsigned(initialValue), null, true); - } - } - @TargetClass(className = "jdk.graal.compiler.serviceprovider.VMSupport", classLoader = LibGraalClassLoaderSupplier.class, onlyWith = LibGraalFeature.IsEnabled.class) static final class Target_jdk_graal_compiler_serviceprovider_VMSupport { diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/GraalCompilerFeature.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/GraalCompilerFeature.java index 0c5b390de35c..fe1f21163b99 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/GraalCompilerFeature.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/GraalCompilerFeature.java @@ -28,8 +28,12 @@ import java.util.List; import java.util.function.BooleanSupplier; +import com.oracle.svm.util.ReflectionUtil; +import jdk.graal.compiler.serviceprovider.GlobalAtomicLong; +import jdk.graal.nativeimage.hosted.GlobalData; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.Feature; +import org.graalvm.nativeimage.hosted.FieldValueTransformer; import org.graalvm.nativeimage.hosted.RuntimeReflection; import com.oracle.svm.core.feature.InternalFeature; @@ -65,10 +69,23 @@ public void duringSetup(DuringSetupAccess c) { ((FeatureImpl.DuringSetupAccessImpl) c).registerClassReachabilityListener(GraalCompilerSupport::registerPhaseStatistics); } + static class GlobalAtomicLongTransformer implements FieldValueTransformer { + void register(BeforeAnalysisAccess access) { + access.registerFieldValueTransformer(ReflectionUtil.lookupField(GlobalAtomicLong.class, "addressSupplier"), this); + } + + @Override + public Object transform(Object receiver, Object originalValue) { + return GlobalData.createGlobal(((GlobalAtomicLong) receiver).getInitialValue()); + } + } + @Override public void beforeAnalysis(BeforeAnalysisAccess c) { DebugContext debug = DebugContext.forCurrentThread(); + new GlobalAtomicLongTransformer().register(c); + // box lowering accesses the caches for those classes and thus needs reflective access for (JavaKind kind : new JavaKind[]{JavaKind.Boolean, JavaKind.Byte, JavaKind.Char, JavaKind.Double, JavaKind.Float, JavaKind.Int, JavaKind.Long, JavaKind.Short}) { diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/substitutions/GraalSubstitutions.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/substitutions/GraalSubstitutions.java index 9302712207de..16a1af639e9c 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/substitutions/GraalSubstitutions.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/substitutions/GraalSubstitutions.java @@ -28,13 +28,11 @@ import static com.oracle.svm.core.annotate.RecomputeFieldValue.Kind.FromAlias; import java.io.PrintStream; -import java.lang.ref.Cleaner; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import jdk.graal.compiler.word.Word; import jdk.graal.compiler.graph.Edges; import org.graalvm.collections.EconomicMap; import org.graalvm.collections.EconomicSet; @@ -43,20 +41,15 @@ import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.FieldValueTransformer; import org.graalvm.nativeimage.impl.IsolateSupport; -import org.graalvm.word.Pointer; import com.oracle.svm.core.SubstrateTargetDescription; import com.oracle.svm.core.annotate.Alias; -import com.oracle.svm.core.annotate.Delete; import com.oracle.svm.core.annotate.Inject; import com.oracle.svm.core.annotate.InjectAccessors; import com.oracle.svm.core.annotate.RecomputeFieldValue; import com.oracle.svm.core.annotate.RecomputeFieldValue.Kind; import com.oracle.svm.core.annotate.Substitute; import com.oracle.svm.core.annotate.TargetClass; -import com.oracle.svm.core.annotate.TargetElement; -import com.oracle.svm.core.c.CGlobalData; -import com.oracle.svm.core.c.CGlobalDataFactory; import com.oracle.svm.core.config.ConfigurationValues; import com.oracle.svm.core.log.Log; import com.oracle.svm.core.option.HostedOptionValues; @@ -96,7 +89,6 @@ import jdk.graal.compiler.printer.NoDeadCodeVerifyHandler; import jdk.graal.compiler.replacements.nodes.BinaryMathIntrinsicNode; import jdk.graal.compiler.replacements.nodes.UnaryMathIntrinsicNode; -import jdk.graal.compiler.serviceprovider.GlobalAtomicLong; import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.meta.ResolvedJavaMethod; @@ -230,42 +222,6 @@ public static long getIsolateID() { } } -class GlobalAtomicLongAddressProvider implements FieldValueTransformer { - @Override - public Object transform(Object receiver, Object originalValue) { - long initialValue = ((GlobalAtomicLong) receiver).getInitialValue(); - return CGlobalDataFactory.createWord(Word.unsigned(initialValue), null, true); - } -} - -@TargetClass(className = "jdk.graal.compiler.serviceprovider.GlobalAtomicLong", onlyWith = GraalCompilerFeature.IsEnabled.class) -final class Target_jdk_graal_compiler_serviceprovider_GlobalAtomicLong { - - @Inject// - @RecomputeFieldValue(kind = Kind.Custom, declClass = GlobalAtomicLongAddressProvider.class) // - private CGlobalData addressSupplier; - - @Delete private long address; - - @Delete private static Cleaner cleaner; - - /** - * Delete the constructor to ensure instances of {@link GlobalAtomicLong} cannot be created at - * runtime. - */ - @Substitute - @TargetElement(name = TargetElement.CONSTRUCTOR_NAME) - @SuppressWarnings({"unused", "static-method"}) - public void constructor(long initialValue) { - throw VMError.unsupportedFeature("Cannot create " + GlobalAtomicLong.class.getName() + " objects in native image runtime"); - } - - @Substitute - private long getAddress() { - return addressSupplier.get().rawValue(); - } -} - /* * The following substitutions replace methods where reflection is used in the Graal code. */ diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/GlobalDataSupportImpl.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/GlobalDataSupportImpl.java new file mode 100644 index 000000000000..1f59cf349233 --- /dev/null +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/GlobalDataSupportImpl.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024, 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.hosted; + +import java.util.function.Supplier; + +import com.oracle.svm.core.c.GlobalLongSupplier; +import com.oracle.svm.core.feature.AutomaticallyRegisteredImageSingleton; + +import jdk.graal.nativeimage.impl.GlobalDataSupport; + +@AutomaticallyRegisteredImageSingleton(GlobalDataSupport.class) +public final class GlobalDataSupportImpl implements GlobalDataSupport { + @Override + public Supplier createGlobal(long initialValue) { + return new GlobalLongSupplier(initialValue); + } +} From f63555caa42e161ab6d0043da8c027778227ad42 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Fri, 29 Nov 2024 23:17:41 +0100 Subject: [PATCH 05/31] folded project com.oracle.svm.graal.hotspot into project com.oracle.svm.graal.hotspot.libgraal --- substratevm/mx.substratevm/suite.py | 30 +-------- .../hotspot/libgraal}/GetCompilerConfig.java | 2 +- .../graal/hotspot/libgraal}/GetJNIConfig.java | 64 +++++++++++-------- .../hotspot/libgraal/LibGraalEntryPoints.java | 1 - .../hotspot/libgraal/LibGraalFeature.java | 6 +- .../libgraal}/LibGraalJNIMethodScope.java | 2 +- 6 files changed, 44 insertions(+), 61 deletions(-) rename substratevm/src/{com.oracle.svm.graal.hotspot/src/com/oracle/svm/graal/hotspot => com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal}/GetCompilerConfig.java (99%) rename substratevm/src/{com.oracle.svm.graal.hotspot/src/com/oracle/svm/graal/hotspot => com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal}/GetJNIConfig.java (85%) rename substratevm/src/{com.oracle.svm.graal.hotspot/src/com/oracle/svm/graal/hotspot => com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal}/LibGraalJNIMethodScope.java (98%) diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py index 66546c067a30..569462cf30be 100644 --- a/substratevm/mx.substratevm/suite.py +++ b/substratevm/mx.substratevm/suite.py @@ -1356,33 +1356,6 @@ "jacoco" : "exclude", }, - "com.oracle.svm.graal.hotspot" : { - "subDir": "src", - "sourceDirs" : [ - "src" - ], - "dependencies": [ - "sdk:JNIUTILS", - "compiler:GRAAL", - "SVM", - ], - "requiresConcealed" : { - "jdk.internal.vm.ci" : [ - "jdk.vm.ci.services", - "jdk.vm.ci.runtime", - "jdk.vm.ci.hotspot", - "jdk.vm.ci.meta" - ], - }, - "annotationProcessors": [ - "compiler:GRAAL_PROCESSOR", - ], - "checkstyle" : "com.oracle.svm.hosted", - "javaCompliance" : "21+", - "workingSets" : "SVM", - "jacoco" : "exclude", - }, - "com.oracle.svm.graal.hotspot.libgraal" : { "subDir": "src", "sourceDirs" : [ @@ -1390,7 +1363,7 @@ "resources", ], "dependencies": [ - "com.oracle.svm.graal.hotspot", + "sdk:JNIUTILS", "sdk:NATIVEIMAGE", "sdk:NATIVEBRIDGE", "compiler:GRAAL", @@ -1405,6 +1378,7 @@ "jdk.internal.misc", ], "jdk.internal.vm.ci" : [ + "jdk.vm.ci.meta", "jdk.vm.ci.services", "jdk.vm.ci.runtime", "jdk.vm.ci.code", diff --git a/substratevm/src/com.oracle.svm.graal.hotspot/src/com/oracle/svm/graal/hotspot/GetCompilerConfig.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/GetCompilerConfig.java similarity index 99% rename from substratevm/src/com.oracle.svm.graal.hotspot/src/com/oracle/svm/graal/hotspot/GetCompilerConfig.java rename to substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/GetCompilerConfig.java index 302d219f380a..8fdb736193ca 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot/src/com/oracle/svm/graal/hotspot/GetCompilerConfig.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/GetCompilerConfig.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.graal.hotspot; +package com.oracle.svm.graal.hotspot.libgraal; import java.io.BufferedReader; import java.io.IOException; diff --git a/substratevm/src/com.oracle.svm.graal.hotspot/src/com/oracle/svm/graal/hotspot/GetJNIConfig.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/GetJNIConfig.java similarity index 85% rename from substratevm/src/com.oracle.svm.graal.hotspot/src/com/oracle/svm/graal/hotspot/GetJNIConfig.java rename to substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/GetJNIConfig.java index 92178a4c508a..5ce365ca0cf2 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot/src/com/oracle/svm/graal/hotspot/GetJNIConfig.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/GetJNIConfig.java @@ -22,19 +22,9 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.graal.hotspot; +package com.oracle.svm.graal.hotspot.libgraal; -import com.oracle.svm.core.OS; -import com.oracle.svm.core.util.UserError; -import com.oracle.svm.core.util.VMError; -import com.oracle.svm.hosted.ImageClassLoader; -import com.oracle.svm.util.LogUtils; -import com.oracle.svm.util.ModuleSupport; -import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; -import jdk.vm.ci.hotspot.HotSpotSignature; -import jdk.vm.ci.meta.JavaType; -import org.graalvm.nativeimage.hosted.RuntimeJNIAccess; -import org.graalvm.nativeimage.hosted.RuntimeReflection; +import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; import java.io.BufferedReader; import java.io.IOException; @@ -51,13 +41,19 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; +import org.graalvm.nativeimage.hosted.RuntimeJNIAccess; +import org.graalvm.nativeimage.hosted.RuntimeReflection; + +import jdk.graal.compiler.debug.GraalError; +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; +import jdk.vm.ci.hotspot.HotSpotSignature; +import jdk.vm.ci.meta.JavaType; /** * Registers the JNI configuration for libgraal by parsing the output of the * {@code -XX:JVMCILibDumpJNIConfig} VM option. */ -public final class GetJNIConfig implements AutoCloseable { +final class GetJNIConfig implements AutoCloseable { /** * VM command executed to read the JNI config. */ @@ -94,7 +90,7 @@ private GetJNIConfig(ClassLoader loader) { try { p = pb.start(); } catch (IOException e) { - throw UserError.abort("Could not run command: %s%n%s", quotedCommand, e); + throw new GraalError(e, "Could not run command: %s", quotedCommand); } String nl = System.lineSeparator(); @@ -105,23 +101,24 @@ private GetJNIConfig(ClassLoader loader) { try { exitValue = p.waitFor(); } catch (InterruptedException e) { - throw UserError.abort("Interrupted waiting for command: %s%n%s", quotedCommand, out); + throw new GraalError(e, "Interrupted waiting for command: %s%n%s", quotedCommand, out); } if (exitValue != 0) { - throw UserError.abort("Command finished with exit value %d: %s%n%s", exitValue, quotedCommand, out); + throw new GraalError("Command finished with exit value %d: %s%n%s", exitValue, quotedCommand, out); } try { lines = Files.readAllLines(configFilePath); } catch (IOException e) { configFilePath = null; - throw UserError.abort("Reading JNI config in %s dumped by command: %s%n%s", configFilePath, quotedCommand, out); + throw new GraalError("Reading JNI config in %s dumped by command: %s%n%s", configFilePath, quotedCommand, out); } } static Path getJavaExe(Path javaHome) { - Path javaExe = javaHome.resolve(Path.of("bin", OS.WINDOWS.isCurrent() ? "java.exe" : "java")); + boolean isWindows = System.getProperty("os.name").contains("Windows"); + Path javaExe = javaHome.resolve(Path.of("bin", isWindows ? "java.exe" : "java")); if (!Files.isExecutable(javaExe)) { - throw UserError.abort("Java launcher %s does not exist or is not executable", javaExe); + throw new GraalError("Java launcher %s does not exist or is not executable", javaExe); } return javaExe; } @@ -133,24 +130,39 @@ public void close() { Files.delete(configFilePath); configFilePath = null; } catch (IOException e) { - LogUtils.warning("Could not delete %s: %s", configFilePath, e); + throw new GraalError(e, "Could not delete %s", configFilePath); } } } + public static Class forPrimitive(String name) { + return switch (name) { + case "boolean" -> boolean.class; + case "char" -> char.class; + case "float" -> float.class; + case "double" -> double.class; + case "byte" -> byte.class; + case "short" -> short.class; + case "int" -> int.class; + case "long" -> long.class; + case "void" -> void.class; + default -> null; + }; + } + private Class findClass(String name) { String internalName = name; if (name.startsWith("L") && name.endsWith(";")) { internalName = name.substring(1, name.length() - 1); } - var primitive = ImageClassLoader.forPrimitive(internalName); + var primitive = forPrimitive(internalName); if (primitive != null) { return primitive; } try { return Class.forName(internalName, false, loader); } catch (ClassNotFoundException e) { - throw VMError.shouldNotReachHere("Cannot find class during LibGraal JNIConfiguration registration", e); + throw new GraalError(e, "Cannot find class during LibGraal JNIConfiguration registration"); } } @@ -160,12 +172,12 @@ private void check(boolean condition, String format, Object... args) { } } - private UserError.UserException error(String format, Object... args) { + private GraalError error(String format, Object... args) { Path path = configFilePath; configFilePath = null; // prevent deletion String errorMessage = String.format(format, args); String errorLine = lines.get(lineNo - 1); - throw UserError.abort("Line %d of %s: %s%n%s%n%s generated by command: %s", + throw new GraalError("Line %d of %s: %s%n%s%n%s generated by command: %s", lineNo, path.toAbsolutePath(), errorMessage, errorLine, path, quotedCommand); } @@ -179,7 +191,7 @@ private UserError.UserException error(String format, Object... args) { @SuppressWarnings("try") public static void register(ClassLoader loader) { // Export all JVMCI packages to this class - ModuleSupport.accessPackagesToClass(ModuleSupport.Access.EXPORT, GetJNIConfig.class, false, "jdk.internal.vm.ci"); + LibGraalFeature.exportModulesToLibGraal("jdk.internal.vm.ci"); try (GetJNIConfig source = new GetJNIConfig(loader)) { Map> classes = new HashMap<>(); diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java index db68c0871cf1..464529201648 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java @@ -44,7 +44,6 @@ import com.oracle.svm.core.option.RuntimeOptionValues; import com.oracle.svm.core.option.XOptions; import com.oracle.svm.core.util.VMError; -import com.oracle.svm.graal.hotspot.LibGraalJNIMethodScope; import com.oracle.svm.util.ClassUtil; import com.oracle.truffle.compiler.TruffleCompilerOptionDescriptor; import com.oracle.truffle.compiler.hotspot.libgraal.TruffleToLibGraal; diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java index f5fc047c6b68..b5854b1f251e 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java @@ -60,8 +60,6 @@ import com.oracle.graal.pointsto.meta.AnalysisType; import com.oracle.graal.pointsto.reports.CallTreePrinter; import com.oracle.svm.core.hub.ClassForNameSupport; -import com.oracle.svm.graal.hotspot.GetCompilerConfig; -import com.oracle.svm.graal.hotspot.GetJNIConfig; import com.oracle.svm.hosted.FeatureImpl.AfterAnalysisAccessImpl; import com.oracle.svm.util.ModuleSupport; import com.oracle.svm.util.ModuleSupport.Access; @@ -198,11 +196,11 @@ private static LibGraalLoader createHostedLibGraalClassLoader(AfterRegistrationA return LibGraalReflectionUtil.newInstance((Class) hostedLibGraalClassLoaderClass); } - private static void exportModulesToLibGraal(String... moduleNames) { + static void exportModulesToLibGraal(String... moduleNames) { accessModulesToClass(Access.EXPORT, LibGraalFeature.class, moduleNames); } - private static void accessModulesToClass(ModuleSupport.Access access, Class accessingClass, String... moduleNames) { + static void accessModulesToClass(ModuleSupport.Access access, Class accessingClass, String... moduleNames) { for (String moduleName : moduleNames) { var module = getBootModule(moduleName); ModuleSupport.accessPackagesToClass(access, accessingClass, false, diff --git a/substratevm/src/com.oracle.svm.graal.hotspot/src/com/oracle/svm/graal/hotspot/LibGraalJNIMethodScope.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalJNIMethodScope.java similarity index 98% rename from substratevm/src/com.oracle.svm.graal.hotspot/src/com/oracle/svm/graal/hotspot/LibGraalJNIMethodScope.java rename to substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalJNIMethodScope.java index 7b9271205fa7..904450cd7b08 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot/src/com/oracle/svm/graal/hotspot/LibGraalJNIMethodScope.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalJNIMethodScope.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.graal.hotspot; +package com.oracle.svm.graal.hotspot.libgraal; import org.graalvm.jniutils.JNI.JNIEnv; import org.graalvm.jniutils.JNIMethodScope; From 84b3037178eae33c1dfb16490a0e3c6ffdc8f393 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Sat, 30 Nov 2024 11:37:30 +0100 Subject: [PATCH 06/31] removed use of com.oracle.svm.util in libgraal --- substratevm/mx.substratevm/mx_substratevm.py | 5 +- substratevm/mx.substratevm/suite.py | 1 + .../svm/graal/hotspot/libgraal/JDKLatest.java | 40 +++ .../hotspot/libgraal/LibGraalEntryPoints.java | 34 +-- .../hotspot/libgraal/LibGraalFeature.java | 36 ++- .../libgraal/LibGraalReflectionUtil.java | 240 --------------- .../graal/hotspot/libgraal/LibGraalUtil.java | 277 ++++++++++++++++++ 7 files changed, 355 insertions(+), 278 deletions(-) create mode 100644 substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/JDKLatest.java delete mode 100644 substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalReflectionUtil.java create mode 100644 substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalUtil.java diff --git a/substratevm/mx.substratevm/mx_substratevm.py b/substratevm/mx.substratevm/mx_substratevm.py index 6f7238f60a35..d1928de529cf 100644 --- a/substratevm/mx.substratevm/mx_substratevm.py +++ b/substratevm/mx.substratevm/mx_substratevm.py @@ -1515,8 +1515,9 @@ def prevent_build_path_in_libgraal(): ## Packages used after option-processing can be opened by the builder (`-J`-prefix not needed) # LibGraalFeature implements com.oracle.svm.core.feature.InternalFeature (needed to be able to instantiate LibGraalFeature) '--add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.feature=ALL-UNNAMED', - # Make ModuleSupport accessible to do the remaining opening-up in LibGraalFeature constructor - '--add-exports=org.graalvm.nativeimage.base/com.oracle.svm.util=ALL-UNNAMED', + # Make jdk.internal.module.Modules accessible to do the remaining opening-up in LibGraalFeature constructor + #'--add-exports=org.graalvm.nativeimage.base/com.oracle.svm.util=ALL-UNNAMED', + '--add-exports=java.base/jdk.internal.module=ALL-UNNAMED', # TruffleLibGraalJVMCIServiceLocator needs access to JVMCIServiceLocator '--add-exports=jdk.internal.vm.ci/jdk.vm.ci.services=ALL-UNNAMED', diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py index 569462cf30be..82c4593b1723 100644 --- a/substratevm/mx.substratevm/suite.py +++ b/substratevm/mx.substratevm/suite.py @@ -1375,6 +1375,7 @@ ], "requiresConcealed" : { "java.base" : [ + "jdk.internal.module", "jdk.internal.misc", ], "jdk.internal.vm.ci" : [ diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/JDKLatest.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/JDKLatest.java new file mode 100644 index 000000000000..8f7a6dd70cd5 --- /dev/null +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/JDKLatest.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024, 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.graal.hotspot.libgraal; + +import java.util.function.BooleanSupplier; + +import jdk.graal.compiler.serviceprovider.JavaVersionUtil; + +/** + * Denotes the latest supported JDK version. It corresponds to the highest key in the + * {@code JVMCI_MIN_VERSIONS} map in {@link jdk.graal.compiler.hotspot.JVMCIVersionCheck}. + */ +public class JDKLatest implements BooleanSupplier { + @Override + public boolean getAsBoolean() { + return JavaVersionUtil.JAVA_SPEC > 21; + } +} diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java index 464529201648..7ee2acf75d6b 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java @@ -43,11 +43,10 @@ import com.oracle.svm.core.heap.UnknownObjectField; import com.oracle.svm.core.option.RuntimeOptionValues; import com.oracle.svm.core.option.XOptions; -import com.oracle.svm.core.util.VMError; -import com.oracle.svm.util.ClassUtil; import com.oracle.truffle.compiler.TruffleCompilerOptionDescriptor; import com.oracle.truffle.compiler.hotspot.libgraal.TruffleToLibGraal; import com.oracle.truffle.compiler.hotspot.libgraal.TruffleToLibGraal.Id; +import jdk.graal.compiler.debug.GraalError; import jdk.graal.compiler.hotspot.libgraal.BuildTime; import jdk.graal.compiler.hotspot.libgraal.RunTime; import jdk.graal.compiler.options.OptionDescriptor; @@ -78,6 +77,7 @@ import org.graalvm.nativeimage.ObjectHandles; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; +import org.graalvm.nativeimage.RuntimeOptions; import org.graalvm.nativeimage.c.function.CEntryPoint; import org.graalvm.nativeimage.c.function.CEntryPoint.Builtin; import org.graalvm.nativeimage.c.function.CEntryPoint.IsolateContext; @@ -132,7 +132,7 @@ static JNI.JNIEnv getJNIEnv() { } catch (RuntimeException | Error e) { throw e; } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); + throw GraalError.shouldNotReachHere(e); } } @@ -145,7 +145,7 @@ static String getSavedProperty(String name) { } catch (RuntimeException | Error e) { throw e; } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); + throw GraalError.shouldNotReachHere(e); } } @@ -158,7 +158,7 @@ static boolean attachCurrentThread(boolean daemon, long[] isolate) { } catch (RuntimeException | Error e) { throw e; } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); + throw GraalError.shouldNotReachHere(e); } } @@ -171,7 +171,7 @@ static boolean detachCurrentThread(boolean release) { } catch (RuntimeException | Error e) { throw e; } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); + throw GraalError.shouldNotReachHere(e); } } @@ -184,7 +184,7 @@ static void ttyPrintf(String format, Object... args) { } catch (RuntimeException | Error e) { throw e; } catch (Throwable e) { - throw VMError.shouldNotReachHere(e); + throw GraalError.shouldNotReachHere(e); } } @@ -429,48 +429,48 @@ final class LibGraalTruffleToLibGraalEntryPoints { String methodName = id.getMethodName(); Method method = graalMethodByName.get(methodName); if (method == null) { - throw VMError.shouldNotReachHere("Missing libgraal entry method %s.%s corresponding to TruffleToLibGraal.Id.%s. " + + throw new GraalError("Missing libgraal entry method %s.%s corresponding to TruffleToLibGraal.Id.%s. " + "To resolve this, add `public static %s()` in %s, where the and correspond to TruffleToLibGraalCalls.%s.", - ClassUtil.getUnqualifiedName(graalEntryPoints), methodName, id, methodName, graalEntryPoints.getName(), methodName); + LibGraalUtil.getUnqualifiedName(graalEntryPoints), methodName, id, methodName, graalEntryPoints.getName(), methodName); } if (!hostMethodByName.contains(methodName)) { - throw VMError.shouldNotReachHere("Missing C entry point method %s.%s corresponding to TruffleToLibGraal.Id.%s. " + + throw new GraalError("Missing C entry point method %s.%s corresponding to TruffleToLibGraal.Id.%s. " + "To resolve this, add `@CEntryPoint(\"Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_%s\") " + "@TruffleToLibGraal(Id.%s) static %s(JNIEnv env, JClass jclass, @IsolateThreadContext long isolateThreadId, " + ")` in %s, where the and correspond to TruffleToLibGraalCalls.%s. " + "Use a MethodHandle to delegate to %s.%s.", - ClassUtil.getUnqualifiedName(getClass()), methodName, id, methodName, id, methodName, getClass().getName(), methodName, + LibGraalUtil.getUnqualifiedName(getClass()), methodName, id, methodName, id, methodName, getClass().getName(), methodName, graalEntryPoints.getName(), methodName); } Field methodHandleField; try { methodHandleField = getClass().getDeclaredField(methodName); } catch (NoSuchFieldException nsf) { - throw VMError.shouldNotReachHere("Missing field %s.%s corresponding to TruffleToLibGraal.Id.%s. " + + throw new GraalError("Missing field %s.%s corresponding to TruffleToLibGraal.Id.%s. " + "To resolve this, add `private final MethodHandle %s = null;` to %s.", - ClassUtil.getUnqualifiedName(getClass()), methodName, id, methodName, getClass().getName()); + LibGraalUtil.getUnqualifiedName(getClass()), methodName, id, methodName, getClass().getName()); } methodHandleField.setAccessible(true); methodHandleField.set(this, libgraalLookup.unreflect(method)); } Method m = graalMethodByName.get("getCurrentJavaThread"); if (m == null) { - throw VMError.shouldNotReachHere("Missing libgraal entry method %s.getCurrentJavaThread.", ClassUtil.getUnqualifiedName(graalEntryPoints)); + throw new GraalError("Missing libgraal entry method %s.getCurrentJavaThread.", LibGraalUtil.getUnqualifiedName(graalEntryPoints)); } getCurrentJavaThread = libgraalLookup.unreflect(m); m = graalMethodByName.get("getLastJavaPCOffset"); if (m == null) { - throw VMError.shouldNotReachHere("Missing libgraal entry method %s.getLastJavaPCOffset.", ClassUtil.getUnqualifiedName(graalEntryPoints)); + throw new GraalError("Missing libgraal entry method %s.getLastJavaPCOffset.", LibGraalUtil.getUnqualifiedName(graalEntryPoints)); } getLastJavaPCOffset = libgraalLookup.unreflect(m); } catch (ReflectiveOperationException e) { - throw VMError.shouldNotReachHere(e); + throw GraalError.shouldNotReachHere(e); } } private static JNIMethodScope openScope(Enum id, JNIEnv env) throws Throwable { Objects.requireNonNull(id, "Id must be non null."); - String scopeName = ClassUtil.getUnqualifiedName(LibGraalTruffleToLibGraalEntryPoints.class) + "::" + id; + String scopeName = LibGraalUtil.getUnqualifiedName(LibGraalTruffleToLibGraalEntryPoints.class) + "::" + id; int offset = lastJavaPCOffset; if (offset == -1) { offset = (int) singleton().getLastJavaPCOffset.invoke(); diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java index b5854b1f251e..73e8361d5acc 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java @@ -61,8 +61,6 @@ import com.oracle.graal.pointsto.reports.CallTreePrinter; import com.oracle.svm.core.hub.ClassForNameSupport; import com.oracle.svm.hosted.FeatureImpl.AfterAnalysisAccessImpl; -import com.oracle.svm.util.ModuleSupport; -import com.oracle.svm.util.ModuleSupport.Access; import jdk.graal.compiler.core.common.Fields; import jdk.graal.compiler.debug.DebugContext; @@ -186,24 +184,24 @@ public void afterRegistration(AfterRegistrationAccess access) { // Guest JVMCI and Graal need access to some JDK internal packages String[] basePackages = {"jdk.internal.misc", "jdk.internal.util", "jdk.internal.vm"}; - ModuleSupport.accessPackagesToClass(ModuleSupport.Access.EXPORT, null, false, "java.base", basePackages); + LibGraalUtil.accessPackagesToClass(LibGraalUtil.Access.EXPORT, null, false, "java.base", basePackages); } @SuppressWarnings("unchecked") private static LibGraalLoader createHostedLibGraalClassLoader(AfterRegistrationAccess access) { var hostedLibGraalClassLoaderClass = access.findClassByName("jdk.graal.compiler.libgraal.loader.HostedLibGraalClassLoader"); - ModuleSupport.accessPackagesToClass(Access.EXPORT, hostedLibGraalClassLoaderClass, false, "java.base", "jdk.internal.module"); - return LibGraalReflectionUtil.newInstance((Class) hostedLibGraalClassLoaderClass); + LibGraalUtil.accessPackagesToClass(LibGraalUtil.Access.EXPORT, hostedLibGraalClassLoaderClass, false, "java.base", "jdk.internal.module"); + return LibGraalUtil.newInstance((Class) hostedLibGraalClassLoaderClass); } static void exportModulesToLibGraal(String... moduleNames) { - accessModulesToClass(Access.EXPORT, LibGraalFeature.class, moduleNames); + accessModulesToClass(LibGraalUtil.Access.EXPORT, LibGraalFeature.class, moduleNames); } - static void accessModulesToClass(ModuleSupport.Access access, Class accessingClass, String... moduleNames) { + static void accessModulesToClass(LibGraalUtil.Access access, Class accessingClass, String... moduleNames) { for (String moduleName : moduleNames) { var module = getBootModule(moduleName); - ModuleSupport.accessPackagesToClass(access, accessingClass, false, + LibGraalUtil.accessPackagesToClass(access, accessingClass, false, module.getName(), module.getPackages().toArray(String[]::new)); } } @@ -339,9 +337,9 @@ class FieldOffsetsTransformer implements FieldValueTransformer { FieldOffsetsTransformer() { edgesClass = loadClassOrFail(Edges.class.getName()); fieldsClass = loadClassOrFail(Fields.class.getName()); - fieldsOffsetsField = LibGraalReflectionUtil.lookupField(fieldsClass, "offsets"); - edgesIterationMaskField = LibGraalReflectionUtil.lookupField(edgesClass, "iterationMask"); - recomputeOffsetsAndIterationMaskMethod = LibGraalReflectionUtil.lookupMethod(fieldsClass, "recomputeOffsetsAndIterationMask", BeforeCompilationAccess.class); + fieldsOffsetsField = LibGraalUtil.lookupField(fieldsClass, "offsets"); + edgesIterationMaskField = LibGraalUtil.lookupField(edgesClass, "iterationMask"); + recomputeOffsetsAndIterationMaskMethod = LibGraalUtil.lookupMethod(fieldsClass, "recomputeOffsetsAndIterationMask", BeforeCompilationAccess.class); } void register(BeforeAnalysisAccess access) { @@ -388,7 +386,7 @@ class GlobalAtomicLongTransformer implements FieldValueTransformer { void register(BeforeAnalysisAccess access) { Class globalAtomicLongClass = loadClassOrFail(GlobalAtomicLong.class.getName()); - Field addressSupplierField = LibGraalReflectionUtil.lookupField(globalAtomicLongClass, "addressSupplier"); + Field addressSupplierField = LibGraalUtil.lookupField(globalAtomicLongClass, "addressSupplier"); access.registerFieldValueTransformer(addressSupplierField, this); try { globalAtomicLongGetInitialValue = mhl.findVirtual(globalAtomicLongClass, "getInitialValue", methodType(long.class)); @@ -424,15 +422,15 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { /* Needed for runtime calls to BoxingSnippets.Templates.getCacheClass(JavaKind) */ RuntimeReflection.registerAllDeclaredClasses(Character.class); - RuntimeReflection.register(LibGraalReflectionUtil.lookupField(LibGraalReflectionUtil.lookupClass("java.lang.Character$CharacterCache"), "cache")); + RuntimeReflection.register(LibGraalUtil.lookupField(LibGraalUtil.lookupClass("java.lang.Character$CharacterCache"), "cache")); RuntimeReflection.registerAllDeclaredClasses(Byte.class); - RuntimeReflection.register(LibGraalReflectionUtil.lookupField(LibGraalReflectionUtil.lookupClass("java.lang.Byte$ByteCache"), "cache")); + RuntimeReflection.register(LibGraalUtil.lookupField(LibGraalUtil.lookupClass("java.lang.Byte$ByteCache"), "cache")); RuntimeReflection.registerAllDeclaredClasses(Short.class); - RuntimeReflection.register(LibGraalReflectionUtil.lookupField(LibGraalReflectionUtil.lookupClass("java.lang.Short$ShortCache"), "cache")); + RuntimeReflection.register(LibGraalUtil.lookupField(LibGraalUtil.lookupClass("java.lang.Short$ShortCache"), "cache")); RuntimeReflection.registerAllDeclaredClasses(Integer.class); - RuntimeReflection.register(LibGraalReflectionUtil.lookupField(LibGraalReflectionUtil.lookupClass("java.lang.Integer$IntegerCache"), "cache")); + RuntimeReflection.register(LibGraalUtil.lookupField(LibGraalUtil.lookupClass("java.lang.Integer$IntegerCache"), "cache")); RuntimeReflection.registerAllDeclaredClasses(Long.class); - RuntimeReflection.register(LibGraalReflectionUtil.lookupField(LibGraalReflectionUtil.lookupClass("java.lang.Long$LongCache"), "cache")); + RuntimeReflection.register(LibGraalUtil.lookupField(LibGraalUtil.lookupClass("java.lang.Long$LongCache"), "cache")); /* Configure static state of Graal. */ try { @@ -456,11 +454,11 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { String.class, // nativeImageLocationQualifier byte[].class // encodedGuestObjects )); - Path libGraalJavaHome = LibGraalReflectionUtil.readField(loader.getClass(), "libGraalJavaHome", loader); + Path libGraalJavaHome = LibGraalUtil.readField(loader.getClass(), "libGraalJavaHome", loader); GetCompilerConfig.Result configResult = GetCompilerConfig.from(libGraalJavaHome); for (var e : configResult.opens().entrySet()) { for (String source : e.getValue()) { - ModuleSupport.accessPackagesToClass(ModuleSupport.Access.OPEN, buildTimeClass, false, e.getKey(), source); + LibGraalUtil.accessPackagesToClass(LibGraalUtil.Access.OPEN, buildTimeClass, false, e.getKey(), source); } } diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalReflectionUtil.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalReflectionUtil.java deleted file mode 100644 index c8394a1b6d87..000000000000 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalReflectionUtil.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (c) 2019, 2019, 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.graal.hotspot.libgraal; - -import java.lang.invoke.MethodHandles; -import java.lang.invoke.VarHandle; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import com.oracle.svm.util.ModuleSupport; - -/** - * This is a copy of {@code com.oracle.svm.util.ReflectionUtil}. - */ -public final class LibGraalReflectionUtil { - - @SuppressWarnings("serial") - public static final class ReflectionUtilError extends Error { - private ReflectionUtilError(Throwable cause) { - super(cause); - } - } - - private LibGraalReflectionUtil() { - } - - /** - * Ensure that this class is allowed to call setAccessible for an element of the provided - * declaring class. - */ - private static void openModule(Class declaringClass) { - ModuleSupport.accessModuleByClass(ModuleSupport.Access.OPEN, LibGraalReflectionUtil.class, declaringClass); - } - - public static Class lookupClass(String className) { - return lookupClass(false, className); - } - - public static Class lookupClass(boolean optional, String className) { - return lookupClass(optional, className, LibGraalReflectionUtil.class.getClassLoader()); - } - - public static Class lookupClass(boolean optional, String className, ClassLoader loader) { - try { - return Class.forName(className, false, loader); - } catch (ClassNotFoundException ex) { - if (optional) { - return null; - } - throw new ReflectionUtilError(ex); - } - } - - public static Method lookupMethod(Class declaringClass, String methodName, Class... parameterTypes) { - return lookupMethod(false, declaringClass, methodName, parameterTypes); - } - - public static Method lookupMethod(boolean optional, Class declaringClass, String methodName, Class... parameterTypes) { - try { - Method result = declaringClass.getDeclaredMethod(methodName, parameterTypes); - openModule(declaringClass); - result.setAccessible(true); - return result; - } catch (ReflectiveOperationException ex) { - if (optional) { - return null; - } - throw new ReflectionUtilError(ex); - } - } - - public static Method lookupPublicMethodInClassHierarchy(Class clazz, String methodName, Class... parameterTypes) { - return lookupPublicMethodInClassHierarchy(false, clazz, methodName, parameterTypes); - } - - public static Method lookupPublicMethodInClassHierarchy(boolean optional, Class clazz, String methodName, Class... parameterTypes) { - try { - Method result = clazz.getMethod(methodName, parameterTypes); - openModule(result.getDeclaringClass()); - result.setAccessible(true); - return result; - } catch (ReflectiveOperationException ex) { - if (optional) { - return null; - } - throw new ReflectionUtilError(ex); - } - } - - public static Constructor lookupConstructor(Class declaringClass, Class... parameterTypes) { - return lookupConstructor(false, declaringClass, parameterTypes); - } - - public static Constructor lookupConstructor(boolean optional, Class declaringClass, Class... parameterTypes) { - try { - Constructor result = declaringClass.getDeclaredConstructor(parameterTypes); - openModule(declaringClass); - result.setAccessible(true); - return result; - } catch (ReflectiveOperationException ex) { - if (optional) { - return null; - } - throw new ReflectionUtilError(ex); - } - } - - /** - * Invokes the provided method, and unwraps a possible {@link InvocationTargetException} so that - * it appears as if the method had been invoked directly without the use of reflection. - */ - @SuppressWarnings("unchecked") - public static T invokeMethod(Method method, Object receiver, Object... arguments) { - try { - method.setAccessible(true); - return (T) method.invoke(receiver, arguments); - } catch (InvocationTargetException ex) { - Throwable cause = ex.getCause(); - if (cause != null) { - throw rethrow(cause); - } - throw new ReflectionUtilError(ex); - } catch (ReflectiveOperationException ex) { - throw new ReflectionUtilError(ex); - } - } - - @SuppressWarnings("unchecked") - private static RuntimeException rethrow(Throwable ex) throws E { - throw (E) ex; - } - - public static T newInstance(Class declaringClass) { - try { - return lookupConstructor(declaringClass).newInstance(); - } catch (ReflectiveOperationException ex) { - throw new ReflectionUtilError(ex); - } - } - - public static T newInstance(Constructor constructor, Object... initArgs) { - try { - return constructor.newInstance(initArgs); - } catch (ReflectiveOperationException ex) { - throw new ReflectionUtilError(ex); - } - } - - public static VarHandle unreflectField(Class declaringClass, String fieldName, MethodHandles.Lookup lookup) { - try { - Field field = LibGraalReflectionUtil.lookupField(declaringClass, fieldName); - MethodHandles.Lookup privateLookup = MethodHandles.privateLookupIn(declaringClass, lookup); - return privateLookup.unreflectVarHandle(field); - } catch (IllegalAccessException ex) { - throw new ReflectionUtilError(ex); - } - } - - public static Field lookupField(Class declaringClass, String fieldName) { - return lookupField(false, declaringClass, fieldName); - } - - private static final Method fieldGetDeclaredFields0 = LibGraalReflectionUtil.lookupMethod(Class.class, "getDeclaredFields0", boolean.class); - - public static Field lookupField(boolean optional, Class declaringClass, String fieldName) { - try { - Field result = declaringClass.getDeclaredField(fieldName); - openModule(declaringClass); - result.setAccessible(true); - return result; - } catch (ReflectiveOperationException ex) { - /* Try to get hidden field */ - try { - Field[] allFields = (Field[]) fieldGetDeclaredFields0.invoke(declaringClass, false); - for (Field field : allFields) { - if (field.getName().equals(fieldName)) { - openModule(declaringClass); - field.setAccessible(true); - return field; - } - } - } catch (ReflectiveOperationException e) { - // ignore - } - if (optional) { - return null; - } - throw new ReflectionUtilError(ex); - } - } - - @SuppressWarnings("unchecked") - public static T readField(Class declaringClass, String fieldName, Object receiver) { - try { - return (T) lookupField(declaringClass, fieldName).get(receiver); - } catch (ReflectiveOperationException ex) { - throw new ReflectionUtilError(ex); - } - } - - public static T readStaticField(Class declaringClass, String fieldName) { - return readField(declaringClass, fieldName, null); - } - - public static void writeField(Class declaringClass, String fieldName, Object receiver, Object value) { - try { - lookupField(declaringClass, fieldName).set(receiver, value); - } catch (ReflectiveOperationException ex) { - throw new ReflectionUtilError(ex); - } - } - - public static void writeStaticField(Class declaringClass, String fieldName, Object value) { - writeField(declaringClass, fieldName, null, value); - } -} diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalUtil.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalUtil.java new file mode 100644 index 000000000000..47bef7bdf885 --- /dev/null +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalUtil.java @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2019, 2019, 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.graal.hotspot.libgraal; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; + +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; + +import jdk.graal.compiler.debug.GraalError; +import jdk.internal.module.Modules; + +/** + * This is a copy of SVM internal classes such as {@code com.oracle.svm.util.ReflectionUtil} and + * {@code com.oracle.svm.util.ModuleSupport}. + */ +public final class LibGraalUtil { + + private LibGraalUtil() { + } + + // + // com.oracle.svm.util.ClassUtil methods + // + + /** + * Alternative to {@link Class#getSimpleName} that does not probe an enclosing class or method, + * which can fail when they cannot be loaded. + * + * Note the differences to {@link Class#getName} and {@link Class#getSimpleName} (which might + * actually be preferable): + * + *
    +     * Class.getName()                              Class.getSimpleName()   ClassUtil.getUnqualifiedName()
    +     * ---------------------------------------------------------------------------------------------------
    +     * int                                          int                     int
    +     * java.lang.String                             String                  String
    +     * [Ljava.lang.String;                          String[]                String[]
    +     * java.util.HashMap$EntrySet                   EntrySet                HashMap$EntrySet
    +     * com.example.ClassWithAnonymousInnerClass$1   ""                      ClassWithAnonymousInnerClass$1
    +     * 
    + */ + public static String getUnqualifiedName(Class clazz) { + String name = clazz.getTypeName(); + return name.substring(name.lastIndexOf('.') + 1); // strip the package name + } + + // + // com.oracle.svm.util.ReflectionUtil methods + // + + /** + * Ensure that this class is allowed to call setAccessible for an element of the provided + * declaring class. + */ + private static void openModule(Class declaringClass) { + accessModuleByClass(Access.OPEN, LibGraalUtil.class, declaringClass); + } + + public static Class lookupClass(String className) { + return lookupClass(false, className); + } + + public static Class lookupClass(boolean optional, String className) { + return lookupClass(optional, className, LibGraalUtil.class.getClassLoader()); + } + + public static Class lookupClass(boolean optional, String className, ClassLoader loader) { + try { + return Class.forName(className, false, loader); + } catch (ClassNotFoundException ex) { + if (optional) { + return null; + } + throw new GraalError(ex); + } + } + + public static Method lookupMethod(Class declaringClass, String methodName, Class... parameterTypes) { + return lookupMethod(false, declaringClass, methodName, parameterTypes); + } + + public static Method lookupMethod(boolean optional, Class declaringClass, String methodName, Class... parameterTypes) { + try { + Method result = declaringClass.getDeclaredMethod(methodName, parameterTypes); + openModule(declaringClass); + result.setAccessible(true); + return result; + } catch (ReflectiveOperationException ex) { + if (optional) { + return null; + } + throw new GraalError(ex); + } + } + + public static Constructor lookupConstructor(Class declaringClass, Class... parameterTypes) { + return lookupConstructor(false, declaringClass, parameterTypes); + } + + public static Constructor lookupConstructor(boolean optional, Class declaringClass, Class... parameterTypes) { + try { + Constructor result = declaringClass.getDeclaredConstructor(parameterTypes); + openModule(declaringClass); + result.setAccessible(true); + return result; + } catch (ReflectiveOperationException ex) { + if (optional) { + return null; + } + throw new GraalError(ex); + } + } + + public static T newInstance(Class declaringClass) { + try { + return lookupConstructor(declaringClass).newInstance(); + } catch (ReflectiveOperationException ex) { + throw new GraalError(ex); + } + } + + public static Field lookupField(Class declaringClass, String fieldName) { + return lookupField(false, declaringClass, fieldName); + } + + private static final Method fieldGetDeclaredFields0 = lookupMethod(Class.class, "getDeclaredFields0", boolean.class); + + public static Field lookupField(boolean optional, Class declaringClass, String fieldName) { + try { + Field result = declaringClass.getDeclaredField(fieldName); + openModule(declaringClass); + result.setAccessible(true); + return result; + } catch (ReflectiveOperationException ex) { + /* Try to get hidden field */ + try { + Field[] allFields = (Field[]) fieldGetDeclaredFields0.invoke(declaringClass, false); + for (Field field : allFields) { + if (field.getName().equals(fieldName)) { + openModule(declaringClass); + field.setAccessible(true); + return field; + } + } + } catch (ReflectiveOperationException e) { + // ignore + } + if (optional) { + return null; + } + throw new GraalError(ex); + } + } + + @SuppressWarnings("unchecked") + public static T readField(Class declaringClass, String fieldName, Object receiver) { + try { + return (T) lookupField(declaringClass, fieldName).get(receiver); + } catch (ReflectiveOperationException ex) { + throw new GraalError(ex); + } + } + + // + // com.oracle.svm.util.ModuleSupport methods + // + + @Platforms(Platform.HOSTED_ONLY.class) + public enum Access { + OPEN { + @Override + void giveAccess(Module accessingModule, Module declaringModule, String packageName) { + if (accessingModule != null) { + if (declaringModule.isOpen(packageName, accessingModule)) { + return; + } + Modules.addOpens(declaringModule, packageName, accessingModule); + } else { + if (declaringModule.isOpen(packageName)) { + return; + } + Modules.addOpensToAllUnnamed(declaringModule, packageName); + } + } + }, + EXPORT { + @Override + void giveAccess(Module accessingModule, Module declaringModule, String packageName) { + if (accessingModule != null) { + if (declaringModule.isExported(packageName, accessingModule)) { + return; + } + Modules.addExports(declaringModule, packageName, accessingModule); + } else { + if (declaringModule.isExported(packageName)) { + return; + } + Modules.addExportsToAllUnnamed(declaringModule, packageName); + } + } + }; + + abstract void giveAccess(Module accessingModule, Module declaringModule, String packageName); + } + + @Platforms(Platform.HOSTED_ONLY.class) + public static void accessModuleByClass(Access access, Class accessingClass, Class declaringClass) { + accessModuleByClass(access, accessingClass, declaringClass.getModule(), declaringClass.getPackageName()); + } + + /** + * Open or export packages {@code packageNames} in the module named {@code moduleName} to module + * of given {@code accessingClass}. If {@code accessingClass} is null packages are opened or + * exported to ALL-UNNAMED. If no packages are given, all packages of the module are opened or + * exported. + */ + @Platforms(Platform.HOSTED_ONLY.class) + public static void accessPackagesToClass(Access access, Class accessingClass, boolean optional, String moduleName, String... packageNames) { + Objects.requireNonNull(moduleName); + Optional module = ModuleLayer.boot().findModule(moduleName); + if (module.isEmpty()) { + if (optional) { + return; + } + String accessor = accessingClass != null ? "class " + accessingClass.getTypeName() : "ALL-UNNAMED"; + String message = access.name().toLowerCase() + " of packages from module " + moduleName + " to " + + accessor + " failed. No module named " + moduleName + " in boot layer."; + throw new GraalError(message); + } + Module declaringModule = module.get(); + Objects.requireNonNull(packageNames); + Set packages = packageNames.length > 0 ? Set.of(packageNames) : declaringModule.getPackages(); + for (String packageName : packages) { + accessModuleByClass(access, accessingClass, declaringModule, packageName); + } + } + + @Platforms(Platform.HOSTED_ONLY.class) + public static void accessModuleByClass(Access access, Class accessingClass, Module declaringModule, String packageName) { + Module namedAccessingModule = null; + if (accessingClass != null) { + Module accessingModule = accessingClass.getModule(); + if (accessingModule.isNamed()) { + namedAccessingModule = accessingModule; + } + } + access.giveAccess(namedAccessingModule, declaringModule, packageName); + } +} From 7850342112079459c2fdfaaaa271cf86c12a989f Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Sat, 30 Nov 2024 17:12:46 +0100 Subject: [PATCH 07/31] tmp --- .../hotspot/HotSpotGraalCompiler.java | 9 +++++- .../compiler/hotspot/HotSpotGraalRuntime.java | 8 +++-- .../compiler/serviceprovider/VMSupport.java | 22 ------------- .../jdk.graal.nativeimage/snapshot.sigtest | 1 + .../graal/nativeimage/LibGraalRuntime.java | 4 +++ .../impl/LibGraalRuntimeSupport.java | 2 ++ .../oracle/svm/core/jdk/RuntimeSupport.java | 5 +++ .../hotspot/libgraal/LibGraalEntryPoints.java | 1 - .../libgraal/LibGraalSubstitutions.java | 31 +++---------------- 9 files changed, 30 insertions(+), 53 deletions(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalCompiler.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalCompiler.java index d4be1177024d..977ef57e3a73 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalCompiler.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalCompiler.java @@ -64,6 +64,7 @@ import jdk.graal.compiler.printer.GraalDebugHandlersFactory; import jdk.graal.compiler.serviceprovider.GlobalAtomicLong; import jdk.graal.compiler.serviceprovider.VMSupport; +import jdk.graal.nativeimage.LibGraalRuntime; import jdk.internal.misc.Unsafe; import jdk.vm.ci.code.CompilationRequest; import jdk.vm.ci.code.CompilationRequestResult; @@ -386,7 +387,13 @@ public boolean notifyCrash(OptionValues options, String crashMessage) { } else { int crashAtIsFatal = HotSpotGraalCompiler.Options.CrashAtIsFatal.getValue(options); if (crashAtIsFatal != 0) { - VMSupport.fatalError(crashMessage, crashAtIsFatal); + try { + Thread.sleep(crashAtIsFatal); + } catch (InterruptedException e) { + // ignore + } + LibGraalRuntime.fatalError(crashMessage); + // If changing this message, update the test for it in mx_vm_gate.py System.out.println("CrashAtIsFatal: no fatalError function pointer installed"); } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalRuntime.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalRuntime.java index ea73421d8dd4..0af0d793dce5 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalRuntime.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalRuntime.java @@ -76,6 +76,7 @@ import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.runtime.JVMCIBackend; +import org.graalvm.nativeimage.VMRuntime; //JaCoCo Exclude @@ -194,7 +195,9 @@ public GlobalMetrics getMetricValues() { this.compilerProfiler = GraalServices.loadSingle(CompilerProfiler.class, false); - VMSupport.startupLibGraal(); + if (ImageInfo.inImageRuntimeCode()) { + VMRuntime.initialize(); + } } /** @@ -429,9 +432,10 @@ synchronized void shutdown() { } String cbClassName = callback.substring(0, lastDot); String cbMethodName = callback.substring(lastDot + 1); + VMSupport.invokeShutdownCallback(cbClassName, cbMethodName); } - VMSupport.shutdownLibGraal(); + VMRuntime.initialize(); } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/VMSupport.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/VMSupport.java index 7cde1693cb7d..e9c0e38156bf 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/VMSupport.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/VMSupport.java @@ -38,28 +38,6 @@ public static AutoCloseable getCompilationRequestScope() { return null; } - /** - * Notifies that a fatal error has occurred. - * - * @param message description of the error - * @param delayMS milliseconds to sleep before exiting the VM - */ - public static void fatalError(String message, int delayMS) { - - } - - /** - * Notifies libgraal when a Graal runtime is being started. - */ - public static void startupLibGraal() { - } - - /** - * Notifies libgraal when a Graal runtime is being shutdown. - */ - public static void shutdownLibGraal() { - } - /** * @param cbClassName name of class declaring the call back method * @param cbMethodName name of the call back method diff --git a/compiler/src/jdk.graal.nativeimage/snapshot.sigtest b/compiler/src/jdk.graal.nativeimage/snapshot.sigtest index af2e39279757..377308f93d8a 100644 --- a/compiler/src/jdk.graal.nativeimage/snapshot.sigtest +++ b/compiler/src/jdk.graal.nativeimage/snapshot.sigtest @@ -15,6 +15,7 @@ CLSS public final jdk.graal.nativeimage.LibGraalRuntime meth public static long getIsolateID() meth public static void notifyLowMemoryPoint(boolean) meth public static void processReferences() +meth public static void fatalError(java.lang.String) supr java.lang.Object CLSS public final jdk.graal.nativeimage.hosted.GlobalData diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java index 39d30cb2a94c..4a011bbfae5d 100644 --- a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java @@ -75,6 +75,10 @@ public static long getIsolateID() { return ImageSingletons.lookup(LibGraalRuntimeSupport.class).getIsolateID(); } + public static void fatalError(String message) { + ImageSingletons.lookup(LibGraalRuntimeSupport.class).fatalError(message); + } + private LibGraalRuntime() { } } diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/impl/LibGraalRuntimeSupport.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/impl/LibGraalRuntimeSupport.java index c9cf75e57eae..d8572ce02120 100644 --- a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/impl/LibGraalRuntimeSupport.java +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/impl/LibGraalRuntimeSupport.java @@ -31,4 +31,6 @@ public interface LibGraalRuntimeSupport { void notifyLowMemoryPoint(boolean suggestFullGC); long getIsolateID(); + + void fatalError(String message); } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RuntimeSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RuntimeSupport.java index 2a2df3be11da..bbc6bc04e7b3 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RuntimeSupport.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RuntimeSupport.java @@ -63,6 +63,11 @@ public long getIsolateID() { return ImageSingletons.lookup(IsolateSupport.class).getIsolateID(); } + @Override + public void fatalError(String message) { + throw VMError.shouldNotReachHere(message); + } + @FunctionalInterface public interface Hook { void execute(boolean isFirstIsolate); diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java index 7ee2acf75d6b..5e4d9e230fd7 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java @@ -77,7 +77,6 @@ import org.graalvm.nativeimage.ObjectHandles; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; -import org.graalvm.nativeimage.RuntimeOptions; import org.graalvm.nativeimage.c.function.CEntryPoint; import org.graalvm.nativeimage.c.function.CEntryPoint.Builtin; import org.graalvm.nativeimage.c.function.CEntryPoint.IsolateContext; diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalSubstitutions.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalSubstitutions.java index 06d03bcdd22f..2575d56a4d80 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalSubstitutions.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalSubstitutions.java @@ -29,17 +29,15 @@ import java.util.Map; import java.util.function.Supplier; +import jdk.graal.nativeimage.LibGraalRuntime; import org.graalvm.jniutils.JNI; import org.graalvm.jniutils.JNIExceptionWrapper; import org.graalvm.jniutils.JNIMethodScope; import org.graalvm.jniutils.JNIUtil; import org.graalvm.nativeimage.ImageSingletons; -import org.graalvm.nativeimage.LogHandler; import org.graalvm.nativeimage.Platform.HOSTED_ONLY; import org.graalvm.nativeimage.Platforms; import org.graalvm.nativeimage.StackValue; -import org.graalvm.nativeimage.VMRuntime; -import org.graalvm.nativeimage.hosted.FieldValueTransformer; import com.oracle.svm.core.annotate.Alias; import com.oracle.svm.core.annotate.RecomputeFieldValue; @@ -201,29 +199,6 @@ public static AutoCloseable getCompilationRequestScope() { return new LibGraalCompilationRequestScope(); } - @Substitute - public static void fatalError(String message, int delayMS) { - LogHandler handler = ImageSingletons.lookup(LogHandler.class); - if (handler instanceof FunctionPointerLogHandler) { - try { - Thread.sleep(delayMS); - } catch (InterruptedException e) { - // ignore - } - GraalError.shouldNotReachHere(message); - } - } - - @Substitute - public static void startupLibGraal() { - VMRuntime.initialize(); - } - - @Substitute - public static void shutdownLibGraal() { - VMRuntime.shutdown(); - } - @Substitute public static void invokeShutdownCallback(String cbClassName, String cbMethodName) { JNI.JNIEnv env = LibGraalEntryPoints.getJNIEnv(); @@ -276,7 +251,9 @@ class LibGraalClassLoaderSupplier implements Supplier { @Override public ClassLoader get() { ClassLoader loader = ImageSingletons.lookup(LibGraalFeature.class).loader; - GraalError.guarantee(loader != null, "NPE"); + if (loader == null) { + LibGraalRuntime.fatalError("loader is null"); + } return loader; } } From 9fdeb36b2f18073e73418b5b833856fc0965b2f1 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Sun, 1 Dec 2024 20:37:33 +0100 Subject: [PATCH 08/31] remove reference to SVM options --- compiler/mx.compiler/suite.py | 2 + .../graal/compiler/options/OptionValues.java | 60 +++++++-------- .../graal/compiler/options/OptionsParser.java | 3 + sdk/mx.sdk/mx_sdk.py | 4 +- .../hotspot/libgraal/LibGraalEntryPoints.java | 75 +++++++++---------- .../hotspot/libgraal/LibGraalFeature.java | 7 +- 6 files changed, 74 insertions(+), 77 deletions(-) diff --git a/compiler/mx.compiler/suite.py b/compiler/mx.compiler/suite.py index 3f7bf49dfbcf..9b9351e28c3d 100644 --- a/compiler/mx.compiler/suite.py +++ b/compiler/mx.compiler/suite.py @@ -180,6 +180,7 @@ "sourceDirs" : ["src"], "dependencies" : [ "GRAAL_NATIVEIMAGE", + "sdk:JNIUTILS", "sdk:WORD", "sdk:COLLECTIONS", "sdk:NATIVEIMAGE", @@ -645,6 +646,7 @@ "sdk:COLLECTIONS", "sdk:WORD", "sdk:NATIVEIMAGE", + "sdk:JNIUTILS", "truffle:TRUFFLE_COMPILER", ], "allowsJavadocWarnings": True, diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/options/OptionValues.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/options/OptionValues.java index 19a5b7efa424..bec6a4150c97 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/options/OptionValues.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/options/OptionValues.java @@ -204,43 +204,42 @@ public void printHelp(Iterable loader, PrintStream out, Strin assert existing == null || existing == desc : "Option named \"" + name + "\" has multiple definitions: " + existing.getLocation() + " and " + desc.getLocation(); } } - int size = 0; - if (all) { - size = sortedOptions.entrySet().size(); - } else { - for (Map.Entry e : sortedOptions.entrySet()) { - OptionDescriptor desc = e.getValue(); - if (!excludeOptionFromHelp(desc)) { - size++; - } - } - } - int i = 0; for (Map.Entry e : sortedOptions.entrySet()) { String key = e.getKey(); OptionDescriptor desc = e.getValue(); if (all || !excludeOptionFromHelp(desc)) { - printHelp(out, namePrefix, key, desc); - if (i++ != size - 1) { - // print new line between options - out.printf("%n"); - } + String edition = String.format("[%s edition]", OptionsParser.isEnterpriseOption(desc) ? "enterprise" : "community"); + printHelp(out, namePrefix, + key, + desc.getOptionKey().getValue(this), + desc.getOptionValueType(), + containsKey(desc.getOptionKey()) ? ":=" : "=", + edition, + desc.getHelp(), + desc.getExtraHelp()); } } } - private void printHelp(PrintStream out, String namePrefix, String key, OptionDescriptor desc) { - Object value = desc.getOptionKey().getValue(this); - if (value instanceof String) { - value = '"' + String.valueOf(value) + '"'; + private static Object quoteNonNullString(Class valueType, Object value) { + if (valueType == String.class && value != null) { + return '"' + String.valueOf(value) + '"'; } - String name = namePrefix + key; - String assign = containsKey(desc.getOptionKey()) ? ":=" : "="; - String typeName = desc.getOptionKey() instanceof EnumOptionKey ? "String" : desc.getOptionValueType().getSimpleName(); + return value; + } - String edition = String.format("[%s edition]", OptionsParser.isEnterpriseOption(desc) ? "enterprise" : "community"); - String linePrefix = String.format("%s %s %s %s", name, assign, value, edition); + public static void printHelp(PrintStream out, String namePrefix, + String key, + Object value, + Class valueType, + String assign, + String edition, + String help, + List extraHelp) { + String name = namePrefix + key; + String linePrefix = String.format("%s %s %s %s", name, assign, quoteNonNullString(valueType, value), edition); + String typeName = valueType.isEnum() ? "String" : valueType.getSimpleName(); int typeStartPos = PROPERTY_LINE_WIDTH - typeName.length(); int linePad = typeStartPos - linePrefix.length(); if (linePad > 0) { @@ -250,16 +249,17 @@ private void printHelp(PrintStream out, String namePrefix, String key, OptionDes } List helpLines; - String help = desc.getHelp(); - if (help.length() != 0) { + if (!help.isEmpty()) { helpLines = wrap(help, PROPERTY_LINE_WIDTH - PROPERTY_HELP_INDENT); - helpLines.addAll(desc.getExtraHelp()); + helpLines.addAll(extraHelp); } else { - helpLines = desc.getExtraHelp(); + helpLines = extraHelp; } for (String line : helpLines) { out.printf("%" + PROPERTY_HELP_INDENT + "s%s%n", "", line); } + // print new line after each option + out.printf("%n"); } private static boolean excludeOptionFromHelp(OptionDescriptor desc) { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/options/OptionsParser.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/options/OptionsParser.java index e6980336fe20..4456fdebe1ee 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/options/OptionsParser.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/options/OptionsParser.java @@ -358,6 +358,9 @@ public static boolean collectFuzzyMatches(Iterable toSearch, S static boolean isEnterpriseOption(OptionDescriptor desc) { if (inImageRuntimeCode()) { + if (libgraalOptions == null) { + return false; + } return Objects.requireNonNull(libgraalOptions.enterpriseOptions, "missing options").contains(desc.getName()); } Class declaringClass = desc.getDeclaringClass(); diff --git a/sdk/mx.sdk/mx_sdk.py b/sdk/mx.sdk/mx_sdk.py index 68982d10b4bc..0824f5aadd05 100644 --- a/sdk/mx.sdk/mx_sdk.py +++ b/sdk/mx.sdk/mx_sdk.py @@ -133,7 +133,7 @@ def upx(args): ) mx_sdk_vm.register_graalvm_component(graalvm_sdk_component) -# SDK modules included the compiler is included +# SDK modules included if the compiler is included graal_sdk_compiler_component = mx_sdk_vm.GraalVmJreComponent( suite=_suite, name='Graal SDK Compiler', @@ -143,7 +143,7 @@ def upx(args): third_party_license_files=[], dependencies=[], jar_distributions=[], - boot_jars=['sdk:WORD', 'sdk:COLLECTIONS', 'sdk:NATIVEIMAGE'], + boot_jars=['sdk:WORD', 'sdk:COLLECTIONS', 'sdk:NATIVEIMAGE', 'sdk:JNIUTILS'], stability="supported", ) mx_sdk_vm.register_graalvm_component(graal_sdk_compiler_component) diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java index 5e4d9e230fd7..d22851149e7b 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java @@ -32,7 +32,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; -import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; @@ -40,25 +40,17 @@ import java.util.function.BiConsumer; import java.util.stream.Collectors; -import com.oracle.svm.core.heap.UnknownObjectField; -import com.oracle.svm.core.option.RuntimeOptionValues; -import com.oracle.svm.core.option.XOptions; import com.oracle.truffle.compiler.TruffleCompilerOptionDescriptor; import com.oracle.truffle.compiler.hotspot.libgraal.TruffleToLibGraal; import com.oracle.truffle.compiler.hotspot.libgraal.TruffleToLibGraal.Id; import jdk.graal.compiler.debug.GraalError; import jdk.graal.compiler.hotspot.libgraal.BuildTime; import jdk.graal.compiler.hotspot.libgraal.RunTime; -import jdk.graal.compiler.options.OptionDescriptor; -import jdk.graal.compiler.options.OptionDescriptors; -import jdk.graal.compiler.options.OptionDescriptorsMap; -import jdk.graal.compiler.options.OptionKey; import jdk.graal.compiler.options.OptionValues; -import jdk.graal.compiler.options.OptionsParser; -import jdk.graal.compiler.word.Word; import jdk.graal.compiler.serviceprovider.IsolateUtil; -import org.graalvm.collections.EconomicMap; +import jdk.graal.compiler.word.Word; import jdk.graal.nativeimage.LibGraalRuntime; +import org.graalvm.collections.EconomicSet; import org.graalvm.jniutils.HSObject; import org.graalvm.jniutils.JNI; import org.graalvm.jniutils.JNI.JByteArray; @@ -77,6 +69,7 @@ import org.graalvm.nativeimage.ObjectHandles; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; +import org.graalvm.nativeimage.RuntimeOptions; import org.graalvm.nativeimage.c.function.CEntryPoint; import org.graalvm.nativeimage.c.function.CEntryPoint.Builtin; import org.graalvm.nativeimage.c.function.CEntryPoint.IsolateContext; @@ -309,45 +302,45 @@ static void doReferenceHandling() { } } - /** - * Options configuring the VM in which libgraal is running. - */ - @UnknownObjectField(fullyQualifiedTypes = "org.graalvm.collections.EconomicMapImpl") // - static EconomicMap vmOptionDescriptors = EconomicMap.create(); + static EconomicSet explicitOptions = EconomicSet.create(); static void initializeOptions(Map settings) { - EconomicMap nonXSettings = processXOptions(settings); - EconomicMap, Object> vmOptionValues = OptionValues.newOptionMap(); - Iterable vmOptionLoader = List.of(new OptionDescriptorsMap(vmOptionDescriptors)); - OptionsParser.parseOptions(nonXSettings, vmOptionValues, vmOptionLoader); - RuntimeOptionValues.singleton().update(vmOptionValues); - } - - /** - * Extracts and processes the {@link XOptions} in {@code settings}. - * - * @return the entries in {@code settings} that do not correspond to {@link XOptions} - */ - private static EconomicMap processXOptions(Map settings) { - EconomicMap nonXSettings = EconomicMap.create(settings.size()); for (var e : settings.entrySet()) { - String key = e.getKey(); - String value = e.getValue(); - if (key.startsWith("X") && value.isEmpty()) { - String xarg = key.substring(1); - if (XOptions.setOption(xarg)) { - continue; + String name = e.getKey(); + String stringValue = e.getValue(); + Object value; + if (name.startsWith("X") && stringValue.isEmpty()) { + name = name.substring(1); + value = stringValue; + } else { + RuntimeOptions.Descriptor desc = RuntimeOptions.getDescriptor(name); + if (desc == null) { + throw new IllegalArgumentException("Could not find option " + name); } + value = desc.convertValue(stringValue); + explicitOptions.add(name); + } + try { + RuntimeOptions.set(name, value); + } catch (RuntimeException ex) { + throw new IllegalArgumentException(ex); } - nonXSettings.put(key, value); } - return nonXSettings; } static void printOptions(PrintStream out, String prefix) { - RuntimeOptionValues vmOptions = RuntimeOptionValues.singleton(); - Iterable vmOptionLoader = Collections.singletonList(new OptionDescriptorsMap(vmOptionDescriptors)); - vmOptions.printHelp(vmOptionLoader, out, prefix, true); + Comparator comparator = Comparator.comparing(RuntimeOptions.Descriptor::name); + RuntimeOptions.listDescriptors().stream().sorted(comparator).forEach(d -> { + String assign = explicitOptions.contains(d.name()) ? ":=" : "="; + OptionValues.printHelp(out, prefix, + d.name(), + RuntimeOptions.get(d.name()), + d.valueType(), + assign, + "[community edition]", + d.help(), + List.of()); + }); } } diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java index 73e8361d5acc..848889866536 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java @@ -215,7 +215,7 @@ public void duringSetup(DuringSetupAccess access) { ClassLoader runtimeLoader = libgraalLoader.getRuntimeClassLoader(); access.registerObjectReplacer(obj -> obj == loader ? runtimeLoader : obj); - optionCollector = new OptionCollector(LibGraalEntryPoints.vmOptionDescriptors); + optionCollector = new OptionCollector(); access.registerObjectReachabilityHandler(optionCollector::accept, OptionKey.class); access.registerObjectReachabilityHandler(optionCollector::accept, loadClassOrFail(OptionKey.class)); GetJNIConfig.register(loader); @@ -236,7 +236,7 @@ private class OptionCollector implements Consumer { /** * Libgraal VM options. */ - private final EconomicMap vmOptionDescriptors; + private final EconomicMap vmOptionDescriptors = EconomicMap.create(); /** * Libgraal compiler options info. @@ -245,8 +245,7 @@ private class OptionCollector implements Consumer { private boolean sealed; - OptionCollector(EconomicMap vmOptionDescriptors) { - this.vmOptionDescriptors = vmOptionDescriptors; + OptionCollector() { try { MethodType mt = methodType(Object.class); MethodHandle mh = mhl.findStatic(buildTimeClass, "initLibgraalOptions", mt); From a851544554425d0d1aeac3b2bfb88ff5f1249faf Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Tue, 3 Dec 2024 11:35:29 +0100 Subject: [PATCH 09/31] move libgraal into compiler --- compiler/mx.compiler/suite.py | 6 +- .../compiler}/libgraal/FromLibGraalCalls.java | 2 +- .../compiler}/libgraal/GetCompilerConfig.java | 9 +- .../compiler}/libgraal/GetJNIConfig.java | 39 +++--- .../graal/compiler}/libgraal/JDKLatest.java | 2 +- .../libgraal/LibGraalEntryPoints.java | 2 +- .../compiler}/libgraal/LibGraalFeature.java | 113 +++++------------- .../libgraal/LibGraalJNIMethodScope.java | 2 +- .../libgraal/LibGraalNativeBridgeSupport.java | 2 +- .../libgraal/LibGraalObjectHandleScope.java | 2 +- .../libgraal/LibGraalObjectHandles.java | 2 +- .../libgraal/LibGraalSubstitutions.java | 9 +- .../compiler}/libgraal/LibGraalUtil.java | 2 +- .../libgraal/NativeImageHostEntryPoints.java | 2 +- .../libgraal/TruffleFromLibGraalCalls.java | 2 +- .../TruffleFromLibGraalStartPoints.java | 100 ++++++++-------- sdk/mx.sdk/mx_sdk.py | 10 +- substratevm/mx.substratevm/mx_substratevm.py | 10 +- substratevm/mx.substratevm/suite.py | 55 --------- 19 files changed, 137 insertions(+), 234 deletions(-) rename {substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot => compiler/src/jdk.graal.compiler/src/jdk/graal/compiler}/libgraal/FromLibGraalCalls.java (99%) rename {substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot => compiler/src/jdk.graal.compiler/src/jdk/graal/compiler}/libgraal/GetCompilerConfig.java (95%) rename {substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot => compiler/src/jdk.graal.compiler/src/jdk/graal/compiler}/libgraal/GetJNIConfig.java (89%) rename {substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot => compiler/src/jdk.graal.compiler/src/jdk/graal/compiler}/libgraal/JDKLatest.java (97%) rename {substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot => compiler/src/jdk.graal.compiler/src/jdk/graal/compiler}/libgraal/LibGraalEntryPoints.java (99%) rename {substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot => compiler/src/jdk.graal.compiler/src/jdk/graal/compiler}/libgraal/LibGraalFeature.java (81%) rename {substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot => compiler/src/jdk.graal.compiler/src/jdk/graal/compiler}/libgraal/LibGraalJNIMethodScope.java (98%) rename {substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot => compiler/src/jdk.graal.compiler/src/jdk/graal/compiler}/libgraal/LibGraalNativeBridgeSupport.java (98%) rename {substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot => compiler/src/jdk.graal.compiler/src/jdk/graal/compiler}/libgraal/LibGraalObjectHandleScope.java (97%) rename {substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot => compiler/src/jdk.graal.compiler/src/jdk/graal/compiler}/libgraal/LibGraalObjectHandles.java (98%) rename {substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot => compiler/src/jdk.graal.compiler/src/jdk/graal/compiler}/libgraal/LibGraalSubstitutions.java (96%) rename {substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot => compiler/src/jdk.graal.compiler/src/jdk/graal/compiler}/libgraal/LibGraalUtil.java (99%) rename {substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot => compiler/src/jdk.graal.compiler/src/jdk/graal/compiler}/libgraal/NativeImageHostEntryPoints.java (98%) rename {substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot => compiler/src/jdk.graal.compiler/src/jdk/graal/compiler}/libgraal/TruffleFromLibGraalCalls.java (97%) rename {substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot => compiler/src/jdk.graal.compiler/src/jdk/graal/compiler}/libgraal/TruffleFromLibGraalStartPoints.java (80%) diff --git a/compiler/mx.compiler/suite.py b/compiler/mx.compiler/suite.py index 9b9351e28c3d..c535387a507f 100644 --- a/compiler/mx.compiler/suite.py +++ b/compiler/mx.compiler/suite.py @@ -184,6 +184,7 @@ "sdk:WORD", "sdk:COLLECTIONS", "sdk:NATIVEIMAGE", + "sdk:NATIVEBRIDGE", "truffle:TRUFFLE_COMPILER", ], "requires" : [ @@ -192,6 +193,7 @@ ], "requiresConcealed" : { "java.base" : [ + "jdk.internal.module", "jdk.internal.misc" ], "jdk.internal.vm.ci" : [ @@ -222,7 +224,8 @@ "jdk.graal.compiler.truffle.substitutions.GraphDecoderInvocationPluginProvider" ], "annotationProcessors" : [ - "GRAAL_PROCESSOR" + "GRAAL_PROCESSOR", + "truffle:TRUFFLE_LIBGRAAL_PROCESSOR", ], "checkPackagePrefix": "false", "checkstyleVersion" : "10.21.0", @@ -646,6 +649,7 @@ "sdk:COLLECTIONS", "sdk:WORD", "sdk:NATIVEIMAGE", + "sdk:NATIVEBRIDGE", "sdk:JNIUTILS", "truffle:TRUFFLE_COMPILER", ], diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/FromLibGraalCalls.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/FromLibGraalCalls.java similarity index 99% rename from substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/FromLibGraalCalls.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/FromLibGraalCalls.java index d774f3286525..127175d7e07a 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/FromLibGraalCalls.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/FromLibGraalCalls.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.graal.hotspot.libgraal; +package jdk.graal.compiler.libgraal; import com.oracle.truffle.compiler.hotspot.libgraal.FromLibGraalId; import org.graalvm.jniutils.JNI.JClass; diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/GetCompilerConfig.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetCompilerConfig.java similarity index 95% rename from substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/GetCompilerConfig.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetCompilerConfig.java index 8fdb736193ca..9cab296cd527 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/GetCompilerConfig.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetCompilerConfig.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.graal.hotspot.libgraal; +package jdk.graal.compiler.libgraal; import java.io.BufferedReader; import java.io.IOException; @@ -112,15 +112,16 @@ public static Result from(Path javaHome) { "-XX:+UnlockExperimentalVMOptions", "-XX:+EnableJVMCI", "-XX:-UseJVMCICompiler", // avoid deadlock with jargraal + + // Required to use Modules class + "--add-exports=java.base/jdk.internal.module=jdk.graal.compiler", addExports, "-Djdk.vm.ci.services.aot=true", "-D%s=%s".formatted(ImageInfo.PROPERTY_IMAGE_CODE_KEY, ImageInfo.PROPERTY_IMAGE_CODE_VALUE_BUILDTIME))); - Module module = ObjectCopier.class.getModule(); - String target = module.isNamed() ? module.getName() : "ALL-UNNAMED"; for (var e : opens.entrySet()) { for (String source : e.getValue()) { - command.add("--add-opens=%s/%s=%s".formatted(e.getKey(), source, target)); + command.add("--add-opens=%s/%s=jdk.graal.compiler".formatted(e.getKey(), source)); } } diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/GetJNIConfig.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetJNIConfig.java similarity index 89% rename from substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/GetJNIConfig.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetJNIConfig.java index 5ce365ca0cf2..2091cc717936 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/GetJNIConfig.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetJNIConfig.java @@ -22,9 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.graal.hotspot.libgraal; - -import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; +package jdk.graal.compiler.libgraal; import java.io.BufferedReader; import java.io.IOException; @@ -34,6 +32,7 @@ import java.lang.reflect.Modifier; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -41,13 +40,11 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.graal.compiler.util.SignatureUtil; import org.graalvm.nativeimage.hosted.RuntimeJNIAccess; import org.graalvm.nativeimage.hosted.RuntimeReflection; import jdk.graal.compiler.debug.GraalError; -import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; -import jdk.vm.ci.hotspot.HotSpotSignature; -import jdk.vm.ci.meta.JavaType; /** * Registers the JNI configuration for libgraal by parsing the output of the @@ -137,14 +134,23 @@ public void close() { public static Class forPrimitive(String name) { return switch (name) { + case "Z" -> boolean.class; case "boolean" -> boolean.class; + case "C" -> char.class; case "char" -> char.class; + case "F" -> float.class; case "float" -> float.class; + case "D" -> double.class; case "double" -> double.class; + case "B" -> byte.class; case "byte" -> byte.class; + case "S" -> short.class; case "short" -> short.class; + case "I" -> int.class; case "int" -> int.class; + case "J" -> long.class; case "long" -> long.class; + case "V" -> void.class; case "void" -> void.class; default -> null; }; @@ -162,7 +168,12 @@ private Class findClass(String name) { try { return Class.forName(internalName, false, loader); } catch (ClassNotFoundException e) { - throw new GraalError(e, "Cannot find class during LibGraal JNIConfiguration registration"); + String externalName = internalName.replace('/', '.'); + try { + return Class.forName(externalName, false, loader); + } catch (ClassNotFoundException e3) { + } + throw new GraalError(e, "Cannot find class %s during LibGraal JNIConfiguration registration", name); } } @@ -225,13 +236,13 @@ public static void register(ClassLoader loader) { case "method": { source.check(tokens.length == 4, "Expected 4 tokens for a method"); String methodName = tokens[2]; - HotSpotJVMCIRuntime runtime = runtime(); String signature = tokens[3]; - HotSpotSignature descriptor = new HotSpotSignature(runtime, signature); - Class[] parameters = Stream.of(descriptor.toParameterTypes(null))// - .map(JavaType::toClassName).map(source::findClass)// + ArrayList buffer = new ArrayList<>(); + SignatureUtil.parseSignature(signature, buffer); + Class[] parameters = buffer.stream()// + .map(source::findClass)// .toList()// - .toArray(new Class[descriptor.getParameterCount(false)]); + .toArray(new Class[0]); assert Arrays.stream(parameters).allMatch(pclazz -> pclazz.getClassLoader() == null || pclazz.getClassLoader() == loader); try { if ("".equals(methodName)) { @@ -247,9 +258,9 @@ public static void register(ClassLoader loader) { RuntimeJNIAccess.register(clazz.getDeclaredMethod(methodName, parameters)); } } catch (NoSuchMethodException e) { - throw source.error("Method %s.%s%s not found: %s", clazz.getTypeName(), methodName, descriptor, e); + throw source.error("Method %s.%s%s not found: %s", clazz.getTypeName(), methodName, signature, e); } catch (NoClassDefFoundError e) { - throw source.error("Could not register method %s.%s%s: %s", clazz.getTypeName(), methodName, descriptor, e); + throw source.error("Could not register method %s.%s%s: %s", clazz.getTypeName(), methodName, signature, e); } break; } diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/JDKLatest.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/JDKLatest.java similarity index 97% rename from substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/JDKLatest.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/JDKLatest.java index 8f7a6dd70cd5..c1fc04af3e67 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/JDKLatest.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/JDKLatest.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.graal.hotspot.libgraal; +package jdk.graal.compiler.libgraal; import java.util.function.BooleanSupplier; diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalEntryPoints.java similarity index 99% rename from substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalEntryPoints.java index d22851149e7b..5896b34480ea 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalEntryPoints.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalEntryPoints.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.graal.hotspot.libgraal; +package jdk.graal.compiler.libgraal; import java.io.ByteArrayOutputStream; import java.io.PrintStream; diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java similarity index 81% rename from substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java index 848889866536..266a269b7325 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java @@ -22,9 +22,10 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.graal.hotspot.libgraal; +package jdk.graal.compiler.libgraal; import static java.lang.invoke.MethodType.methodType; +import static jdk.graal.compiler.serviceprovider.GraalServices.getSavedProperty; import java.lang.annotation.Annotation; import java.lang.invoke.MethodHandle; @@ -46,6 +47,7 @@ import java.util.function.Consumer; import java.util.regex.Pattern; +import jdk.vm.ci.code.Architecture; import org.graalvm.collections.EconomicMap; import org.graalvm.jniutils.NativeBridgeSupport; import org.graalvm.nativeimage.ImageSingletons; @@ -56,12 +58,6 @@ import org.graalvm.nativeimage.hosted.RuntimeClassInitialization; import org.graalvm.nativeimage.hosted.RuntimeReflection; -import com.oracle.graal.pointsto.BigBang; -import com.oracle.graal.pointsto.meta.AnalysisType; -import com.oracle.graal.pointsto.reports.CallTreePrinter; -import com.oracle.svm.core.hub.ClassForNameSupport; -import com.oracle.svm.hosted.FeatureImpl.AfterAnalysisAccessImpl; - import jdk.graal.compiler.core.common.Fields; import jdk.graal.compiler.debug.DebugContext; import jdk.graal.compiler.debug.GraalError; @@ -76,8 +72,6 @@ import jdk.graal.nativeimage.LibGraalFeatureComponent; import jdk.graal.nativeimage.LibGraalLoader; import jdk.graal.nativeimage.hosted.GlobalData; -import jdk.vm.ci.code.Architecture; -import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; import jdk.vm.ci.hotspot.HotSpotModifiers; /** @@ -176,9 +170,8 @@ public void afterRegistration(AfterRegistrationAccess access) { ImageSingletons.add(NativeBridgeSupport.class, new LibGraalNativeBridgeSupport()); - libgraalLoader = createHostedLibGraalClassLoader(access); + libgraalLoader = (LibGraalLoader) getClass().getClassLoader();// createHostedLibGraalClassLoader(access); loader = libgraalLoader.getClassLoader(); - ImageSingletons.lookup(ClassForNameSupport.class).setLibGraalLoader(loader); buildTimeClass = loadClassOrFail(BuildTime.class); @@ -187,12 +180,14 @@ public void afterRegistration(AfterRegistrationAccess access) { LibGraalUtil.accessPackagesToClass(LibGraalUtil.Access.EXPORT, null, false, "java.base", basePackages); } - @SuppressWarnings("unchecked") - private static LibGraalLoader createHostedLibGraalClassLoader(AfterRegistrationAccess access) { - var hostedLibGraalClassLoaderClass = access.findClassByName("jdk.graal.compiler.libgraal.loader.HostedLibGraalClassLoader"); - LibGraalUtil.accessPackagesToClass(LibGraalUtil.Access.EXPORT, hostedLibGraalClassLoaderClass, false, "java.base", "jdk.internal.module"); - return LibGraalUtil.newInstance((Class) hostedLibGraalClassLoaderClass); - } +// @SuppressWarnings("unchecked") +// private static LibGraalLoader createHostedLibGraalClassLoader(AfterRegistrationAccess access) { +// var hostedLibGraalClassLoaderClass = +// access.findClassByName("jdk.graal.compiler.libgraal.loader.HostedLibGraalClassLoader"); +// LibGraalUtil.accessPackagesToClass(LibGraalUtil.Access.EXPORT, hostedLibGraalClassLoaderClass, +// false, "java.base", "jdk.internal.module"); +// return LibGraalUtil.newInstance((Class) hostedLibGraalClassLoaderClass); +// } static void exportModulesToLibGraal(String... moduleNames) { accessModulesToClass(LibGraalUtil.Access.EXPORT, LibGraalFeature.class, moduleNames); @@ -226,7 +221,7 @@ public void duringSetup(DuringSetupAccess access) { /** * Collects all options that are reachable at run time. Reachable options are the * {@link OptionKey} instances reached by the static analysis. The VM options are instances of - * {@link OptionKey} loaded by the {@link com.oracle.svm.hosted.NativeImageClassLoader} and + * {@link OptionKey} loaded by the {@code com.oracle.svm.hosted.NativeImageClassLoader} and * compiler options are instances of {@link OptionKey} loaded by the * {@code HostedLibGraalClassLoader}. */ @@ -461,8 +456,7 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { } } - Architecture arch = HotSpotJVMCIRuntime.runtime().getHostJVMCIBackend().getTarget().arch; - configureGraalForLibGraal.invoke(arch.getName(), + configureGraalForLibGraal.invoke(getJVMCIArch(), libGraalFeatureComponents, guestServiceClasses, registerAsInHeap, @@ -477,6 +471,20 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { } } + /** + * Gets a name for the current architecture that is compatible with + * {@link Architecture#getName()}. + */ + private static String getJVMCIArch() { + String rawArch = getSavedProperty("os.arch"); + return switch (rawArch) { + case "x86_64" -> "AMD64"; + case "aarch64" -> "aarch64"; + case "riscv64" -> "riscv64"; + default -> throw new GraalError("Unknown or unsupported arch: %s", rawArch); + }; + } + @Override public void duringAnalysis(DuringAnalysisAccess access) { for (var c : libGraalFeatureComponents) { @@ -501,74 +509,9 @@ private void initializeTruffle() throws Throwable { @Override public void afterAnalysis(AfterAnalysisAccess access) { - checkForbiddenTypes((AfterAnalysisAccessImpl) access); optionCollector.afterAnalysis(access); } - @SuppressWarnings("try") - private void checkForbiddenTypes(AfterAnalysisAccessImpl access) { - /* - * Verify we only have JVMCI & Graal classes reachable that are coming from - * LibGraalClassLoader except for hosted JVMCI & Graal classes that are legitimately used by - * SubstrateVM runtime implementation classes (mostly from package com.oracle.svm.core). - */ - List hostedAllowed = List.of( - classesPattern("jdk.graal.compiler.core.common", - "NumUtil"), - classesPattern("jdk.graal.compiler.core.common.util", - "AbstractTypeReader", "TypeConversion", "TypeReader", "UnsafeArrayTypeReader"), - classesPattern("jdk.graal.compiler.core.common.type", - "CompressibleConstant"), - classesPattern("jdk.graal.compiler.debug", - "GraalError"), - classesPattern("jdk.graal.compiler.options", - "ModifiableOptionValues", "Option.*"), - classesPattern("jdk.graal.compiler.util.json", - "JsonWriter", "JsonBuilder.*"), - classesPattern("org.graalvm.collections", - "EconomicMap.*", "EmptyMap.*", "Equivalence.*", "Pair"), - classesPattern("jdk.vm.ci.amd64", - "AMD64.*"), - classesPattern("jdk.vm.ci.aarch64", - "AArch64.*"), - classesPattern("jdk.vm.ci.riscv64", - "RISCV64.*"), - classesPattern("jdk.vm.ci.code", - "Architecture", "Register.*", "TargetDescription"), - classesPattern("jdk.vm.ci.meta", - "JavaConstant", "JavaKind", "MetaUtil", "NullConstant", "PrimitiveConstant")); - - Set forbiddenHostedModules = Set.of("jdk.internal.vm.ci", "org.graalvm.collections", "org.graalvm.word", "jdk.graal.compiler"); - - BigBang bigBang = access.getBigBang(); - CallTreePrinter callTreePrinter = new CallTreePrinter(bigBang); - callTreePrinter.buildCallTree(); - - DebugContext debug = bigBang.getDebug(); - List forbiddenReachableTypes = new ArrayList<>(); - try (DebugContext.Scope ignored = debug.scope("LibGraalEntryPoints")) { - for (AnalysisType analysisType : callTreePrinter.usedAnalysisTypes()) { - Class reachableType = analysisType.getJavaClass(); - if (reachableType.getClassLoader() == loader || reachableType.isArray()) { - continue; - } - Module module = reachableType.getModule(); - if (module.isNamed() && forbiddenHostedModules.contains(module.getName())) { - String fqn = reachableType.getName(); - if (hostedAllowed.stream().anyMatch(pattern -> pattern.matcher(fqn).matches())) { - debug.log("Allowing hosted class %s from %s", fqn, module); - continue; - } - forbiddenReachableTypes.add(String.format("%s/%s", module.getName(), fqn)); - } - } - } - if (!forbiddenReachableTypes.isEmpty()) { - CallTreePrinter.print(bigBang, "reports", "report"); - throw new GraalError("LibGraalEntryPoints build found forbidden hosted types as reachable: %s", String.join(", ", forbiddenReachableTypes)); - } - } - private static Pattern classesPattern(String packageName, String... regexes) { return Pattern.compile("%s(%s)".formatted(Pattern.quote(packageName + '.'), String.join("|", regexes))); } diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalJNIMethodScope.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalJNIMethodScope.java similarity index 98% rename from substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalJNIMethodScope.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalJNIMethodScope.java index 904450cd7b08..47ad9f5fd524 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalJNIMethodScope.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalJNIMethodScope.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.graal.hotspot.libgraal; +package jdk.graal.compiler.libgraal; import org.graalvm.jniutils.JNI.JNIEnv; import org.graalvm.jniutils.JNIMethodScope; diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalNativeBridgeSupport.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalNativeBridgeSupport.java similarity index 98% rename from substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalNativeBridgeSupport.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalNativeBridgeSupport.java index 444efca1372b..f7af8c1e983d 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalNativeBridgeSupport.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalNativeBridgeSupport.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.graal.hotspot.libgraal; +package jdk.graal.compiler.libgraal; import java.util.concurrent.atomic.AtomicInteger; diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalObjectHandleScope.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalObjectHandleScope.java similarity index 97% rename from substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalObjectHandleScope.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalObjectHandleScope.java index 3619c9c32819..6a200d09c32c 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalObjectHandleScope.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalObjectHandleScope.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.graal.hotspot.libgraal; +package jdk.graal.compiler.libgraal; import java.io.Closeable; diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalObjectHandles.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalObjectHandles.java similarity index 98% rename from substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalObjectHandles.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalObjectHandles.java index 9e9819d0beb0..6b4cb7ae5ec7 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalObjectHandles.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalObjectHandles.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.graal.hotspot.libgraal; +package jdk.graal.compiler.libgraal; import jdk.graal.compiler.word.Word; import org.graalvm.nativeimage.ObjectHandles; diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalSubstitutions.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java similarity index 96% rename from substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalSubstitutions.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java index 2575d56a4d80..ba7b6a3ed293 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalSubstitutions.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.graal.hotspot.libgraal; +package jdk.graal.compiler.libgraal; import java.io.PrintStream; import java.lang.ref.ReferenceQueue; @@ -87,13 +87,6 @@ static final class Target_jdk_vm_ci_services_Services { @TargetClass(className = "jdk.vm.ci.hotspot.Cleaner", classLoader = LibGraalClassLoaderSupplier.class, onlyWith = LibGraalFeature.IsEnabled.class) static final class Target_jdk_vm_ci_hotspot_Cleaner { - /* - * Ensure the ReferenceQueue instance in Cleaner.queue that is in libgraal is not - * tainted by any use of the Cleaner class at image build-time. - */ - @Alias // - @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.NewInstance, isFinal = true, declClass = ReferenceQueue.class)// - private static ReferenceQueue queue; /* * Make package-private clean() accessible so that it can be called from diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalUtil.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalUtil.java similarity index 99% rename from substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalUtil.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalUtil.java index 47bef7bdf885..0c39baa72bc2 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalUtil.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalUtil.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.graal.hotspot.libgraal; +package jdk.graal.compiler.libgraal; import java.lang.reflect.Constructor; import java.lang.reflect.Field; diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/NativeImageHostEntryPoints.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/NativeImageHostEntryPoints.java similarity index 98% rename from substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/NativeImageHostEntryPoints.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/NativeImageHostEntryPoints.java index 40d44b7f3f68..5f1744aac3d3 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/NativeImageHostEntryPoints.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/NativeImageHostEntryPoints.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.graal.hotspot.libgraal; +package jdk.graal.compiler.libgraal; import com.oracle.truffle.compiler.TruffleCompilerOptionDescriptor; import jdk.graal.compiler.word.Word; diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/TruffleFromLibGraalCalls.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/TruffleFromLibGraalCalls.java similarity index 97% rename from substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/TruffleFromLibGraalCalls.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/TruffleFromLibGraalCalls.java index 644cee8f9809..f545171bd64f 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/TruffleFromLibGraalCalls.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/TruffleFromLibGraalCalls.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.graal.hotspot.libgraal; +package jdk.graal.compiler.libgraal; import static org.graalvm.jniutils.JNIUtil.NewGlobalRef; diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/TruffleFromLibGraalStartPoints.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/TruffleFromLibGraalStartPoints.java similarity index 80% rename from substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/TruffleFromLibGraalStartPoints.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/TruffleFromLibGraalStartPoints.java index f42aecce5bca..f140c07db87f 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/TruffleFromLibGraalStartPoints.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/TruffleFromLibGraalStartPoints.java @@ -22,55 +22,55 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.graal.hotspot.libgraal; - -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callAddInlinedTarget; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callAddTargetToDequeue; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callAsJavaConstant; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callCancelCompilation; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callCompilableToString; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callConsumeOptimizedAssumptionDependency; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callCountDirectCallNodes; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callCreateStringSupplier; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callEngineId; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callGetCompilableCallCount; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callGetCompilableName; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callGetCompilerOptions; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callGetConstantFieldInfo; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callGetDebugProperties; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callGetDescription; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callGetFailedSpeculationsAddress; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callGetKnownCallSiteCount; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callGetLanguage; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callGetLineNumber; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callGetNodeClassName; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callGetNodeId; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callGetNonTrivialNodeCount; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callGetOffsetEnd; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callGetOffsetStart; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callGetPartialEvaluationMethodInfo; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callGetPosition; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callGetSuppliedString; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callGetURI; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callHasNextTier; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callIsCancelled; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callIsLastTier; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callIsSameOrSplit; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callIsSuppressedFailure; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callIsTrivial; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callIsValueType; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callLog; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callOnCodeInstallation; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callOnCompilationFailed; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callOnCompilationRetry; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callOnFailure; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callOnGraalTierFinished; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callOnIsolateShutdown; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callOnSuccess; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callOnTruffleTierFinished; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callPrepareForCompilation; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callRegisterOptimizedAssumptionDependency; -import static com.oracle.svm.graal.hotspot.libgraal.TruffleFromLibGraalStartPointsGen.callSetCallCounts; +package jdk.graal.compiler.libgraal; + +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callAddInlinedTarget; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callAddTargetToDequeue; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callAsJavaConstant; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callCancelCompilation; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callCompilableToString; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callConsumeOptimizedAssumptionDependency; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callCountDirectCallNodes; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callCreateStringSupplier; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callEngineId; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetCompilableCallCount; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetCompilableName; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetCompilerOptions; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetConstantFieldInfo; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetDebugProperties; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetDescription; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetFailedSpeculationsAddress; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetKnownCallSiteCount; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetLanguage; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetLineNumber; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetNodeClassName; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetNodeId; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetNonTrivialNodeCount; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetOffsetEnd; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetOffsetStart; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetPartialEvaluationMethodInfo; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetPosition; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetSuppliedString; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetURI; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callHasNextTier; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callIsCancelled; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callIsLastTier; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callIsSameOrSplit; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callIsSuppressedFailure; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callIsTrivial; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callIsValueType; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callLog; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callOnCodeInstallation; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callOnCompilationFailed; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callOnCompilationRetry; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callOnFailure; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callOnGraalTierFinished; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callOnIsolateShutdown; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callOnSuccess; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callOnTruffleTierFinished; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callPrepareForCompilation; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callRegisterOptimizedAssumptionDependency; +import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callSetCallCounts; import static org.graalvm.jniutils.JNIMethodScope.env; import static org.graalvm.jniutils.JNIUtil.ExceptionClear; import static org.graalvm.jniutils.JNIUtil.GetStaticMethodID; @@ -102,7 +102,7 @@ import com.oracle.truffle.compiler.hotspot.libgraal.TruffleFromLibGraal.Id; /** - * JNI calls to HotSpot called by guest Graal using method handles. + * JNI calls to HotSpot called by LibGraal using JNI method handles. */ public final class TruffleFromLibGraalStartPoints { diff --git a/sdk/mx.sdk/mx_sdk.py b/sdk/mx.sdk/mx_sdk.py index 0824f5aadd05..0df91ed88653 100644 --- a/sdk/mx.sdk/mx_sdk.py +++ b/sdk/mx.sdk/mx_sdk.py @@ -133,7 +133,7 @@ def upx(args): ) mx_sdk_vm.register_graalvm_component(graalvm_sdk_component) -# SDK modules included if the compiler is included +# SDK modules included if the Graal compiler is included graal_sdk_compiler_component = mx_sdk_vm.GraalVmJreComponent( suite=_suite, name='Graal SDK Compiler', @@ -143,7 +143,13 @@ def upx(args): third_party_license_files=[], dependencies=[], jar_distributions=[], - boot_jars=['sdk:WORD', 'sdk:COLLECTIONS', 'sdk:NATIVEIMAGE', 'sdk:JNIUTILS'], + boot_jars=[ + 'sdk:WORD', + 'sdk:COLLECTIONS', + 'sdk:NATIVEIMAGE', + 'sdk:NATIVEBRIDGE', + 'sdk:JNIUTILS' + ], stability="supported", ) mx_sdk_vm.register_graalvm_component(graal_sdk_compiler_component) diff --git a/substratevm/mx.substratevm/mx_substratevm.py b/substratevm/mx.substratevm/mx_substratevm.py index d1928de529cf..7de1354377fc 100644 --- a/substratevm/mx.substratevm/mx_substratevm.py +++ b/substratevm/mx.substratevm/mx_substratevm.py @@ -1463,8 +1463,7 @@ def _native_image_launcher_extra_jvm_args(): libgraal_jar_distributions = [ 'sdk:NATIVEBRIDGE', 'sdk:JNIUTILS', - 'compiler:LIBGRAAL_LOADER', - 'substratevm:LIBGRAAL_LIBRARY'] + 'compiler:LIBGRAAL_LOADER'] def allow_build_path_in_libgraal(): """ @@ -1495,7 +1494,7 @@ def prevent_build_path_in_libgraal(): return [] libgraal_features = [ - 'com.oracle.svm.graal.hotspot.libgraal.LibGraalFeature' + 'jdk.graal.compiler.libgraal.LibGraalFeature' ] libgraal_build_args = [ @@ -1512,11 +1511,11 @@ def prevent_build_path_in_libgraal(): '-J--add-exports=org.graalvm.truffle.compiler/com.oracle.truffle.compiler=ALL-UNNAMED', '-J--add-exports=org.graalvm.nativeimage/com.oracle.svm.core.annotate=ALL-UNNAMED', '-J--add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.option=ALL-UNNAMED', + '-J--add-exports=java.base/jdk.internal.module=ALL-UNNAMED', + '-J--add-exports=org.graalvm.word/org.graalvm.word.impl=ALL-UNNAMED', ## Packages used after option-processing can be opened by the builder (`-J`-prefix not needed) - # LibGraalFeature implements com.oracle.svm.core.feature.InternalFeature (needed to be able to instantiate LibGraalFeature) '--add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.feature=ALL-UNNAMED', # Make jdk.internal.module.Modules accessible to do the remaining opening-up in LibGraalFeature constructor - #'--add-exports=org.graalvm.nativeimage.base/com.oracle.svm.util=ALL-UNNAMED', '--add-exports=java.base/jdk.internal.module=ALL-UNNAMED', # TruffleLibGraalJVMCIServiceLocator needs access to JVMCIServiceLocator '--add-exports=jdk.internal.vm.ci/jdk.vm.ci.services=ALL-UNNAMED', @@ -1531,6 +1530,7 @@ def prevent_build_path_in_libgraal(): # If building on the console, use as many cores as available f'--parallelism={mx.cpu_count()}', ] if mx.is_interactive() else []) + svm_experimental_options([ + "-H:LibGraalClassLoader=jdk.graal.compiler.libgraal.loader.HostedLibGraalClassLoader", '-H:-UseServiceLoaderFeature', '-H:+AllowFoldMethods', '-Dtruffle.TruffleRuntime=', diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py index 82c4593b1723..c6ad111c7c00 100644 --- a/substratevm/mx.substratevm/suite.py +++ b/substratevm/mx.substratevm/suite.py @@ -1356,46 +1356,6 @@ "jacoco" : "exclude", }, - "com.oracle.svm.graal.hotspot.libgraal" : { - "subDir": "src", - "sourceDirs" : [ - "src", - "resources", - ], - "dependencies": [ - "sdk:JNIUTILS", - "sdk:NATIVEIMAGE", - "sdk:NATIVEBRIDGE", - "compiler:GRAAL", - "SVM", - ], - "requires": [ - "java.management", - "jdk.management", - ], - "requiresConcealed" : { - "java.base" : [ - "jdk.internal.module", - "jdk.internal.misc", - ], - "jdk.internal.vm.ci" : [ - "jdk.vm.ci.meta", - "jdk.vm.ci.services", - "jdk.vm.ci.runtime", - "jdk.vm.ci.code", - "jdk.vm.ci.hotspot" - ], - }, - "annotationProcessors": [ - "compiler:GRAAL_PROCESSOR", - "truffle:TRUFFLE_LIBGRAAL_PROCESSOR", - ], - "checkstyle" : "com.oracle.svm.hosted", - "javaCompliance" : "21+", - "workingSets" : "SVM", - "jacoco" : "exclude", - }, - "com.oracle.svm.configure": { "subDir": "src", "sourceDirs": [ @@ -1974,21 +1934,6 @@ "maven" : False, }, - "LIBGRAAL_LIBRARY": { - "subDir": "src", - "description" : "LibGraal feature", - "javaCompliance" : "21+", - "dependencies": [ - "com.oracle.svm.graal.hotspot.libgraal", - ], - "distDependencies": [ - "SVM", - "sdk:JNIUTILS", - "sdk:NATIVEBRIDGE", - ], - "maven": False, - }, - # # Native Projects # From e27626a3b1eeab652e3697b5b8b1eeed5fa7de2f Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Sun, 8 Dec 2024 16:17:54 +0100 Subject: [PATCH 10/31] remove reflection in non-truffle libgraal --- .../compiler/hotspot/libgraal/BuildTime.java | 32 ------ .../compiler/hotspot/libgraal/RunTime.java | 2 +- .../libgraal/LibGraalEntryPoints.java | 101 +----------------- .../compiler/libgraal/LibGraalFeature.java | 6 -- .../libgraal/LibGraalNativeBridgeSupport.java | 8 +- .../libgraal/LibGraalSubstitutions.java | 17 ++- 6 files changed, 16 insertions(+), 150 deletions(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/BuildTime.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/BuildTime.java index c9e9754c0db7..59d3102da6fa 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/BuildTime.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/BuildTime.java @@ -202,36 +202,4 @@ public static void configureGraalForLibGraal( throw GraalError.shouldNotReachHere(e); } } - - private static final Lookup MHL = MethodHandles.lookup(); - - /** - * Gets method handles to call Graal and JVMCI methods. - * - * @return a named set of handles - */ - public static Map getRuntimeHandles() { - try { - return Map.of("compileMethod", MHL.findStatic(RunTime.class, "compileMethod", - methodType(long.class, long.class, - boolean.class, boolean.class, boolean.class, boolean.class, - long.class, int.class, int.class, - String.class, BiConsumer.class)), - "hashConstantOopFields", MHL.findStatic(RunTime.class, "hashConstantOopFields", - methodType(long.class, long.class, boolean.class, int.class, int.class, - boolean.class, Runnable.class)), - "getJNIEnv", MHL.findStatic(RunTime.class, "getJNIEnv", - methodType(long.class)), - "attachCurrentThread", MHL.findStatic(RunTime.class, "attachCurrentThread", - methodType(boolean.class, boolean.class, long[].class)), - "detachCurrentThread", MHL.findStatic(RunTime.class, "detachCurrentThread", - methodType(boolean.class, boolean.class)), - "getSavedProperty", MHL.findStatic(GraalServices.class, "getSavedProperty", - methodType(String.class, String.class)), - "ttyPrintf", MHL.findStatic(TTY.class, "printf", - methodType(void.class, String.class, Object[].class))); - } catch (Throwable e) { - throw GraalError.shouldNotReachHere(e); - } - } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/RunTime.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/RunTime.java index 7d7eb7e9f040..1121c7033c98 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/RunTime.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/RunTime.java @@ -219,7 +219,7 @@ private static long getJniEnvironmentOffset() { /** * Gets the JNIEnv value for the current HotSpot thread. */ - static long getJNIEnv() { + public static long getJNIEnv() { HotSpotJVMCIRuntime jvmciRuntime = HotSpotJVMCIRuntime.runtime(); long offset = getJniEnvironmentOffset(); long javaThreadAddr = jvmciRuntime.getCurrentJavaThread(); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalEntryPoints.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalEntryPoints.java index 5896b34480ea..673e6234411c 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalEntryPoints.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalEntryPoints.java @@ -44,7 +44,6 @@ import com.oracle.truffle.compiler.hotspot.libgraal.TruffleToLibGraal; import com.oracle.truffle.compiler.hotspot.libgraal.TruffleToLibGraal.Id; import jdk.graal.compiler.debug.GraalError; -import jdk.graal.compiler.hotspot.libgraal.BuildTime; import jdk.graal.compiler.hotspot.libgraal.RunTime; import jdk.graal.compiler.options.OptionValues; import jdk.graal.compiler.serviceprovider.IsolateUtil; @@ -52,7 +51,6 @@ import jdk.graal.nativeimage.LibGraalRuntime; import org.graalvm.collections.EconomicSet; import org.graalvm.jniutils.HSObject; -import org.graalvm.jniutils.JNI; import org.graalvm.jniutils.JNI.JByteArray; import org.graalvm.jniutils.JNI.JClass; import org.graalvm.jniutils.JNI.JNIEnv; @@ -81,103 +79,12 @@ import jdk.internal.misc.Unsafe; /** - * Encapsulates {@link CEntryPoint} implementations as well as method handles for invoking LibGraal - * and JVMCI functionality via {@link MethodHandle}s. The method handles (initialized by - * {@link BuildTime#getRuntimeHandles()}) are only invoked in static methods which allows Native - * Image to fold them to direct calls to the method handle targets. + * Encapsulates {@link CEntryPoint} implementations. */ final class LibGraalEntryPoints { - private final MethodHandle getJNIEnv; - private final MethodHandle getSavedProperty; - private final MethodHandle ttyPrintf; - private final MethodHandle compileMethod; - private final MethodHandle hashConstantOopFields; - private final MethodHandle attachCurrentThread; - private final MethodHandle detachCurrentThread; - - /** - * Returns the {@link LibGraalEntryPoints} instance registered in the {@link ImageSingletons}. - */ - private static LibGraalEntryPoints singleton() { - return ImageSingletons.lookup(LibGraalEntryPoints.class); - } - @Platforms(Platform.HOSTED_ONLY.class) - LibGraalEntryPoints(Map handles) { - this.getJNIEnv = handles.get("getJNIEnv"); - this.getSavedProperty = handles.get("getSavedProperty"); - this.ttyPrintf = handles.get("ttyPrintf"); - this.compileMethod = handles.get("compileMethod"); - this.hashConstantOopFields = handles.get("hashConstantOopFields"); - this.attachCurrentThread = handles.get("attachCurrentThread"); - this.detachCurrentThread = handles.get("detachCurrentThread"); - } - - /** - * Calls {@code jdk.graal.compiler.hotspot.libgraal.RunTime#getJNIEnv()}. - */ - static JNI.JNIEnv getJNIEnv() { - try { - long raw = (long) singleton().getJNIEnv.invoke(); - return Word.unsigned(raw); - } catch (RuntimeException | Error e) { - throw e; - } catch (Throwable e) { - throw GraalError.shouldNotReachHere(e); - } - } - - /** - * Calls {@code jdk.graal.compiler.serviceprovider.GraalServices#getSavedProperty(String)}. - */ - static String getSavedProperty(String name) { - try { - return (String) singleton().getSavedProperty.invoke(name); - } catch (RuntimeException | Error e) { - throw e; - } catch (Throwable e) { - throw GraalError.shouldNotReachHere(e); - } - } - - /** - * Calls {@link RunTime#attachCurrentThread}. - */ - static boolean attachCurrentThread(boolean daemon, long[] isolate) { - try { - return (boolean) singleton().attachCurrentThread.invoke(daemon, isolate); - } catch (RuntimeException | Error e) { - throw e; - } catch (Throwable e) { - throw GraalError.shouldNotReachHere(e); - } - } - - /** - * Calls {@link RunTime#detachCurrentThread}. - */ - static boolean detachCurrentThread(boolean release) { - try { - return (boolean) singleton().detachCurrentThread.invoke(release); - } catch (RuntimeException | Error e) { - throw e; - } catch (Throwable e) { - throw GraalError.shouldNotReachHere(e); - } - } - - /** - * Calls {@code jdk.graal.compiler.debug.TTY#printf(String, Object...)}. - */ - static void ttyPrintf(String format, Object... args) { - try { - singleton().ttyPrintf.invoke(format, args); - } catch (RuntimeException | Error e) { - throw e; - } catch (Throwable e) { - throw GraalError.shouldNotReachHere(e); - } + LibGraalEntryPoints() { } /** @@ -251,7 +158,7 @@ private static long compileMethod(JNIEnv jniEnv, timeAndMemConsumer = null; } - return (long) singleton().compileMethod.invoke(methodHandle, useProfilingInfo, + return RunTime.compileMethod(methodHandle, useProfilingInfo, installAsDefault, printMetrics, eagerResolving, optionsAddress, optionsSize, optionsHash, profileLoadPath, timeAndMemConsumer); @@ -284,7 +191,7 @@ private static long hashConstantOopFields(JNIEnv jniEnv, boolean verbose) { try (JNIMethodScope scope = new JNIMethodScope("hashConstantOopFields", jniEnv)) { Runnable doReferenceHandling = LibGraalEntryPoints::doReferenceHandling; - return (long) singleton().hashConstantOopFields.invoke(typeHandle, useScope, iterations, oopsPerIteration, verbose, doReferenceHandling); + return RunTime.hashConstantOopFields(typeHandle, useScope, iterations, oopsPerIteration, verbose, doReferenceHandling); } catch (Throwable t) { JNIExceptionWrapper.throwInHotSpot(jniEnv, t); return 0; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java index 266a269b7325..d4c42fefe8db 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java @@ -464,7 +464,6 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { nativeImageLocationQualifier, configResult.encodedConfig()); - initGraalRuntimeHandles(mhl.findStatic(buildTimeClass, "getRuntimeHandles", methodType(Map.class))); initializeTruffle(); } catch (Throwable e) { throw GraalError.shouldNotReachHere(e); @@ -492,11 +491,6 @@ public void duringAnalysis(DuringAnalysisAccess access) { } } - @SuppressWarnings("unchecked") - private static void initGraalRuntimeHandles(MethodHandle getRuntimeHandles) throws Throwable { - ImageSingletons.add(LibGraalEntryPoints.class, new LibGraalEntryPoints((Map) getRuntimeHandles.invoke())); - } - @SuppressWarnings("unchecked") private void initializeTruffle() throws Throwable { Class truffleBuildTimeClass = loadClassOrFail("jdk.graal.compiler.hotspot.libgraal.truffle.BuildTime"); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalNativeBridgeSupport.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalNativeBridgeSupport.java index f7af8c1e983d..e06f4c085f2a 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalNativeBridgeSupport.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalNativeBridgeSupport.java @@ -26,6 +26,8 @@ import java.util.concurrent.atomic.AtomicInteger; +import jdk.graal.compiler.debug.TTY; +import jdk.graal.compiler.serviceprovider.GraalServices; import jdk.graal.compiler.serviceprovider.IsolateUtil; import org.graalvm.jniutils.JNIMethodScope; import org.graalvm.jniutils.NativeBridgeSupport; @@ -68,7 +70,7 @@ public void trace(String message) { sb.append(" ".repeat(2 + (scope.depth() * 2))); } sb.append(message); - LibGraalEntryPoints.ttyPrintf("%s%n", sb); + TTY.printf("%s%n", sb); } finally { inTrace.remove(); } @@ -78,12 +80,12 @@ public void trace(String message) { private int traceLevel() { int res = traceLevel.get(); if (res == UNINITIALIZED_TRACE_LEVEL) { - String var = LibGraalEntryPoints.getSavedProperty(JNI_LIBGRAAL_TRACE_LEVEL_PROPERTY_NAME); + String var = GraalServices.getSavedProperty(JNI_LIBGRAAL_TRACE_LEVEL_PROPERTY_NAME); if (var != null) { try { res = Integer.parseInt(var); } catch (NumberFormatException e) { - LibGraalEntryPoints.ttyPrintf("Invalid value for %s: %s%n", JNI_LIBGRAAL_TRACE_LEVEL_PROPERTY_NAME, e); + TTY.printf("Invalid value for %s: %s%n", JNI_LIBGRAAL_TRACE_LEVEL_PROPERTY_NAME, e); res = 0; } } else { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java index ba7b6a3ed293..175dc1138291 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java @@ -25,10 +25,11 @@ package jdk.graal.compiler.libgraal; import java.io.PrintStream; -import java.lang.ref.ReferenceQueue; import java.util.Map; import java.util.function.Supplier; +import jdk.graal.compiler.hotspot.libgraal.RunTime; +import jdk.graal.compiler.word.Word; import jdk.graal.nativeimage.LibGraalRuntime; import org.graalvm.jniutils.JNI; import org.graalvm.jniutils.JNIExceptionWrapper; @@ -43,12 +44,6 @@ import com.oracle.svm.core.annotate.RecomputeFieldValue; import com.oracle.svm.core.annotate.Substitute; import com.oracle.svm.core.annotate.TargetClass; -import com.oracle.svm.core.jdk.JDKLatest; -import com.oracle.svm.core.log.FunctionPointerLogHandler; -import com.oracle.svm.graal.hotspot.LibGraalJNIMethodScope; - -import jdk.graal.compiler.debug.GraalError; -import jdk.graal.compiler.libgraal.LibGraalFeature; class LibGraalJVMCISubstitutions { @@ -162,7 +157,7 @@ static class LibGraalCompilationRequestScope implements AutoCloseable { final JNIMethodScope scope; LibGraalCompilationRequestScope() { - JNI.JNIEnv env = LibGraalEntryPoints.getJNIEnv(); + JNI.JNIEnv env = Word.unsigned(RunTime.getJNIEnv()); /* * This scope is required to allow Graal compilations of host methods to call * methods in the TruffleCompilerRuntime. This is, for example, required to find out @@ -194,7 +189,7 @@ public static AutoCloseable getCompilationRequestScope() { @Substitute public static void invokeShutdownCallback(String cbClassName, String cbMethodName) { - JNI.JNIEnv env = LibGraalEntryPoints.getJNIEnv(); + JNI.JNIEnv env = Word.unsigned(RunTime.getJNIEnv()); JNI.JClass cbClass = JNIUtil.findClass(env, JNIUtil.getSystemClassLoader(env), JNIUtil.getBinaryName(cbClassName), true); JNI.JMethodID cbMethod = JNIUtil.findMethod(env, cbClass, true, cbMethodName, "()V"); @@ -222,7 +217,7 @@ static final class Target_jdk_graal_compiler_core_GraalServiceThread { @Substitute() void beforeRun() { Thread thread = cast(this, Thread.class); - if (!LibGraalEntryPoints.attachCurrentThread(thread.isDaemon(), null)) { + if (!RunTime.attachCurrentThread(thread.isDaemon(), null)) { throw new InternalError("Couldn't attach to HotSpot runtime"); } } @@ -230,7 +225,7 @@ void beforeRun() { @Substitute @SuppressWarnings("static-method") void afterRun() { - LibGraalEntryPoints.detachCurrentThread(false); + RunTime.detachCurrentThread(false); } } } From 77237b2da00bc8eb0337c9b3b03fc431d245767b Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Tue, 10 Dec 2024 21:29:44 +0100 Subject: [PATCH 11/31] remove reflection in truffle libgraal --- .../loader/HostedLibGraalClassLoader.java | 4 +- .../hotspot/libgraal/truffle/BuildTime.java | 126 +--- .../libgraal/truffle}/FromLibGraalCalls.java | 2 +- .../libgraal/truffle/GraalEntryPoints.java | 193 ------ .../hotspot/libgraal/truffle/HSConsumer.java | 16 +- .../libgraal/truffle/HSIndirectHandle.java | 14 - .../libgraal/truffle/HSTruffleCompilable.java | 123 +--- .../truffle/HSTruffleCompilationTask.java | 69 +-- .../truffle/HSTruffleCompilerListener.java | 44 +- .../truffle/HSTruffleCompilerRuntime.java | 91 +-- .../HSTruffleSourceLanguagePosition.java | 66 +- .../truffle}/LibGraalObjectHandleScope.java | 2 +- .../truffle}/LibGraalObjectHandles.java | 2 +- .../truffle/LibGraalTruffleEntryPoints.java | 541 ++++++++++++++++ .../LibGraalTruffleHostEnvironment.java | 7 +- .../LibGraalTruffleHostEnvironmentLookup.java | 11 +- .../LibGraalTruffleScopeEntryPoints.java | 30 + .../truffle/NativeImageHostCalls.java | 108 ---- .../truffle}/TruffleFromLibGraalCalls.java | 2 +- .../TruffleFromLibGraalStartPoints.java | 98 +-- .../truffle/TruffleLibGraalShutdownHook.java | 15 +- .../libgraal/LibGraalEntryPoints.java | 582 ------------------ .../compiler/libgraal/LibGraalFeature.java | 12 +- .../libgraal/LibGraalSubstitutions.java | 5 +- .../libgraal/NativeImageHostEntryPoints.java | 2 +- 25 files changed, 715 insertions(+), 1450 deletions(-) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{libgraal => hotspot/libgraal/truffle}/FromLibGraalCalls.java (99%) delete mode 100644 compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/GraalEntryPoints.java rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{libgraal => hotspot/libgraal/truffle}/LibGraalObjectHandleScope.java (97%) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{libgraal => hotspot/libgraal/truffle}/LibGraalObjectHandles.java (97%) create mode 100644 compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleEntryPoints.java create mode 100644 compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleScopeEntryPoints.java delete mode 100644 compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/NativeImageHostCalls.java rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{libgraal => hotspot/libgraal/truffle}/TruffleFromLibGraalCalls.java (97%) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{libgraal => hotspot/libgraal/truffle}/TruffleFromLibGraalStartPoints.java (80%) diff --git a/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/HostedLibGraalClassLoader.java b/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/HostedLibGraalClassLoader.java index 6410bb2dc25d..b18a486302b3 100644 --- a/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/HostedLibGraalClassLoader.java +++ b/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/HostedLibGraalClassLoader.java @@ -89,8 +89,8 @@ public final class HostedLibGraalClassLoader extends ClassLoader implements LibG */ private static final Set LIBGRAAL_MODULES = Set.of( "jdk.internal.vm.ci", - "org.graalvm.collections", - "org.graalvm.word", +// "org.graalvm.collections", +// "org.graalvm.word", "jdk.graal.compiler", "org.graalvm.truffle.compiler", "com.oracle.graal.graal_enterprise"); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/BuildTime.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/BuildTime.java index 2e82e70c908a..65521b979bf4 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/BuildTime.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/BuildTime.java @@ -24,25 +24,10 @@ */ package jdk.graal.compiler.hotspot.libgraal.truffle; -import com.oracle.truffle.compiler.hotspot.libgraal.TruffleFromLibGraal.Id; -import jdk.graal.compiler.truffle.host.TruffleHostEnvironment; -import org.graalvm.nativeimage.ImageInfo; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodHandles.Lookup; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Map.Entry; -import java.util.NoSuchElementException; -import java.util.Objects; -import java.util.Set; +import jdk.graal.compiler.truffle.host.TruffleHostEnvironment; /** * Class used to initialize the Truffle extensions to the Graal compiler in the image build time. @@ -50,119 +35,10 @@ @Platforms(Platform.HOSTED_ONLY.class) public class BuildTime { - private static Lookup hostLookup; - private static Class truffleFromLibGraalStartPoint; - private static Class nativeImageHostEntryPoint; - private static Map hostMethods; - /** * Configures Truffle services to the Graal compiler in the image build time. */ public static void configureGraalForLibGraal() { TruffleHostEnvironment.overrideLookup(new LibGraalTruffleHostEnvironmentLookup()); } - - /** - * Obtains a {@link Lookup} instance for resolving method handles to invoke Graal and JVMCI - * methods. - *

    - * This method is invoked reflectively by {@code LibGraalFeature.initializeTruffle()} in the - * native-image classloader to facilitate the exchange of lookup instances between the - * native-image classloader and the LibGraalClassLoader. - *

    - * - * @param lookup a {@link Lookup} instance used to resolve handles for calling into the - * native-image host. - * @param fromLibGraal a class that contains methods for making calls to HotSpot using the JNI - * API. - * @param nativeImageSupport a class that provides native-image and JNI helper methods. - * @return a {@link Entry} containing a {@link Lookup} instance and a class with compiler entry - * methods. The {@link Lookup} instance can be used to resolve the compiler entry - * methods within the provided class. - */ - public static Entry> initializeLookup(Lookup lookup, Class fromLibGraal, Class nativeImageSupport) { - if (hostLookup != null) { - throw new IllegalStateException("Host lookup has already been initialized. BuildTime.initializeLookup should only be called once during the native image build process."); - } - hostLookup = Objects.requireNonNull(lookup, "lookup must be non null"); - truffleFromLibGraalStartPoint = Objects.requireNonNull(fromLibGraal, "fromLibGraal must be non null"); - nativeImageHostEntryPoint = Objects.requireNonNull(nativeImageSupport, "nativeImageSupport must be non null"); - return Map.entry(MethodHandles.lookup(), GraalEntryPoints.class); - } - - static MethodHandle getHostMethodHandleOrFail(Id id) { - return getHostMethodHandleOrFail(id.getMethodName()); - } - - static MethodHandle getHostMethodHandleOrFail(String name) { - if (ImageInfo.inImageBuildtimeCode()) { - /* - * Native-image initializes BuildTime also in the platform classloader. In this case we - * return null. - */ - ClassLoader myLoader = BuildTime.class.getClassLoader(); - if (myLoader == null || myLoader == ClassLoader.getPlatformClassLoader() || myLoader == ClassLoader.getSystemClassLoader()) { - return null; - } - if (hostMethods == null) { - hostMethods = initializeHostMethods(); - } - MethodHandle handle = hostMethods.get(name); - if (handle != null) { - return handle; - } else { - throw new NoSuchElementException(name); - } - } else if (ImageInfo.inImageRuntimeCode()) { - /* - * The getHostMethodHandleOrFail should never be called in the native-image execution - * time. - */ - throw new IllegalStateException("Should not be reachable at libgraal runtime"); - } else { - /* - * HS proxy classes and BuildTime are not used in Jargraal, but the CheckGraalInvariants - * test eagerly initializes these proxy classes, leading to a call to - * getHostMethodHandleOrFail. In this scenario, we return null to prevent the test from - * crashing. - */ - return null; - } - } - - private static Map initializeHostMethods() { - try { - Map result = new HashMap<>(); - Set methodNames = new HashSet<>(); - Arrays.stream(Id.values()).map(Id::getMethodName).forEach(methodNames::add); - for (Method m : truffleFromLibGraalStartPoint.getDeclaredMethods()) { - if (Modifier.isStatic(m.getModifiers()) && Modifier.isPublic(m.getModifiers())) { - String methodName = m.getName(); - if (methodNames.remove(methodName)) { - result.put(methodName, hostLookup.unreflect(m)); - } - } - } - if (!methodNames.isEmpty()) { - throw new RuntimeException(String.format("Cannot find methods for following ids %s in %s", methodNames, truffleFromLibGraalStartPoint.getName())); - } - Arrays.stream(NativeImageHostCalls.class.getDeclaredMethods()).map(Method::getName).forEach(methodNames::add); - for (Method m : nativeImageHostEntryPoint.getDeclaredMethods()) { - if (Modifier.isStatic(m.getModifiers()) && Modifier.isPublic(m.getModifiers())) { - String methodName = m.getName(); - if (methodNames.remove(methodName)) { - if (result.put(methodName, hostLookup.unreflect(m)) != null) { - throw new RuntimeException(String.format("Duplicate methods for name %s in %s", methodName, nativeImageHostEntryPoint)); - } - } - } - } - if (!methodNames.isEmpty()) { - throw new RuntimeException(String.format("Cannot find following methods %s in %s", methodNames, nativeImageHostEntryPoint)); - } - return result; - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/FromLibGraalCalls.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/FromLibGraalCalls.java similarity index 99% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/FromLibGraalCalls.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/FromLibGraalCalls.java index 127175d7e07a..6a4f5e19ed3f 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/FromLibGraalCalls.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/FromLibGraalCalls.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.libgraal; +package jdk.graal.compiler.hotspot.libgraal.truffle; import com.oracle.truffle.compiler.hotspot.libgraal.FromLibGraalId; import org.graalvm.jniutils.JNI.JClass; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/GraalEntryPoints.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/GraalEntryPoints.java deleted file mode 100644 index a98a5dac143f..000000000000 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/GraalEntryPoints.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (c) 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 jdk.graal.compiler.hotspot.libgraal.truffle; - -import com.oracle.truffle.compiler.TruffleCompilable; -import com.oracle.truffle.compiler.TruffleCompilerListener.CompilationResultInfo; -import com.oracle.truffle.compiler.TruffleCompilerListener.GraphInfo; -import com.oracle.truffle.compiler.TruffleCompilerOptionDescriptor; -import jdk.graal.compiler.hotspot.CompilationContext; -import jdk.graal.compiler.hotspot.HotSpotGraalServices; -import jdk.graal.compiler.truffle.TruffleCompilerOptions; -import jdk.graal.compiler.truffle.hotspot.HotSpotTruffleCompilationSupport; -import jdk.graal.compiler.truffle.hotspot.HotSpotTruffleCompilerImpl; -import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; -import jdk.vm.ci.hotspot.HotSpotVMConfigAccess; -import jdk.vm.ci.meta.ResolvedJavaMethod; - -import java.util.function.Supplier; - -/** - * Guest Graal entry points for Truffle to libgraal calls. - */ -public final class GraalEntryPoints { - - private GraalEntryPoints() { - } - - // HotSpot to libgraal entry points - - public static void initializeIsolate() { - TruffleLibGraalShutdownHook.registerShutdownHook(); - } - - public static boolean registerRuntime(long truffleRuntimeWeakRef) { - return LibGraalTruffleHostEnvironmentLookup.registerRuntime(truffleRuntimeWeakRef); - } - - public static Object initializeRuntime(Object hsHandle, long hsClassLoaderDelegate) { - return new HSTruffleCompilerRuntime(hsHandle, hsClassLoaderDelegate); - } - - public static Object newCompiler(Object truffleCompilerRuntime) { - /* - * Unlike `LibGraalTruffleHostEnvironment`, Truffle libgraal entry points use the global - * compilation context by default, so we don't need to call - * `HotSpotGraalServices.enterGlobalCompilationContext()` before creating - * `TruffleCompilerImpl`. The `doCompile` method enters a local compilation context through - * its own call to `HotSpotGraalServices.openLocalCompilationContext`. - */ - return HotSpotTruffleCompilerImpl.create((HSTruffleCompilerRuntime) truffleCompilerRuntime, null); - } - - public static void initializeCompiler(Object compiler, Object compilableHsHandle, boolean firstInitialization) { - HotSpotTruffleCompilerImpl truffleCompiler = (HotSpotTruffleCompilerImpl) compiler; - TruffleCompilable compilable = new HSTruffleCompilable(compilableHsHandle); - truffleCompiler.initialize(compilable, firstInitialization); - } - - public static String getCompilerConfigurationFactoryName() { - return HotSpotTruffleCompilationSupport.getLazyCompilerConfigurationName(); - } - - @SuppressWarnings("try") - public static void doCompile(Object compiler, Object taskHsHandle, Object compilableHsHandle, Object listenerHsHandle) { - HotSpotTruffleCompilerImpl truffleCompiler = (HotSpotTruffleCompilerImpl) compiler; - HSTruffleCompilationTask task = taskHsHandle == null ? null : new HSTruffleCompilationTask(taskHsHandle); - HSTruffleCompilerListener listener = listenerHsHandle == null ? null : new HSTruffleCompilerListener(listenerHsHandle); - HSTruffleCompilable compilable = new HSTruffleCompilable(compilableHsHandle); - try (CompilationContext hotSpotObjectConstantScope = HotSpotGraalServices.openLocalCompilationContext(compilable)) { - truffleCompiler.doCompile(task, compilable, listener); - } - } - - public static void shutdown(Object compiler) { - ((HotSpotTruffleCompilerImpl) compiler).shutdown(); - } - - public static void installTruffleCallBoundaryMethod(Object compiler, long methodHandle) { - HotSpotTruffleCompilerImpl truffleCompiler = (HotSpotTruffleCompilerImpl) compiler; - truffleCompiler.installTruffleCallBoundaryMethod(HotSpotJVMCIRuntime.runtime().unhand(ResolvedJavaMethod.class, methodHandle), null); - } - - public static void installTruffleReservedOopMethod(Object compiler, long methodHandle) { - HotSpotTruffleCompilerImpl truffleCompiler = (HotSpotTruffleCompilerImpl) compiler; - truffleCompiler.installTruffleReservedOopMethod(HotSpotJVMCIRuntime.runtime().unhand(ResolvedJavaMethod.class, methodHandle), null); - } - - public static int pendingTransferToInterpreterOffset(Object compiler, Object compilableHsHandle) { - HotSpotTruffleCompilerImpl truffleCompiler = (HotSpotTruffleCompilerImpl) compiler; - TruffleCompilable compilable = new HSTruffleCompilable(compilableHsHandle); - return truffleCompiler.pendingTransferToInterpreterOffset(compilable); - } - - @SuppressWarnings("unchecked") - public static String getSuppliedString(Object stringSupplier) { - return ((Supplier) stringSupplier).get(); - } - - public static int getNodeCount(Object graphInfo) { - return ((GraphInfo) graphInfo).getNodeCount(); - } - - public static String[] getNodeTypes(Object graphInfo, boolean simpleNames) { - return ((GraphInfo) graphInfo).getNodeTypes(simpleNames); - } - - public static int getTargetCodeSize(Object compilationResultInfo) { - return ((CompilationResultInfo) compilationResultInfo).getTargetCodeSize(); - } - - public static int getTotalFrameSize(Object compilationResultInfo) { - return ((CompilationResultInfo) compilationResultInfo).getTotalFrameSize(); - } - - public static int getExceptionHandlersCount(Object compilationResultInfo) { - return ((CompilationResultInfo) compilationResultInfo).getExceptionHandlersCount(); - } - - public static int getInfopointsCount(Object compilationResultInfo) { - return ((CompilationResultInfo) compilationResultInfo).getInfopointsCount(); - } - - public static String[] getInfopoints(Object compilationResultInfo) { - return ((CompilationResultInfo) compilationResultInfo).getInfopoints(); - } - - public static int getMarksCount(Object compilationResultInfo) { - return ((CompilationResultInfo) compilationResultInfo).getMarksCount(); - } - - public static int getDataPatchesCount(Object compilationResultInfo) { - return ((CompilationResultInfo) compilationResultInfo).getDataPatchesCount(); - } - - public static Object[] listCompilerOptions() { - TruffleCompilerOptionDescriptor[] options = TruffleCompilerOptions.listOptions(); - Object[] result = new Object[options.length]; - for (int i = 0; i < options.length; i++) { - TruffleCompilerOptionDescriptor option = options[i]; - result[i] = NativeImageHostCalls.createTruffleCompilerOptionDescriptor(option.name(), option.type().ordinal(), option.deprecated(), option.help(), option.deprecationMessage()); - } - return result; - } - - public static boolean compilerOptionExists(String optionName) { - return TruffleCompilerOptions.optionExists(optionName); - } - - public static String validateCompilerOption(String optionName, String optionValue) { - return TruffleCompilerOptions.validateOption(optionName, optionValue); - } - - public static void purgePartialEvaluationCaches(Object compiler) { - ((HotSpotTruffleCompilerImpl) compiler).purgePartialEvaluationCaches(); - } - - public static String getCompilerVersion() { - return HSTruffleCompilerRuntime.COMPILER_VERSION; - } - - public static long getCurrentJavaThread() { - return HotSpotJVMCIRuntime.runtime().getCurrentJavaThread(); - } - - public static int getLastJavaPCOffset() { - HotSpotVMConfigAccess configAccess = new HotSpotVMConfigAccess(HotSpotJVMCIRuntime.runtime().getConfigStore()); - int anchor = configAccess.getFieldOffset("JavaThread::_anchor", Integer.class, "JavaFrameAnchor"); - int lastJavaPc = configAccess.getFieldOffset("JavaFrameAnchor::_last_Java_pc", Integer.class, "address"); - return anchor + lastJavaPc; - } -} diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSConsumer.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSConsumer.java index 29237f692c0d..ac82fd8a3a66 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSConsumer.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSConsumer.java @@ -27,18 +27,12 @@ import com.oracle.truffle.compiler.OptimizedAssumptionDependency; import com.oracle.truffle.compiler.TruffleCompilable; import com.oracle.truffle.compiler.TruffleCompilerAssumptionDependency; -import com.oracle.truffle.compiler.hotspot.libgraal.TruffleFromLibGraal.Id; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; -import java.lang.invoke.MethodHandle; import java.util.function.Consumer; -import static jdk.graal.compiler.hotspot.libgraal.truffle.BuildTime.getHostMethodHandleOrFail; - final class HSConsumer extends HSIndirectHandle implements Consumer { - private static final Handles HANDLES = new Handles(); - HSConsumer(Object hsHandle) { super(hsHandle); } @@ -64,14 +58,6 @@ public void accept(OptimizedAssumptionDependency optimizedDependency) { } installedCode = HotSpotJVMCIRuntime.runtime().translate(dependency.getInstalledCode()); } - try { - HANDLES.consumeOptimizedAssumptionDependency.invoke(hsHandle, compilableHsHandle, installedCode); - } catch (Throwable t) { - throw handleException(t); - } - } - - private static final class Handles { - final MethodHandle consumeOptimizedAssumptionDependency = getHostMethodHandleOrFail(Id.ConsumeOptimizedAssumptionDependency); + TruffleFromLibGraalStartPoints.consumeOptimizedAssumptionDependency(hsHandle, compilableHsHandle, installedCode); } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSIndirectHandle.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSIndirectHandle.java index 184a9e396ac5..afad30d1e04e 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSIndirectHandle.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSIndirectHandle.java @@ -56,18 +56,4 @@ class HSIndirectHandle { HSIndirectHandle(Object hsHandle) { this.hsHandle = Objects.requireNonNull(hsHandle, "HsHandle must be non-null"); } - - /** - * Handles exceptions by rethrowing them as either {@link RuntimeException} or {@link Error}, or - * wrapping them in a {@link RuntimeException} if they are of another type. - */ - static RuntimeException handleException(Throwable t) { - if (t instanceof RuntimeException rt) { - throw rt; - } else if (t instanceof Error e) { - throw e; - } else { - throw new RuntimeException(t); - } - } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilable.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilable.java index a3c3839e9c0c..d932c110df07 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilable.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilable.java @@ -25,23 +25,17 @@ package jdk.graal.compiler.hotspot.libgraal.truffle; import com.oracle.truffle.compiler.TruffleCompilable; -import com.oracle.truffle.compiler.hotspot.libgraal.TruffleFromLibGraal.Id; import jdk.graal.compiler.debug.GraalError; import jdk.graal.compiler.hotspot.HotSpotGraalServices; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.SpeculationLog; -import java.lang.invoke.MethodHandle; import java.util.Map; import java.util.function.Supplier; -import static jdk.graal.compiler.hotspot.libgraal.truffle.BuildTime.getHostMethodHandleOrFail; - final class HSTruffleCompilable extends HSIndirectHandle implements TruffleCompilable { - private static final Handles HANDLES = new Handles(); - /** * Handle to {@code speculationLog} field of the {@code OptimizedCallTarget}. */ @@ -57,12 +51,8 @@ final class HSTruffleCompilable extends HSIndirectHandle implements TruffleCompi public SpeculationLog getCompilationSpeculationLog() { Long res = cachedFailedSpeculationsAddress; if (res == null) { - try { - res = (long) HANDLES.getFailedSpeculationsAddress.invoke(hsHandle); - cachedFailedSpeculationsAddress = res; - } catch (Throwable t) { - throw handleException(t); - } + res = TruffleFromLibGraalStartPoints.getFailedSpeculationsAddress(hsHandle); + cachedFailedSpeculationsAddress = res; } return HotSpotGraalServices.newHotSpotSpeculationLog(cachedFailedSpeculationsAddress); } @@ -70,59 +60,35 @@ public SpeculationLog getCompilationSpeculationLog() { @Override @SuppressWarnings("unchecked") public Map getCompilerOptions() { - try { - return (Map) HANDLES.getCompilerOptions.invoke(hsHandle); - } catch (Throwable t) { - throw handleException(t); - } + return TruffleFromLibGraalStartPoints.getCompilerOptions(hsHandle); } @Override public long engineId() { - try { - return (long) HANDLES.engineId.invoke(hsHandle); - } catch (Throwable t) { - throw handleException(t); - } + return TruffleFromLibGraalStartPoints.engineId(hsHandle); } @Override public boolean prepareForCompilation(boolean rootCompilation, int compilationTier, boolean lastTier) { - try { - return (boolean) HANDLES.prepareForCompilation.invoke(hsHandle, rootCompilation, compilationTier, lastTier); - } catch (Throwable t) { - throw handleException(t); - } + return TruffleFromLibGraalStartPoints.prepareForCompilation(hsHandle, rootCompilation, compilationTier, lastTier); } @Override public boolean isTrivial() { - try { - return (boolean) HANDLES.isTrivial.invoke(hsHandle); - } catch (Throwable t) { - throw handleException(t); - } + return TruffleFromLibGraalStartPoints.isTrivial(hsHandle); } @Override public JavaConstant asJavaConstant() { long constantHandle; - try { - constantHandle = (long) HANDLES.asJavaConstant.invoke(hsHandle); - } catch (Throwable t) { - throw handleException(t); - } + constantHandle = TruffleFromLibGraalStartPoints.asJavaConstant(hsHandle); return HotSpotJVMCIRuntime.runtime().unhand(JavaConstant.class, constantHandle); } @Override public void onCompilationFailed(Supplier serializedException, boolean suppressed, boolean bailout, boolean permanentBailout, boolean graphTooBig) { - try { - Object serializedExceptionHsHandle = HANDLES.createStringSupplier.invoke(serializedException); - HANDLES.onCompilationFailed.invoke(hsHandle, serializedExceptionHsHandle, suppressed, bailout, permanentBailout, graphTooBig); - } catch (Throwable t) { - throw handleException(t); - } + Object serializedExceptionHsHandle = TruffleFromLibGraalStartPoints.createStringSupplier(serializedException); + TruffleFromLibGraalStartPoints.onCompilationFailed(hsHandle, serializedExceptionHsHandle, suppressed, bailout, permanentBailout, graphTooBig); } @Override @@ -134,12 +100,8 @@ public boolean onInvalidate(Object source, CharSequence reason, boolean wasActiv public String getName() { String res = cachedName; if (res == null) { - try { - res = (String) HANDLES.getCompilableName.invoke(hsHandle); - cachedName = res; - } catch (Throwable t) { - throw handleException(t); - } + res = TruffleFromLibGraalStartPoints.getCompilableName(hsHandle); + cachedName = res; } return res; } @@ -148,86 +110,39 @@ public String getName() { public String toString() { String res = cachedString; if (res == null) { - try { - res = (String) HANDLES.compilableToString.invoke(hsHandle); - cachedString = res; - } catch (Throwable t) { - throw handleException(t); - } + res = TruffleFromLibGraalStartPoints.compilableToString(hsHandle); + cachedString = res; } return res; } @Override public int getNonTrivialNodeCount() { - try { - return (int) HANDLES.getNonTrivialNodeCount.invoke(hsHandle); - } catch (Throwable t) { - throw handleException(t); - } + return TruffleFromLibGraalStartPoints.getNonTrivialNodeCount(hsHandle); } @Override public int countDirectCallNodes() { - try { - return (int) HANDLES.countDirectCallNodes.invoke(hsHandle); - } catch (Throwable t) { - throw handleException(t); - } + return TruffleFromLibGraalStartPoints.countDirectCallNodes(hsHandle); } @Override public int getCallCount() { - try { - return (int) HANDLES.getCompilableCallCount.invoke(hsHandle); - } catch (Throwable t) { - throw handleException(t); - } + return TruffleFromLibGraalStartPoints.getCompilableCallCount(hsHandle); } @Override public boolean cancelCompilation(CharSequence reason) { - try { - return (boolean) HANDLES.cancelCompilation.invoke(hsHandle, reason); - } catch (Throwable t) { - throw handleException(t); - } + return TruffleFromLibGraalStartPoints.cancelCompilation(hsHandle, reason); } @Override public boolean isSameOrSplit(TruffleCompilable ast) { - try { - return (boolean) HANDLES.isSameOrSplit.invoke(hsHandle, ast == null ? null : ((HSTruffleCompilable) ast).hsHandle); - } catch (Throwable t) { - throw handleException(t); - } + return TruffleFromLibGraalStartPoints.isSameOrSplit(hsHandle, ast == null ? null : ((HSTruffleCompilable) ast).hsHandle); } @Override public int getKnownCallSiteCount() { - try { - return (int) HANDLES.getKnownCallSiteCount.invoke(hsHandle); - } catch (Throwable t) { - throw handleException(t); - } - } - - private static final class Handles { - final MethodHandle getFailedSpeculationsAddress = getHostMethodHandleOrFail(Id.GetFailedSpeculationsAddress); - final MethodHandle getCompilerOptions = getHostMethodHandleOrFail(Id.GetCompilerOptions); - final MethodHandle engineId = getHostMethodHandleOrFail(Id.EngineId); - final MethodHandle prepareForCompilation = getHostMethodHandleOrFail(Id.PrepareForCompilation); - final MethodHandle isTrivial = getHostMethodHandleOrFail(Id.IsTrivial); - final MethodHandle asJavaConstant = getHostMethodHandleOrFail(Id.AsJavaConstant); - final MethodHandle getCompilableName = getHostMethodHandleOrFail(Id.GetCompilableName); - final MethodHandle createStringSupplier = getHostMethodHandleOrFail(Id.CreateStringSupplier); - final MethodHandle onCompilationFailed = getHostMethodHandleOrFail(Id.OnCompilationFailed); - final MethodHandle getNonTrivialNodeCount = getHostMethodHandleOrFail(Id.GetNonTrivialNodeCount); - final MethodHandle countDirectCallNodes = getHostMethodHandleOrFail(Id.CountDirectCallNodes); - final MethodHandle getCompilableCallCount = getHostMethodHandleOrFail(Id.GetCompilableCallCount); - final MethodHandle compilableToString = getHostMethodHandleOrFail(Id.CompilableToString); - final MethodHandle cancelCompilation = getHostMethodHandleOrFail(Id.CancelCompilation); - final MethodHandle isSameOrSplit = getHostMethodHandleOrFail(Id.IsSameOrSplit); - final MethodHandle getKnownCallSiteCount = getHostMethodHandleOrFail(Id.GetKnownCallSiteCount); + return TruffleFromLibGraalStartPoints.getKnownCallSiteCount(hsHandle); } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilationTask.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilationTask.java index ef2fae863c73..e1d0cce4e3c9 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilationTask.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilationTask.java @@ -27,59 +27,36 @@ import com.oracle.truffle.compiler.TruffleCompilable; import com.oracle.truffle.compiler.TruffleCompilationTask; import com.oracle.truffle.compiler.TruffleSourceLanguagePosition; -import com.oracle.truffle.compiler.hotspot.libgraal.TruffleFromLibGraal.Id; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; import jdk.vm.ci.meta.JavaConstant; -import java.lang.invoke.MethodHandle; import java.util.Map; -import static jdk.graal.compiler.hotspot.libgraal.truffle.BuildTime.getHostMethodHandleOrFail; - final class HSTruffleCompilationTask extends HSIndirectHandle implements TruffleCompilationTask { - private static final Handles HANDLES = new Handles(); - HSTruffleCompilationTask(Object hsHandle) { super(hsHandle); } @Override public boolean isCancelled() { - try { - return (boolean) HANDLES.isCancelled.invoke(hsHandle); - } catch (Throwable t) { - throw handleException(t); - } + return TruffleFromLibGraalStartPoints.isCancelled(hsHandle); } @Override public boolean isLastTier() { - try { - return (boolean) HANDLES.isLastTier.invoke(hsHandle); - } catch (Throwable t) { - throw handleException(t); - } + return TruffleFromLibGraalStartPoints.isLastTier(hsHandle); } @Override public boolean hasNextTier() { - try { - return (boolean) HANDLES.hasNextTier.invoke(hsHandle); - } catch (Throwable t) { - throw handleException(t); - } + return TruffleFromLibGraalStartPoints.hasNextTier(hsHandle); } @Override public TruffleSourceLanguagePosition getPosition(JavaConstant node) { long nodeHandle = HotSpotJVMCIRuntime.runtime().translate(node); - Object positionHsHandle; - try { - positionHsHandle = HANDLES.getPosition.invoke(hsHandle, nodeHandle); - } catch (Throwable t) { - throw handleException(t); - } + Object positionHsHandle = TruffleFromLibGraalStartPoints.getPosition(hsHandle, nodeHandle); if (positionHsHandle == null) { return null; } else { @@ -89,50 +66,22 @@ public TruffleSourceLanguagePosition getPosition(JavaConstant node) { @Override public void addTargetToDequeue(TruffleCompilable target) { - try { - HANDLES.addTargetToDequeue.invoke(hsHandle, ((HSTruffleCompilable) target).hsHandle); - } catch (Throwable t) { - throw handleException(t); - } + TruffleFromLibGraalStartPoints.addTargetToDequeue(hsHandle, ((HSTruffleCompilable) target).hsHandle); } @Override public void setCallCounts(int total, int inlined) { - try { - HANDLES.setCallCounts.invoke(hsHandle, total, inlined); - } catch (Throwable t) { - throw handleException(t); - } + TruffleFromLibGraalStartPoints.setCallCounts(hsHandle, total, inlined); } @Override public void addInlinedTarget(TruffleCompilable target) { - try { - HANDLES.addInlinedTarget.invoke(hsHandle, ((HSTruffleCompilable) target).hsHandle); - } catch (Throwable t) { - throw handleException(t); - } + TruffleFromLibGraalStartPoints.addInlinedTarget(hsHandle, ((HSTruffleCompilable) target).hsHandle); } @Override - @SuppressWarnings("unchecked") public Map getDebugProperties(JavaConstant node) { - try { - long nodeHandle = HotSpotJVMCIRuntime.runtime().translate(node); - return (Map) HANDLES.getDebugProperties.invoke(hsHandle, nodeHandle); - } catch (Throwable t) { - throw handleException(t); - } - } - - private static final class Handles { - final MethodHandle isCancelled = getHostMethodHandleOrFail(Id.IsCancelled); - final MethodHandle hasNextTier = getHostMethodHandleOrFail(Id.HasNextTier); - final MethodHandle isLastTier = getHostMethodHandleOrFail(Id.IsLastTier); - final MethodHandle getPosition = getHostMethodHandleOrFail(Id.GetPosition); - final MethodHandle addTargetToDequeue = getHostMethodHandleOrFail(Id.AddTargetToDequeue); - final MethodHandle setCallCounts = getHostMethodHandleOrFail(Id.SetCallCounts); - final MethodHandle addInlinedTarget = getHostMethodHandleOrFail(Id.AddInlinedTarget); - final MethodHandle getDebugProperties = getHostMethodHandleOrFail(Id.GetDebugProperties); + long nodeHandle = HotSpotJVMCIRuntime.runtime().translate(node); + return TruffleFromLibGraalStartPoints.getDebugProperties(hsHandle, nodeHandle); } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilerListener.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilerListener.java index 8741ddac9cde..79f653b059fc 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilerListener.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilerListener.java @@ -27,17 +27,11 @@ import com.oracle.truffle.compiler.TruffleCompilable; import com.oracle.truffle.compiler.TruffleCompilationTask; import com.oracle.truffle.compiler.TruffleCompilerListener; -import com.oracle.truffle.compiler.hotspot.libgraal.TruffleFromLibGraal.Id; -import java.lang.invoke.MethodHandle; import java.util.function.Supplier; -import static jdk.graal.compiler.hotspot.libgraal.truffle.BuildTime.getHostMethodHandleOrFail; - final class HSTruffleCompilerListener extends HSIndirectHandle implements TruffleCompilerListener { - private static final Handles HANDLES = new Handles(); - HSTruffleCompilerListener(Object hsHandle) { super(hsHandle); } @@ -46,60 +40,32 @@ final class HSTruffleCompilerListener extends HSIndirectHandle implements Truffl public void onSuccess(TruffleCompilable compilable, TruffleCompilationTask task, GraphInfo graphInfo, CompilationResultInfo compilationResultInfo, int tier) { Object hsCompilable = ((HSTruffleCompilable) compilable).hsHandle; Object hsTask = ((HSTruffleCompilationTask) task).hsHandle; - try { - HANDLES.onSuccess.invoke(hsHandle, hsCompilable, hsTask, graphInfo, compilationResultInfo, tier); - } catch (Throwable t) { - throw handleException(t); - } + TruffleFromLibGraalStartPoints.onSuccess(hsHandle, hsCompilable, hsTask, graphInfo, compilationResultInfo, tier); } @Override public void onTruffleTierFinished(TruffleCompilable compilable, TruffleCompilationTask task, GraphInfo graph) { Object hsCompilable = ((HSTruffleCompilable) compilable).hsHandle; Object hsTask = ((HSTruffleCompilationTask) task).hsHandle; - try { - HANDLES.onTruffleTierFinished.invoke(hsHandle, hsCompilable, hsTask, graph); - } catch (Throwable t) { - throw handleException(t); - } + TruffleFromLibGraalStartPoints.onTruffleTierFinished(hsHandle, hsCompilable, hsTask, graph); } @Override public void onGraalTierFinished(TruffleCompilable compilable, GraphInfo graph) { Object hsCompilable = ((HSTruffleCompilable) compilable).hsHandle; - try { - HANDLES.onGraalTierFinished.invoke(hsHandle, hsCompilable, graph); - } catch (Throwable t) { - throw handleException(t); - } + TruffleFromLibGraalStartPoints.onGraalTierFinished(hsHandle, hsCompilable, graph); } @Override public void onFailure(TruffleCompilable compilable, String reason, boolean bailout, boolean permanentBailout, int tier, Supplier lazyStackTrace) { Object hsCompilable = ((HSTruffleCompilable) compilable).hsHandle; - try { - HANDLES.onFailure.invoke(hsHandle, hsCompilable, reason, bailout, permanentBailout, tier, lazyStackTrace); - } catch (Throwable t) { - throw handleException(t); - } + TruffleFromLibGraalStartPoints.onFailure(hsHandle, hsCompilable, reason, bailout, permanentBailout, tier, lazyStackTrace); } @Override public void onCompilationRetry(TruffleCompilable compilable, TruffleCompilationTask task) { Object hsCompilable = ((HSTruffleCompilable) compilable).hsHandle; Object hsTask = ((HSTruffleCompilationTask) task).hsHandle; - try { - HANDLES.onCompilationRetry.invoke(hsHandle, hsCompilable, hsTask); - } catch (Throwable t) { - throw handleException(t); - } - } - - private static final class Handles { - final MethodHandle onSuccess = getHostMethodHandleOrFail(Id.OnSuccess); - final MethodHandle onTruffleTierFinished = getHostMethodHandleOrFail(Id.OnTruffleTierFinished); - final MethodHandle onGraalTierFinished = getHostMethodHandleOrFail(Id.OnGraalTierFinished); - final MethodHandle onFailure = getHostMethodHandleOrFail(Id.OnFailure); - final MethodHandle onCompilationRetry = getHostMethodHandleOrFail(Id.OnCompilationRetry); + TruffleFromLibGraalStartPoints.onCompilationRetry(hsHandle, hsCompilable, hsTask); } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilerRuntime.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilerRuntime.java index e645e0fb4cff..2de5f52261a8 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilerRuntime.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilerRuntime.java @@ -30,9 +30,10 @@ import com.oracle.truffle.compiler.PartialEvaluationMethodInfo; import com.oracle.truffle.compiler.TruffleCompilable; import com.oracle.truffle.compiler.TruffleCompilerRuntime; -import com.oracle.truffle.compiler.hotspot.libgraal.TruffleFromLibGraal.Id; import jdk.graal.compiler.debug.GraalError; +import jdk.graal.compiler.libgraal.LibGraalUtil; +import jdk.graal.compiler.libgraal.NativeImageHostEntryPoints; import jdk.graal.compiler.truffle.hotspot.HotSpotTruffleCompilationSupport; import jdk.vm.ci.code.InstalledCode; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; @@ -45,51 +46,36 @@ import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; import jdk.vm.ci.meta.UnresolvedJavaType; +import org.graalvm.jniutils.HSObject; +import org.graalvm.jniutils.JNIMethodScope; +import org.graalvm.word.WordFactory; -import java.lang.invoke.MethodHandle; import java.util.Arrays; import java.util.function.Consumer; import java.util.function.Supplier; -import static jdk.graal.compiler.hotspot.libgraal.truffle.BuildTime.getHostMethodHandleOrFail; - final class HSTruffleCompilerRuntime extends HSIndirectHandle implements TruffleCompilerRuntime { - private static final Handles HANDLES = new Handles(); - static final String COMPILER_VERSION = HotSpotTruffleCompilationSupport.readCompilerVersion(); - private static final Class TRANSLATED_EXCEPTION; - static { - Class clz; - try { - clz = Class.forName("jdk.internal.vm.TranslatedException"); - } catch (ClassNotFoundException cnf) { - clz = null; - } - TRANSLATED_EXCEPTION = clz; - } + // TranslatedException is package-private + private static final Class TRANSLATED_EXCEPTION = LibGraalUtil.lookupClass("jdk.internal.vm.TranslatedException"); private final ResolvedJavaType classLoaderDelegate; - HSTruffleCompilerRuntime(Object hsHandle, long runtimeClass) { + public HSTruffleCompilerRuntime(Object hsHandle, long runtimeClass) { super(hsHandle); this.classLoaderDelegate = HotSpotJVMCIRuntime.runtime().asResolvedJavaType(runtimeClass); if (this.classLoaderDelegate == null) { throw GraalError.shouldNotReachHere("The object class needs to be available for a Truffle runtime object."); } - NativeImageHostCalls.initializeHost(runtimeClass); + NativeImageHostEntryPoints.initializeHost(runtimeClass); } @Override public PartialEvaluationMethodInfo getPartialEvaluationMethodInfo(ResolvedJavaMethod method) { long methodHandle = HotSpotJVMCIRuntime.runtime().translate(method); - byte[] array; - try { - array = (byte[]) HANDLES.getPartialEvaluationMethodInfo.invoke(hsHandle, methodHandle); - } catch (Throwable t) { - throw handleException(t); - } + byte[] array = TruffleFromLibGraalStartPoints.getPartialEvaluationMethodInfo(hsHandle, methodHandle); LoopExplosionKind loopExplosionKind = LoopExplosionKind.values()[array[0]]; InlineKind peInlineKind = InlineKind.values()[array[1]]; InlineKind inlineKind = InlineKind.values()[array[2]]; @@ -109,40 +95,31 @@ public TruffleCompilable asCompilableTruffleAST(JavaConstant constant) { return null; } long jniLocalRef = HotSpotJVMCIRuntime.runtime().getJObjectValue((HotSpotObjectConstant) constant); - Object compilableHsHandle = NativeImageHostCalls.createLocalHandleForLocalReference(jniLocalRef); - return compilableHsHandle == null ? null : new HSTruffleCompilable(compilableHsHandle); + JNIMethodScope scope = JNIMethodScope.scopeOrNull(); + if (scope == null) { + return null; + } + return new HSTruffleCompilable(new HSObject(scope, WordFactory.pointer(jniLocalRef))); } @Override public void onCodeInstallation(TruffleCompilable compilable, InstalledCode installedCode) { long installedCodeHandle = HotSpotJVMCIRuntime.runtime().translate(installedCode); - try { - HANDLES.onCodeInstallation.invoke(hsHandle, ((HSTruffleCompilable) compilable).hsHandle, installedCodeHandle); - } catch (Throwable t) { - throw handleException(t); - } + TruffleFromLibGraalStartPoints.onCodeInstallation(hsHandle, ((HSTruffleCompilable) compilable).hsHandle, installedCodeHandle); } @Override public Consumer registerOptimizedAssumptionDependency(JavaConstant optimizedAssumption) { long optimizedAssumptionHandle = HotSpotJVMCIRuntime.runtime().translate(optimizedAssumption); Object hsDependencyHandle; - try { - hsDependencyHandle = HANDLES.registerOptimizedAssumptionDependency.invoke(hsHandle, optimizedAssumptionHandle); - } catch (Throwable t) { - throw handleException(t); - } + hsDependencyHandle = TruffleFromLibGraalStartPoints.registerOptimizedAssumptionDependency(hsHandle, optimizedAssumptionHandle); return hsDependencyHandle == null ? null : new HSConsumer(hsDependencyHandle); } @Override public boolean isValueType(ResolvedJavaType type) { long typeHandle = HotSpotJVMCIRuntime.runtime().translate(type); - try { - return (boolean) HANDLES.isValueType.invoke(hsHandle, typeHandle); - } catch (Throwable t) { - throw handleException(t); - } + return TruffleFromLibGraalStartPoints.isValueType(hsHandle, typeHandle); } @Override @@ -166,12 +143,7 @@ public ConstantFieldInfo getConstantFieldInfo(ResolvedJavaField field) { Arrays.toString(declaredFields))); } long typeHandle = HotSpotJVMCIRuntime.runtime().translate(enclosingType); - int rawValue; - try { - rawValue = (int) HANDLES.getConstantFieldInfo.invoke(hsHandle, typeHandle, isStatic, fieldIndex); - } catch (Throwable t) { - throw handleException(t); - } + int rawValue = TruffleFromLibGraalStartPoints.getConstantFieldInfo(hsHandle, typeHandle, isStatic, fieldIndex); return switch (rawValue) { case Integer.MIN_VALUE -> null; case -1 -> ConstantFieldInfo.CHILD; @@ -224,31 +196,12 @@ private static String getInternalName(String fqn) { @Override public void log(String loggerId, TruffleCompilable compilable, String message) { - try { - HANDLES.log.invoke(hsHandle, loggerId, ((HSTruffleCompilable) compilable).hsHandle, message); - } catch (Throwable t) { - throw handleException(t); - } + TruffleFromLibGraalStartPoints.log(hsHandle, loggerId, ((HSTruffleCompilable) compilable).hsHandle, message); } @Override public boolean isSuppressedFailure(TruffleCompilable compilable, Supplier serializedException) { - try { - Object supplierHsHandle = HANDLES.createStringSupplier.invoke(serializedException); - return (boolean) HANDLES.isSuppressedFailure.invoke(hsHandle, ((HSTruffleCompilable) compilable).hsHandle, supplierHsHandle); - } catch (Throwable t) { - throw handleException(t); - } - } - - private static final class Handles { - final MethodHandle getPartialEvaluationMethodInfo = getHostMethodHandleOrFail(Id.GetPartialEvaluationMethodInfo); - final MethodHandle onCodeInstallation = getHostMethodHandleOrFail(Id.OnCodeInstallation); - final MethodHandle registerOptimizedAssumptionDependency = getHostMethodHandleOrFail(Id.RegisterOptimizedAssumptionDependency); - final MethodHandle isValueType = getHostMethodHandleOrFail(Id.IsValueType); - final MethodHandle getConstantFieldInfo = getHostMethodHandleOrFail(Id.GetConstantFieldInfo); - final MethodHandle log = getHostMethodHandleOrFail(Id.Log); - final MethodHandle createStringSupplier = getHostMethodHandleOrFail(Id.CreateStringSupplier); - final MethodHandle isSuppressedFailure = getHostMethodHandleOrFail(Id.IsSuppressedFailure); + Object supplierHsHandle = TruffleFromLibGraalStartPoints.createStringSupplier(serializedException); + return TruffleFromLibGraalStartPoints.isSuppressedFailure(hsHandle, ((HSTruffleCompilable) compilable).hsHandle, supplierHsHandle); } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleSourceLanguagePosition.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleSourceLanguagePosition.java index 0895789ec68c..088eb216a6ca 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleSourceLanguagePosition.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleSourceLanguagePosition.java @@ -25,103 +25,53 @@ package jdk.graal.compiler.hotspot.libgraal.truffle; import com.oracle.truffle.compiler.TruffleSourceLanguagePosition; -import com.oracle.truffle.compiler.hotspot.libgraal.TruffleFromLibGraal.Id; -import java.lang.invoke.MethodHandle; import java.net.URI; -import static jdk.graal.compiler.hotspot.libgraal.truffle.BuildTime.getHostMethodHandleOrFail; - final class HSTruffleSourceLanguagePosition extends HSIndirectHandle implements TruffleSourceLanguagePosition { - private static final Handles HANDLES = new Handles(); - HSTruffleSourceLanguagePosition(Object hsHandle) { super(hsHandle); } @Override public String getDescription() { - try { - return (String) HANDLES.getDescription.invoke(hsHandle); - } catch (Throwable t) { - throw handleException(t); - } + return TruffleFromLibGraalStartPoints.getDescription(hsHandle); } @Override public int getOffsetEnd() { - try { - return (int) HANDLES.getOffsetEnd.invoke(hsHandle); - } catch (Throwable t) { - throw handleException(t); - } + return TruffleFromLibGraalStartPoints.getOffsetEnd(hsHandle); } @Override public int getOffsetStart() { - try { - return (int) HANDLES.getOffsetStart.invoke(hsHandle); - } catch (Throwable t) { - throw handleException(t); - } + return TruffleFromLibGraalStartPoints.getOffsetStart(hsHandle); } @Override public int getLineNumber() { - try { - return (int) HANDLES.getLineNumber.invoke(hsHandle); - } catch (Throwable t) { - throw handleException(t); - } + return TruffleFromLibGraalStartPoints.getLineNumber(hsHandle); } @Override public URI getURI() { - String uri; - try { - uri = (String) HANDLES.getURI.invoke(hsHandle); - } catch (Throwable t) { - throw handleException(t); - } + String uri = TruffleFromLibGraalStartPoints.getURI(hsHandle); return uri == null ? null : URI.create(uri); } @Override public String getLanguage() { - try { - return (String) HANDLES.getLanguage.invoke(hsHandle); - } catch (Throwable t) { - throw handleException(t); - } + return TruffleFromLibGraalStartPoints.getLanguage(hsHandle); } @Override public int getNodeId() { - try { - return (int) HANDLES.getNodeId.invoke(hsHandle); - } catch (Throwable t) { - throw handleException(t); - } + return TruffleFromLibGraalStartPoints.getNodeId(hsHandle); } @Override public String getNodeClassName() { - try { - return (String) HANDLES.getNodeClassName.invoke(hsHandle); - } catch (Throwable t) { - throw handleException(t); - } - } - - private static final class Handles { - final MethodHandle getOffsetStart = getHostMethodHandleOrFail(Id.GetOffsetStart); - final MethodHandle getOffsetEnd = getHostMethodHandleOrFail(Id.GetOffsetEnd); - final MethodHandle getLineNumber = getHostMethodHandleOrFail(Id.GetLineNumber); - final MethodHandle getLanguage = getHostMethodHandleOrFail(Id.GetLanguage); - final MethodHandle getDescription = getHostMethodHandleOrFail(Id.GetDescription); - final MethodHandle getURI = getHostMethodHandleOrFail(Id.GetURI); - final MethodHandle getNodeClassName = getHostMethodHandleOrFail(Id.GetNodeClassName); - final MethodHandle getNodeId = getHostMethodHandleOrFail(Id.GetNodeId); + return TruffleFromLibGraalStartPoints.getNodeClassName(hsHandle); } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalObjectHandleScope.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalObjectHandleScope.java similarity index 97% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalObjectHandleScope.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalObjectHandleScope.java index 6a200d09c32c..bc70d1810bd3 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalObjectHandleScope.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalObjectHandleScope.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.libgraal; +package jdk.graal.compiler.hotspot.libgraal.truffle; import java.io.Closeable; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalObjectHandles.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalObjectHandles.java similarity index 97% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalObjectHandles.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalObjectHandles.java index 6b4cb7ae5ec7..44183a37107e 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalObjectHandles.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalObjectHandles.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.libgraal; +package jdk.graal.compiler.hotspot.libgraal.truffle; import jdk.graal.compiler.word.Word; import org.graalvm.nativeimage.ObjectHandles; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleEntryPoints.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleEntryPoints.java new file mode 100644 index 000000000000..18573fc00dee --- /dev/null +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleEntryPoints.java @@ -0,0 +1,541 @@ +/* + * Copyright (c) 2024, 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 jdk.graal.compiler.hotspot.libgraal.truffle; + +import java.util.Objects; +import java.util.function.Supplier; + +import org.graalvm.jniutils.HSObject; +import org.graalvm.jniutils.JNI.JByteArray; +import org.graalvm.jniutils.JNI.JClass; +import org.graalvm.jniutils.JNI.JNIEnv; +import org.graalvm.jniutils.JNI.JObject; +import org.graalvm.jniutils.JNI.JObjectArray; +import org.graalvm.jniutils.JNI.JString; +import org.graalvm.jniutils.JNIExceptionWrapper; +import org.graalvm.jniutils.JNIMethodScope; +import org.graalvm.jniutils.JNIUtil; +import org.graalvm.nativebridge.BinaryOutput; +import org.graalvm.nativeimage.ObjectHandles; +import org.graalvm.nativeimage.c.function.CEntryPoint; +import org.graalvm.nativeimage.c.function.CEntryPoint.IsolateThreadContext; +import org.graalvm.nativeimage.c.type.CLongPointer; +import org.graalvm.word.PointerBase; +import org.graalvm.word.WordFactory; + +import com.oracle.truffle.compiler.TruffleCompilable; +import com.oracle.truffle.compiler.TruffleCompilerListener; +import com.oracle.truffle.compiler.TruffleCompilerOptionDescriptor; +import com.oracle.truffle.compiler.hotspot.libgraal.TruffleToLibGraal; +import com.oracle.truffle.compiler.hotspot.libgraal.TruffleToLibGraal.Id; + +import jdk.graal.compiler.hotspot.CompilationContext; +import jdk.graal.compiler.hotspot.HotSpotGraalServices; +import jdk.graal.compiler.libgraal.LibGraalFeature; +import jdk.graal.compiler.libgraal.LibGraalJNIMethodScope; +import jdk.graal.compiler.libgraal.LibGraalUtil; +import jdk.graal.compiler.libgraal.NativeImageHostEntryPoints; +import jdk.graal.compiler.truffle.TruffleCompilerOptions; +import jdk.graal.compiler.truffle.hotspot.HotSpotTruffleCompilationSupport; +import jdk.graal.compiler.truffle.hotspot.HotSpotTruffleCompilerImpl; +import jdk.graal.nativeimage.LibGraalRuntime; +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; +import jdk.vm.ci.hotspot.HotSpotVMConfigAccess; +import jdk.vm.ci.meta.ResolvedJavaMethod; + +/** + * Truffle specific {@link CEntryPoint} implementations. + */ +public class LibGraalTruffleEntryPoints { + + private static volatile int lastJavaPCOffset = -1; + + private static JNIMethodScope openScope(Enum id, JNIEnv env) { + Objects.requireNonNull(id, "Id must be non null."); + String scopeName = LibGraalUtil.getUnqualifiedName(LibGraalTruffleEntryPoints.class) + "::" + id; + int offset = lastJavaPCOffset; + if (offset == -1) { + HotSpotVMConfigAccess configAccess = new HotSpotVMConfigAccess(HotSpotJVMCIRuntime.runtime().getConfigStore()); + int anchor = configAccess.getFieldOffset("JavaThread::_anchor", Integer.class, "JavaFrameAnchor"); + int lastJavaPc = configAccess.getFieldOffset("JavaFrameAnchor::_last_Java_pc", Integer.class, "address"); + offset = anchor + lastJavaPc; + lastJavaPCOffset = offset; + } + + long currentJavaThread = HotSpotJVMCIRuntime.runtime().getCurrentJavaThread(); + CLongPointer currentThreadLastJavaPCOffset = (CLongPointer) WordFactory.unsigned(currentJavaThread).add(offset); + PointerBase javaFrameAnchor = WordFactory.pointer(currentThreadLastJavaPCOffset.read()); + return LibGraalJNIMethodScope.open(scopeName, env, javaFrameAnchor.isNonNull()); + } + + @SuppressWarnings({"unused", "try"}) + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_initializeIsolate", include = LibGraalFeature.IsEnabled.class) + @TruffleToLibGraal(Id.InitializeIsolate) + public static void initializeIsolate(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, JClass runtimeClass) { + try (JNIMethodScope s = openScope(Id.InitializeIsolate, env)) { + TruffleFromLibGraalStartPoints.initializeJNI(runtimeClass); + TruffleLibGraalShutdownHook.registerShutdownHook(); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + } + } + + @SuppressWarnings({"unused", "try"}) + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_registerRuntime", include = LibGraalFeature.IsEnabled.class) + @TruffleToLibGraal(Id.RegisterRuntime) + public static boolean registerRuntime(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, JObject truffleRuntime) { + try (JNIMethodScope s = openScope(Id.RegisterRuntime, env)) { + long truffleRuntimeWeakRef = JNIUtil.NewWeakGlobalRef(env, truffleRuntime, "TruffleCompilerRuntime").rawValue(); + return LibGraalTruffleHostEnvironmentLookup.registerRuntime(truffleRuntimeWeakRef); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + return false; + } + } + + @SuppressWarnings({"unused", "try"}) + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_initializeRuntime", include = LibGraalFeature.IsEnabled.class) + @TruffleToLibGraal(Id.InitializeRuntime) + public static long initializeRuntime(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, + JObject truffleRuntime, JClass hsClassLoaderDelegate) { + try (JNIMethodScope s = openScope(Id.InitializeRuntime, env)) { + HSObject hsHandle = new HSObject(env, truffleRuntime, true, false); + HSTruffleCompilerRuntime hsTruffleRuntime = new HSTruffleCompilerRuntime(hsHandle, hsClassLoaderDelegate.rawValue()); + return LibGraalObjectHandles.create(hsTruffleRuntime); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + return 0L; + } + } + + @SuppressWarnings({"unused", "try"}) + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_newCompiler", include = LibGraalFeature.IsEnabled.class) + @TruffleToLibGraal(Id.NewCompiler) + public static long newCompiler(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long truffleRuntimeHandle) { + try (JNIMethodScope s = openScope(Id.NewCompiler, env)) { + Object truffleRuntime = LibGraalObjectHandles.resolve(truffleRuntimeHandle, Object.class); + /* + * Unlike `LibGraalTruffleHostEnvironment`, Truffle libgraal entry points use the global + * compilation context by default, so we don't need to call + * `HotSpotGraalServices.enterGlobalCompilationContext()` before creating + * `TruffleCompilerImpl`. The `doCompile` method enters a local compilation context + * through its own call to `HotSpotGraalServices.openLocalCompilationContext`. + */ + HotSpotTruffleCompilerImpl compiler = HotSpotTruffleCompilerImpl.create((HSTruffleCompilerRuntime) truffleRuntime, null); + return LibGraalObjectHandles.create(compiler); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + return 0; + } + } + + @SuppressWarnings("unused") + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_initializeCompiler", include = LibGraalFeature.IsEnabled.class) + @TruffleToLibGraal(Id.InitializeRuntime) + public static void initializeCompiler(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long compilerHandle, JObject hsCompilable, + boolean firstInitialization) { + try (JNIMethodScope scope = openScope(Id.InitializeCompiler, env)) { + HotSpotTruffleCompilerImpl compiler = LibGraalObjectHandles.resolve(compilerHandle, HotSpotTruffleCompilerImpl.class); + Object compilableHsHandle = new HSObject(scope, hsCompilable); + TruffleCompilable compilable = new HSTruffleCompilable(compilableHsHandle); + compiler.initialize(compilable, firstInitialization); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + } + } + + @SuppressWarnings({"unused", "try"}) + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getCompilerConfigurationFactoryName", include = LibGraalFeature.IsEnabled.class) + @TruffleToLibGraal(Id.GetCompilerConfigurationFactoryName) + public static JString getCompilerConfigurationFactoryName(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long truffleRuntimeHandle) { + try { + JNIMethodScope scope = openScope(Id.GetCompilerConfigurationFactoryName, env); + try (JNIMethodScope s = scope) { + String name = HotSpotTruffleCompilationSupport.getLazyCompilerConfigurationName(); + scope.setObjectResult(JNIUtil.createHSString(env, name)); + } + return scope.getObjectResult(); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + return WordFactory.nullPointer(); + } + } + + @SuppressWarnings({"unused", "try"}) + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_doCompile", include = LibGraalFeature.IsEnabled.class) + @TruffleToLibGraal(Id.DoCompile) + public static void doCompile(JNIEnv env, + JClass hsClazz, + @IsolateThreadContext long isolateThreadId, + long compilerHandle, + JObject hsTask, + JObject hsCompilable, + JObject hsListener) { + try (JNIMethodScope scope = openScope(Id.DoCompile, env)) { + HotSpotTruffleCompilerImpl compiler = LibGraalObjectHandles.resolve(compilerHandle, HotSpotTruffleCompilerImpl.class); + Object taskHsHandle = hsTask.isNull() ? null : new HSObject(scope, hsTask); + Object compilableHsHandle = new HSObject(scope, hsCompilable); + Object listenerHsHandle = hsListener.isNull() ? null : new HSObject(scope, hsListener); + try { + HSTruffleCompilationTask task = taskHsHandle == null ? null : new HSTruffleCompilationTask(taskHsHandle); + HSTruffleCompilerListener listener = listenerHsHandle == null ? null : new HSTruffleCompilerListener(listenerHsHandle); + HSTruffleCompilable compilable = new HSTruffleCompilable(compilableHsHandle); + try (CompilationContext hotSpotObjectConstantScope = HotSpotGraalServices.openLocalCompilationContext(compilable)) { + compiler.doCompile(task, compilable, listener); + } + } finally { + LibGraalRuntime.processReferences(); + LibGraalRuntime.notifyLowMemoryPoint(true); + } + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + } + } + + @SuppressWarnings({"unused", "try"}) + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_shutdown", include = LibGraalFeature.IsEnabled.class) + @TruffleToLibGraal(Id.Shutdown) + public static void shutdown(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle) { + try (JNIMethodScope s = openScope(Id.Shutdown, env)) { + HotSpotTruffleCompilerImpl compiler = LibGraalObjectHandles.resolve(handle, HotSpotTruffleCompilerImpl.class); + compiler.shutdown(); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + } + } + + @SuppressWarnings({"unused", "try"}) + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_installTruffleCallBoundaryMethod", include = LibGraalFeature.IsEnabled.class) + @TruffleToLibGraal(Id.InstallTruffleCallBoundaryMethod) + public static void installTruffleCallBoundaryMethod(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle, long methodHandle) { + try (JNIMethodScope s = openScope(Id.InstallTruffleCallBoundaryMethod, env)) { + HotSpotTruffleCompilerImpl compiler = LibGraalObjectHandles.resolve(handle, HotSpotTruffleCompilerImpl.class); + compiler.installTruffleCallBoundaryMethod(HotSpotJVMCIRuntime.runtime().unhand(ResolvedJavaMethod.class, methodHandle), null); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + } + } + + @SuppressWarnings({"unused", "try"}) + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_installTruffleReservedOopMethod", include = LibGraalFeature.IsEnabled.class) + @TruffleToLibGraal(Id.InstallTruffleReservedOopMethod) + public static void installTruffleReservedOopMethod(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle, long methodHandle) { + try (JNIMethodScope s = openScope(Id.InstallTruffleReservedOopMethod, env)) { + HotSpotTruffleCompilerImpl compiler = LibGraalObjectHandles.resolve(handle, HotSpotTruffleCompilerImpl.class); + compiler.installTruffleReservedOopMethod(HotSpotJVMCIRuntime.runtime().unhand(ResolvedJavaMethod.class, methodHandle), null); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + } + } + + @SuppressWarnings("unused") + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_pendingTransferToInterpreterOffset", include = LibGraalFeature.IsEnabled.class) + @TruffleToLibGraal(Id.PendingTransferToInterpreterOffset) + public static int pendingTransferToInterpreterOffset(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle, JObject hsCompilable) { + try (JNIMethodScope scope = openScope(Id.PendingTransferToInterpreterOffset, env)) { + HotSpotTruffleCompilerImpl compiler = LibGraalObjectHandles.resolve(handle, HotSpotTruffleCompilerImpl.class); + Object compilableHsHandle = new HSObject(scope, hsCompilable); + TruffleCompilable compilable = new HSTruffleCompilable(compilableHsHandle); + return compiler.pendingTransferToInterpreterOffset(compilable); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + return 0; + } + } + + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getSuppliedString", include = LibGraalFeature.IsEnabled.class) + @SuppressWarnings({"unused", "try", "unchecked"}) + @TruffleToLibGraal(Id.GetSuppliedString) + public static JString getSuppliedString(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle) { + try { + JNIMethodScope scope = openScope(Id.GetSuppliedString, env); + try (JNIMethodScope s = scope) { + Supplier stringSupplier = LibGraalObjectHandles.resolve(handle, Supplier.class); + if (stringSupplier != null) { + String stackTrace = stringSupplier.get(); + scope.setObjectResult(JNIUtil.createHSString(env, stackTrace)); + } else { + scope.setObjectResult(WordFactory.nullPointer()); + } + } + return scope.getObjectResult(); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + return WordFactory.nullPointer(); + } + } + + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getNodeCount", include = LibGraalFeature.IsEnabled.class) + @SuppressWarnings({"unused", "try"}) + @TruffleToLibGraal(Id.GetNodeCount) + public static int getNodeCount(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle) { + try (JNIMethodScope s = openScope(Id.GetNodeCount, env)) { + Object graphInfo = LibGraalObjectHandles.resolve(handle, Object.class); + return ((TruffleCompilerListener.GraphInfo) graphInfo).getNodeCount(); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + return 0; + } + } + + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getNodeTypes", include = LibGraalFeature.IsEnabled.class) + @SuppressWarnings({"unused", "try"}) + @TruffleToLibGraal(Id.GetNodeTypes) + public static JObjectArray getNodeTypes(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle, boolean simpleNames) { + try { + JNIMethodScope scope = openScope(Id.GetNodeTypes, env); + try (JNIMethodScope s = scope) { + Object graphInfo = LibGraalObjectHandles.resolve(handle, Object.class); + String[] nodeTypes = ((TruffleCompilerListener.GraphInfo) graphInfo).getNodeTypes(simpleNames); + JClass componentType = getStringClass(env); + JObjectArray res = JNIUtil.NewObjectArray(env, nodeTypes.length, componentType, WordFactory.nullPointer()); + for (int i = 0; i < nodeTypes.length; i++) { + JNIUtil.SetObjectArrayElement(env, res, i, JNIUtil.createHSString(env, nodeTypes[i])); + } + scope.setObjectResult(res); + } + return scope.getObjectResult(); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + return WordFactory.nullPointer(); + } + } + + private static JClass getStringClass(JNIEnv env) { + return JNIUtil.NewGlobalRef(env, JNIUtil.findClass(env, "java/lang/String"), "Class"); + } + + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getTargetCodeSize", include = LibGraalFeature.IsEnabled.class) + @SuppressWarnings({"unused", "try"}) + @TruffleToLibGraal(Id.GetTargetCodeSize) + public static int getTargetCodeSize(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle) { + try (JNIMethodScope s = openScope(Id.GetTargetCodeSize, env)) { + Object compilationResultInfo = LibGraalObjectHandles.resolve(handle, Object.class); + return ((TruffleCompilerListener.CompilationResultInfo) compilationResultInfo).getTargetCodeSize(); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + return 0; + } + } + + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getTotalFrameSize", include = LibGraalFeature.IsEnabled.class) + @SuppressWarnings({"unused", "try"}) + @TruffleToLibGraal(Id.GetTotalFrameSize) + public static int getTotalFrameSize(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle) { + try (JNIMethodScope s = openScope(Id.GetTotalFrameSize, env)) { + Object compilationResultInfo = LibGraalObjectHandles.resolve(handle, Object.class); + return ((TruffleCompilerListener.CompilationResultInfo) compilationResultInfo).getTotalFrameSize(); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + return 0; + } + } + + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getExceptionHandlersCount", include = LibGraalFeature.IsEnabled.class) + @SuppressWarnings({"unused", "try"}) + @TruffleToLibGraal(Id.GetExceptionHandlersCount) + public static int getExceptionHandlersCount(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle) { + try (JNIMethodScope s = openScope(Id.GetExceptionHandlersCount, env)) { + Object compilationResultInfo = LibGraalObjectHandles.resolve(handle, Object.class); + return ((TruffleCompilerListener.CompilationResultInfo) compilationResultInfo).getExceptionHandlersCount(); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + return 0; + } + } + + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getInfopointsCount", include = LibGraalFeature.IsEnabled.class) + @SuppressWarnings({"unused", "try"}) + @TruffleToLibGraal(Id.GetInfopointsCount) + public static int getInfopointsCount(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle) { + try (JNIMethodScope s = openScope(Id.GetInfopointsCount, env)) { + Object compilationResultInfo = LibGraalObjectHandles.resolve(handle, Object.class); + return ((TruffleCompilerListener.CompilationResultInfo) compilationResultInfo).getInfopointsCount(); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + return 0; + } + } + + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getInfopoints", include = LibGraalFeature.IsEnabled.class) + @SuppressWarnings({"unused", "try"}) + @TruffleToLibGraal(Id.GetInfopoints) + public static JObjectArray getInfopoints(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle) { + try { + JNIMethodScope scope = openScope(Id.GetInfopoints, env); + try (JNIMethodScope s = scope) { + Object compilationResultInfo = LibGraalObjectHandles.resolve(handle, Object.class); + String[] infoPoints = ((TruffleCompilerListener.CompilationResultInfo) compilationResultInfo).getInfopoints(); + JClass componentType = getStringClass(env); + JObjectArray res = JNIUtil.NewObjectArray(env, infoPoints.length, componentType, WordFactory.nullPointer()); + for (int i = 0; i < infoPoints.length; i++) { + JNIUtil.SetObjectArrayElement(env, res, i, JNIUtil.createHSString(env, infoPoints[i])); + } + scope.setObjectResult(res); + } + return scope.getObjectResult(); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + return WordFactory.nullPointer(); + } + } + + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getMarksCount", include = LibGraalFeature.IsEnabled.class) + @SuppressWarnings({"unused", "try"}) + @TruffleToLibGraal(Id.GetMarksCount) + public static int getMarksCount(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle) { + try (JNIMethodScope s = openScope(Id.GetMarksCount, env)) { + Object compilationResultInfo = LibGraalObjectHandles.resolve(handle, Object.class); + return ((TruffleCompilerListener.CompilationResultInfo) compilationResultInfo).getMarksCount(); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + return 0; + } + } + + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getDataPatchesCount", include = LibGraalFeature.IsEnabled.class) + @SuppressWarnings({"unused", "try"}) + @TruffleToLibGraal(Id.GetDataPatchesCount) + public static int getDataPatchesCount(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle) { + try (JNIMethodScope s = openScope(Id.GetDataPatchesCount, env)) { + Object compilationResultInfo = LibGraalObjectHandles.resolve(handle, Object.class); + return ((TruffleCompilerListener.CompilationResultInfo) compilationResultInfo).getDataPatchesCount(); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + return 0; + } + } + + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_listCompilerOptions", include = LibGraalFeature.IsEnabled.class) + @SuppressWarnings({"unused", "try"}) + @TruffleToLibGraal(Id.ListCompilerOptions) + public static JByteArray listCompilerOptions(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId) { + try { + JNIMethodScope scope = openScope(Id.ListCompilerOptions, env); + try (JNIMethodScope s = scope) { + TruffleCompilerOptionDescriptor[] options1 = TruffleCompilerOptions.listOptions(); + Object[] result = new Object[options1.length]; + for (int i1 = 0; i1 < options1.length; i1++) { + TruffleCompilerOptionDescriptor option = options1[i1]; + result[i1] = NativeImageHostEntryPoints.createTruffleCompilerOptionDescriptor(option.name(), option.type().ordinal(), option.deprecated(), option.help(), + option.deprecationMessage()); + } + Object[] options = result; + BinaryOutput.ByteArrayBinaryOutput out = BinaryOutput.create(); + out.writeInt(options.length); + for (int i = 0; i < options.length; i++) { + TruffleCompilerOptionDescriptor descriptor = (TruffleCompilerOptionDescriptor) options[i]; + out.writeUTF(descriptor.name()); + out.writeInt(descriptor.type().ordinal()); + out.writeBoolean(descriptor.deprecated()); + out.writeUTF(descriptor.help()); + out.writeUTF(descriptor.deprecationMessage()); + } + JByteArray res = JNIUtil.createHSArray(env, out.getArray()); + scope.setObjectResult(res); + } + return scope.getObjectResult(); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + return WordFactory.nullPointer(); + } + } + + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_compilerOptionExists", include = LibGraalFeature.IsEnabled.class) + @SuppressWarnings({"unused", "try"}) + @TruffleToLibGraal(Id.CompilerOptionExists) + public static boolean compilerOptionExists(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, JString optionName) { + try (JNIMethodScope scope = openScope(Id.CompilerOptionExists, env)) { + String optionName1 = JNIUtil.createString(env, optionName); + return TruffleCompilerOptions.optionExists(optionName1); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + return false; + } + } + + private static String validateCompilerOption(String optionName, String optionValue) { + return TruffleCompilerOptions.validateOption(optionName, optionValue); + } + + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_validateCompilerOption", include = LibGraalFeature.IsEnabled.class) + @SuppressWarnings({"unused", "try"}) + @TruffleToLibGraal(Id.ValidateCompilerOption) + public static JString validateCompilerOption(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, JString optionName, JString optionValue) { + try { + JNIMethodScope scope = openScope(Id.ValidateCompilerOption, env); + try (JNIMethodScope s = scope) { + String result = validateCompilerOption(JNIUtil.createString(env, optionName), JNIUtil.createString(env, optionValue)); + scope.setObjectResult(JNIUtil.createHSString(env, result)); + } + return scope.getObjectResult(); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + return WordFactory.nullPointer(); + } + } + + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_purgePartialEvaluationCaches", include = LibGraalFeature.IsEnabled.class) + @SuppressWarnings({"unused", "try"}) + @TruffleToLibGraal(Id.PurgePartialEvaluationCaches) + public static void purgePartialEvaluationCaches(JNIEnv env, JClass hsClass, @IsolateThreadContext long isolateThreadId, long compilerHandle) { + try (JNIMethodScope s = openScope(Id.PurgePartialEvaluationCaches, env)) { + HotSpotTruffleCompilerImpl compiler = LibGraalObjectHandles.resolve(compilerHandle, HotSpotTruffleCompilerImpl.class); + if (compiler != null) { + compiler.purgePartialEvaluationCaches(); + } + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + } + } + + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getCompilerVersion", include = LibGraalFeature.IsEnabled.class) + @SuppressWarnings({"unused", "try"}) + @TruffleToLibGraal(Id.GetCompilerVersion) + public static JString getCompilerVersion(JNIEnv env, JClass hsClass, @IsolateThreadContext long isolateThreadId) { + try { + JNIMethodScope scope = openScope(Id.GetCompilerVersion, env); + try (JNIMethodScope s = scope) { + String version = HSTruffleCompilerRuntime.COMPILER_VERSION; + scope.setObjectResult(JNIUtil.createHSString(env, version)); + } + return scope.getObjectResult(); + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(env, t); + return WordFactory.nullPointer(); + } + } + + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_LibGraalObject_releaseHandle", include = LibGraalFeature.IsEnabled.class) + @SuppressWarnings("unused") + public static boolean releaseHandle(JNIEnv jniEnv, JClass jclass, @IsolateThreadContext long isolateThreadId, long handle) { + try { + ObjectHandles.getGlobal().destroy(WordFactory.pointer(handle)); + return true; + } catch (Throwable t) { + return false; + } + } +} diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleHostEnvironment.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleHostEnvironment.java index 3ac8c3faa522..8712155becbe 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleHostEnvironment.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleHostEnvironment.java @@ -131,10 +131,9 @@ private static MethodHandle findCompilerThreadCanCallJavaScopeConstructor() { try { return MethodHandles.lookup().findConstructor(Class.forName("jdk.vm.ci.hotspot.CompilerThreadCanCallJavaScope"), MethodType.methodType(void.class, boolean.class)); } catch (ReflectiveOperationException e) { -// GR-58987: Uncomment when OpenJDK pull request is merged -// if (Runtime.version().feature() >= 24) { -// throw new InternalError(e); -// } + if (Runtime.version().feature() >= 24) { + throw new InternalError(e); + } } return null; } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleHostEnvironmentLookup.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleHostEnvironmentLookup.java index bc5f5e185814..72aaf3ee9bbd 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleHostEnvironmentLookup.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleHostEnvironmentLookup.java @@ -24,6 +24,7 @@ */ package jdk.graal.compiler.hotspot.libgraal.truffle; +import jdk.graal.compiler.libgraal.NativeImageHostEntryPoints; import jdk.graal.compiler.serviceprovider.GlobalAtomicLong; import jdk.graal.compiler.truffle.host.TruffleHostEnvironment; import jdk.graal.compiler.truffle.host.TruffleHostEnvironment.TruffleRuntimeScope; @@ -59,7 +60,7 @@ public TruffleHostEnvironment lookup(ResolvedJavaType forType) { // fast path if Truffle was not initialized return null; } - Object runtimeLocalHandle = NativeImageHostCalls.createLocalHandleForWeakGlobalReference(globalReference); + Object runtimeLocalHandle = NativeImageHostEntryPoints.createLocalHandleForWeakGlobalReference(globalReference); if (runtimeLocalHandle == null) { // The Truffle runtime was collected by the GC return null; @@ -67,7 +68,7 @@ public TruffleHostEnvironment lookup(ResolvedJavaType forType) { TruffleHostEnvironment environment = this.previousRuntime; if (environment != null) { Object cached = hsRuntime(environment).hsHandle; - if (NativeImageHostCalls.isSameObject(cached, runtimeLocalHandle)) { + if (NativeImageHostEntryPoints.isSameObject(cached, runtimeLocalHandle)) { // fast path for registered and cached Truffle runtime handle return environment; } @@ -77,7 +78,9 @@ public TruffleHostEnvironment lookup(ResolvedJavaType forType) { * per type. So in theory multiple truffle runtimes can be loaded. */ try (TruffleRuntimeScope scope = LibGraalTruffleHostEnvironment.openTruffleRuntimeScopeImpl()) { - HSTruffleCompilerRuntime runtime = new HSTruffleCompilerRuntime(NativeImageHostCalls.createGlobalHandle(runtimeLocalHandle, true), NativeImageHostCalls.getObjectClass(runtimeLocalHandle)); + HSTruffleCompilerRuntime runtime = new HSTruffleCompilerRuntime( + NativeImageHostEntryPoints.createGlobalHandle(runtimeLocalHandle, true), + NativeImageHostEntryPoints.getObjectClass(runtimeLocalHandle)); this.previousRuntime = environment = new LibGraalTruffleHostEnvironment(runtime, HotSpotJVMCIRuntime.runtime().getHostJVMCIBackend().getMetaAccess()); return environment; } @@ -87,7 +90,7 @@ private static HSTruffleCompilerRuntime hsRuntime(TruffleHostEnvironment environ return (HSTruffleCompilerRuntime) environment.runtime(); } - static boolean registerRuntime(long truffleRuntimeWeakRef) { + public static boolean registerRuntime(long truffleRuntimeWeakRef) { // TODO GR-44222 support multiple runtimes. return WEAK_TRUFFLE_RUNTIME_INSTANCE.compareAndSet(0, truffleRuntimeWeakRef); } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleScopeEntryPoints.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleScopeEntryPoints.java new file mode 100644 index 000000000000..1da61a7c549a --- /dev/null +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleScopeEntryPoints.java @@ -0,0 +1,30 @@ +package jdk.graal.compiler.hotspot.libgraal.truffle; + +import org.graalvm.nativeimage.Isolate; +import org.graalvm.nativeimage.IsolateThread; +import org.graalvm.nativeimage.c.function.CEntryPoint; +import org.graalvm.word.PointerBase; + +import jdk.graal.compiler.libgraal.LibGraalFeature; +import jdk.graal.compiler.serviceprovider.IsolateUtil; + +/** + * Truffle specific {@link CEntryPoint} implementations. + */ +final class LibGraalTruffleScopeEntryPoints { + + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_LibGraalScope_getIsolateThreadIn", builtin = CEntryPoint.Builtin.GET_CURRENT_THREAD, include = LibGraalFeature.IsEnabled.class) + private static native IsolateThread getIsolateThreadIn(PointerBase env, PointerBase hsClazz, @CEntryPoint.IsolateContext Isolate isolate); + + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_LibGraalScope_attachThreadTo", builtin = CEntryPoint.Builtin.ATTACH_THREAD, include = LibGraalFeature.IsEnabled.class) + static native long attachThreadTo(PointerBase env, PointerBase hsClazz, @CEntryPoint.IsolateContext long isolate); + + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_LibGraalScope_detachThreadFrom", builtin = CEntryPoint.Builtin.DETACH_THREAD, include = LibGraalFeature.IsEnabled.class) + static native void detachThreadFrom(PointerBase env, PointerBase hsClazz, @CEntryPoint.IsolateThreadContext long isolateThread); + + @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_LibGraalScope_getIsolateId", include = LibGraalFeature.IsEnabled.class) + @SuppressWarnings("unused") + public static long getIsolateId(PointerBase env, PointerBase jclass, @CEntryPoint.IsolateThreadContext long isolateThreadId) { + return IsolateUtil.getIsolateID(); + } +} diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/NativeImageHostCalls.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/NativeImageHostCalls.java deleted file mode 100644 index 89b9f7470b2c..000000000000 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/NativeImageHostCalls.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 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 jdk.graal.compiler.hotspot.libgraal.truffle; - -import java.lang.invoke.MethodHandle; - -import static jdk.graal.compiler.hotspot.libgraal.truffle.BuildTime.getHostMethodHandleOrFail; - -/** - * Methods to call Native image specific API. - */ -final class NativeImageHostCalls { - - private static final Handles HANDLES = new Handles(); - - private NativeImageHostCalls() { - } - - // libgraal to native-image upcalls - - static void initializeHost(long runtimeClass) { - try { - HANDLES.initializeHost.invoke(runtimeClass); - } catch (Throwable t) { - throw HSIndirectHandle.handleException(t); - } - } - - static Object createLocalHandleForLocalReference(long jniLocalHandle) { - try { - return HANDLES.createLocalHandleForLocalReference.invoke(jniLocalHandle); - } catch (Throwable t) { - throw HSIndirectHandle.handleException(t); - } - } - - static Object createLocalHandleForWeakGlobalReference(long jniLocalHandle) { - try { - return HANDLES.createLocalHandleForWeakGlobalReference.invoke(jniLocalHandle); - } catch (Throwable t) { - throw HSIndirectHandle.handleException(t); - } - } - - static Object createGlobalHandle(Object hsHandle, boolean allowGlobalDuplicates) { - try { - return HANDLES.createGlobalHandle.invoke(hsHandle, allowGlobalDuplicates); - } catch (Throwable t) { - throw HSIndirectHandle.handleException(t); - } - } - - static boolean isSameObject(Object o1, Object o2) { - try { - return (boolean) HANDLES.isSameObject.invoke(o1, o2); - } catch (Throwable t) { - throw HSIndirectHandle.handleException(t); - } - } - - static long getObjectClass(Object o) { - try { - return (long) HANDLES.getObjectClass.invoke(o); - } catch (Throwable t) { - throw HSIndirectHandle.handleException(t); - } - } - - static Object createTruffleCompilerOptionDescriptor(String name, int type, boolean deprecated, String help, String deprecationMessage) { - try { - return HANDLES.createTruffleCompilerOptionDescriptor.invoke(name, type, deprecated, help, deprecationMessage); - } catch (Throwable t) { - throw HSIndirectHandle.handleException(t); - } - } - - private static final class Handles { - final MethodHandle initializeHost = getHostMethodHandleOrFail("initializeHost"); - final MethodHandle createLocalHandleForLocalReference = getHostMethodHandleOrFail("createLocalHandleForLocalReference"); - final MethodHandle createLocalHandleForWeakGlobalReference = getHostMethodHandleOrFail("createLocalHandleForWeakGlobalReference"); - final MethodHandle createGlobalHandle = getHostMethodHandleOrFail("createGlobalHandle"); - final MethodHandle isSameObject = getHostMethodHandleOrFail("isSameObject"); - final MethodHandle getObjectClass = getHostMethodHandleOrFail("getObjectClass"); - final MethodHandle createTruffleCompilerOptionDescriptor = getHostMethodHandleOrFail("createTruffleCompilerOptionDescriptor"); - } -} diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/TruffleFromLibGraalCalls.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/TruffleFromLibGraalCalls.java similarity index 97% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/TruffleFromLibGraalCalls.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/TruffleFromLibGraalCalls.java index f545171bd64f..73f581244d0f 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/TruffleFromLibGraalCalls.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/TruffleFromLibGraalCalls.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.libgraal; +package jdk.graal.compiler.hotspot.libgraal.truffle; import static org.graalvm.jniutils.JNIUtil.NewGlobalRef; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/TruffleFromLibGraalStartPoints.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/TruffleFromLibGraalStartPoints.java similarity index 80% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/TruffleFromLibGraalStartPoints.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/TruffleFromLibGraalStartPoints.java index f140c07db87f..ffe25165a39f 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/TruffleFromLibGraalStartPoints.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/TruffleFromLibGraalStartPoints.java @@ -22,55 +22,55 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.libgraal; - -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callAddInlinedTarget; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callAddTargetToDequeue; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callAsJavaConstant; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callCancelCompilation; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callCompilableToString; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callConsumeOptimizedAssumptionDependency; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callCountDirectCallNodes; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callCreateStringSupplier; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callEngineId; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetCompilableCallCount; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetCompilableName; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetCompilerOptions; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetConstantFieldInfo; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetDebugProperties; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetDescription; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetFailedSpeculationsAddress; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetKnownCallSiteCount; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetLanguage; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetLineNumber; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetNodeClassName; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetNodeId; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetNonTrivialNodeCount; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetOffsetEnd; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetOffsetStart; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetPartialEvaluationMethodInfo; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetPosition; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetSuppliedString; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callGetURI; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callHasNextTier; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callIsCancelled; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callIsLastTier; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callIsSameOrSplit; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callIsSuppressedFailure; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callIsTrivial; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callIsValueType; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callLog; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callOnCodeInstallation; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callOnCompilationFailed; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callOnCompilationRetry; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callOnFailure; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callOnGraalTierFinished; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callOnIsolateShutdown; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callOnSuccess; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callOnTruffleTierFinished; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callPrepareForCompilation; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callRegisterOptimizedAssumptionDependency; -import static jdk.graal.compiler.libgraal.TruffleFromLibGraalStartPointsGen.callSetCallCounts; +package jdk.graal.compiler.hotspot.libgraal.truffle; + +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callAddInlinedTarget; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callAddTargetToDequeue; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callAsJavaConstant; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callCancelCompilation; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callCompilableToString; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callConsumeOptimizedAssumptionDependency; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callCountDirectCallNodes; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callCreateStringSupplier; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callEngineId; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetCompilableCallCount; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetCompilableName; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetCompilerOptions; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetConstantFieldInfo; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetDebugProperties; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetDescription; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetFailedSpeculationsAddress; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetKnownCallSiteCount; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetLanguage; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetLineNumber; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetNodeClassName; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetNodeId; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetNonTrivialNodeCount; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetOffsetEnd; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetOffsetStart; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetPartialEvaluationMethodInfo; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetPosition; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetSuppliedString; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetURI; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callHasNextTier; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callIsCancelled; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callIsLastTier; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callIsSameOrSplit; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callIsSuppressedFailure; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callIsTrivial; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callIsValueType; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callLog; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnCodeInstallation; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnCompilationFailed; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnCompilationRetry; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnFailure; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnGraalTierFinished; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnIsolateShutdown; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnSuccess; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnTruffleTierFinished; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callPrepareForCompilation; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callRegisterOptimizedAssumptionDependency; +import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callSetCallCounts; import static org.graalvm.jniutils.JNIMethodScope.env; import static org.graalvm.jniutils.JNIUtil.ExceptionClear; import static org.graalvm.jniutils.JNIUtil.GetStaticMethodID; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/TruffleLibGraalShutdownHook.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/TruffleLibGraalShutdownHook.java index 8f7c013202fc..6c8b13ba4781 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/TruffleLibGraalShutdownHook.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/TruffleLibGraalShutdownHook.java @@ -24,16 +24,11 @@ */ package jdk.graal.compiler.hotspot.libgraal.truffle; -import com.oracle.truffle.compiler.hotspot.libgraal.TruffleFromLibGraal.Id; import jdk.graal.compiler.serviceprovider.IsolateUtil; import jdk.graal.compiler.serviceprovider.ServiceProvider; import jdk.vm.ci.hotspot.HotSpotVMEventListener; import jdk.vm.ci.services.JVMCIServiceLocator; -import java.lang.invoke.MethodHandle; - -import static jdk.graal.compiler.hotspot.libgraal.truffle.BuildTime.getHostMethodHandleOrFail; - @ServiceProvider(JVMCIServiceLocator.class) public class TruffleLibGraalShutdownHook extends JVMCIServiceLocator { @@ -48,21 +43,19 @@ protected S getProvider(Class service) { return null; } - static void registerShutdownHook() { + public static void registerShutdownHook() { registeredHook = new ShutdownHook(); } static class ShutdownHook implements HotSpotVMEventListener { - private static final Handles HANDLES = new Handles(); - ShutdownHook() { } @Override public void notifyShutdown() { try { - HANDLES.onIsolateShutdown.invoke(IsolateUtil.getIsolateID()); + TruffleFromLibGraalStartPoints.onIsolateShutdown(IsolateUtil.getIsolateID()); } catch (RuntimeException | Error e) { throw e; } catch (Throwable t) { @@ -70,8 +63,4 @@ public void notifyShutdown() { } } } - - private static final class Handles { - final MethodHandle onIsolateShutdown = getHostMethodHandleOrFail(Id.OnIsolateShutdown); - } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalEntryPoints.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalEntryPoints.java index 673e6234411c..a887343037e7 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalEntryPoints.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalEntryPoints.java @@ -26,53 +26,25 @@ import java.io.ByteArrayOutputStream; import java.io.PrintStream; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles.Lookup; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Map; -import java.util.Objects; -import java.util.Set; import java.util.function.BiConsumer; -import java.util.stream.Collectors; -import com.oracle.truffle.compiler.TruffleCompilerOptionDescriptor; -import com.oracle.truffle.compiler.hotspot.libgraal.TruffleToLibGraal; -import com.oracle.truffle.compiler.hotspot.libgraal.TruffleToLibGraal.Id; -import jdk.graal.compiler.debug.GraalError; import jdk.graal.compiler.hotspot.libgraal.RunTime; import jdk.graal.compiler.options.OptionValues; -import jdk.graal.compiler.serviceprovider.IsolateUtil; import jdk.graal.compiler.word.Word; import jdk.graal.nativeimage.LibGraalRuntime; import org.graalvm.collections.EconomicSet; -import org.graalvm.jniutils.HSObject; -import org.graalvm.jniutils.JNI.JByteArray; -import org.graalvm.jniutils.JNI.JClass; import org.graalvm.jniutils.JNI.JNIEnv; -import org.graalvm.jniutils.JNI.JObject; -import org.graalvm.jniutils.JNI.JObjectArray; -import org.graalvm.jniutils.JNI.JString; import org.graalvm.jniutils.JNIExceptionWrapper; import org.graalvm.jniutils.JNIMethodScope; -import org.graalvm.jniutils.JNIUtil; -import org.graalvm.nativebridge.BinaryOutput; -import org.graalvm.nativeimage.ImageSingletons; -import org.graalvm.nativeimage.Isolate; -import org.graalvm.nativeimage.IsolateThread; -import org.graalvm.nativeimage.ObjectHandles; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; import org.graalvm.nativeimage.RuntimeOptions; import org.graalvm.nativeimage.c.function.CEntryPoint; -import org.graalvm.nativeimage.c.function.CEntryPoint.Builtin; -import org.graalvm.nativeimage.c.function.CEntryPoint.IsolateContext; import org.graalvm.nativeimage.c.function.CEntryPoint.IsolateThreadContext; -import org.graalvm.nativeimage.c.type.CLongPointer; import org.graalvm.nativeimage.c.type.CTypeConversion; import org.graalvm.word.PointerBase; @@ -250,557 +222,3 @@ static void printOptions(PrintStream out, String prefix) { }); } } - -final class LibGraalScopeEntryPoints { - - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_LibGraalScope_getIsolateThreadIn", builtin = Builtin.GET_CURRENT_THREAD) - private static native IsolateThread getIsolateThreadIn(PointerBase env, PointerBase hsClazz, @IsolateContext Isolate isolate); - - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_LibGraalScope_attachThreadTo", builtin = Builtin.ATTACH_THREAD) - static native long attachThreadTo(PointerBase env, PointerBase hsClazz, @IsolateContext long isolate); - - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_LibGraalScope_detachThreadFrom", builtin = Builtin.DETACH_THREAD) - static native void detachThreadFrom(PointerBase env, PointerBase hsClazz, @IsolateThreadContext long isolateThread); - - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_LibGraalScope_getIsolateId") - @SuppressWarnings("unused") - public static long getIsolateId(PointerBase env, PointerBase jclass, @IsolateThreadContext long isolateThreadId) { - return IsolateUtil.getIsolateID(); - } -} - -final class LibGraalTruffleToLibGraalEntryPoints { - - private static volatile int lastJavaPCOffset = -1; - - /* - * Each of the following MethodHandle fields corresponds to a TruffleToLibGraal.Id value. The - * naming convention requires that each field name match the method name returned by - * TruffleToLibGraal.Id.getMethodName(). Additionally, the GraalEntryPoints method that the - * MethodHandle references must also follow this naming convention. The null MethodHandle values - * are overwritten reflectively in the constructor - */ - private final MethodHandle initializeIsolate = null; - private final MethodHandle registerRuntime = null; - private final MethodHandle initializeRuntime = null; - private final MethodHandle newCompiler = null; - private final MethodHandle initializeCompiler = null; - private final MethodHandle getCompilerConfigurationFactoryName = null; - private final MethodHandle doCompile = null; - private final MethodHandle shutdown = null; - private final MethodHandle installTruffleCallBoundaryMethod = null; - private final MethodHandle installTruffleReservedOopMethod = null; - private final MethodHandle pendingTransferToInterpreterOffset = null; - private final MethodHandle getSuppliedString = null; - private final MethodHandle getNodeCount = null; - private final MethodHandle getNodeTypes = null; - private final MethodHandle getTargetCodeSize = null; - private final MethodHandle getTotalFrameSize = null; - private final MethodHandle getExceptionHandlersCount = null; - private final MethodHandle getInfopointsCount = null; - private final MethodHandle getInfopoints = null; - private final MethodHandle listCompilerOptions = null; - private final MethodHandle compilerOptionExists = null; - private final MethodHandle validateCompilerOption = null; - private final MethodHandle getMarksCount = null; - private final MethodHandle getDataPatchesCount = null; - private final MethodHandle purgePartialEvaluationCaches = null; - private final MethodHandle getCompilerVersion = null; - - private final MethodHandle getCurrentJavaThread; - private final MethodHandle getLastJavaPCOffset; - - @Platforms(Platform.HOSTED_ONLY.class) - LibGraalTruffleToLibGraalEntryPoints(Lookup libgraalLookup, Class graalEntryPoints) { - try { - Map graalMethodByName = Arrays.stream(graalEntryPoints.getDeclaredMethods()).// - filter((m) -> Modifier.isStatic(m.getModifiers()) && Modifier.isPublic(m.getModifiers())).// - collect(Collectors.toMap(Method::getName, (m) -> m)); - /* - * hostMethodByName is used solely to ensure that all delegation methods have been - * implemented. - */ - Set hostMethodByName = Arrays.stream(getClass().getDeclaredMethods()).// - filter((m) -> Modifier.isStatic(m.getModifiers()) && m.getAnnotation(TruffleToLibGraal.class) != null).// - map(Method::getName).// - collect(Collectors.toSet()); - for (Id id : Id.values()) { - String methodName = id.getMethodName(); - Method method = graalMethodByName.get(methodName); - if (method == null) { - throw new GraalError("Missing libgraal entry method %s.%s corresponding to TruffleToLibGraal.Id.%s. " + - "To resolve this, add `public static %s()` in %s, where the and correspond to TruffleToLibGraalCalls.%s.", - LibGraalUtil.getUnqualifiedName(graalEntryPoints), methodName, id, methodName, graalEntryPoints.getName(), methodName); - } - if (!hostMethodByName.contains(methodName)) { - throw new GraalError("Missing C entry point method %s.%s corresponding to TruffleToLibGraal.Id.%s. " + - "To resolve this, add `@CEntryPoint(\"Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_%s\") " + - "@TruffleToLibGraal(Id.%s) static %s(JNIEnv env, JClass jclass, @IsolateThreadContext long isolateThreadId, " + - ")` in %s, where the and correspond to TruffleToLibGraalCalls.%s. " + - "Use a MethodHandle to delegate to %s.%s.", - LibGraalUtil.getUnqualifiedName(getClass()), methodName, id, methodName, id, methodName, getClass().getName(), methodName, - graalEntryPoints.getName(), methodName); - } - Field methodHandleField; - try { - methodHandleField = getClass().getDeclaredField(methodName); - } catch (NoSuchFieldException nsf) { - throw new GraalError("Missing field %s.%s corresponding to TruffleToLibGraal.Id.%s. " + - "To resolve this, add `private final MethodHandle %s = null;` to %s.", - LibGraalUtil.getUnqualifiedName(getClass()), methodName, id, methodName, getClass().getName()); - } - methodHandleField.setAccessible(true); - methodHandleField.set(this, libgraalLookup.unreflect(method)); - } - Method m = graalMethodByName.get("getCurrentJavaThread"); - if (m == null) { - throw new GraalError("Missing libgraal entry method %s.getCurrentJavaThread.", LibGraalUtil.getUnqualifiedName(graalEntryPoints)); - } - getCurrentJavaThread = libgraalLookup.unreflect(m); - m = graalMethodByName.get("getLastJavaPCOffset"); - if (m == null) { - throw new GraalError("Missing libgraal entry method %s.getLastJavaPCOffset.", LibGraalUtil.getUnqualifiedName(graalEntryPoints)); - } - getLastJavaPCOffset = libgraalLookup.unreflect(m); - } catch (ReflectiveOperationException e) { - throw GraalError.shouldNotReachHere(e); - } - } - - private static JNIMethodScope openScope(Enum id, JNIEnv env) throws Throwable { - Objects.requireNonNull(id, "Id must be non null."); - String scopeName = LibGraalUtil.getUnqualifiedName(LibGraalTruffleToLibGraalEntryPoints.class) + "::" + id; - int offset = lastJavaPCOffset; - if (offset == -1) { - offset = (int) singleton().getLastJavaPCOffset.invoke(); - lastJavaPCOffset = offset; - } - CLongPointer currentThreadLastJavaPCOffset = (CLongPointer) Word.unsigned((long) singleton().getCurrentJavaThread.invoke()).add(offset); - PointerBase javaFrameAnchor = Word.pointer(currentThreadLastJavaPCOffset.read()); - return LibGraalJNIMethodScope.open(scopeName, env, javaFrameAnchor.isNonNull()); - } - - private static LibGraalTruffleToLibGraalEntryPoints singleton() { - return ImageSingletons.lookup(LibGraalTruffleToLibGraalEntryPoints.class); - } - - @SuppressWarnings({"unused", "try"}) - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_initializeIsolate") - @TruffleToLibGraal(Id.InitializeIsolate) - public static void initializeIsolate(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, JClass runtimeClass) { - try (JNIMethodScope s = openScope(Id.InitializeIsolate, env)) { - TruffleFromLibGraalStartPoints.initializeJNI(runtimeClass); - singleton().initializeIsolate.invoke(); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - } - } - - @SuppressWarnings({"unused", "try"}) - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_registerRuntime") - @TruffleToLibGraal(Id.RegisterRuntime) - public static boolean registerRuntime(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, JObject truffleRuntime) { - try (JNIMethodScope s = openScope(Id.RegisterRuntime, env)) { - return (boolean) singleton().registerRuntime.invoke(JNIUtil.NewWeakGlobalRef(env, truffleRuntime, "TruffleCompilerRuntime").rawValue()); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - return false; - } - } - - @SuppressWarnings({"unused", "try"}) - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_initializeRuntime") - @TruffleToLibGraal(Id.InitializeRuntime) - public static long initializeRuntime(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, - JObject truffleRuntime, JClass hsClassLoaderDelegate) { - try (JNIMethodScope s = openScope(Id.InitializeRuntime, env)) { - HSObject hsHandle = new HSObject(env, truffleRuntime, true, false); - Object hsTruffleRuntime = singleton().initializeRuntime.invoke(hsHandle, hsClassLoaderDelegate.rawValue()); - return LibGraalObjectHandles.create(hsTruffleRuntime); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - return 0L; - } - } - - @SuppressWarnings({"unused", "try"}) - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_newCompiler") - @TruffleToLibGraal(Id.NewCompiler) - public static long newCompiler(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long truffleRuntimeHandle) { - try (JNIMethodScope s = openScope(Id.NewCompiler, env)) { - Object truffleRuntime = LibGraalObjectHandles.resolve(truffleRuntimeHandle, Object.class); - Object compiler = singleton().newCompiler.invoke(truffleRuntime); - return LibGraalObjectHandles.create(compiler); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - return 0; - } - } - - @SuppressWarnings("unused") - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_initializeCompiler") - @TruffleToLibGraal(Id.InitializeRuntime) - public static void initializeCompiler(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long compilerHandle, JObject hsCompilable, - boolean firstInitialization) { - try (JNIMethodScope scope = openScope(Id.InitializeCompiler, env)) { - Object compiler = LibGraalObjectHandles.resolve(compilerHandle, Object.class); - singleton().initializeCompiler.invoke(compiler, new HSObject(scope, hsCompilable), firstInitialization); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - } - } - - @SuppressWarnings({"unused", "try"}) - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getCompilerConfigurationFactoryName") - @TruffleToLibGraal(Id.GetCompilerConfigurationFactoryName) - public static JString getCompilerConfigurationFactoryName(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long truffleRuntimeHandle) { - try { - JNIMethodScope scope = openScope(Id.GetCompilerConfigurationFactoryName, env); - try (JNIMethodScope s = scope) { - String name = (String) singleton().getCompilerConfigurationFactoryName.invoke(); - scope.setObjectResult(JNIUtil.createHSString(env, name)); - } - return scope.getObjectResult(); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - return Word.nullPointer(); - } - } - - @SuppressWarnings({"unused", "try"}) - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_doCompile") - @TruffleToLibGraal(Id.DoCompile) - public static void doCompile(JNIEnv env, - JClass hsClazz, - @IsolateThreadContext long isolateThreadId, - long compilerHandle, - JObject hsTask, - JObject hsCompilable, - JObject hsListener) { - try (JNIMethodScope scope = openScope(Id.DoCompile, env)) { - Object compiler = LibGraalObjectHandles.resolve(compilerHandle, Object.class); - Object taskHsHandle = hsTask.isNull() ? null : new HSObject(scope, hsTask); - Object compilableHsHandle = new HSObject(scope, hsCompilable); - Object listenerHsHandle = hsListener.isNull() ? null : new HSObject(scope, hsListener); - try { - singleton().doCompile.invoke(compiler, taskHsHandle, compilableHsHandle, listenerHsHandle); - } finally { - LibGraalRuntime.processReferences(); - LibGraalRuntime.notifyLowMemoryPoint(true); - } - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - } - } - - @SuppressWarnings({"unused", "try"}) - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_shutdown") - @TruffleToLibGraal(Id.Shutdown) - public static void shutdown(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle) { - try (JNIMethodScope s = openScope(Id.Shutdown, env)) { - Object compiler = LibGraalObjectHandles.resolve(handle, Object.class); - singleton().shutdown.invoke(compiler); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - } - } - - @SuppressWarnings({"unused", "try"}) - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_installTruffleCallBoundaryMethod") - @TruffleToLibGraal(Id.InstallTruffleCallBoundaryMethod) - public static void installTruffleCallBoundaryMethod(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle, long methodHandle) { - try (JNIMethodScope s = openScope(Id.InstallTruffleCallBoundaryMethod, env)) { - Object compiler = LibGraalObjectHandles.resolve(handle, Object.class); - singleton().installTruffleCallBoundaryMethod.invoke(compiler, methodHandle); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - } - } - - @SuppressWarnings({"unused", "try"}) - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_installTruffleReservedOopMethod") - @TruffleToLibGraal(Id.InstallTruffleReservedOopMethod) - public static void installTruffleReservedOopMethod(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle, long methodHandle) { - try (JNIMethodScope s = openScope(Id.InstallTruffleReservedOopMethod, env)) { - Object compiler = LibGraalObjectHandles.resolve(handle, Object.class); - singleton().installTruffleReservedOopMethod.invoke(compiler, methodHandle); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - } - } - - @SuppressWarnings("unused") - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_pendingTransferToInterpreterOffset") - @TruffleToLibGraal(Id.PendingTransferToInterpreterOffset) - public static int pendingTransferToInterpreterOffset(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle, JObject hsCompilable) { - try (JNIMethodScope scope = openScope(Id.PendingTransferToInterpreterOffset, env)) { - Object compiler = LibGraalObjectHandles.resolve(handle, Object.class); - return (int) singleton().pendingTransferToInterpreterOffset.invoke(compiler, new HSObject(scope, hsCompilable)); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - return 0; - } - } - - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getSuppliedString") - @SuppressWarnings({"unused", "try"}) - @TruffleToLibGraal(Id.GetSuppliedString) - public static JString getSuppliedString(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle) { - try { - JNIMethodScope scope = openScope(Id.GetSuppliedString, env); - try (JNIMethodScope s = scope) { - Object stringSupplier = LibGraalObjectHandles.resolve(handle, Object.class); - if (stringSupplier != null) { - String stackTrace = (String) singleton().getSuppliedString.invoke(stringSupplier); - scope.setObjectResult(JNIUtil.createHSString(env, stackTrace)); - } else { - scope.setObjectResult(Word.nullPointer()); - } - } - return scope.getObjectResult(); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - return Word.nullPointer(); - } - } - - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getNodeCount") - @SuppressWarnings({"unused", "try"}) - @TruffleToLibGraal(Id.GetNodeCount) - public static int getNodeCount(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle) { - try (JNIMethodScope s = openScope(Id.GetNodeCount, env)) { - Object graphInfo = LibGraalObjectHandles.resolve(handle, Object.class); - return (int) singleton().getNodeCount.invoke(graphInfo); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - return 0; - } - } - - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getNodeTypes") - @SuppressWarnings({"unused", "try"}) - @TruffleToLibGraal(Id.GetNodeTypes) - public static JObjectArray getNodeTypes(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle, boolean simpleNames) { - try { - JNIMethodScope scope = openScope(Id.GetNodeTypes, env); - try (JNIMethodScope s = scope) { - Object graphInfo = LibGraalObjectHandles.resolve(handle, Object.class); - String[] nodeTypes = (String[]) singleton().getNodeTypes.invoke(graphInfo, simpleNames); - JClass componentType = getStringClass(env); - JObjectArray res = JNIUtil.NewObjectArray(env, nodeTypes.length, componentType, Word.nullPointer()); - for (int i = 0; i < nodeTypes.length; i++) { - JNIUtil.SetObjectArrayElement(env, res, i, JNIUtil.createHSString(env, nodeTypes[i])); - } - scope.setObjectResult(res); - } - return scope.getObjectResult(); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - return Word.nullPointer(); - } - } - - private static JClass getStringClass(JNIEnv env) { - return JNIUtil.NewGlobalRef(env, JNIUtil.findClass(env, "java/lang/String"), "Class"); - } - - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getTargetCodeSize") - @SuppressWarnings({"unused", "try"}) - @TruffleToLibGraal(Id.GetTargetCodeSize) - public static int getTargetCodeSize(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle) { - try (JNIMethodScope s = openScope(Id.GetTargetCodeSize, env)) { - Object compilationResultInfo = LibGraalObjectHandles.resolve(handle, Object.class); - return (int) singleton().getTargetCodeSize.invoke(compilationResultInfo); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - return 0; - } - } - - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getTotalFrameSize") - @SuppressWarnings({"unused", "try"}) - @TruffleToLibGraal(Id.GetTotalFrameSize) - public static int getTotalFrameSize(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle) { - try (JNIMethodScope s = openScope(Id.GetTotalFrameSize, env)) { - Object compilationResultInfo = LibGraalObjectHandles.resolve(handle, Object.class); - return (int) singleton().getTotalFrameSize.invoke(compilationResultInfo); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - return 0; - } - } - - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getExceptionHandlersCount") - @SuppressWarnings({"unused", "try"}) - @TruffleToLibGraal(Id.GetExceptionHandlersCount) - public static int getExceptionHandlersCount(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle) { - try (JNIMethodScope s = openScope(Id.GetExceptionHandlersCount, env)) { - Object compilationResultInfo = LibGraalObjectHandles.resolve(handle, Object.class); - return (int) singleton().getExceptionHandlersCount.invoke(compilationResultInfo); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - return 0; - } - } - - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getInfopointsCount") - @SuppressWarnings({"unused", "try"}) - @TruffleToLibGraal(Id.GetInfopointsCount) - public static int getInfopointsCount(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle) { - try (JNIMethodScope s = openScope(Id.GetInfopointsCount, env)) { - Object compilationResultInfo = LibGraalObjectHandles.resolve(handle, Object.class); - return (int) singleton().getInfopointsCount.invoke(compilationResultInfo); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - return 0; - } - } - - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getInfopoints") - @SuppressWarnings({"unused", "try"}) - @TruffleToLibGraal(Id.GetInfopoints) - public static JObjectArray getInfopoints(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle) { - try { - JNIMethodScope scope = openScope(Id.GetInfopoints, env); - try (JNIMethodScope s = scope) { - Object compilationResultInfo = LibGraalObjectHandles.resolve(handle, Object.class); - String[] infoPoints = (String[]) singleton().getInfopoints.invoke(compilationResultInfo); - JClass componentType = getStringClass(env); - JObjectArray res = JNIUtil.NewObjectArray(env, infoPoints.length, componentType, Word.nullPointer()); - for (int i = 0; i < infoPoints.length; i++) { - JNIUtil.SetObjectArrayElement(env, res, i, JNIUtil.createHSString(env, infoPoints[i])); - } - scope.setObjectResult(res); - } - return scope.getObjectResult(); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - return Word.nullPointer(); - } - } - - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getMarksCount") - @SuppressWarnings({"unused", "try"}) - @TruffleToLibGraal(Id.GetMarksCount) - public static int getMarksCount(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle) { - try (JNIMethodScope s = openScope(Id.GetMarksCount, env)) { - Object compilationResultInfo = LibGraalObjectHandles.resolve(handle, Object.class); - return (int) singleton().getMarksCount.invoke(compilationResultInfo); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - return 0; - } - } - - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getDataPatchesCount") - @SuppressWarnings({"unused", "try"}) - @TruffleToLibGraal(Id.GetDataPatchesCount) - public static int getDataPatchesCount(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, long handle) { - try (JNIMethodScope s = openScope(Id.GetDataPatchesCount, env)) { - Object compilationResultInfo = LibGraalObjectHandles.resolve(handle, Object.class); - return (int) singleton().getDataPatchesCount.invoke(compilationResultInfo); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - return 0; - } - } - - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_listCompilerOptions") - @SuppressWarnings({"unused", "try"}) - @TruffleToLibGraal(Id.ListCompilerOptions) - public static JByteArray listCompilerOptions(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId) { - try { - JNIMethodScope scope = openScope(Id.ListCompilerOptions, env); - try (JNIMethodScope s = scope) { - Object[] options = (Object[]) singleton().listCompilerOptions.invoke(); - BinaryOutput.ByteArrayBinaryOutput out = BinaryOutput.create(); - out.writeInt(options.length); - for (int i = 0; i < options.length; i++) { - TruffleCompilerOptionDescriptor descriptor = (TruffleCompilerOptionDescriptor) options[i]; - out.writeUTF(descriptor.name()); - out.writeInt(descriptor.type().ordinal()); - out.writeBoolean(descriptor.deprecated()); - out.writeUTF(descriptor.help()); - out.writeUTF(descriptor.deprecationMessage()); - } - JByteArray res = JNIUtil.createHSArray(env, out.getArray()); - scope.setObjectResult(res); - } - return scope.getObjectResult(); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - return Word.nullPointer(); - } - } - - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_compilerOptionExists") - @SuppressWarnings({"unused", "try"}) - @TruffleToLibGraal(Id.CompilerOptionExists) - public static boolean compilerOptionExists(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, JString optionName) { - try (JNIMethodScope scope = openScope(Id.CompilerOptionExists, env)) { - return (boolean) singleton().compilerOptionExists.invoke(JNIUtil.createString(env, optionName)); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - return false; - } - } - - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_validateCompilerOption") - @SuppressWarnings({"unused", "try"}) - @TruffleToLibGraal(Id.ValidateCompilerOption) - public static JString validateCompilerOption(JNIEnv env, JClass hsClazz, @IsolateThreadContext long isolateThreadId, JString optionName, JString optionValue) { - try { - JNIMethodScope scope = openScope(Id.ValidateCompilerOption, env); - try (JNIMethodScope s = scope) { - String result = (String) singleton().validateCompilerOption.invoke(JNIUtil.createString(env, optionName), JNIUtil.createString(env, optionValue)); - scope.setObjectResult(JNIUtil.createHSString(env, result)); - } - return scope.getObjectResult(); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - return Word.nullPointer(); - } - } - - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_purgePartialEvaluationCaches") - @SuppressWarnings({"unused", "try"}) - @TruffleToLibGraal(Id.PurgePartialEvaluationCaches) - public static void purgePartialEvaluationCaches(JNIEnv env, JClass hsClass, @IsolateThreadContext long isolateThreadId, long compilerHandle) { - try (JNIMethodScope s = openScope(Id.PurgePartialEvaluationCaches, env)) { - Object compiler = LibGraalObjectHandles.resolve(compilerHandle, Object.class); - if (compiler != null) { - singleton().purgePartialEvaluationCaches.invoke(compiler); - } - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - } - } - - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_getCompilerVersion") - @SuppressWarnings({"unused", "try"}) - @TruffleToLibGraal(Id.GetCompilerVersion) - public static JString getCompilerVersion(JNIEnv env, JClass hsClass, @IsolateThreadContext long isolateThreadId) { - try { - JNIMethodScope scope = openScope(Id.GetCompilerVersion, env); - try (JNIMethodScope s = scope) { - String version = (String) singleton().getCompilerVersion.invoke(); - scope.setObjectResult(JNIUtil.createHSString(env, version)); - } - return scope.getObjectResult(); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(env, t); - return Word.nullPointer(); - } - } - - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_LibGraalObject_releaseHandle") - @SuppressWarnings("unused") - public static boolean releaseHandle(JNIEnv jniEnv, JClass jclass, @IsolateThreadContext long isolateThreadId, long handle) { - try { - ObjectHandles.getGlobal().destroy(Word.pointer(handle)); - return true; - } catch (Throwable t) { - return false; - } - } -} diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java index d4c42fefe8db..38c6505b052f 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java @@ -30,7 +30,6 @@ import java.lang.annotation.Annotation; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.MethodType; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -87,7 +86,13 @@ public final class LibGraalFeature implements Feature { public static final class IsEnabled implements BooleanSupplier { @Override public boolean getAsBoolean() { - return ImageSingletons.contains(LibGraalFeature.class); + Class clazz = LibGraalFeature.class; + if (ImageSingletons.contains(clazz)) { + GraalError.guarantee("LibGraalClassLoader".equals(IsEnabled.class.getClassLoader().getName()), + "Only ever return true when LibGraalFeature got loaded by HostedLibGraalClassLoader"); + return true; + } + return false; } } @@ -494,9 +499,6 @@ public void duringAnalysis(DuringAnalysisAccess access) { @SuppressWarnings("unchecked") private void initializeTruffle() throws Throwable { Class truffleBuildTimeClass = loadClassOrFail("jdk.graal.compiler.hotspot.libgraal.truffle.BuildTime"); - MethodHandle getLookup = mhl.findStatic(truffleBuildTimeClass, "initializeLookup", methodType(Map.Entry.class, Lookup.class, Class.class, Class.class)); - Map.Entry> truffleLibGraal = (Map.Entry>) getLookup.invoke(mhl, TruffleFromLibGraalStartPoints.class, NativeImageHostEntryPoints.class); - ImageSingletons.add(LibGraalTruffleToLibGraalEntryPoints.class, new LibGraalTruffleToLibGraalEntryPoints(truffleLibGraal.getKey(), truffleLibGraal.getValue())); MethodHandle truffleConfigureGraalForLibGraal = mhl.findStatic(truffleBuildTimeClass, "configureGraalForLibGraal", methodType(void.class)); truffleConfigureGraalForLibGraal.invoke(); } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java index 175dc1138291..21edebb92e94 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java @@ -109,7 +109,7 @@ Target_jdk_vm_ci_hotspot_HotSpotResolvedJavaType lookupType(ClassLoader classLoa } else if (classLoader == ClassLoader.getSystemClassLoader()) { accessingClassLoader = 2; } else if (classLoader == getClass().getClassLoader()) { - accessingClassLoader = 2; + throw new IllegalArgumentException("is this case really needed? Unsupported class loader for lookup: " + name + " " + classLoader); } else { throw new IllegalArgumentException("Unsupported class loader for lookup: " + classLoader); } @@ -238,6 +238,9 @@ void afterRun() { class LibGraalClassLoaderSupplier implements Supplier { @Override public ClassLoader get() { + if (!ImageSingletons.contains(LibGraalFeature.class)) { + return null; + } ClassLoader loader = ImageSingletons.lookup(LibGraalFeature.class).loader; if (loader == null) { LibGraalRuntime.fatalError("loader is null"); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/NativeImageHostEntryPoints.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/NativeImageHostEntryPoints.java index 5f1744aac3d3..1637c64c2830 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/NativeImageHostEntryPoints.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/NativeImageHostEntryPoints.java @@ -40,7 +40,7 @@ private NativeImageHostEntryPoints() { } public static void initializeHost(long runtimeClass) { - TruffleFromLibGraalStartPoints.initializeJNI(Word.pointer(runtimeClass)); + // TruffleFromLibGraalStartPoints.initializeJNI(Word.pointer(runtimeClass)); } public static Object createLocalHandleForLocalReference(long jniLocalRef) { From c5c0cebbcbade50c26b60f3b4ed54ccbb0d8486f Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Mon, 23 Dec 2024 12:33:21 +0100 Subject: [PATCH 12/31] removed more reflection --- .../loader/HostedLibGraalClassLoader.java | 23 +- .../core/test/VerifyAssertionUsage.java | 18 +- .../test/VerifyLibGraalContextChecks.java | 12 +- .../compiler/core/CompilationWatchDog.java | 3 +- .../compiler/core/GraalServiceThread.java | 24 +- .../graal/compiler/debug/DebugContext.java | 3 +- .../graal/compiler/debug/IgvDumpChannel.java | 5 +- .../hotspot/CompilerConfigurationFactory.java | 32 +- .../hotspot/HotSpotGraalCompiler.java | 49 ++- .../hotspot/HotSpotGraalCompilerFactory.java | 5 - .../HotSpotGraalJVMCIServiceLocator.java | 5 +- .../hotspot/HotSpotGraalOptionValues.java | 75 ++-- .../compiler/hotspot/HotSpotGraalRuntime.java | 68 +++- .../graal/compiler/hotspot/HotSpotMarkId.java | 3 +- .../hotspot/HotSpotReplacementsImpl.java | 5 +- .../hotspot/HotSpotTTYStreamProvider.java | 3 +- .../compiler/hotspot/SnippetSignature.java | 3 +- .../hotspot/SymbolicSnippetEncoder.java | 3 +- .../compiler/hotspot/libgraal/BuildTime.java | 205 ----------- .../compiler/hotspot/libgraal/RunTime.java | 259 -------------- .../stubs/AbstractForeignCallStub.java | 4 +- .../libgraal/CompilerConfig.java | 9 +- .../compiler/libgraal/GetCompilerConfig.java | 7 +- .../graal/compiler/libgraal/GetJNIConfig.java | 11 +- .../BuildTime.java => libgraal/JDK21.java} | 24 +- .../libgraal/LibGraalEntryPoints.java | 220 +++++++----- .../compiler/libgraal/LibGraalFeature.java | 334 +++++++----------- .../libgraal/LibGraalSubstitutions.java | 201 +---------- .../graal/compiler/libgraal/LibGraalUtil.java | 3 +- .../libgraal/NativeImageHostEntryPoints.java | 78 ---- .../libgraal/truffle/FromLibGraalCalls.java | 2 +- .../libgraal/truffle/HSConsumer.java | 2 +- .../libgraal/truffle/HSIndirectHandle.java | 2 +- .../libgraal/truffle/HSTruffleCompilable.java | 2 +- .../truffle/HSTruffleCompilationTask.java | 2 +- .../truffle/HSTruffleCompilerListener.java | 2 +- .../truffle/HSTruffleCompilerRuntime.java | 9 +- .../HSTruffleSourceLanguagePosition.java | 2 +- .../truffle/LibGraalObjectHandleScope.java | 2 +- .../truffle/LibGraalObjectHandles.java | 2 +- .../truffle/LibGraalTruffleEntryPoints.java | 60 ++-- .../LibGraalTruffleHostEnvironment.java | 5 +- .../LibGraalTruffleHostEnvironmentLookup.java | 30 +- .../LibGraalTruffleScopeEntryPoints.java | 2 +- .../truffle/TruffleFromLibGraalCalls.java | 2 +- .../TruffleFromLibGraalStartPoints.java | 100 +++--- .../truffle/TruffleLibGraalShutdownHook.java | 2 +- .../compiler/nodes/PluginReplacementNode.java | 3 +- .../GeneratedFoldInvocationPlugin.java | 4 +- .../GeneratedInvocationPlugin.java | 21 +- .../graphbuilderconf/InvocationPlugins.java | 3 +- .../nodes/IntrinsicMethodNodeInterface.java | 4 +- .../serviceprovider/GraalServices.java | 93 ++++- .../compiler/serviceprovider/VMSupport.java | 47 --- .../compiler/truffle/TruffleCompilerImpl.java | 5 - ...otSpotTruffleSafepointLoweringSnippet.java | 5 +- .../jdk.graal.nativeimage/snapshot.sigtest | 3 + .../jdk/graal/nativeimage/FoldNodePlugin.java | 10 + .../jdk/graal/nativeimage/LibGraalLoader.java | 8 + .../graal/nativeimage/LibGraalRuntime.java | 8 + .../graal/GenScavengeGCFeature.java | 5 + .../svm/core/jdk/JVMCISubstitutions.java | 9 - .../GraalGraphObjectReplacer.java | 6 +- .../hosted/NativeImageClassLoaderSupport.java | 2 - .../ClassInitializationSupport.java | 15 + .../hosted/doc-files/LibGraalClassLoader.txt | 12 +- .../svm/hosted/meta/UniverseBuilder.java | 3 +- .../AnnotationSubstitutionProcessor.java | 11 - truffle/mx.truffle/suite.py | 5 - 69 files changed, 784 insertions(+), 1420 deletions(-) delete mode 100644 compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/BuildTime.java delete mode 100644 compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/RunTime.java rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{hotspot => }/libgraal/CompilerConfig.java (97%) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{hotspot/libgraal/truffle/BuildTime.java => libgraal/JDK21.java} (62%) delete mode 100644 compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/NativeImageHostEntryPoints.java rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{hotspot => }/libgraal/truffle/FromLibGraalCalls.java (99%) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{hotspot => }/libgraal/truffle/HSConsumer.java (98%) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{hotspot => }/libgraal/truffle/HSIndirectHandle.java (97%) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{hotspot => }/libgraal/truffle/HSTruffleCompilable.java (99%) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{hotspot => }/libgraal/truffle/HSTruffleCompilationTask.java (98%) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{hotspot => }/libgraal/truffle/HSTruffleCompilerListener.java (98%) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{hotspot => }/libgraal/truffle/HSTruffleCompilerRuntime.java (96%) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{hotspot => }/libgraal/truffle/HSTruffleSourceLanguagePosition.java (97%) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{hotspot => }/libgraal/truffle/LibGraalObjectHandleScope.java (97%) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{hotspot => }/libgraal/truffle/LibGraalObjectHandles.java (97%) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{hotspot => }/libgraal/truffle/LibGraalTruffleEntryPoints.java (92%) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{hotspot => }/libgraal/truffle/LibGraalTruffleHostEnvironment.java (97%) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{hotspot => }/libgraal/truffle/LibGraalTruffleHostEnvironmentLookup.java (78%) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{hotspot => }/libgraal/truffle/LibGraalTruffleScopeEntryPoints.java (97%) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{hotspot => }/libgraal/truffle/TruffleFromLibGraalCalls.java (97%) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{hotspot => }/libgraal/truffle/TruffleFromLibGraalStartPoints.java (79%) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{hotspot => }/libgraal/truffle/TruffleLibGraalShutdownHook.java (97%) delete mode 100644 compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/VMSupport.java create mode 100644 compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/FoldNodePlugin.java diff --git a/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/HostedLibGraalClassLoader.java b/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/HostedLibGraalClassLoader.java index b18a486302b3..e2ee2524aa29 100644 --- a/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/HostedLibGraalClassLoader.java +++ b/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/HostedLibGraalClassLoader.java @@ -55,13 +55,16 @@ import java.util.Set; /** - * A classloader, that reads class files and resources from a jimage file at image build time. + * A classloader that reads class files and resources from a jimage file at image build time. */ @Platforms(Platform.HOSTED_ONLY.class) public final class HostedLibGraalClassLoader extends ClassLoader implements LibGraalLoader { - private static final String JAVA_HOME_PROPERTY_KEY = "jdk.graal.internal.libgraal.javahome"; - private static final String JAVA_HOME_PROPERTY_VALUE = System.getProperty(JAVA_HOME_PROPERTY_KEY, System.getProperty("java.home")); + /** + * Name of the system property specifying the {@code java.home} of the JDK whose runtime image + * contains the Graal and JVMCI classes from which libgraal will be built. + */ + private static final String LIBGRAAL_JAVA_HOME_PROPERTY_NAME = "libgraal.java.home"; /** * Reader for the image. @@ -85,12 +88,10 @@ public final class HostedLibGraalClassLoader extends ClassLoader implements LibG private final Map modules; /** - * Modules in which Graal classes and their dependencies are defined. + * Modules in which Graal and JVMCI classes are defined. */ private static final Set LIBGRAAL_MODULES = Set.of( "jdk.internal.vm.ci", -// "org.graalvm.collections", -// "org.graalvm.word", "jdk.graal.compiler", "org.graalvm.truffle.compiler", "com.oracle.graal.graal_enterprise"); @@ -107,12 +108,16 @@ public final class HostedLibGraalClassLoader extends ClassLoader implements LibG ClassLoader.registerAsParallelCapable(); } - public final Path libGraalJavaHome; + private final Path libgraalJavaHome = Path.of(System.getProperty(LIBGRAAL_JAVA_HOME_PROPERTY_NAME, System.getProperty("java.home"))); + + @Override + public Path getJavaHome() { + return libgraalJavaHome; + } @SuppressWarnings("unused") public HostedLibGraalClassLoader() { super(LibGraalClassLoader.LOADER_NAME, Feature.class.getClassLoader()); - libGraalJavaHome = Path.of(JAVA_HOME_PROPERTY_VALUE); try { /* @@ -131,7 +136,7 @@ public HostedLibGraalClassLoader() { Map modulesMap = new HashMap<>(); - Path imagePath = libGraalJavaHome.resolve(Path.of("lib", "modules")); + Path imagePath = libgraalJavaHome.resolve(Path.of("lib", "modules")); this.imageReader = BasicImageReader.open(imagePath); for (var entry : imageReader.getEntryNames()) { int secondSlash = entry.indexOf('/', 1); diff --git a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/VerifyAssertionUsage.java b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/VerifyAssertionUsage.java index c2fa9631600a..c7e857b6a09f 100644 --- a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/VerifyAssertionUsage.java +++ b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/VerifyAssertionUsage.java @@ -122,7 +122,7 @@ public class VerifyAssertionUsage extends VerifyStringFormatterUsage { private final boolean log; /* - * GR-49601: only check non boolean assertion calls for now. + * GR-49601: only check non-boolean assertion calls for now. */ private final boolean verifyBooleanAssertionConditions; @@ -471,19 +471,19 @@ private void reportSuperfluousAssertions(StringBuilder allErrorMessages) { } private void reportMissingAssertions(StringBuilder allErrorMessages) { - StringBuilder sbMissingAssertionMessages = new StringBuilder(); + List missingAssertionMessages = new ArrayList<>(); for (AssertionCall ac : assertionCallsWithoutMessage) { ResolvedJavaMethod callee = ac.callee; if (callee == null || !getMethodInfo(callee).canBeCalledWithoutErrorMessage()) { - sbMissingAssertionMessages.append(formatNSP(ac.nsp)).append(System.lineSeparator()); + missingAssertionMessages.add(formatNSP(ac.nsp)); } } - if (!sbMissingAssertionMessages.isEmpty()) { - allErrorMessages.append(String.format("Found the following assertions that need error messages %n%s%n " + - "This is because you added a new assertion without an error message. " + - "Please fix all assertions in the report above such that they have error messages." + - "Consider using API from " + Assertions.class.getName() + " to format assertion error messages with more context.", - sbMissingAssertionMessages)); + if (!missingAssertionMessages.isEmpty()) { + String sep = String.format("%n "); + allErrorMessages.append(String.format("Found the assertions that need error messages at:%s%s%n" + + "Please fix all above assertions such that they have error messages. " + + "Consider using API from %s to format assertion error messages with more context.", + sep, String.join(sep, missingAssertionMessages), Assertions.class)); allErrorMessages.append(System.lineSeparator()); } } diff --git a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/VerifyLibGraalContextChecks.java b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/VerifyLibGraalContextChecks.java index 10a48b8aa4da..5c67cf2d7f15 100644 --- a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/VerifyLibGraalContextChecks.java +++ b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/VerifyLibGraalContextChecks.java @@ -40,12 +40,10 @@ /** * Ensures that the only code directly accessing - * {@link jdk.vm.ci.services.Services#IS_IN_NATIVE_IMAGE} and - * {@link jdk.vm.ci.services.Services#IS_BUILDING_NATIVE_IMAGE} is in + * {@link jdk.vm.ci.services.Services#IS_IN_NATIVE_IMAGE} is in * {@link jdk.graal.compiler.serviceprovider.GraalServices}. All other code must use one of the * following methods: *
      - *
    • {@link GraalServices#isBuildingLibgraal()}
    • *
    • {@link GraalServices#isInLibgraal()}
    • *
    • {@link ImageInfo#inImageCode()}
    • *
    • {@link ImageInfo#inImageBuildtimeCode()}
    • @@ -79,14 +77,12 @@ protected void verify(StructuredGraph graph, CoreProviders context) { for (LoadFieldNode load : loads) { ResolvedJavaField field = load.field(); if (field.getDeclaringClass().toJavaName().equals(Services.class.getName())) { - if (field.getName().equals("IS_BUILDING_NATIVE_IMAGE") || field.getName().equals("IS_IN_NATIVE_IMAGE")) { + if (field.getName().equals("IS_IN_NATIVE_IMAGE")) { if (!isAllowedToAccess(graph.method())) { - String recommendation = field.getName().equals("IS_BUILDING_NATIVE_IMAGE") ? "isBuildingLibgraal" : "isInLibgraal"; - throw new VerificationError("reading %s in %s is prohibited - use %s.%s() instead", + throw new VerificationError("reading %s in %s is prohibited - use %s.isInLibgraal() instead", field.format("%H.%n"), graph.method().format("%H.%n(%p)"), - GraalServices.class.getName(), - recommendation); + GraalServices.class.getName()); } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/CompilationWatchDog.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/CompilationWatchDog.java index ddf4d39ffcc6..78e64afee3ed 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/CompilationWatchDog.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/CompilationWatchDog.java @@ -42,7 +42,6 @@ import jdk.graal.compiler.options.OptionValues; import jdk.graal.compiler.serviceprovider.GraalServices; import jdk.graal.compiler.serviceprovider.IsolateUtil; -import jdk.vm.ci.common.NativeImageReinitialize; /** * A watch dog for {@linkplain #watch watching} and reporting on long running compilations. @@ -292,7 +291,7 @@ public void run() { } } - @NativeImageReinitialize private static ScheduledExecutorService watchDogService; + private static ScheduledExecutorService watchDogService; private static synchronized ScheduledFuture schedule(CompilationWatchDog watchdog, int delay) { if (watchDogService == null) { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/GraalServiceThread.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/GraalServiceThread.java index 7c5f25485341..34a0425e420a 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/GraalServiceThread.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/GraalServiceThread.java @@ -25,6 +25,7 @@ package jdk.graal.compiler.core; import jdk.graal.compiler.serviceprovider.GraalServices; +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; /** * This is a utility class for Threads started by the compiler itself. In certain execution @@ -42,7 +43,11 @@ public GraalServiceThread(String name, Runnable runnable) { @Override public final void run() { try { - beforeRun(); + if (GraalServices.isInLibgraal()) { + if (!HotSpotJVMCIRuntime.runtime().attachCurrentThread(isDaemon(), null)) { + throw new InternalError("Couldn't attach to HotSpot runtime"); + } + } } catch (InternalError t) { // There was a problem attaching this thread to the libgraal peer runtime. // Not much that can be done apart from terminating the thread. @@ -52,7 +57,9 @@ public final void run() { try { runnable.run(); } finally { - afterRun(); + if (GraalServices.isInLibgraal()) { + HotSpotJVMCIRuntime.runtime().detachCurrentThread(false); + } } } @@ -70,17 +77,4 @@ protected void onAttachError(InternalError error) { } } - /** - * Substituted by {@code Target_jdk_graal_compiler_core_GraalServiceThread} to attach to the - * peer runtime if required. - */ - private void afterRun() { - } - - /** - * Substituted by {@code Target_jdk_graal_compiler_core_GraalServiceThread} to attach to the - * peer runtime if required. - */ - private void beforeRun() { - } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/debug/DebugContext.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/debug/DebugContext.java index 46c46d8c7789..5dd8b723e488 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/debug/DebugContext.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/debug/DebugContext.java @@ -56,7 +56,6 @@ import jdk.graal.compiler.options.OptionKey; import jdk.graal.compiler.options.OptionValues; import jdk.graal.compiler.serviceprovider.GraalServices; -import jdk.vm.ci.common.NativeImageReinitialize; import jdk.vm.ci.meta.JavaMethod; import jdk.vm.ci.meta.ResolvedJavaMethod; @@ -878,7 +877,7 @@ public DebugContext.Scope scope(Object name) { * Arbitrary threads cannot be in the image so null out {@code DebugContext.invariants} which * holds onto a thread and is only used for assertions. */ - @NativeImageReinitialize private final Invariants invariants = Assertions.assertionsEnabled() ? new Invariants() : null; + private final Invariants invariants = Assertions.assertionsEnabled() ? new Invariants() : null; static StackTraceElement[] getStackTrace(Thread thread) { return thread.getStackTrace(); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/debug/IgvDumpChannel.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/debug/IgvDumpChannel.java index 08f5c1a71eac..8dd00142c345 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/debug/IgvDumpChannel.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/debug/IgvDumpChannel.java @@ -43,7 +43,6 @@ import jdk.graal.compiler.options.OptionValues; import jdk.graal.compiler.serviceprovider.GraalServices; -import jdk.vm.ci.common.NativeImageReinitialize; import org.graalvm.nativeimage.ImageInfo; final class IgvDumpChannel implements WritableByteChannel { @@ -93,7 +92,7 @@ void realClose() throws IOException { } } - @NativeImageReinitialize private static boolean networkDumpingUnsupportedWarned; + private static boolean networkDumpingUnsupportedWarned; WritableByteChannel channel() throws IOException { if (closed) { @@ -147,7 +146,7 @@ private static WritableByteChannel createNetworkChannel(Supplier pathPro } } - @NativeImageReinitialize private static String lastTargetAnnouncement; + private static String lastTargetAnnouncement; private static void maybeAnnounceTarget(String targetAnnouncement) { if (!targetAnnouncement.equals(lastTargetAnnouncement)) { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/CompilerConfigurationFactory.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/CompilerConfigurationFactory.java index c8375e6f980a..19aec283db9b 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/CompilerConfigurationFactory.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/CompilerConfigurationFactory.java @@ -25,6 +25,7 @@ package jdk.graal.compiler.hotspot; import static jdk.vm.ci.common.InitTimer.timer; +import static jdk.graal.nativeimage.LibGraalRuntime.NATIVE_IMAGE_SETTING_KEY_PREFIX; import java.util.ArrayList; import java.util.Collections; @@ -275,31 +276,24 @@ public static CompilerConfigurationFactory selectFactory(String name, OptionValu */ private Object getLoadedFromLocation(boolean verbose) { if (ImageInfo.inImageRuntimeCode()) { - if (nativeImageLocationQualifier != null) { - return "a " + nativeImageLocationQualifier + " Native Image shared library"; + String justification = "properties initialized via org.graalvm.nativeimage.hosted.RuntimeSystemProperties " + + "are not accessible via GraalServices.getSavedProperties()"; + String settings = GraalServices.getSystemProperties(justification).entrySet().stream()// + .filter(e -> e.getKey().toString().startsWith(NATIVE_IMAGE_SETTING_KEY_PREFIX))// + .map(e -> { + String key = e.getKey().toString().substring(NATIVE_IMAGE_SETTING_KEY_PREFIX.length()); + String val = e.getValue().toString(); + return val.isEmpty() ? key : key + "=" + val; + })// + .collect(Collectors.joining(", ")); + if (!settings.isEmpty()) { + return "a Native Image shared library (" + settings + ")"; } return "a Native Image shared library"; } return verbose ? getClass().getResource(getClass().getSimpleName() + ".class") : "class files"; } - private static String nativeImageLocationQualifier; - - /** - * Gets the qualifier for the libgraal library (e.g., "PGO optimized"). - */ - public static String getNativeImageLocationQualifier() { - return nativeImageLocationQualifier; - } - - /** - * Records a qualifier for the libgraal library (e.g., "PGO optimized"). - */ - public static void setNativeImageLocationQualifier(String s) { - GraalError.guarantee(nativeImageLocationQualifier == null, "Native image location qualifier is already set to %s", nativeImageLocationQualifier); - nativeImageLocationQualifier = s; - } - private static void printConfigInfo(CompilerConfigurationFactory factory) { Object location = factory.getLoadedFromLocation(false); TTY.printf("Using \"%s\" loaded from %s%n", factory.info, location); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalCompiler.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalCompiler.java index 977ef57e3a73..7a0e7df0ad7b 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalCompiler.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalCompiler.java @@ -46,6 +46,7 @@ import jdk.graal.compiler.hotspot.meta.HotSpotProviders; import jdk.graal.compiler.hotspot.phases.OnStackReplacementPhase; import jdk.graal.compiler.java.GraphBuilderPhase; +import jdk.graal.compiler.libgraal.LibGraalJNIMethodScope; import jdk.graal.compiler.lir.asm.CompilationResultBuilderFactory; import jdk.graal.compiler.lir.phases.LIRSuites; import jdk.graal.compiler.nodes.Cancellable; @@ -63,7 +64,7 @@ import jdk.graal.compiler.phases.tiers.Suites; import jdk.graal.compiler.printer.GraalDebugHandlersFactory; import jdk.graal.compiler.serviceprovider.GlobalAtomicLong; -import jdk.graal.compiler.serviceprovider.VMSupport; +import jdk.graal.compiler.word.Word; import jdk.graal.nativeimage.LibGraalRuntime; import jdk.internal.misc.Unsafe; import jdk.vm.ci.code.CompilationRequest; @@ -78,6 +79,8 @@ import jdk.vm.ci.meta.SpeculationLog; import jdk.vm.ci.meta.TriState; import jdk.vm.ci.runtime.JVMCICompiler; +import org.graalvm.jniutils.JNI; +import org.graalvm.jniutils.JNIMethodScope; import org.graalvm.nativeimage.ImageInfo; public class HotSpotGraalCompiler implements GraalJVMCICompiler, Cancellable, JVMCICompilerShadow, GraalCompiler.RequestedCrashHandler { @@ -126,12 +129,52 @@ public HotSpotGraalRuntimeProvider getGraalRuntime() { return graalRuntime; } + /** + * Performs the following actions around a libgraal compilation: + *
        + *
      • before: opens a JNIMethodScope to allow Graal compilations of Truffle host methods to + * call methods on the TruffleCompilerRuntime.
      • + *
      • after: closes the above JNIMethodScope
      • + *
      • after: triggers GC weak reference processing as SVM does not use a separate thread for + * this in libgraal
      • + *
      + */ + static class LibGraalCompilationRequestScope implements AutoCloseable { + final JNIMethodScope scope; + + LibGraalCompilationRequestScope() { + JNI.JNIEnv env = Word.unsigned(HotSpotGraalRuntime.getJNIEnv()); + /* + * This scope is required to allow Graal compilations of host methods to call methods in + * the TruffleCompilerRuntime. This is, for example, required to find out about + * Truffle-specific method annotations. + */ + scope = LibGraalJNIMethodScope.open("", env, false); + } + + @Override + public void close() { + try { + if (scope != null) { + scope.close(); + } + } finally { + /* + * libgraal doesn't use a dedicated reference handler thread, so trigger the + * reference handling manually when a compilation finishes. + */ + HotSpotGraalRuntime.doReferenceHandling(); + } + } + } + @SuppressWarnings("try") @Override public CompilationRequestResult compileMethod(CompilationRequest request) { - try (AutoCloseable ignored = VMSupport.getCompilationRequestScope()) { + try (AutoCloseable ignored = ImageInfo.inImageRuntimeCode() ? new LibGraalCompilationRequestScope() : null) { return compileMethod(request, true, getGraalRuntime().getOptions()); } catch (Exception e) { + e.printStackTrace(System.out); return HotSpotCompilationRequestResult.failure(e.toString(), false); } } @@ -140,7 +183,7 @@ public CompilationRequestResult compileMethod(CompilationRequest request) { public CompilationRequestResult compileMethod(CompilationRequest request, boolean installAsDefault, OptionValues initialOptions) { try (CompilationContext scope = HotSpotGraalServices.openLocalCompilationContext(request)) { if (graalRuntime.isShutdown()) { - return HotSpotCompilationRequestResult.failure(String.format("Shutdown entered"), true); + return HotSpotCompilationRequestResult.failure("Shutdown entered", true); } ResolvedJavaMethod method = request.getMethod(); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalCompilerFactory.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalCompilerFactory.java index 667302fa26e8..7ce5c1584e5e 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalCompilerFactory.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalCompilerFactory.java @@ -47,7 +47,6 @@ import jdk.vm.ci.meta.Signature; import jdk.vm.ci.runtime.JVMCICompilerFactory; import jdk.vm.ci.runtime.JVMCIRuntime; -import jdk.vm.ci.services.Services; import org.graalvm.nativeimage.ImageInfo; public final class HotSpotGraalCompilerFactory implements JVMCICompilerFactory { @@ -172,10 +171,6 @@ public HotSpotGraalCompiler createCompiler(JVMCIRuntime runtime) { // is true so verify that here. throw new GraalError("Invariant violation: inImageBuildtimeCode && inImageRuntimeCode must not both be true"); } - if (Services.IS_BUILDING_NATIVE_IMAGE && Services.IS_IN_NATIVE_IMAGE) { - // Same check as above but for the JVMCI equivalent properties. - throw new GraalError("Invariant violation: IS_BUILDING_NATIVE_IMAGE && IS_IN_NATIVE_IMAGE must not both be true"); - } HotSpotJVMCIRuntime hsRuntime = (HotSpotJVMCIRuntime) runtime; checkUnsafeAccess(hsRuntime); ensureInitialized(); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalJVMCIServiceLocator.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalJVMCIServiceLocator.java index 576fb3b3c227..bb77e7a29ea7 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalJVMCIServiceLocator.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalJVMCIServiceLocator.java @@ -26,7 +26,6 @@ import jdk.graal.compiler.serviceprovider.ServiceProvider; -import jdk.vm.ci.common.NativeImageReinitialize; import jdk.vm.ci.hotspot.HotSpotVMEventListener; import jdk.vm.ci.runtime.JVMCICompilerFactory; import jdk.vm.ci.services.JVMCIServiceLocator; @@ -59,8 +58,8 @@ T getProvider(Class service, HotSpotGraalJVMCIServiceLocator locator) { return null; } - @NativeImageReinitialize private HotSpotGraalRuntime graalRuntime; - @NativeImageReinitialize private HotSpotGraalVMEventListener vmEventListener; + private HotSpotGraalRuntime graalRuntime; + private HotSpotGraalVMEventListener vmEventListener; /** * Notifies this object of the compiler created via {@link HotSpotGraalJVMCIServiceLocator}. diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalOptionValues.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalOptionValues.java index 8ffad619f1a5..1da599ea8cfd 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalOptionValues.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalOptionValues.java @@ -27,7 +27,8 @@ import static jdk.vm.ci.common.InitTimer.timer; import java.io.PrintStream; -import java.util.HashMap; +import java.util.Comparator; +import java.util.List; import java.util.Map; import java.util.Set; @@ -41,7 +42,10 @@ import jdk.graal.compiler.options.OptionsParser; import jdk.vm.ci.common.InitTimer; -import jdk.vm.ci.common.NativeImageReinitialize; +import org.graalvm.collections.EconomicSet; +import org.graalvm.collections.MapCursor; +import org.graalvm.nativeimage.ImageInfo; +import org.graalvm.nativeimage.RuntimeOptions; /** * The {@link #defaultOptions()} method returns the options values initialized in a HotSpot VM. The @@ -82,7 +86,7 @@ public static String asSystemPropertySetting(OptionValues options, OptionKey return GRAAL_OPTION_PROPERTY_PREFIX + value.getName() + "=" + value.getValue(options); } - @NativeImageReinitialize private static volatile OptionValues hotspotOptions; + private static volatile OptionValues hotspotOptions; public static OptionValues defaultOptions() { OptionValues res = hotspotOptions; @@ -112,8 +116,7 @@ public static EconomicMap, Object> parseOptions() { Map savedProps = GraalServices.getSavedProperties(); EconomicMap compilerOptionSettings = EconomicMap.create(); - // Need to use Map as it's a shared type between guest and host in LibGraal. - Map vmOptionSettings = new HashMap<>(); + EconomicMap vmOptionSettings = EconomicMap.create(); for (Map.Entry e : savedProps.entrySet()) { String name = e.getKey(); @@ -168,14 +171,42 @@ private static String stripPrefix(String name, String prefix) { } /** - * Substituted by {@code Target_jdk_graal_compiler_hotspot_HotSpotGraalOptionValues}. - * * @param settings unparsed libgraal option values */ - private static void notifyLibgraalOptions(Map settings) { - System.err.printf("WARNING: Ignoring the following libgraal VM option(s) while executing jargraal: %s%n", String.join(", ", settings.keySet())); + private static void notifyLibgraalOptions(EconomicMap settings) { + if (ImageInfo.inImageRuntimeCode()) { + MapCursor cursor = settings.getEntries(); + while (cursor.advance()) { + String name = cursor.getKey(); + String stringValue = cursor.getValue(); + Object value; + if (name.startsWith("X") && stringValue.isEmpty()) { + name = name.substring(1); + value = stringValue; + } else { + RuntimeOptions.Descriptor desc = RuntimeOptions.getDescriptor(name); + if (desc == null) { + throw new IllegalArgumentException("Could not find option " + name); + } + value = desc.convertValue(stringValue); + explicitOptions.add(name); + } + try { + RuntimeOptions.set(name, value); + } catch (RuntimeException ex) { + throw new IllegalArgumentException(ex); + } + } + } else { + System.err.printf("WARNING: Ignoring the following libgraal VM option(s) while executing jargraal: %s%n", settings.toString()); + } } + /** + * The set of libgraal options seen on the command line. + */ + static EconomicSet explicitOptions = EconomicSet.create(); + private static OptionValues initializeOptions() { EconomicMap, Object> values = parseOptions(); OptionValues options = new OptionValues(values); @@ -188,17 +219,21 @@ private static OptionValues initializeOptions() { static void printProperties(OptionValues compilerOptions, PrintStream out) { boolean all = HotSpotGraalCompilerFactory.Options.PrintPropertiesAll.getValue(compilerOptions); compilerOptions.printHelp(OptionsParser.getOptionsLoader(), out, GRAAL_OPTION_PROPERTY_PREFIX, all); - if (all) { - printLibgraalProperties(out, LIBGRAAL_VM_OPTION_PROPERTY_PREFIX); + if (all && ImageInfo.inImageRuntimeCode()) { + if (ImageInfo.inImageRuntimeCode()) { + Comparator comparator = Comparator.comparing(RuntimeOptions.Descriptor::name); + RuntimeOptions.listDescriptors().stream().sorted(comparator).forEach(d -> { + String assign = explicitOptions.contains(d.name()) ? ":=" : "="; + OptionValues.printHelp(out, LIBGRAAL_VM_OPTION_PROPERTY_PREFIX, + d.name(), + RuntimeOptions.get(d.name()), + d.valueType(), + assign, + "[community edition]", + d.help(), + List.of()); + }); + } } } - - /** - * Substituted by {@code Target_jdk_graal_compiler_hotspot_HotSpotGraalOptionValues}. - * - * @param out where help is to be printed - * @param prefix system property prefix for libgraal VM options - */ - private static void printLibgraalProperties(PrintStream out, String prefix) { - } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalRuntime.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalRuntime.java index 0af0d793dce5..11052d7c19c3 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalRuntime.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalRuntime.java @@ -35,6 +35,15 @@ import java.util.Map; import java.util.function.Predicate; +import com.oracle.svm.core.annotate.Alias; +import com.oracle.svm.core.annotate.TargetClass; +import jdk.graal.compiler.libgraal.LibGraalFeature; +import jdk.graal.compiler.word.Word; +import jdk.graal.nativeimage.LibGraalRuntime; +import jdk.vm.ci.hotspot.HotSpotVMConfigAccess; +import org.graalvm.jniutils.JNI; +import org.graalvm.jniutils.JNIExceptionWrapper; +import org.graalvm.jniutils.JNIUtil; import org.graalvm.nativeimage.ImageInfo; import org.graalvm.collections.EconomicMap; import org.graalvm.collections.Equivalence; @@ -67,7 +76,6 @@ import jdk.graal.compiler.runtime.RuntimeProvider; import jdk.graal.compiler.serviceprovider.GraalServices; import jdk.graal.compiler.serviceprovider.JavaVersionUtil; -import jdk.graal.compiler.serviceprovider.VMSupport; import jdk.vm.ci.code.Architecture; import jdk.vm.ci.code.stack.StackIntrospection; import jdk.vm.ci.common.InitTimer; @@ -76,6 +84,7 @@ import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.runtime.JVMCIBackend; +import org.graalvm.nativeimage.StackValue; import org.graalvm.nativeimage.VMRuntime; //JaCoCo Exclude @@ -101,6 +110,31 @@ private static boolean checkArrayIndexScaleInvariants(MetaAccessProvider metaAcc private final String compilerConfigurationName; private final HotSpotBackend hostBackend; + /** + * Since reference handling is synchronous in libgraal, explicitly perform it here and then run + * any code which is expecting to process a reference queue to let it clean up. + */ + public static void doReferenceHandling() { + LibGraalRuntime.processReferences(); + + /* + * Thanks to JDK-8346781, this can be replaced with jdk.vm.ci.hotspot.Cleaner.clean() once + * JDK 21 support is no longer necessary. + */ + Target_jdk_vm_ci_hotspot_Cleaner.clean(); + } + + @TargetClass(className = "jdk.vm.ci.hotspot.Cleaner", onlyWith = LibGraalFeature.IsEnabled.class) + static final class Target_jdk_vm_ci_hotspot_Cleaner { + + /* + * Make package-private clean() accessible so that it can be called from + * LibGraalEntryPoints.doReferenceHandling(). + */ + @Alias + public static native void clean(); + } + public GlobalMetrics getMetricValues() { return metricValues; } @@ -433,10 +467,38 @@ synchronized void shutdown() { String cbClassName = callback.substring(0, lastDot); String cbMethodName = callback.substring(lastDot + 1); - VMSupport.invokeShutdownCallback(cbClassName, cbMethodName); + JNI.JNIEnv env = Word.unsigned(getJNIEnv()); + JNI.JClass cbClass = JNIUtil.findClass(env, JNIUtil.getSystemClassLoader(env), + JNIUtil.getBinaryName(cbClassName), true); + JNI.JMethodID cbMethod = JNIUtil.findMethod(env, cbClass, true, cbMethodName, "()V"); + env.getFunctions().getCallStaticVoidMethodA().call(env, cbClass, cbMethod, StackValue.get(0)); + JNIExceptionWrapper.wrapAndThrowPendingJNIException(env); + } - VMRuntime.initialize(); + VMRuntime.shutdown(); + } + } + + private static long jniEnvironmentOffset = Integer.MAX_VALUE; + + private static long getJniEnvironmentOffset() { + if (jniEnvironmentOffset == Integer.MAX_VALUE) { + HotSpotJVMCIRuntime jvmciRuntime = HotSpotJVMCIRuntime.runtime(); + HotSpotVMConfigStore store = jvmciRuntime.getConfigStore(); + HotSpotVMConfigAccess config = new HotSpotVMConfigAccess(store); + jniEnvironmentOffset = config.getFieldOffset("JavaThread::_jni_environment", Integer.class, "JNIEnv"); } + return jniEnvironmentOffset; + } + + /** + * Gets the JNIEnv value for the current HotSpot thread. + */ + static long getJNIEnv() { + HotSpotJVMCIRuntime jvmciRuntime = HotSpotJVMCIRuntime.runtime(); + long offset = getJniEnvironmentOffset(); + long javaThreadAddr = jvmciRuntime.getCurrentJavaThread(); + return javaThreadAddr + offset; } void clearMetrics() { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotMarkId.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotMarkId.java index 0dbf1371b059..9f6d49f5884b 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotMarkId.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotMarkId.java @@ -27,7 +27,6 @@ import jdk.graal.compiler.code.CompilationResult; import jdk.graal.compiler.debug.GraalError; -import jdk.vm.ci.common.NativeImageReinitialize; /** * Constants used to mark special positions in code being installed into the code cache by Graal C++ @@ -72,7 +71,7 @@ public enum HotSpotMarkId implements CompilationResult.MarkId { Z_BARRIER_RELOCATION_FORMAT_STORE_GOOD_BEFORE_MOV("aarch64"), Z_BARRIER_RELOCATION_FORMAT_STORE_BAD_BEFORE_MOV("aarch64"); - @NativeImageReinitialize private Integer value; + private Integer value; private final String arch; HotSpotMarkId() { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotReplacementsImpl.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotReplacementsImpl.java index 1ed9fd3af364..8837119cc068 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotReplacementsImpl.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotReplacementsImpl.java @@ -60,7 +60,6 @@ import jdk.graal.compiler.replacements.IntrinsicGraphBuilder; import jdk.graal.compiler.replacements.ReplacementsImpl; import jdk.vm.ci.code.TargetDescription; -import jdk.vm.ci.common.NativeImageReinitialize; import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; @@ -185,7 +184,7 @@ public StructuredGraph getInlineSubstitution(ResolvedJavaMethod method, int invo // When assertions are enabled, these fields are used to ensure all snippets are // registered during Graal initialization which in turn ensures that native image // building will not miss any snippets. - @NativeImageReinitialize private EconomicSet registeredSnippets = EconomicSet.create(); + private EconomicSet registeredSnippets = EconomicSet.create(); private boolean snippetRegistrationClosed; @Override @@ -252,7 +251,7 @@ public boolean encode(OptionValues options) { private static volatile EncodedSnippets encodedSnippets; - @NativeImageReinitialize private static SymbolicSnippetEncoder snippetEncoder; + private static SymbolicSnippetEncoder snippetEncoder; @SuppressWarnings("try") @Override diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotTTYStreamProvider.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotTTYStreamProvider.java index 44a325fec502..6828310acbfe 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotTTYStreamProvider.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotTTYStreamProvider.java @@ -43,7 +43,6 @@ import jdk.graal.compiler.serviceprovider.GraalServices; import jdk.graal.compiler.serviceprovider.IsolateUtil; import jdk.graal.compiler.serviceprovider.ServiceProvider; -import jdk.vm.ci.common.NativeImageReinitialize; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; @ServiceProvider(TTYStreamProvider.class) @@ -154,7 +153,7 @@ private static String makeFilename(String nameTemplate) { * initialization. */ class DelayedOutputStream extends OutputStream { - @NativeImageReinitialize private volatile OutputStream lazy; + private volatile OutputStream lazy; private OutputStream lazy() { if (lazy == null) { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/SnippetSignature.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/SnippetSignature.java index 7ab6f7e0685b..95463aa81bd5 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/SnippetSignature.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/SnippetSignature.java @@ -29,7 +29,6 @@ import java.util.List; import jdk.graal.compiler.util.SignatureUtil; -import jdk.vm.ci.common.NativeImageReinitialize; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.meta.MetaAccessProvider; @@ -49,7 +48,7 @@ public final class SnippetSignature implements Signature { private final String returnType; private final String originalString; - @NativeImageReinitialize private static EnumMap primitiveTypes = null; + private static EnumMap primitiveTypes = null; static synchronized void initPrimitiveKindCache(MetaAccessProvider metaAccess) { if (primitiveTypes == null) { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/SymbolicSnippetEncoder.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/SymbolicSnippetEncoder.java index 4c00b133d5f7..c781d37f76f6 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/SymbolicSnippetEncoder.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/SymbolicSnippetEncoder.java @@ -42,7 +42,6 @@ import java.util.Set; import java.util.function.BiFunction; -import jdk.graal.compiler.serviceprovider.GraalServices; import org.graalvm.collections.EconomicMap; import org.graalvm.collections.EconomicSet; import org.graalvm.collections.MapCursor; @@ -143,7 +142,7 @@ * method references into a symbolic form that can be resolved at graph decode time using * {@link SymbolicJVMCIReference}. *

      - * An instance of this class only exist when {@link GraalServices#isBuildingLibgraal()} is true. + * An instance of this class only exist when building libgraal. */ public class SymbolicSnippetEncoder { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/BuildTime.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/BuildTime.java deleted file mode 100644 index 59d3102da6fa..000000000000 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/BuildTime.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 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 jdk.graal.compiler.hotspot.libgraal; - -import static java.lang.invoke.MethodType.methodType; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodHandles.Lookup; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.ServiceLoader; -import java.util.function.BiConsumer; -import java.util.function.Consumer; - -import jdk.graal.compiler.core.common.Fields; -import jdk.graal.nativeimage.LibGraalFeatureComponent; -import org.graalvm.collections.EconomicMap; - -import jdk.graal.compiler.core.ArchitectureSpecific; -import jdk.graal.compiler.core.common.spi.ForeignCallSignature; -import jdk.graal.compiler.debug.GraalError; -import jdk.graal.compiler.debug.TTY; -import jdk.graal.compiler.graph.NodeClass; -import jdk.graal.compiler.hotspot.CompilerConfigurationFactory; -import jdk.graal.compiler.hotspot.EncodedSnippets; -import jdk.graal.compiler.hotspot.HotSpotForeignCallLinkage; -import jdk.graal.compiler.hotspot.HotSpotReplacementsImpl; -import jdk.graal.compiler.nodes.graphbuilderconf.GeneratedInvocationPlugin; -import jdk.graal.compiler.options.OptionDescriptor; -import jdk.graal.compiler.options.OptionKey; -import jdk.graal.compiler.options.OptionsParser; -import jdk.graal.compiler.serviceprovider.GraalServices; -import jdk.graal.compiler.util.ObjectCopier; -import jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory; -import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; -import jdk.vm.ci.services.JVMCIServiceLocator; -import org.graalvm.nativeimage.Platform; -import org.graalvm.nativeimage.Platforms; - -/** - * This class is used at image build-time when a libgraal image gets built. Its static methods are - * called from {@code com.oracle.svm.graal.hotspot.libgraal.LibGraalFeature} before static analysis. - * These methods ensure the static field state of Graal and JVMCI classes loaded by the - * LibGraalClassLoader is set up correctly for getting built into libgraal. - */ -@Platforms(Platform.HOSTED_ONLY.class) -public class BuildTime { - - private static final String VALID_LOADER_NAME = "LibGraalClassLoader"; - private static final ClassLoader LOADER = BuildTime.class.getClassLoader(); - - /** - * Creates and registers the data structures used for looking up libgraal compiler options and - * determining which of them are enterprise options. - */ - @SuppressWarnings("unused") - public static Object initLibgraalOptions() { - return OptionsParser.setLibgraalOptions(OptionsParser.LibGraalOptionsInfo.create()); - } - - /** - * Processes the entries in {@code optionObjects} and adds their - * {@linkplain OptionDescriptor#isServiceLoaded() non-service loaded} descriptors to - * {@code descriptorsObject}. - * - * @param optionObjects a list of {@link OptionKey} objects - * @param optionsInfoObject the value returned by {@link #initLibgraalOptions()} - * @param modules unmodifiable map from the {@linkplain Class#forName(String) name} of a class - * to the name of its enclosing module. - * @return the {@link OptionDescriptor} objects added to {@code descriptorsObject} - */ - @SuppressWarnings("unused") - public static Iterable finalizeLibgraalOptions(List optionObjects, Object optionsInfoObject, Map modules) { - GraalError.guarantee(VALID_LOADER_NAME.equals(LOADER.getName()), - "Only call this method from classloader " + VALID_LOADER_NAME); - OptionsParser.LibGraalOptionsInfo optionsInfo = (OptionsParser.LibGraalOptionsInfo) optionsInfoObject; - for (Object optionObject : optionObjects) { - OptionKey option = (OptionKey) optionObject; - OptionDescriptor descriptor = option.getDescriptor(); - if (descriptor.isServiceLoaded()) { - String name = option.getName(); - optionsInfo.descriptors().put(name, descriptor); - String module = modules.get(descriptor.getDeclaringClass().getName()); - if (module.contains("enterprise")) { - optionsInfo.enterpriseOptions().add(name); - } - } - } - return optionsInfo.descriptors().getValues(); - } - - @SuppressWarnings("unused") - public static long[] getInputEdgesOffsets(Object rawNodeClass) { - /* Used by LibGraalFieldsOffsetsFeature.IterationMaskRecomputation */ - NodeClass nodeclass = (NodeClass) rawNodeClass; - return nodeclass.getInputEdges().getOffsets(); - } - - @SuppressWarnings("unused") - public static long[] getSuccessorEdgesOffsets(Object rawNodeClass) { - /* Used by LibGraalFieldsOffsetsFeature.IterationMaskRecomputation */ - NodeClass nodeclass = (NodeClass) rawNodeClass; - return nodeclass.getSuccessorEdges().getOffsets(); - } - - @SuppressWarnings("unchecked") - private static void addProviders(Map, List> services, String arch, Class service) { - List providers = (List) services.computeIfAbsent(service, key -> new ArrayList<>()); - for (Object provider : ServiceLoader.load(service, LOADER)) { - if (provider instanceof ArchitectureSpecific as && !as.getArchitecture().equals(arch)) { - // Skip provider for another architecture - continue; - } - providers.add(provider); - } - } - - /** - * Configures the static state needed for libgraal. - * - * @param arch a value compatible with {@link ArchitectureSpecific#getArchitecture()} - */ - @SuppressWarnings({"try", "unused", "unchecked"}) - public static void configureGraalForLibGraal( - String arch, - Collection libGraalFeatureComponents, - List> guestServiceClasses, - Consumer> registerAsInHeap, - Consumer>> hostedGraalSetFoldNodePluginClasses, - String nativeImageLocationQualifier, - byte[] encodedGuestObjects) { - GraalError.guarantee(VALID_LOADER_NAME.equals(LOADER.getName()), - "Only call this method from classloader " + VALID_LOADER_NAME); - - Fields.setLibGraalFeatureComponents(libGraalFeatureComponents); - Map, List> services = new HashMap<>(); - guestServiceClasses.forEach(c -> addProviders(services, arch, c)); - GraalServices.setLibgraalServices(services); - - CompilerConfigurationFactory.setNativeImageLocationQualifier(nativeImageLocationQualifier); - - try { - Field cachedHotSpotJVMCIBackendFactoriesField = ObjectCopier.getField(HotSpotJVMCIRuntime.class, "cachedHotSpotJVMCIBackendFactories"); - GraalError.guarantee(cachedHotSpotJVMCIBackendFactoriesField.get(null) == null, "Expect cachedHotSpotJVMCIBackendFactories to be null"); - ServiceLoader load = ServiceLoader.load(HotSpotJVMCIBackendFactory.class, LOADER); - List backendFactories = load.stream()// - .map(ServiceLoader.Provider::get)// - .filter(s -> s.getArchitecture().equals(arch))// - .toList(); - cachedHotSpotJVMCIBackendFactoriesField.set(null, backendFactories); - GraalError.guarantee(backendFactories.size() == 1, "%s", backendFactories); - - var jvmciServiceLocatorCachedLocatorsField = ObjectCopier.getField(JVMCIServiceLocator.class, "cachedLocators"); - GraalError.guarantee(jvmciServiceLocatorCachedLocatorsField.get(null) == null, "Expect cachedLocators to be null"); - Iterable serviceLocators = ServiceLoader.load(JVMCIServiceLocator.class, LOADER); - List cachedLocators = new ArrayList<>(); - serviceLocators.forEach(cachedLocators::add); - jvmciServiceLocatorCachedLocatorsField.set(null, cachedLocators); - - EconomicMap libgraalObjects = (EconomicMap) ObjectCopier.decode(encodedGuestObjects, LOADER); - EncodedSnippets encodedSnippets = (EncodedSnippets) libgraalObjects.get("encodedSnippets"); - - // Mark all the Node classes as allocated so they are available during graph decoding. - for (NodeClass nodeClass : encodedSnippets.getSnippetNodeClasses()) { - registerAsInHeap.accept(nodeClass.getClazz()); - } - HotSpotReplacementsImpl.setEncodedSnippets(encodedSnippets); - - List foreignCallSignatures = (List) libgraalObjects.get("foreignCallSignatures"); - HotSpotForeignCallLinkage.Stubs.initStubs(foreignCallSignatures); - - hostedGraalSetFoldNodePluginClasses.accept(GeneratedInvocationPlugin.getFoldNodePluginClasses()); - - } catch (ReflectiveOperationException e) { - throw GraalError.shouldNotReachHere(e); - } - } -} diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/RunTime.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/RunTime.java deleted file mode 100644 index 1121c7033c98..000000000000 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/RunTime.java +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) 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 jdk.graal.compiler.hotspot.libgraal; - -import java.util.Arrays; -import java.util.Map; -import java.util.function.BiConsumer; - -import org.graalvm.collections.EconomicMap; - -import jdk.graal.compiler.debug.GlobalMetrics; -import jdk.graal.compiler.hotspot.CompilationContext; -import jdk.graal.compiler.hotspot.CompilationTask; -import jdk.graal.compiler.hotspot.HotSpotGraalCompiler; -import jdk.graal.compiler.hotspot.HotSpotGraalRuntime; -import jdk.graal.compiler.hotspot.HotSpotGraalServices; -import jdk.graal.compiler.hotspot.ProfileReplaySupport; -import jdk.graal.compiler.options.OptionDescriptors; -import jdk.graal.compiler.options.OptionKey; -import jdk.graal.compiler.options.OptionValues; -import jdk.graal.compiler.options.OptionsParser; -import jdk.graal.compiler.util.OptionsEncoder; -import jdk.internal.misc.Unsafe; -import jdk.vm.ci.hotspot.HotSpotCompilationRequest; -import jdk.vm.ci.hotspot.HotSpotInstalledCode; -import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; -import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; -import jdk.vm.ci.hotspot.HotSpotResolvedJavaType; -import jdk.vm.ci.hotspot.HotSpotVMConfigAccess; -import jdk.vm.ci.hotspot.HotSpotVMConfigStore; -import jdk.vm.ci.meta.ConstantReflectionProvider; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.ResolvedJavaField; -import jdk.vm.ci.runtime.JVMCIBackend; -import jdk.vm.ci.runtime.JVMCICompiler; - -import static jdk.graal.compiler.serviceprovider.GraalServices.getCurrentThreadAllocatedBytes; -import static jdk.graal.compiler.serviceprovider.GraalServices.isThreadAllocatedMemorySupported; - -/** - * This class provides implementations for {@code @CEntryPoint}s that libgraal has to provide as a - * JVM JIT compiler as well as handles (created by {@link BuildTime#getRuntimeHandles}) to other - * utility methods needed by {@code LibGraalFeature}. - */ -public class RunTime { - - private static final Unsafe UNSAFE = Unsafe.getUnsafe(); - - private record CachedOptions(OptionValues options, long hash) { - } - - private static final ThreadLocal CACHED_OPTIONS_THREAD_LOCAL = new ThreadLocal<>(); - - private static OptionValues decodeOptions(long address, int size, int hash) { - CachedOptions options = CACHED_OPTIONS_THREAD_LOCAL.get(); - if (options == null || options.hash != hash) { - byte[] buffer = new byte[size]; - UNSAFE.copyMemory(null, address, buffer, Unsafe.ARRAY_BYTE_BASE_OFFSET, size); - int actualHash = Arrays.hashCode(buffer); - if (actualHash != hash) { - throw new IllegalArgumentException(actualHash + " != " + hash); - } - Map srcMap = OptionsEncoder.decode(buffer); - final EconomicMap, Object> dstMap = OptionValues.newOptionMap(); - final Iterable loader = OptionsParser.getOptionsLoader(); - for (Map.Entry e : srcMap.entrySet()) { - final String optionName = e.getKey(); - final Object optionValue = e.getValue(); - OptionsParser.parseOption(optionName, optionValue, dstMap, loader); - } - - options = new CachedOptions(new OptionValues(dstMap), hash); - CACHED_OPTIONS_THREAD_LOCAL.set(options); - } - return options.options; - } - - /** - * This is the implementation that {@code @CEntryPoint}-method - * {@code com.oracle.svm.graal.hotspot.libgraal.LibGraalEntryPoints#compileMethod} delegates to. - * Most parameters are identical to the caller method parameters except for the following: - * - * @param profileLoadPath value of the {@code Options#LoadProfiles} option or null - * @param timeAndMemConsumer allows caller to get info about compile time and memory consumption - */ - @SuppressWarnings("try") - public static long compileMethod(long methodHandle, boolean useProfilingInfo, - boolean installAsDefault, boolean printMetrics, boolean eagerResolving, - long optionsAddress, int optionsSize, int optionsHash, - String profileLoadPath, BiConsumer timeAndMemConsumer) { - - HotSpotJVMCIRuntime runtime = HotSpotJVMCIRuntime.runtime(); - HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) runtime.getCompiler(); - if (methodHandle == 0L) { - return 0L; - } - - int entryBCI = JVMCICompiler.INVOCATION_ENTRY_BCI; - HotSpotResolvedJavaMethod method = runtime.unhand(HotSpotResolvedJavaMethod.class, methodHandle); - HotSpotCompilationRequest request = new HotSpotCompilationRequest(method, entryBCI, 0L); - try (CompilationContext ignored = HotSpotGraalServices.openLocalCompilationContext(request)) { - CompilationTask task = new CompilationTask(runtime, compiler, request, useProfilingInfo, false, false, eagerResolving, installAsDefault); - long allocatedBytesBefore = 0; - long timeBefore = 0; - if (timeAndMemConsumer != null) { - allocatedBytesBefore = isThreadAllocatedMemorySupported() ? getCurrentThreadAllocatedBytes() : -1; - timeBefore = System.nanoTime(); - } - OptionValues options = decodeOptions(optionsAddress, optionsSize, optionsHash); - if (profileLoadPath != null) { - options = new OptionValues(options, ProfileReplaySupport.Options.LoadProfiles, profileLoadPath); - } - task.runCompilation(options); - if (timeAndMemConsumer != null) { - long allocatedBytesAfter = allocatedBytesBefore == -1 ? -1 : getCurrentThreadAllocatedBytes(); - long bytesAllocated = allocatedBytesAfter - allocatedBytesBefore; - long timeAfter = System.nanoTime(); - long timeSpent = timeAfter - timeBefore; - timeAndMemConsumer.accept(timeSpent, bytesAllocated); - } - HotSpotInstalledCode installedCode = task.getInstalledCode(); - if (printMetrics) { - GlobalMetrics metricValues = ((HotSpotGraalRuntime) compiler.getGraalRuntime()).getMetricValues(); - metricValues.print(options); - metricValues.clear(); - } - return runtime.translate(installedCode); - } - } - - @SuppressWarnings({"unused", "try"}) - public static long hashConstantOopFields(long typeHandle, boolean useScope, int iterations, - int oopsPerIteration, boolean verbose, Runnable doReferenceHandling) { - HotSpotJVMCIRuntime runtime = HotSpotJVMCIRuntime.runtime(); - JVMCIBackend backend = runtime.getHostJVMCIBackend(); - ConstantReflectionProvider constantReflection = backend.getConstantReflection(); - HotSpotResolvedJavaType type = runtime.unhand(HotSpotResolvedJavaType.class, typeHandle); - ResolvedJavaField[] staticFields = type.getStaticFields(); - JavaConstant receiver = null; - long hash = 13; - - Object scopeDescription = "TestingOopHandles"; - - int remainingIterations = iterations; - while (remainingIterations-- > 0) { - ResolvedJavaField lastReadField = null; - try (CompilationContext scope = useScope ? HotSpotGraalServices.openLocalCompilationContext(scopeDescription) : null) { - if (verbose && useScope) { - System.out.println("Opened " + scopeDescription); - } - int remainingOops = oopsPerIteration; - while (remainingOops-- > 0) { - for (ResolvedJavaField field : staticFields) { - if (field.getType().getJavaKind() == JavaKind.Object) { - JavaConstant value = constantReflection.readFieldValue(field, receiver); - if (value != null) { - lastReadField = field; - hash = hash ^ value.hashCode(); - } - } - } - } - } - if (!useScope) { - System.gc(); - if (verbose) { - System.out.println("calling reference handling"); - } - doReferenceHandling.run(); - if (verbose) { - System.out.println("called reference handling"); - } - // Need one more remote oop creation to trigger releasing - // of remote oops that were wrapped in weakly reachable - // IndirectHotSpotObjectConstantImpl objects just collected. - constantReflection.readFieldValue(lastReadField, receiver); - } else if (verbose) { - System.out.println(" Closed " + scopeDescription); - } - } - return hash; - } - - private static long jniEnvironmentOffset = Integer.MAX_VALUE; - - private static long getJniEnvironmentOffset() { - if (jniEnvironmentOffset == Integer.MAX_VALUE) { - HotSpotJVMCIRuntime jvmciRuntime = HotSpotJVMCIRuntime.runtime(); - HotSpotVMConfigStore store = jvmciRuntime.getConfigStore(); - HotSpotVMConfigAccess config = new HotSpotVMConfigAccess(store); - jniEnvironmentOffset = config.getFieldOffset("JavaThread::_jni_environment", Integer.class, "JNIEnv"); - } - return jniEnvironmentOffset; - } - - /** - * Gets the JNIEnv value for the current HotSpot thread. - */ - public static long getJNIEnv() { - HotSpotJVMCIRuntime jvmciRuntime = HotSpotJVMCIRuntime.runtime(); - long offset = getJniEnvironmentOffset(); - long javaThreadAddr = jvmciRuntime.getCurrentJavaThread(); - return javaThreadAddr + offset; - } - - /** - * Ensures the current thread is attached to the peer runtime. - * - * @param isDaemon if the thread is not yet attached, should it be attached as a daemon - * @param isolate if non-null, the isolate for the current thread is returned in element 0 - * @return {@code true} if this call attached the current thread, {@code false} if the current - * thread was already attached - */ - public static boolean attachCurrentThread(boolean isDaemon, long[] isolate) { - long[] javaVMInfo = isolate != null ? new long[4] : null; - boolean res = HotSpotJVMCIRuntime.runtime().attachCurrentThread(isDaemon, javaVMInfo); - if (isolate != null) { - isolate[0] = javaVMInfo[1]; - } - return res; - } - - /** - * Detaches the current thread from the peer runtime. - * - * @param release if {@code true} and the VM supports releasing the {@code JavaVM} associated - * with libgraal runtimes and this is the last thread attached to a libgraal runtime, - * then this call destroys the associated {@code JavaVM} instance, releasing its - * resources - * @return {@code true} if the {@code JavaVM} associated with the libgraal runtime was destroyed - * as a result of this call - */ - public static boolean detachCurrentThread(boolean release) { - return HotSpotJVMCIRuntime.runtime().detachCurrentThread(release); - } -} diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/stubs/AbstractForeignCallStub.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/stubs/AbstractForeignCallStub.java index 38a8ba58551b..980a8e575877 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/stubs/AbstractForeignCallStub.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/stubs/AbstractForeignCallStub.java @@ -50,7 +50,6 @@ import jdk.graal.compiler.options.OptionValues; import jdk.graal.compiler.replacements.GraphKit; import jdk.graal.compiler.replacements.nodes.ReadRegisterNode; -import jdk.graal.compiler.serviceprovider.GraalServices; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; import jdk.vm.ci.hotspot.HotSpotSignature; import jdk.vm.ci.meta.JavaMethod; @@ -59,6 +58,7 @@ import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; import jdk.vm.ci.meta.Signature; +import org.graalvm.nativeimage.ImageInfo; /** * A {@linkplain #getGraph generated} stub for a {@link Transition non-leaf} foreign call from @@ -276,7 +276,7 @@ private ResolvedJavaMethod getGraphMethod() { if (thisMethod == null) { throw new InternalError("Can't find " + getClass().getSimpleName() + ".getGraph"); } - if (GraalServices.isBuildingLibgraal()) { + if (ImageInfo.inImageBuildtimeCode()) { HotSpotReplacementsImpl replacements = (HotSpotReplacementsImpl) providers.getReplacements(); replacements.findSnippetMethod(thisMethod); } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/CompilerConfig.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/CompilerConfig.java similarity index 97% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/CompilerConfig.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/CompilerConfig.java index 70bae2af222e..4577db416c59 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/CompilerConfig.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/CompilerConfig.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.hotspot.libgraal; +package jdk.graal.compiler.libgraal; import java.lang.reflect.Field; import java.nio.file.Files; @@ -49,6 +49,8 @@ import jdk.graal.compiler.truffle.hotspot.HotSpotTruffleCompilerImpl; import jdk.graal.compiler.util.ObjectCopier; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; /** * A command line program that initializes the compiler data structures to be serialized into the @@ -61,6 +63,7 @@ * {@link jdk.graal.compiler.hotspot.HotSpotForeignCallLinkage.Stubs#initStubs} * */ +@Platforms(Platform.HOSTED_ONLY.class) public class CompilerConfig { /** @@ -74,7 +77,7 @@ public static void main(String[] args) throws Exception { HotSpotReplacementsImpl replacements = (HotSpotReplacementsImpl) hostProviders.getReplacements(); OptionValues options = graalRuntime.getCapability(OptionValues.class); - List foreignCallSignatures = getForeignCallSignatures(replacements, options, graalRuntime); + List foreignCallSignatures = getForeignCallSignatures(replacements, options); EncodedSnippets encodedSnippets = getEncodedSnippets(replacements, options); List externalValueFields = ObjectCopier.getExternalValueFields(); @@ -103,7 +106,7 @@ private static EncodedSnippets getEncodedSnippets(HotSpotReplacementsImpl replac return snippetEncoder.encodeSnippets(options); } - private static List getForeignCallSignatures(HotSpotReplacementsImpl replacements, OptionValues options, HotSpotGraalRuntimeProvider graalRuntime) { + private static List getForeignCallSignatures(HotSpotReplacementsImpl replacements, OptionValues options) { List sigs = new ArrayList<>(); EconomicMap foreignCalls = collectForeignCalls(replacements, options); MapCursor cursor = foreignCalls.getEntries(); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetCompilerConfig.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetCompilerConfig.java index 9cab296cd527..f89fbf2224da 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetCompilerConfig.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetCompilerConfig.java @@ -36,16 +36,19 @@ import java.util.stream.Collectors; import jdk.graal.compiler.debug.GraalError; -import jdk.graal.compiler.hotspot.libgraal.CompilerConfig; +import jdk.graal.compiler.serviceprovider.GraalServices; import jdk.graal.compiler.util.ObjectCopier; import org.graalvm.nativeimage.ImageInfo; +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; /** * Gets the map created in a JVM subprocess by running {@link CompilerConfig}. */ +@Platforms(Platform.HOSTED_ONLY.class) public class GetCompilerConfig { - private static final boolean DEBUG = Boolean.getBoolean("debug." + GetCompilerConfig.class.getName()); + private static final boolean DEBUG = Boolean.parseBoolean(GraalServices.getSavedProperty("debug." + GetCompilerConfig.class.getName())); /** * Result returned by {@link GetCompilerConfig#from}. diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetJNIConfig.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetJNIConfig.java index 2091cc717936..5deebf2c4435 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetJNIConfig.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetJNIConfig.java @@ -40,7 +40,10 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.graal.compiler.serviceprovider.GraalServices; import jdk.graal.compiler.util.SignatureUtil; +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; import org.graalvm.nativeimage.hosted.RuntimeJNIAccess; import org.graalvm.nativeimage.hosted.RuntimeReflection; @@ -50,6 +53,7 @@ * Registers the JNI configuration for libgraal by parsing the output of the * {@code -XX:JVMCILibDumpJNIConfig} VM option. */ +@Platforms(Platform.HOSTED_ONLY.class) final class GetJNIConfig implements AutoCloseable { /** * VM command executed to read the JNI config. @@ -76,7 +80,7 @@ final class GetJNIConfig implements AutoCloseable { private GetJNIConfig(ClassLoader loader) { this.loader = loader; - Path javaExe = getJavaExe(Path.of(System.getProperty("java.home"))); + Path javaExe = getJavaExe(Path.of(GraalServices.getSavedProperty("java.home"))); configFilePath = Path.of("libgraal_jniconfig.txt"); String[] command = {javaExe.toFile().getAbsolutePath(), "-XX:+UnlockExperimentalVMOptions", "-XX:+EnableJVMCI", "-XX:JVMCILibDumpJNIConfig=" + configFilePath}; @@ -112,7 +116,7 @@ private GetJNIConfig(ClassLoader loader) { } static Path getJavaExe(Path javaHome) { - boolean isWindows = System.getProperty("os.name").contains("Windows"); + boolean isWindows = GraalServices.getSavedProperty("os.name").contains("Windows"); Path javaExe = javaHome.resolve(Path.of("bin", isWindows ? "java.exe" : "java")); if (!Files.isExecutable(javaExe)) { throw new GraalError("Java launcher %s does not exist or is not executable", javaExe); @@ -186,7 +190,7 @@ private void check(boolean condition, String format, Object... args) { private GraalError error(String format, Object... args) { Path path = configFilePath; configFilePath = null; // prevent deletion - String errorMessage = String.format(format, args); + String errorMessage = format.formatted(args); String errorLine = lines.get(lineNo - 1); throw new GraalError("Line %d of %s: %s%n%s%n%s generated by command: %s", lineNo, path.toAbsolutePath(), errorMessage, errorLine, path, quotedCommand); @@ -214,7 +218,6 @@ public static void register(ClassLoader loader) { Class clazz = classes.get(className); if (clazz == null) { clazz = source.findClass(className); - assert clazz.getClassLoader() == null || clazz.getClassLoader() == loader; RuntimeJNIAccess.register(clazz); RuntimeJNIAccess.register(Array.newInstance(clazz, 0).getClass()); classes.put(className, clazz); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/BuildTime.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/JDK21.java similarity index 62% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/BuildTime.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/JDK21.java index 65521b979bf4..baba61097948 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/BuildTime.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/JDK21.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 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 @@ -22,23 +22,15 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.hotspot.libgraal.truffle; +package jdk.graal.compiler.libgraal; -import org.graalvm.nativeimage.Platform; -import org.graalvm.nativeimage.Platforms; +import java.util.function.BooleanSupplier; -import jdk.graal.compiler.truffle.host.TruffleHostEnvironment; +import jdk.graal.compiler.serviceprovider.JavaVersionUtil; -/** - * Class used to initialize the Truffle extensions to the Graal compiler in the image build time. - */ -@Platforms(Platform.HOSTED_ONLY.class) -public class BuildTime { - - /** - * Configures Truffle services to the Graal compiler in the image build time. - */ - public static void configureGraalForLibGraal() { - TruffleHostEnvironment.overrideLookup(new LibGraalTruffleHostEnvironmentLookup()); +public class JDK21 implements BooleanSupplier { + @Override + public boolean getAsBoolean() { + return JavaVersionUtil.JAVA_SPEC == 21; } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalEntryPoints.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalEntryPoints.java index a887343037e7..33a90ef043d6 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalEntryPoints.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalEntryPoints.java @@ -27,22 +27,38 @@ import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.util.Arrays; -import java.util.Comparator; -import java.util.List; import java.util.Map; -import java.util.function.BiConsumer; -import jdk.graal.compiler.hotspot.libgraal.RunTime; +import jdk.graal.compiler.debug.GlobalMetrics; +import jdk.graal.compiler.hotspot.CompilationContext; +import jdk.graal.compiler.hotspot.CompilationTask; +import jdk.graal.compiler.hotspot.HotSpotGraalCompiler; +import jdk.graal.compiler.hotspot.HotSpotGraalRuntime; +import jdk.graal.compiler.hotspot.HotSpotGraalServices; +import jdk.graal.compiler.hotspot.ProfileReplaySupport; +import jdk.graal.compiler.options.OptionDescriptors; +import jdk.graal.compiler.options.OptionKey; import jdk.graal.compiler.options.OptionValues; +import jdk.graal.compiler.options.OptionsParser; +import jdk.graal.compiler.util.OptionsEncoder; import jdk.graal.compiler.word.Word; -import jdk.graal.nativeimage.LibGraalRuntime; -import org.graalvm.collections.EconomicSet; +import jdk.vm.ci.hotspot.HotSpotCompilationRequest; +import jdk.vm.ci.hotspot.HotSpotInstalledCode; +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; +import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; +import jdk.vm.ci.hotspot.HotSpotResolvedJavaType; +import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.ResolvedJavaField; +import jdk.vm.ci.runtime.JVMCIBackend; +import jdk.vm.ci.runtime.JVMCICompiler; +import org.graalvm.collections.EconomicMap; import org.graalvm.jniutils.JNI.JNIEnv; import org.graalvm.jniutils.JNIExceptionWrapper; import org.graalvm.jniutils.JNIMethodScope; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; -import org.graalvm.nativeimage.RuntimeOptions; import org.graalvm.nativeimage.c.function.CEntryPoint; import org.graalvm.nativeimage.c.function.CEntryPoint.IsolateThreadContext; import org.graalvm.nativeimage.c.type.CTypeConversion; @@ -50,19 +66,52 @@ import jdk.internal.misc.Unsafe; +import static jdk.graal.compiler.serviceprovider.GraalServices.getCurrentThreadAllocatedBytes; +import static jdk.graal.compiler.serviceprovider.GraalServices.isThreadAllocatedMemorySupported; + /** * Encapsulates {@link CEntryPoint} implementations. */ final class LibGraalEntryPoints { @Platforms(Platform.HOSTED_ONLY.class) - LibGraalEntryPoints() { + private LibGraalEntryPoints() { + } + + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); + + private record CachedOptions(OptionValues options, long hash) { + } + + private static final ThreadLocal CACHED_OPTIONS_THREAD_LOCAL = new ThreadLocal<>(); + + private static OptionValues decodeOptions(long address, int size, int hash) { + CachedOptions options = CACHED_OPTIONS_THREAD_LOCAL.get(); + if (options == null || options.hash != hash) { + byte[] buffer = new byte[size]; + UNSAFE.copyMemory(null, address, buffer, Unsafe.ARRAY_BYTE_BASE_OFFSET, size); + int actualHash = Arrays.hashCode(buffer); + if (actualHash != hash) { + throw new IllegalArgumentException(actualHash + " != " + hash); + } + Map srcMap = OptionsEncoder.decode(buffer); + final EconomicMap, Object> dstMap = OptionValues.newOptionMap(); + final Iterable loader = OptionsParser.getOptionsLoader(); + for (Map.Entry e : srcMap.entrySet()) { + final String optionName = e.getKey(); + final Object optionValue = e.getValue(); + OptionsParser.parseOption(optionName, optionValue, dstMap, loader); + } + + options = new CachedOptions(new OptionValues(dstMap), hash); + CACHED_OPTIONS_THREAD_LOCAL.set(options); + } + return options.options; } /** * The implementation of * {@code jdk.graal.compiler.hotspot.test.LibGraalCompilationDriver#compileMethodInLibgraal}. - * Calls {@link RunTime#compileMethod}. * * @param methodHandle the method to be compiled. This is a handle to a * {@code HotSpotResolvedJavaMethod} in HotSpot's heap. A value of 0L can be passed @@ -114,26 +163,45 @@ private static long compileMethod(JNIEnv jniEnv, long timeAndMemBufferAddress, long profilePathBufferAddress) { try (JNIMethodScope jniScope = new JNIMethodScope("compileMethod", jniEnv)) { - String profileLoadPath; - if (profilePathBufferAddress > 0) { - profileLoadPath = CTypeConversion.toJavaString(Word.pointer(profilePathBufferAddress)); - } else { - profileLoadPath = null; + HotSpotJVMCIRuntime runtime = HotSpotJVMCIRuntime.runtime(); + HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) runtime.getCompiler(); + if (methodHandle == 0L) { + return 0L; } - BiConsumer timeAndMemConsumer; - if (timeAndMemBufferAddress != 0) { - timeAndMemConsumer = (timeSpent, bytesAllocated) -> { + + int entryBCI = JVMCICompiler.INVOCATION_ENTRY_BCI; + HotSpotResolvedJavaMethod method = runtime.unhand(HotSpotResolvedJavaMethod.class, methodHandle); + HotSpotCompilationRequest request = new HotSpotCompilationRequest(method, entryBCI, 0L); + try (CompilationContext ignored = HotSpotGraalServices.openLocalCompilationContext(request)) { + CompilationTask task = new CompilationTask(runtime, compiler, request, useProfilingInfo, false, false, eagerResolving, installAsDefault); + long allocatedBytesBefore = 0; + long timeBefore = 0; + if (timeAndMemBufferAddress != 0) { + allocatedBytesBefore = isThreadAllocatedMemorySupported() ? getCurrentThreadAllocatedBytes() : -1; + timeBefore = System.nanoTime(); + } + OptionValues options = decodeOptions(optionsAddress, optionsSize, optionsHash); + if (profilePathBufferAddress > 0) { + String profileLoadPath = CTypeConversion.toJavaString(Word.pointer(profilePathBufferAddress)); + options = new OptionValues(options, ProfileReplaySupport.Options.LoadProfiles, profileLoadPath); + } + task.runCompilation(options); + if (timeAndMemBufferAddress != 0) { + long allocatedBytesAfter = allocatedBytesBefore == -1 ? -1 : getCurrentThreadAllocatedBytes(); + long bytesAllocated = allocatedBytesAfter - allocatedBytesBefore; + long timeAfter = System.nanoTime(); + long timeSpent = timeAfter - timeBefore; Unsafe.getUnsafe().putLong(timeAndMemBufferAddress, bytesAllocated); Unsafe.getUnsafe().putLong(timeAndMemBufferAddress + 8, timeSpent); - }; - } else { - timeAndMemConsumer = null; + } + HotSpotInstalledCode installedCode = task.getInstalledCode(); + if (printMetrics) { + GlobalMetrics metricValues = ((HotSpotGraalRuntime) compiler.getGraalRuntime()).getMetricValues(); + metricValues.print(options); + metricValues.clear(); + } + return runtime.translate(installedCode); } - - return RunTime.compileMethod(methodHandle, useProfilingInfo, - installAsDefault, printMetrics, eagerResolving, - optionsAddress, optionsSize, optionsHash, - profileLoadPath, timeAndMemConsumer); } catch (Throwable t) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); t.printStackTrace(new PrintStream(baos)); @@ -147,7 +215,7 @@ private static long compileMethod(JNIEnv jniEnv, * libgraal doesn't use a dedicated reference handler thread, so we trigger the * reference handling manually when a compilation finishes. */ - doReferenceHandling(); + HotSpotGraalRuntime.doReferenceHandling(); } } @@ -162,63 +230,57 @@ private static long hashConstantOopFields(JNIEnv jniEnv, int oopsPerIteration, boolean verbose) { try (JNIMethodScope scope = new JNIMethodScope("hashConstantOopFields", jniEnv)) { - Runnable doReferenceHandling = LibGraalEntryPoints::doReferenceHandling; - return RunTime.hashConstantOopFields(typeHandle, useScope, iterations, oopsPerIteration, verbose, doReferenceHandling); - } catch (Throwable t) { - JNIExceptionWrapper.throwInHotSpot(jniEnv, t); - return 0; - } - } + HotSpotJVMCIRuntime runtime = HotSpotJVMCIRuntime.runtime(); + JVMCIBackend backend = runtime.getHostJVMCIBackend(); + ConstantReflectionProvider constantReflection = backend.getConstantReflection(); + HotSpotResolvedJavaType type = runtime.unhand(HotSpotResolvedJavaType.class, typeHandle); + ResolvedJavaField[] staticFields = type.getStaticFields(); + JavaConstant receiver = null; + long hash = 13; - /** - * Since reference handling is synchronous in libgraal, explicitly perform it here and then run - * any code which is expecting to process a reference queue to let it clean up. - */ - static void doReferenceHandling() { - LibGraalRuntime.processReferences(); - synchronized (LibGraalJVMCISubstitutions.Target_jdk_vm_ci_hotspot_Cleaner.class) { - LibGraalJVMCISubstitutions.Target_jdk_vm_ci_hotspot_Cleaner.clean(); - } - } + Object scopeDescription = "TestingOopHandles"; - static EconomicSet explicitOptions = EconomicSet.create(); - - static void initializeOptions(Map settings) { - for (var e : settings.entrySet()) { - String name = e.getKey(); - String stringValue = e.getValue(); - Object value; - if (name.startsWith("X") && stringValue.isEmpty()) { - name = name.substring(1); - value = stringValue; - } else { - RuntimeOptions.Descriptor desc = RuntimeOptions.getDescriptor(name); - if (desc == null) { - throw new IllegalArgumentException("Could not find option " + name); + int remainingIterations = iterations; + while (remainingIterations-- > 0) { + ResolvedJavaField lastReadField = null; + try (CompilationContext scope1 = useScope ? HotSpotGraalServices.openLocalCompilationContext(scopeDescription) : null) { + if (verbose && useScope) { + System.out.println("Opened " + scopeDescription); + } + int remainingOops = oopsPerIteration; + while (remainingOops-- > 0) { + for (ResolvedJavaField field : staticFields) { + if (field.getType().getJavaKind() == JavaKind.Object) { + JavaConstant value = constantReflection.readFieldValue(field, receiver); + if (value != null) { + lastReadField = field; + hash = hash ^ value.hashCode(); + } + } + } + } + } + if (!useScope) { + System.gc(); + if (verbose) { + System.out.println("calling reference handling"); + } + HotSpotGraalRuntime.doReferenceHandling(); + if (verbose) { + System.out.println("called reference handling"); + } + // Need one more remote oop creation to trigger releasing + // of remote oops that were wrapped in weakly reachable + // IndirectHotSpotObjectConstantImpl objects just collected. + constantReflection.readFieldValue(lastReadField, receiver); + } else if (verbose) { + System.out.println(" Closed " + scopeDescription); } - value = desc.convertValue(stringValue); - explicitOptions.add(name); - } - try { - RuntimeOptions.set(name, value); - } catch (RuntimeException ex) { - throw new IllegalArgumentException(ex); } + return hash; + } catch (Throwable t) { + JNIExceptionWrapper.throwInHotSpot(jniEnv, t); + return 0; } } - - static void printOptions(PrintStream out, String prefix) { - Comparator comparator = Comparator.comparing(RuntimeOptions.Descriptor::name); - RuntimeOptions.listDescriptors().stream().sorted(comparator).forEach(d -> { - String assign = explicitOptions.contains(d.name()) ? ":=" : "="; - OptionValues.printHelp(out, prefix, - d.name(), - RuntimeOptions.get(d.name()), - d.valueType(), - assign, - "[community edition]", - d.help(), - List.of()); - }); - } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java index 38c6505b052f..b5993adf1d95 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java @@ -25,28 +25,37 @@ package jdk.graal.compiler.libgraal; import static java.lang.invoke.MethodType.methodType; -import static jdk.graal.compiler.serviceprovider.GraalServices.getSavedProperty; -import java.lang.annotation.Annotation; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.nio.file.Path; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.IdentityHashMap; import java.util.List; import java.util.Map; +import java.util.ServiceLoader; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.BooleanSupplier; import java.util.function.Consumer; -import java.util.regex.Pattern; -import jdk.vm.ci.code.Architecture; +import jdk.graal.compiler.core.common.spi.ForeignCallSignature; +import jdk.graal.compiler.graph.NodeClass; +import jdk.graal.compiler.hotspot.EncodedSnippets; +import jdk.graal.compiler.hotspot.HotSpotForeignCallLinkage; +import jdk.graal.compiler.hotspot.HotSpotReplacementsImpl; +import jdk.graal.compiler.libgraal.truffle.LibGraalTruffleHostEnvironmentLookup; +import jdk.graal.compiler.options.OptionsParser; +import jdk.graal.compiler.serviceprovider.GraalServices; +import jdk.graal.compiler.truffle.host.TruffleHostEnvironment; +import jdk.graal.compiler.util.ObjectCopier; +import jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory; +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; +import jdk.vm.ci.services.JVMCIServiceLocator; +import jdk.vm.ci.services.Services; import org.graalvm.collections.EconomicMap; import org.graalvm.jniutils.NativeBridgeSupport; import org.graalvm.nativeimage.ImageSingletons; @@ -61,13 +70,9 @@ import jdk.graal.compiler.debug.DebugContext; import jdk.graal.compiler.debug.GraalError; import jdk.graal.compiler.graph.Edges; -import jdk.graal.compiler.hotspot.CompilerConfigurationFactory; -import jdk.graal.compiler.hotspot.libgraal.BuildTime; -import jdk.graal.compiler.nodes.graphbuilderconf.GeneratedInvocationPlugin; import jdk.graal.compiler.options.OptionDescriptor; import jdk.graal.compiler.options.OptionKey; import jdk.graal.compiler.serviceprovider.GlobalAtomicLong; -import jdk.graal.compiler.serviceprovider.LibGraalService; import jdk.graal.nativeimage.LibGraalFeatureComponent; import jdk.graal.nativeimage.LibGraalLoader; import jdk.graal.nativeimage.hosted.GlobalData; @@ -75,10 +80,6 @@ /** * This feature builds the libgraal shared library (e.g., libjvmcicompiler.so on linux). - *

      - * With use of {@code -Djdk.graal.internal.libgraal.javahome=path}, the Graal and JVMCI classes from - * which libgraal is built can be from a "guest" JDK that may be different from the JDK on which - * Native Image is running. */ @Platforms(Platform.HOSTED_ONLY.class) public final class LibGraalFeature implements Feature { @@ -98,70 +99,13 @@ public boolean getAsBoolean() { final MethodHandles.Lookup mhl = MethodHandles.lookup(); - LibGraalLoader libgraalLoader; - - /** - * Loader used for loading classes from the guest GraalVM. - */ - ClassLoader loader; - - /** - * Handle to {@link BuildTime} in the guest. - */ - Class buildTimeClass; + final LibGraalLoader libgraalLoader = (LibGraalLoader) getClass().getClassLoader(); /** * Set of {@link LibGraalFeatureComponent}s created during analysis. */ private final Set libGraalFeatureComponents = ConcurrentHashMap.newKeySet(); - /** - * Loads the class {@code c} in the libgraal class loader. - * - * @throws Error if loading fails - */ - public Class loadClassOrFail(Class c) { - if (c.getClassLoader() == loader) { - return c; - } - if (c.isArray()) { - return loadClassOrFail(c.getComponentType()).arrayType(); - } - return loadClassOrFail(c.getName()); - } - - /** - * Loads the class named {@code name} in the libgraal class loader. The - * {@link #loadClassOrFail(Class)} method should be used instead if the relevant class literal - * is accessible. - * - * @throws Error if loading fails - */ - public Class loadClassOrFail(String name) { - try { - return loader.loadClass(name); - } catch (ClassNotFoundException e) { - throw new AssertionError("%s unable to load class '%s'".formatted(loader.getName(), name)); - } - } - - public Class loadClassOrNull(String name) { - try { - return loader.loadClass(name); - } catch (Throwable e) { - return null; - } - } - - /** - * Performs tasks once this feature is registered. - *

        - *
      • Create the {@code HostedLibGraalClassLoader} instance.
      • - *
      • Get a handle to the {@link BuildTime} class in the guest.
      • - *
      • Initializes the options in the guest.
      • - *
      • Initializes some state needed by {@link LibGraalSubstitutions}.
      • - *
      - */ @Override public void afterRegistration(AfterRegistrationAccess access) { // LibGraalEntryPoints uses a number of classes in org.graalvm.nativeimage.builder @@ -175,25 +119,14 @@ public void afterRegistration(AfterRegistrationAccess access) { ImageSingletons.add(NativeBridgeSupport.class, new LibGraalNativeBridgeSupport()); - libgraalLoader = (LibGraalLoader) getClass().getClassLoader();// createHostedLibGraalClassLoader(access); - loader = libgraalLoader.getClassLoader(); - - buildTimeClass = loadClassOrFail(BuildTime.class); - // Guest JVMCI and Graal need access to some JDK internal packages - String[] basePackages = {"jdk.internal.misc", "jdk.internal.util", "jdk.internal.vm"}; + String[] basePackages = { + "jdk.internal.misc", + "jdk.internal.util", + "jdk.internal.vm"}; LibGraalUtil.accessPackagesToClass(LibGraalUtil.Access.EXPORT, null, false, "java.base", basePackages); } -// @SuppressWarnings("unchecked") -// private static LibGraalLoader createHostedLibGraalClassLoader(AfterRegistrationAccess access) { -// var hostedLibGraalClassLoaderClass = -// access.findClassByName("jdk.graal.compiler.libgraal.loader.HostedLibGraalClassLoader"); -// LibGraalUtil.accessPackagesToClass(LibGraalUtil.Access.EXPORT, hostedLibGraalClassLoaderClass, -// false, "java.base", "jdk.internal.module"); -// return LibGraalUtil.newInstance((Class) hostedLibGraalClassLoaderClass); -// } - static void exportModulesToLibGraal(String... moduleNames) { accessModulesToClass(LibGraalUtil.Access.EXPORT, LibGraalFeature.class, moduleNames); } @@ -213,12 +146,12 @@ static Module getBootModule(String moduleName) { @Override public void duringSetup(DuringSetupAccess access) { ClassLoader runtimeLoader = libgraalLoader.getRuntimeClassLoader(); - access.registerObjectReplacer(obj -> obj == loader ? runtimeLoader : obj); + ClassLoader cl = libgraalLoader.getClassLoader(); + access.registerObjectReplacer(obj -> obj == cl ? runtimeLoader : obj); optionCollector = new OptionCollector(); access.registerObjectReachabilityHandler(optionCollector::accept, OptionKey.class); - access.registerObjectReachabilityHandler(optionCollector::accept, loadClassOrFail(OptionKey.class)); - GetJNIConfig.register(loader); + GetJNIConfig.register(cl); } private OptionCollector optionCollector; @@ -230,33 +163,22 @@ public void duringSetup(DuringSetupAccess access) { * compiler options are instances of {@link OptionKey} loaded by the * {@code HostedLibGraalClassLoader}. */ - private class OptionCollector implements Consumer { - private final Set options = Collections.newSetFromMap(new ConcurrentHashMap<>()); - - /** - * Libgraal VM options. - */ - private final EconomicMap vmOptionDescriptors = EconomicMap.create(); + private class OptionCollector implements Consumer> { + private final Set> options = Collections.newSetFromMap(new ConcurrentHashMap<>()); /** * Libgraal compiler options info. */ - private final Object compilerOptionsInfo; + private final OptionsParser.LibGraalOptionsInfo compilerOptionsInfo; private boolean sealed; OptionCollector() { - try { - MethodType mt = methodType(Object.class); - MethodHandle mh = mhl.findStatic(buildTimeClass, "initLibgraalOptions", mt); - compilerOptionsInfo = mh.invoke(); - } catch (Throwable e) { - throw GraalError.shouldNotReachHere(e); - } + compilerOptionsInfo = OptionsParser.setLibgraalOptions(OptionsParser.LibGraalOptionsInfo.create()); } @Override - public void accept(Object option) { + public void accept(OptionKey option) { if (sealed) { GraalError.guarantee(options.contains(option), "All options must have been discovered during static analysis: %s", option); } else { @@ -264,56 +186,27 @@ public void accept(Object option) { } } - @SuppressWarnings("unchecked") void afterAnalysis(AfterAnalysisAccess access) { sealed = true; - List compilerOptions = new ArrayList<>(options.size()); - for (Object option : options) { - if (option instanceof OptionKey optionKey) { - OptionDescriptor descriptor = optionKey.getDescriptor(); - if (descriptor.isServiceLoaded()) { - GraalError.guarantee(access.isReachable(option.getClass()), "%s", option.getClass()); - GraalError.guarantee(access.isReachable(descriptor.getClass()), "%s", descriptor.getClass()); - vmOptionDescriptors.put(optionKey.getName(), descriptor); - } - } else { - ClassLoader optionCL = option.getClass().getClassLoader(); - GraalError.guarantee(optionCL == loader, "unexpected option loader: %s", optionCL); - compilerOptions.add(option); - } - } - try { - MethodType mt = methodType(Iterable.class, List.class, Object.class, Map.class); - MethodHandle mh = mhl.findStatic(buildTimeClass, "finalizeLibgraalOptions", mt); - LibGraalLoader manifest = (LibGraalLoader) loader; - Map modules = manifest.getModuleMap(); - Iterable values = (Iterable) mh.invoke(compilerOptions, compilerOptionsInfo, modules); - for (Object descriptor : values) { + Map modules = libgraalLoader.getModuleMap(); + for (OptionKey option : options) { + OptionDescriptor descriptor = option.getDescriptor(); + if (descriptor.isServiceLoaded()) { + GraalError.guarantee(access.isReachable(option.getClass()), "%s", option.getClass()); GraalError.guarantee(access.isReachable(descriptor.getClass()), "%s", descriptor.getClass()); + + String name = option.getName(); + compilerOptionsInfo.descriptors().put(name, descriptor); + + String module = modules.get(descriptor.getDeclaringClass().getName()); + if (module.contains("enterprise")) { + compilerOptionsInfo.enterpriseOptions().add(name); + } } - } catch (Throwable e) { - throw GraalError.shouldNotReachHere(e); } } } - @SuppressWarnings("unchecked") - public List> findLibGraalServices() { - LibGraalLoader manifest = (LibGraalLoader) loader; - Set libgraalServicesModules = manifest.getServicesModules(); - Map modules = manifest.getModuleMap(); - - Class service = (Class) loadClassOrFail(LibGraalService.class); - List> libgraalServices = new ArrayList<>(); - modules.entrySet().stream()// - .filter(e -> libgraalServicesModules.contains(e.getValue())) - .map(Map.Entry::getKey)// - .map(this::loadClassOrNull)// - .filter(c -> c != null && c.getAnnotation(service) != null)// - .forEach(libgraalServices::add); - return libgraalServices; - } - private BeforeCompilationAccess beforeCompilationAccess; /** @@ -334,8 +227,8 @@ class FieldOffsetsTransformer implements FieldValueTransformer { final Method recomputeOffsetsAndIterationMaskMethod; FieldOffsetsTransformer() { - edgesClass = loadClassOrFail(Edges.class.getName()); - fieldsClass = loadClassOrFail(Fields.class.getName()); + edgesClass = Edges.class; + fieldsClass = Fields.class; fieldsOffsetsField = LibGraalUtil.lookupField(fieldsClass, "offsets"); edgesIterationMaskField = LibGraalUtil.lookupField(edgesClass, "iterationMask"); recomputeOffsetsAndIterationMaskMethod = LibGraalUtil.lookupMethod(fieldsClass, "recomputeOffsetsAndIterationMask", BeforeCompilationAccess.class); @@ -384,11 +277,10 @@ class GlobalAtomicLongTransformer implements FieldValueTransformer { private MethodHandle globalAtomicLongGetInitialValue; void register(BeforeAnalysisAccess access) { - Class globalAtomicLongClass = loadClassOrFail(GlobalAtomicLong.class.getName()); - Field addressSupplierField = LibGraalUtil.lookupField(globalAtomicLongClass, "addressSupplier"); + Field addressSupplierField = LibGraalUtil.lookupField(GlobalAtomicLong.class, "addressSupplier"); access.registerFieldValueTransformer(addressSupplierField, this); try { - globalAtomicLongGetInitialValue = mhl.findVirtual(globalAtomicLongClass, "getInitialValue", methodType(long.class)); + globalAtomicLongGetInitialValue = mhl.findVirtual(GlobalAtomicLong.class, "getInitialValue", methodType(long.class)); } catch (Throwable e) { GraalError.shouldNotReachHere(e); } @@ -406,6 +298,7 @@ public Object transform(Object receiver, Object originalValue) { } } + @SuppressWarnings("unchecked") @Override public void beforeAnalysis(BeforeAnalysisAccess access) { @@ -413,11 +306,11 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { new GlobalAtomicLongTransformer().register(access); /* Contains static fields that depend on HotSpotJVMCIRuntime */ - RuntimeClassInitialization.initializeAtRunTime(loadClassOrFail(HotSpotModifiers.class)); - RuntimeClassInitialization.initializeAtRunTime(loadClassOrFail("jdk.vm.ci.hotspot.HotSpotCompiledCodeStream")); - RuntimeClassInitialization.initializeAtRunTime(loadClassOrFail("jdk.vm.ci.hotspot.HotSpotCompiledCodeStream$Tag")); + RuntimeClassInitialization.initializeAtRunTime(HotSpotModifiers.class); + RuntimeClassInitialization.initializeAtRunTime(LibGraalUtil.lookupClass("jdk.vm.ci.hotspot.HotSpotCompiledCodeStream")); + RuntimeClassInitialization.initializeAtRunTime(LibGraalUtil.lookupClass("jdk.vm.ci.hotspot.HotSpotCompiledCodeStream$Tag")); /* ThreadLocal in static field jdk.graal.compiler.debug.DebugContext.activated */ - RuntimeClassInitialization.initializeAtRunTime(loadClassOrFail(DebugContext.class)); + RuntimeClassInitialization.initializeAtRunTime(DebugContext.class); /* Needed for runtime calls to BoxingSnippets.Templates.getCacheClass(JavaKind) */ RuntimeReflection.registerAllDeclaredClasses(Character.class); @@ -431,62 +324,84 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { RuntimeReflection.registerAllDeclaredClasses(Long.class); RuntimeReflection.register(LibGraalUtil.lookupField(LibGraalUtil.lookupClass("java.lang.Long$LongCache"), "cache")); - /* Configure static state of Graal. */ - try { - Consumer> registerAsInHeap = access::registerAsInHeap; - - Consumer>> hostedGraalSetFoldNodePluginClasses = GeneratedInvocationPlugin::setFoldNodePluginClasses; - - List> guestServiceClasses = findLibGraalServices(); - - // Transfer libgraal qualifier (e.g. "PGO optimized") from host to guest. - String nativeImageLocationQualifier = CompilerConfigurationFactory.getNativeImageLocationQualifier(); - - MethodHandle configureGraalForLibGraal = mhl.findStatic(buildTimeClass, - "configureGraalForLibGraal", - methodType(void.class, - String.class, // arch - Collection.class, // libGraalFeatureComponents - List.class, // guestServiceClasses - Consumer.class, // registerAsInHeap - Consumer.class, // hostedGraalSetFoldNodePluginClasses - String.class, // nativeImageLocationQualifier - byte[].class // encodedGuestObjects - )); - Path libGraalJavaHome = LibGraalUtil.readField(loader.getClass(), "libGraalJavaHome", loader); - GetCompilerConfig.Result configResult = GetCompilerConfig.from(libGraalJavaHome); - for (var e : configResult.opens().entrySet()) { - for (String source : e.getValue()) { - LibGraalUtil.accessPackagesToClass(LibGraalUtil.Access.OPEN, buildTimeClass, false, e.getKey(), source); - } + doLegacyJVMCIInitialization(); + + Path libGraalJavaHome = libgraalLoader.getJavaHome(); + GetCompilerConfig.Result configResult = GetCompilerConfig.from(libGraalJavaHome); + for (var e : configResult.opens().entrySet()) { + for (String source : e.getValue()) { + LibGraalUtil.accessPackagesToClass(LibGraalUtil.Access.OPEN, getClass(), false, e.getKey(), source); } + } + + Fields.setLibGraalFeatureComponents(libGraalFeatureComponents); - configureGraalForLibGraal.invoke(getJVMCIArch(), - libGraalFeatureComponents, - guestServiceClasses, - registerAsInHeap, - hostedGraalSetFoldNodePluginClasses, - nativeImageLocationQualifier, - configResult.encodedConfig()); + EconomicMap libgraalObjects = (EconomicMap) ObjectCopier.decode(configResult.encodedConfig(), libgraalLoader.getClassLoader()); + EncodedSnippets encodedSnippets = (EncodedSnippets) libgraalObjects.get("encodedSnippets"); - initializeTruffle(); + // Mark all the Node classes as allocated so they are available during graph decoding. + for (NodeClass nodeClass : encodedSnippets.getSnippetNodeClasses()) { + access.registerAsInHeap(nodeClass.getClazz()); + } + HotSpotReplacementsImpl.setEncodedSnippets(encodedSnippets); + + List foreignCallSignatures = (List) libgraalObjects.get("foreignCallSignatures"); + HotSpotForeignCallLinkage.Stubs.initStubs(foreignCallSignatures); + + TruffleHostEnvironment.overrideLookup(new LibGraalTruffleHostEnvironmentLookup()); + } + + /** + * Initialization of JVMCI code that needs to be done for JDK versions that do not include + * JDK-8346781. + */ + private void doLegacyJVMCIInitialization() { + if (has8346781()) { + return; + } + try { + String rawArch = GraalServices.getSavedProperty("os.arch"); + String arch = switch (rawArch) { + case "x86_64" -> "AMD64"; + case "amd64" -> "AMD64"; + case "aarch64" -> "aarch64"; + case "riscv64" -> "riscv64"; + default -> throw new GraalError("Unknown or unsupported arch: %s", rawArch); + }; + + ClassLoader cl = libgraalLoader.getClassLoader(); + Field cachedHotSpotJVMCIBackendFactoriesField = ObjectCopier.getField(HotSpotJVMCIRuntime.class, "cachedHotSpotJVMCIBackendFactories"); + GraalError.guarantee(cachedHotSpotJVMCIBackendFactoriesField.get(null) == null, "Expect cachedHotSpotJVMCIBackendFactories to be null"); + ServiceLoader load = ServiceLoader.load(HotSpotJVMCIBackendFactory.class, cl); + List backendFactories = load.stream()// + .map(ServiceLoader.Provider::get)// + .filter(s -> s.getArchitecture().equals(arch))// + .toList(); + cachedHotSpotJVMCIBackendFactoriesField.set(null, backendFactories); + GraalError.guarantee(backendFactories.size() == 1, "%s", backendFactories); + + var jvmciServiceLocatorCachedLocatorsField = ObjectCopier.getField(JVMCIServiceLocator.class, "cachedLocators"); + GraalError.guarantee(jvmciServiceLocatorCachedLocatorsField.get(null) == null, "Expect cachedLocators to be null"); + Iterable serviceLocators = ServiceLoader.load(JVMCIServiceLocator.class, cl); + List cachedLocators = new ArrayList<>(); + serviceLocators.forEach(cachedLocators::add); + jvmciServiceLocatorCachedLocatorsField.set(null, cachedLocators); } catch (Throwable e) { - throw GraalError.shouldNotReachHere(e); + throw new GraalError(e); } } /** - * Gets a name for the current architecture that is compatible with - * {@link Architecture#getName()}. + * Determines if the JDK runtime includes JDK-8346781. Without it, initialization of some JVMCI + * static cache fields must be done explicitly by {@link LibGraalFeature}. */ - private static String getJVMCIArch() { - String rawArch = getSavedProperty("os.arch"); - return switch (rawArch) { - case "x86_64" -> "AMD64"; - case "aarch64" -> "aarch64"; - case "riscv64" -> "riscv64"; - default -> throw new GraalError("Unknown or unsupported arch: %s", rawArch); - }; + private static boolean has8346781() { + try { + Services.class.getField("IS_BUILDING_NATIVE_IMAGE"); + return false; + } catch (NoSuchFieldException e) { + return true; + } } @Override @@ -496,22 +411,11 @@ public void duringAnalysis(DuringAnalysisAccess access) { } } - @SuppressWarnings("unchecked") - private void initializeTruffle() throws Throwable { - Class truffleBuildTimeClass = loadClassOrFail("jdk.graal.compiler.hotspot.libgraal.truffle.BuildTime"); - MethodHandle truffleConfigureGraalForLibGraal = mhl.findStatic(truffleBuildTimeClass, "configureGraalForLibGraal", methodType(void.class)); - truffleConfigureGraalForLibGraal.invoke(); - } - @Override public void afterAnalysis(AfterAnalysisAccess access) { optionCollector.afterAnalysis(access); } - private static Pattern classesPattern(String packageName, String... regexes) { - return Pattern.compile("%s(%s)".formatted(Pattern.quote(packageName + '.'), String.join("|", regexes))); - } - @Override public void beforeCompilation(BeforeCompilationAccess access) { beforeCompilationAccess = access; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java index 21edebb92e94..f9592f6090e3 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java @@ -24,30 +24,14 @@ */ package jdk.graal.compiler.libgraal; -import java.io.PrintStream; -import java.util.Map; -import java.util.function.Supplier; - -import jdk.graal.compiler.hotspot.libgraal.RunTime; -import jdk.graal.compiler.word.Word; -import jdk.graal.nativeimage.LibGraalRuntime; -import org.graalvm.jniutils.JNI; -import org.graalvm.jniutils.JNIExceptionWrapper; -import org.graalvm.jniutils.JNIMethodScope; -import org.graalvm.jniutils.JNIUtil; -import org.graalvm.nativeimage.ImageSingletons; -import org.graalvm.nativeimage.Platform.HOSTED_ONLY; -import org.graalvm.nativeimage.Platforms; -import org.graalvm.nativeimage.StackValue; - import com.oracle.svm.core.annotate.Alias; import com.oracle.svm.core.annotate.RecomputeFieldValue; -import com.oracle.svm.core.annotate.Substitute; import com.oracle.svm.core.annotate.TargetClass; +import com.oracle.svm.core.annotate.TargetElement; -class LibGraalJVMCISubstitutions { +class LibGraalSubstitutions { - @TargetClass(className = "jdk.vm.ci.services.Services", classLoader = LibGraalClassLoaderSupplier.class, onlyWith = LibGraalFeature.IsEnabled.class) + @TargetClass(className = "jdk.vm.ci.services.Services", onlyWith = LibGraalFeature.IsEnabled.class) static final class Target_jdk_vm_ci_services_Services { /** * Ensures field returns false if seen by the analysis. @@ -55,6 +39,7 @@ static final class Target_jdk_vm_ci_services_Services { // Checkstyle: stop @Alias // @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FromAlias, isFinal = true)// + @TargetElement(onlyWith = JDK21.class)// public static boolean IS_BUILDING_NATIVE_IMAGE = false; // Checkstyle: resume @@ -68,183 +53,5 @@ static final class Target_jdk_vm_ci_services_Services { @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FromAlias, isFinal = true)// public static boolean IS_IN_NATIVE_IMAGE = true; // Checkstyle: resume - - /* - * Reset Services.savedProperties to null so that we cannot get the hosted savedProperties - * into the libgraal image-heap. This also guarantees that at libgraal-runtime the - * savedProperties are initialized with the system properties state of the JVM that uses - * libgraal. - */ - @Alias // - @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset) // - private static Map savedProperties; - } - - @TargetClass(className = "jdk.vm.ci.hotspot.Cleaner", classLoader = LibGraalClassLoaderSupplier.class, onlyWith = LibGraalFeature.IsEnabled.class) - static final class Target_jdk_vm_ci_hotspot_Cleaner { - - /* - * Make package-private clean() accessible so that it can be called from - * LibGraalEntryPoints.doReferenceHandling(). - */ - @Alias - static native void clean(); - } - - @TargetClass(className = "jdk.vm.ci.hotspot.CompilerToVM", classLoader = LibGraalClassLoaderSupplier.class, onlyWith = {LibGraalFeature.IsEnabled.class, JDKLatest.class}) - static final class Target_jdk_vm_ci_hotspot_CompilerToVM { - /* - * For libgraal the implementation of CompilerToVM.lookupType needs to take into account - * that the passed-in classloader can also be an instance of LibGraalClassLoader. Checking - * if that classLoader is the same as the one of the HotSpotResolvedJavaType class itself - * (which is the LibGraalClassLoader) takes care of that. - */ - @Substitute - Target_jdk_vm_ci_hotspot_HotSpotResolvedJavaType lookupType(ClassLoader classLoader, String name) throws NoClassDefFoundError { - int accessingClassLoader; - if (classLoader == null) { - accessingClassLoader = 0; - } else if (classLoader == ClassLoader.getPlatformClassLoader()) { - accessingClassLoader = 1; - } else if (classLoader == ClassLoader.getSystemClassLoader()) { - accessingClassLoader = 2; - } else if (classLoader == getClass().getClassLoader()) { - throw new IllegalArgumentException("is this case really needed? Unsupported class loader for lookup: " + name + " " + classLoader); - } else { - throw new IllegalArgumentException("Unsupported class loader for lookup: " + classLoader); - } - return lookupType(name, null, 0L, accessingClassLoader, true); - } - - @Alias - native Target_jdk_vm_ci_hotspot_HotSpotResolvedJavaType lookupType(String name, Target_jdk_vm_ci_hotspot_HotSpotResolvedObjectTypeImpl accessingClass, - long accessingKlassPointer, int accessingClassLoader, boolean resolve) throws NoClassDefFoundError; - } - - @TargetClass(className = "jdk.vm.ci.hotspot.HotSpotResolvedJavaType", classLoader = LibGraalClassLoaderSupplier.class, onlyWith = LibGraalFeature.IsEnabled.class) - static final class Target_jdk_vm_ci_hotspot_HotSpotResolvedJavaType { - } - - @TargetClass(className = "jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl", classLoader = LibGraalClassLoaderSupplier.class, onlyWith = LibGraalFeature.IsEnabled.class) - static final class Target_jdk_vm_ci_hotspot_HotSpotResolvedObjectTypeImpl { - } -} - -public class LibGraalSubstitutions { - /** - * Used to avoid complaints by javac about casts that appear to violate the Java type system - * rules but are safe in the context of SVM substitutions. - */ - @SuppressWarnings({"unused", "unchecked"}) - public static T cast(Object obj, Class toType) { - return (T) obj; - } - - @TargetClass(className = "jdk.graal.compiler.serviceprovider.VMSupport", classLoader = LibGraalClassLoaderSupplier.class, onlyWith = LibGraalFeature.IsEnabled.class) - static final class Target_jdk_graal_compiler_serviceprovider_VMSupport { - - /** - * Performs the following actions around a libgraal compilation: - *
        - *
      • before: opens a JNIMethodScope to allow Graal compilations of Truffle host methods to - * call methods on the TruffleCompilerRuntime.
      • - *
      • after: closes the above JNIMethodScope
      • - *
      • after: triggers GC weak reference processing as SVM does not use a separate thread - * for this in libgraal
      • - *
      - */ - static class LibGraalCompilationRequestScope implements AutoCloseable { - final JNIMethodScope scope; - - LibGraalCompilationRequestScope() { - JNI.JNIEnv env = Word.unsigned(RunTime.getJNIEnv()); - /* - * This scope is required to allow Graal compilations of host methods to call - * methods in the TruffleCompilerRuntime. This is, for example, required to find out - * about Truffle-specific method annotations. - */ - scope = LibGraalJNIMethodScope.open("", env, false); - } - - @Override - public void close() { - try { - if (scope != null) { - scope.close(); - } - } finally { - /* - * libgraal doesn't use a dedicated reference handler thread, so we trigger the - * reference handling manually when a compilation finishes. - */ - LibGraalEntryPoints.doReferenceHandling(); - } - } - } - - @Substitute - public static AutoCloseable getCompilationRequestScope() { - return new LibGraalCompilationRequestScope(); - } - - @Substitute - public static void invokeShutdownCallback(String cbClassName, String cbMethodName) { - JNI.JNIEnv env = Word.unsigned(RunTime.getJNIEnv()); - JNI.JClass cbClass = JNIUtil.findClass(env, JNIUtil.getSystemClassLoader(env), - JNIUtil.getBinaryName(cbClassName), true); - JNI.JMethodID cbMethod = JNIUtil.findMethod(env, cbClass, true, cbMethodName, "()V"); - env.getFunctions().getCallStaticVoidMethodA().call(env, cbClass, cbMethod, StackValue.get(0)); - JNIExceptionWrapper.wrapAndThrowPendingJNIException(env); - } - } - - @TargetClass(className = "jdk.graal.compiler.hotspot.HotSpotGraalOptionValues", classLoader = LibGraalClassLoaderSupplier.class, onlyWith = LibGraalFeature.IsEnabled.class) - static final class Target_jdk_graal_compiler_hotspot_HotSpotGraalOptionValues { - - @Substitute - private static void notifyLibgraalOptions(Map vmOptionSettings) { - LibGraalEntryPoints.initializeOptions(vmOptionSettings); - } - - @Substitute - private static void printLibgraalProperties(PrintStream out, String prefix) { - LibGraalEntryPoints.printOptions(out, prefix); - } - } - - @TargetClass(className = "jdk.graal.compiler.core.GraalServiceThread", classLoader = LibGraalClassLoaderSupplier.class, onlyWith = LibGraalFeature.IsEnabled.class) - static final class Target_jdk_graal_compiler_core_GraalServiceThread { - @Substitute() - void beforeRun() { - Thread thread = cast(this, Thread.class); - if (!RunTime.attachCurrentThread(thread.isDaemon(), null)) { - throw new InternalError("Couldn't attach to HotSpot runtime"); - } - } - - @Substitute - @SuppressWarnings("static-method") - void afterRun() { - RunTime.detachCurrentThread(false); - } - } -} - -/* - * This supplier is used by all LibGraalSubstitutions and ensures that the substitution target - * classes are classes from the LibGraalClassLoader (instead of hosted Graal & JVMCI classes). - */ -@Platforms(HOSTED_ONLY.class) -class LibGraalClassLoaderSupplier implements Supplier { - @Override - public ClassLoader get() { - if (!ImageSingletons.contains(LibGraalFeature.class)) { - return null; - } - ClassLoader loader = ImageSingletons.lookup(LibGraalFeature.class).loader; - if (loader == null) { - LibGraalRuntime.fatalError("loader is null"); - } - return loader; } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalUtil.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalUtil.java index 0c39baa72bc2..2dc6eef8cb35 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalUtil.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalUtil.java @@ -27,6 +27,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.util.Locale; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -251,7 +252,7 @@ public static void accessPackagesToClass(Access access, Class accessingClass, return; } String accessor = accessingClass != null ? "class " + accessingClass.getTypeName() : "ALL-UNNAMED"; - String message = access.name().toLowerCase() + " of packages from module " + moduleName + " to " + + String message = access.name().toLowerCase(Locale.ROOT) + " of packages from module " + moduleName + " to " + accessor + " failed. No module named " + moduleName + " in boot layer."; throw new GraalError(message); } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/NativeImageHostEntryPoints.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/NativeImageHostEntryPoints.java deleted file mode 100644 index 1637c64c2830..000000000000 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/NativeImageHostEntryPoints.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2024, 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 jdk.graal.compiler.libgraal; - -import com.oracle.truffle.compiler.TruffleCompilerOptionDescriptor; -import jdk.graal.compiler.word.Word; -import org.graalvm.jniutils.HSObject; -import org.graalvm.jniutils.JNI.JObject; -import org.graalvm.jniutils.JNIMethodScope; -import org.graalvm.jniutils.JNIUtil; - -/** - * Entry points for native-image specific methods called by guest Graal using method handles. - */ -public final class NativeImageHostEntryPoints { - - private NativeImageHostEntryPoints() { - } - - public static void initializeHost(long runtimeClass) { - // TruffleFromLibGraalStartPoints.initializeJNI(Word.pointer(runtimeClass)); - } - - public static Object createLocalHandleForLocalReference(long jniLocalRef) { - JNIMethodScope scope = JNIMethodScope.scopeOrNull(); - if (scope == null) { - return null; - } - return new HSObject(scope, Word.pointer(jniLocalRef)); - } - - public static Object createLocalHandleForWeakGlobalReference(long jniWeakGlobalRef) { - JNIMethodScope scope = JNIMethodScope.scope(); - JObject localRef = JNIUtil.NewLocalRef(scope.getEnv(), Word.pointer(jniWeakGlobalRef)); - return localRef.isNull() ? null : new HSObject(scope, localRef); - } - - public static Object createGlobalHandle(Object hsHandle, boolean allowGlobalDuplicates) { - if (hsHandle == null) { - return null; - } - return new HSObject(JNIMethodScope.env(), ((HSObject) hsHandle).getHandle(), allowGlobalDuplicates, false); - } - - public static boolean isSameObject(Object o1, Object o2) { - return JNIUtil.IsSameObject(JNIMethodScope.env(), ((HSObject) o1).getHandle(), ((HSObject) o2).getHandle()); - } - - public static long getObjectClass(Object o) { - return JNIUtil.GetObjectClass(JNIMethodScope.env(), ((HSObject) o).getHandle()).rawValue(); - } - - public static Object createTruffleCompilerOptionDescriptor(String name, int type, boolean deprecated, String help, String deprecationMessage) { - return new TruffleCompilerOptionDescriptor(name, TruffleCompilerOptionDescriptor.Type.values()[type], deprecated, help, deprecationMessage); - } -} diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/FromLibGraalCalls.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/FromLibGraalCalls.java similarity index 99% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/FromLibGraalCalls.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/FromLibGraalCalls.java index 6a4f5e19ed3f..173e464edf0d 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/FromLibGraalCalls.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/FromLibGraalCalls.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.hotspot.libgraal.truffle; +package jdk.graal.compiler.libgraal.truffle; import com.oracle.truffle.compiler.hotspot.libgraal.FromLibGraalId; import org.graalvm.jniutils.JNI.JClass; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSConsumer.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSConsumer.java similarity index 98% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSConsumer.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSConsumer.java index ac82fd8a3a66..ddf6cc810c39 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSConsumer.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSConsumer.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.hotspot.libgraal.truffle; +package jdk.graal.compiler.libgraal.truffle; import com.oracle.truffle.compiler.OptimizedAssumptionDependency; import com.oracle.truffle.compiler.TruffleCompilable; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSIndirectHandle.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSIndirectHandle.java similarity index 97% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSIndirectHandle.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSIndirectHandle.java index afad30d1e04e..e2445ef12830 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSIndirectHandle.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSIndirectHandle.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.hotspot.libgraal.truffle; +package jdk.graal.compiler.libgraal.truffle; import java.util.Objects; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilable.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilable.java similarity index 99% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilable.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilable.java index d932c110df07..d5c55af9cf55 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilable.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilable.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.hotspot.libgraal.truffle; +package jdk.graal.compiler.libgraal.truffle; import com.oracle.truffle.compiler.TruffleCompilable; import jdk.graal.compiler.debug.GraalError; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilationTask.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilationTask.java similarity index 98% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilationTask.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilationTask.java index e1d0cce4e3c9..6589973242f0 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilationTask.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilationTask.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.hotspot.libgraal.truffle; +package jdk.graal.compiler.libgraal.truffle; import com.oracle.truffle.compiler.TruffleCompilable; import com.oracle.truffle.compiler.TruffleCompilationTask; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilerListener.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilerListener.java similarity index 98% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilerListener.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilerListener.java index 79f653b059fc..a7a41c74bfc9 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilerListener.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilerListener.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.hotspot.libgraal.truffle; +package jdk.graal.compiler.libgraal.truffle; import com.oracle.truffle.compiler.TruffleCompilable; import com.oracle.truffle.compiler.TruffleCompilationTask; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilerRuntime.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilerRuntime.java similarity index 96% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilerRuntime.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilerRuntime.java index 2de5f52261a8..81774682895a 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilerRuntime.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilerRuntime.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.hotspot.libgraal.truffle; +package jdk.graal.compiler.libgraal.truffle; import com.oracle.truffle.compiler.ConstantFieldInfo; import com.oracle.truffle.compiler.HostMethodInfo; @@ -33,8 +33,8 @@ import jdk.graal.compiler.debug.GraalError; import jdk.graal.compiler.libgraal.LibGraalUtil; -import jdk.graal.compiler.libgraal.NativeImageHostEntryPoints; import jdk.graal.compiler.truffle.hotspot.HotSpotTruffleCompilationSupport; +import jdk.graal.compiler.word.Word; import jdk.vm.ci.code.InstalledCode; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; import jdk.vm.ci.hotspot.HotSpotObjectConstant; @@ -48,7 +48,6 @@ import jdk.vm.ci.meta.UnresolvedJavaType; import org.graalvm.jniutils.HSObject; import org.graalvm.jniutils.JNIMethodScope; -import org.graalvm.word.WordFactory; import java.util.Arrays; import java.util.function.Consumer; @@ -69,7 +68,7 @@ public HSTruffleCompilerRuntime(Object hsHandle, long runtimeClass) { if (this.classLoaderDelegate == null) { throw GraalError.shouldNotReachHere("The object class needs to be available for a Truffle runtime object."); } - NativeImageHostEntryPoints.initializeHost(runtimeClass); + TruffleFromLibGraalStartPoints.initializeJNI(Word.pointer(runtimeClass)); } @Override @@ -99,7 +98,7 @@ public TruffleCompilable asCompilableTruffleAST(JavaConstant constant) { if (scope == null) { return null; } - return new HSTruffleCompilable(new HSObject(scope, WordFactory.pointer(jniLocalRef))); + return new HSTruffleCompilable(new HSObject(scope, Word.pointer(jniLocalRef))); } @Override diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleSourceLanguagePosition.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleSourceLanguagePosition.java similarity index 97% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleSourceLanguagePosition.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleSourceLanguagePosition.java index 088eb216a6ca..683378ecff1f 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleSourceLanguagePosition.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleSourceLanguagePosition.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.hotspot.libgraal.truffle; +package jdk.graal.compiler.libgraal.truffle; import com.oracle.truffle.compiler.TruffleSourceLanguagePosition; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalObjectHandleScope.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalObjectHandleScope.java similarity index 97% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalObjectHandleScope.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalObjectHandleScope.java index bc70d1810bd3..bf7754171aa4 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalObjectHandleScope.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalObjectHandleScope.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.hotspot.libgraal.truffle; +package jdk.graal.compiler.libgraal.truffle; import java.io.Closeable; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalObjectHandles.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalObjectHandles.java similarity index 97% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalObjectHandles.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalObjectHandles.java index 44183a37107e..f3dcccabf4f1 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalObjectHandles.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalObjectHandles.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.hotspot.libgraal.truffle; +package jdk.graal.compiler.libgraal.truffle; import jdk.graal.compiler.word.Word; import org.graalvm.nativeimage.ObjectHandles; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleEntryPoints.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleEntryPoints.java similarity index 92% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleEntryPoints.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleEntryPoints.java index 18573fc00dee..454e83c61cfb 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleEntryPoints.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleEntryPoints.java @@ -22,11 +22,12 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.hotspot.libgraal.truffle; +package jdk.graal.compiler.libgraal.truffle; import java.util.Objects; import java.util.function.Supplier; +import jdk.graal.compiler.word.Word; import org.graalvm.jniutils.HSObject; import org.graalvm.jniutils.JNI.JByteArray; import org.graalvm.jniutils.JNI.JClass; @@ -43,7 +44,6 @@ import org.graalvm.nativeimage.c.function.CEntryPoint.IsolateThreadContext; import org.graalvm.nativeimage.c.type.CLongPointer; import org.graalvm.word.PointerBase; -import org.graalvm.word.WordFactory; import com.oracle.truffle.compiler.TruffleCompilable; import com.oracle.truffle.compiler.TruffleCompilerListener; @@ -56,7 +56,6 @@ import jdk.graal.compiler.libgraal.LibGraalFeature; import jdk.graal.compiler.libgraal.LibGraalJNIMethodScope; import jdk.graal.compiler.libgraal.LibGraalUtil; -import jdk.graal.compiler.libgraal.NativeImageHostEntryPoints; import jdk.graal.compiler.truffle.TruffleCompilerOptions; import jdk.graal.compiler.truffle.hotspot.HotSpotTruffleCompilationSupport; import jdk.graal.compiler.truffle.hotspot.HotSpotTruffleCompilerImpl; @@ -85,8 +84,8 @@ private static JNIMethodScope openScope(Enum id, JNIEnv env) { } long currentJavaThread = HotSpotJVMCIRuntime.runtime().getCurrentJavaThread(); - CLongPointer currentThreadLastJavaPCOffset = (CLongPointer) WordFactory.unsigned(currentJavaThread).add(offset); - PointerBase javaFrameAnchor = WordFactory.pointer(currentThreadLastJavaPCOffset.read()); + CLongPointer currentThreadLastJavaPCOffset = (CLongPointer) Word.unsigned(currentJavaThread).add(offset); + PointerBase javaFrameAnchor = Word.pointer(currentThreadLastJavaPCOffset.read()); return LibGraalJNIMethodScope.open(scopeName, env, javaFrameAnchor.isNonNull()); } @@ -179,7 +178,7 @@ public static JString getCompilerConfigurationFactoryName(JNIEnv env, JClass hsC return scope.getObjectResult(); } catch (Throwable t) { JNIExceptionWrapper.throwInHotSpot(env, t); - return WordFactory.nullPointer(); + return Word.nullPointer(); } } @@ -277,13 +276,13 @@ public static JString getSuppliedString(JNIEnv env, JClass hsClazz, @IsolateThre String stackTrace = stringSupplier.get(); scope.setObjectResult(JNIUtil.createHSString(env, stackTrace)); } else { - scope.setObjectResult(WordFactory.nullPointer()); + scope.setObjectResult(Word.nullPointer()); } } return scope.getObjectResult(); } catch (Throwable t) { JNIExceptionWrapper.throwInHotSpot(env, t); - return WordFactory.nullPointer(); + return Word.nullPointer(); } } @@ -310,7 +309,7 @@ public static JObjectArray getNodeTypes(JNIEnv env, JClass hsClazz, @IsolateThre Object graphInfo = LibGraalObjectHandles.resolve(handle, Object.class); String[] nodeTypes = ((TruffleCompilerListener.GraphInfo) graphInfo).getNodeTypes(simpleNames); JClass componentType = getStringClass(env); - JObjectArray res = JNIUtil.NewObjectArray(env, nodeTypes.length, componentType, WordFactory.nullPointer()); + JObjectArray res = JNIUtil.NewObjectArray(env, nodeTypes.length, componentType, Word.nullPointer()); for (int i = 0; i < nodeTypes.length; i++) { JNIUtil.SetObjectArrayElement(env, res, i, JNIUtil.createHSString(env, nodeTypes[i])); } @@ -319,7 +318,7 @@ public static JObjectArray getNodeTypes(JNIEnv env, JClass hsClazz, @IsolateThre return scope.getObjectResult(); } catch (Throwable t) { JNIExceptionWrapper.throwInHotSpot(env, t); - return WordFactory.nullPointer(); + return Word.nullPointer(); } } @@ -389,7 +388,7 @@ public static JObjectArray getInfopoints(JNIEnv env, JClass hsClazz, @IsolateThr Object compilationResultInfo = LibGraalObjectHandles.resolve(handle, Object.class); String[] infoPoints = ((TruffleCompilerListener.CompilationResultInfo) compilationResultInfo).getInfopoints(); JClass componentType = getStringClass(env); - JObjectArray res = JNIUtil.NewObjectArray(env, infoPoints.length, componentType, WordFactory.nullPointer()); + JObjectArray res = JNIUtil.NewObjectArray(env, infoPoints.length, componentType, Word.nullPointer()); for (int i = 0; i < infoPoints.length; i++) { JNIUtil.SetObjectArrayElement(env, res, i, JNIUtil.createHSString(env, infoPoints[i])); } @@ -398,7 +397,7 @@ public static JObjectArray getInfopoints(JNIEnv env, JClass hsClazz, @IsolateThr return scope.getObjectResult(); } catch (Throwable t) { JNIExceptionWrapper.throwInHotSpot(env, t); - return WordFactory.nullPointer(); + return Word.nullPointer(); } } @@ -435,23 +434,15 @@ public static JByteArray listCompilerOptions(JNIEnv env, JClass hsClazz, @Isolat try { JNIMethodScope scope = openScope(Id.ListCompilerOptions, env); try (JNIMethodScope s = scope) { - TruffleCompilerOptionDescriptor[] options1 = TruffleCompilerOptions.listOptions(); - Object[] result = new Object[options1.length]; - for (int i1 = 0; i1 < options1.length; i1++) { - TruffleCompilerOptionDescriptor option = options1[i1]; - result[i1] = NativeImageHostEntryPoints.createTruffleCompilerOptionDescriptor(option.name(), option.type().ordinal(), option.deprecated(), option.help(), - option.deprecationMessage()); - } - Object[] options = result; + TruffleCompilerOptionDescriptor[] options = TruffleCompilerOptions.listOptions(); BinaryOutput.ByteArrayBinaryOutput out = BinaryOutput.create(); out.writeInt(options.length); - for (int i = 0; i < options.length; i++) { - TruffleCompilerOptionDescriptor descriptor = (TruffleCompilerOptionDescriptor) options[i]; - out.writeUTF(descriptor.name()); - out.writeInt(descriptor.type().ordinal()); - out.writeBoolean(descriptor.deprecated()); - out.writeUTF(descriptor.help()); - out.writeUTF(descriptor.deprecationMessage()); + for (TruffleCompilerOptionDescriptor option : options) { + out.writeUTF(option.name()); + out.writeInt(option.type().ordinal()); + out.writeBoolean(option.deprecated()); + out.writeUTF(option.help()); + out.writeUTF(option.deprecationMessage()); } JByteArray res = JNIUtil.createHSArray(env, out.getArray()); scope.setObjectResult(res); @@ -459,7 +450,7 @@ public static JByteArray listCompilerOptions(JNIEnv env, JClass hsClazz, @Isolat return scope.getObjectResult(); } catch (Throwable t) { JNIExceptionWrapper.throwInHotSpot(env, t); - return WordFactory.nullPointer(); + return Word.nullPointer(); } } @@ -476,10 +467,6 @@ public static boolean compilerOptionExists(JNIEnv env, JClass hsClazz, @IsolateT } } - private static String validateCompilerOption(String optionName, String optionValue) { - return TruffleCompilerOptions.validateOption(optionName, optionValue); - } - @CEntryPoint(name = "Java_com_oracle_truffle_runtime_hotspot_libgraal_TruffleToLibGraalCalls_validateCompilerOption", include = LibGraalFeature.IsEnabled.class) @SuppressWarnings({"unused", "try"}) @TruffleToLibGraal(Id.ValidateCompilerOption) @@ -487,13 +474,14 @@ public static JString validateCompilerOption(JNIEnv env, JClass hsClazz, @Isolat try { JNIMethodScope scope = openScope(Id.ValidateCompilerOption, env); try (JNIMethodScope s = scope) { - String result = validateCompilerOption(JNIUtil.createString(env, optionName), JNIUtil.createString(env, optionValue)); + String optionName1 = JNIUtil.createString(env, optionName); + String result = TruffleCompilerOptions.validateOption(optionName1, JNIUtil.createString(env, optionValue)); scope.setObjectResult(JNIUtil.createHSString(env, result)); } return scope.getObjectResult(); } catch (Throwable t) { JNIExceptionWrapper.throwInHotSpot(env, t); - return WordFactory.nullPointer(); + return Word.nullPointer(); } } @@ -524,7 +512,7 @@ public static JString getCompilerVersion(JNIEnv env, JClass hsClass, @IsolateThr return scope.getObjectResult(); } catch (Throwable t) { JNIExceptionWrapper.throwInHotSpot(env, t); - return WordFactory.nullPointer(); + return Word.nullPointer(); } } @@ -532,7 +520,7 @@ public static JString getCompilerVersion(JNIEnv env, JClass hsClass, @IsolateThr @SuppressWarnings("unused") public static boolean releaseHandle(JNIEnv jniEnv, JClass jclass, @IsolateThreadContext long isolateThreadId, long handle) { try { - ObjectHandles.getGlobal().destroy(WordFactory.pointer(handle)); + ObjectHandles.getGlobal().destroy(Word.pointer(handle)); return true; } catch (Throwable t) { return false; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleHostEnvironment.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleHostEnvironment.java similarity index 97% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleHostEnvironment.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleHostEnvironment.java index 8712155becbe..1adaebafda5a 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleHostEnvironment.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleHostEnvironment.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.hotspot.libgraal.truffle; +package jdk.graal.compiler.libgraal.truffle; import com.oracle.truffle.compiler.HostMethodInfo; import com.oracle.truffle.compiler.TruffleCompilable; @@ -30,6 +30,7 @@ import jdk.graal.compiler.core.common.util.MethodKey; import jdk.graal.compiler.hotspot.CompilationContext; import jdk.graal.compiler.hotspot.HotSpotGraalServices; +import jdk.graal.compiler.serviceprovider.JavaVersionUtil; import jdk.graal.compiler.truffle.TruffleCompilerImpl; import jdk.graal.compiler.truffle.TruffleElementCache; import jdk.graal.compiler.truffle.host.TruffleHostEnvironment; @@ -131,7 +132,7 @@ private static MethodHandle findCompilerThreadCanCallJavaScopeConstructor() { try { return MethodHandles.lookup().findConstructor(Class.forName("jdk.vm.ci.hotspot.CompilerThreadCanCallJavaScope"), MethodType.methodType(void.class, boolean.class)); } catch (ReflectiveOperationException e) { - if (Runtime.version().feature() >= 24) { + if (JavaVersionUtil.JAVA_SPEC != 21) { throw new InternalError(e); } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleHostEnvironmentLookup.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleHostEnvironmentLookup.java similarity index 78% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleHostEnvironmentLookup.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleHostEnvironmentLookup.java index 72aaf3ee9bbd..0de0a8f231de 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleHostEnvironmentLookup.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleHostEnvironmentLookup.java @@ -22,15 +22,18 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.hotspot.libgraal.truffle; +package jdk.graal.compiler.libgraal.truffle; -import jdk.graal.compiler.libgraal.NativeImageHostEntryPoints; import jdk.graal.compiler.serviceprovider.GlobalAtomicLong; import jdk.graal.compiler.truffle.host.TruffleHostEnvironment; import jdk.graal.compiler.truffle.host.TruffleHostEnvironment.TruffleRuntimeScope; -import jdk.vm.ci.common.NativeImageReinitialize; +import jdk.graal.compiler.word.Word; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; import jdk.vm.ci.meta.ResolvedJavaType; +import org.graalvm.jniutils.HSObject; +import org.graalvm.jniutils.JNI; +import org.graalvm.jniutils.JNIMethodScope; +import org.graalvm.jniutils.JNIUtil; /** * This handles the Truffle host environment lookup on HotSpot with Libgraal. @@ -50,7 +53,13 @@ public final class LibGraalTruffleHostEnvironmentLookup implements TruffleHostEn private static final int NO_TRUFFLE_REGISTERED = 0; private static final GlobalAtomicLong WEAK_TRUFFLE_RUNTIME_INSTANCE = new GlobalAtomicLong("WEAK_TRUFFLE_RUNTIME_INSTANCE", NO_TRUFFLE_REGISTERED); - @NativeImageReinitialize private TruffleHostEnvironment previousRuntime; + private TruffleHostEnvironment previousRuntime; + + public static Object createLocalHandleForWeakGlobalReference(long jniWeakGlobalRef) { + JNIMethodScope scope = JNIMethodScope.scope(); + JNI.JObject localRef = JNIUtil.NewLocalRef(scope.getEnv(), Word.pointer(jniWeakGlobalRef)); + return localRef.isNull() ? null : new HSObject(scope, localRef); + } @Override @SuppressWarnings("try") @@ -60,15 +69,18 @@ public TruffleHostEnvironment lookup(ResolvedJavaType forType) { // fast path if Truffle was not initialized return null; } - Object runtimeLocalHandle = NativeImageHostEntryPoints.createLocalHandleForWeakGlobalReference(globalReference); - if (runtimeLocalHandle == null) { + + JNIMethodScope jniScope = JNIMethodScope.scope(); + JNI.JObject localRef = JNIUtil.NewLocalRef(jniScope.getEnv(), Word.pointer(globalReference)); + if (localRef.isNull()) { // The Truffle runtime was collected by the GC return null; } + HSObject runtimeLocalHandle = new HSObject(jniScope, localRef); TruffleHostEnvironment environment = this.previousRuntime; if (environment != null) { Object cached = hsRuntime(environment).hsHandle; - if (NativeImageHostEntryPoints.isSameObject(cached, runtimeLocalHandle)) { + if (JNIUtil.IsSameObject(JNIMethodScope.env(), ((HSObject) cached).getHandle(), runtimeLocalHandle.getHandle())) { // fast path for registered and cached Truffle runtime handle return environment; } @@ -79,8 +91,8 @@ public TruffleHostEnvironment lookup(ResolvedJavaType forType) { */ try (TruffleRuntimeScope scope = LibGraalTruffleHostEnvironment.openTruffleRuntimeScopeImpl()) { HSTruffleCompilerRuntime runtime = new HSTruffleCompilerRuntime( - NativeImageHostEntryPoints.createGlobalHandle(runtimeLocalHandle, true), - NativeImageHostEntryPoints.getObjectClass(runtimeLocalHandle)); + new HSObject(JNIMethodScope.env(), runtimeLocalHandle.getHandle(), true, false), + JNIUtil.GetObjectClass(JNIMethodScope.env(), runtimeLocalHandle.getHandle()).rawValue()); this.previousRuntime = environment = new LibGraalTruffleHostEnvironment(runtime, HotSpotJVMCIRuntime.runtime().getHostJVMCIBackend().getMetaAccess()); return environment; } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleScopeEntryPoints.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleScopeEntryPoints.java similarity index 97% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleScopeEntryPoints.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleScopeEntryPoints.java index 1da61a7c549a..8070b3ecc542 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/LibGraalTruffleScopeEntryPoints.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleScopeEntryPoints.java @@ -1,4 +1,4 @@ -package jdk.graal.compiler.hotspot.libgraal.truffle; +package jdk.graal.compiler.libgraal.truffle; import org.graalvm.nativeimage.Isolate; import org.graalvm.nativeimage.IsolateThread; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/TruffleFromLibGraalCalls.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/TruffleFromLibGraalCalls.java similarity index 97% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/TruffleFromLibGraalCalls.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/TruffleFromLibGraalCalls.java index 73f581244d0f..04e4c1484f67 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/TruffleFromLibGraalCalls.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/TruffleFromLibGraalCalls.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.hotspot.libgraal.truffle; +package jdk.graal.compiler.libgraal.truffle; import static org.graalvm.jniutils.JNIUtil.NewGlobalRef; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/TruffleFromLibGraalStartPoints.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/TruffleFromLibGraalStartPoints.java similarity index 79% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/TruffleFromLibGraalStartPoints.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/TruffleFromLibGraalStartPoints.java index ffe25165a39f..0c2890cf3b80 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/TruffleFromLibGraalStartPoints.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/TruffleFromLibGraalStartPoints.java @@ -22,55 +22,55 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.hotspot.libgraal.truffle; - -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callAddInlinedTarget; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callAddTargetToDequeue; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callAsJavaConstant; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callCancelCompilation; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callCompilableToString; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callConsumeOptimizedAssumptionDependency; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callCountDirectCallNodes; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callCreateStringSupplier; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callEngineId; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetCompilableCallCount; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetCompilableName; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetCompilerOptions; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetConstantFieldInfo; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetDebugProperties; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetDescription; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetFailedSpeculationsAddress; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetKnownCallSiteCount; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetLanguage; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetLineNumber; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetNodeClassName; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetNodeId; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetNonTrivialNodeCount; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetOffsetEnd; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetOffsetStart; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetPartialEvaluationMethodInfo; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetPosition; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetSuppliedString; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetURI; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callHasNextTier; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callIsCancelled; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callIsLastTier; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callIsSameOrSplit; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callIsSuppressedFailure; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callIsTrivial; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callIsValueType; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callLog; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnCodeInstallation; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnCompilationFailed; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnCompilationRetry; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnFailure; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnGraalTierFinished; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnIsolateShutdown; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnSuccess; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnTruffleTierFinished; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callPrepareForCompilation; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callRegisterOptimizedAssumptionDependency; -import static jdk.graal.compiler.hotspot.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callSetCallCounts; +package jdk.graal.compiler.libgraal.truffle; + +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callAddInlinedTarget; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callAddTargetToDequeue; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callAsJavaConstant; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callCancelCompilation; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callCompilableToString; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callConsumeOptimizedAssumptionDependency; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callCountDirectCallNodes; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callCreateStringSupplier; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callEngineId; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetCompilableCallCount; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetCompilableName; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetCompilerOptions; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetConstantFieldInfo; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetDebugProperties; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetDescription; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetFailedSpeculationsAddress; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetKnownCallSiteCount; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetLanguage; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetLineNumber; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetNodeClassName; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetNodeId; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetNonTrivialNodeCount; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetOffsetEnd; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetOffsetStart; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetPartialEvaluationMethodInfo; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetPosition; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetSuppliedString; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callGetURI; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callHasNextTier; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callIsCancelled; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callIsLastTier; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callIsSameOrSplit; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callIsSuppressedFailure; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callIsTrivial; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callIsValueType; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callLog; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnCodeInstallation; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnCompilationFailed; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnCompilationRetry; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnFailure; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnGraalTierFinished; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnIsolateShutdown; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnSuccess; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callOnTruffleTierFinished; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callPrepareForCompilation; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callRegisterOptimizedAssumptionDependency; +import static jdk.graal.compiler.libgraal.truffle.TruffleFromLibGraalStartPointsGen.callSetCallCounts; import static org.graalvm.jniutils.JNIMethodScope.env; import static org.graalvm.jniutils.JNIUtil.ExceptionClear; import static org.graalvm.jniutils.JNIUtil.GetStaticMethodID; @@ -112,7 +112,7 @@ public final class TruffleFromLibGraalStartPoints { private TruffleFromLibGraalStartPoints() { } - static void initializeJNI(JClass runtimeClass) { + public static void initializeJNI(JClass runtimeClass) { TruffleFromLibGraalCalls localCalls = calls; if (localCalls == null) { initialize(runtimeClass); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/TruffleLibGraalShutdownHook.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/TruffleLibGraalShutdownHook.java similarity index 97% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/TruffleLibGraalShutdownHook.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/TruffleLibGraalShutdownHook.java index 6c8b13ba4781..66495dcbfead 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/TruffleLibGraalShutdownHook.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/TruffleLibGraalShutdownHook.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.hotspot.libgraal.truffle; +package jdk.graal.compiler.libgraal.truffle; import jdk.graal.compiler.serviceprovider.IsolateUtil; import jdk.graal.compiler.serviceprovider.ServiceProvider; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PluginReplacementNode.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PluginReplacementNode.java index ce7bbf170484..9df63c222b0b 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PluginReplacementNode.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PluginReplacementNode.java @@ -35,6 +35,7 @@ import jdk.graal.compiler.nodeinfo.Verbosity; import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderContext; import jdk.graal.compiler.nodes.spi.Replacements; +import jdk.graal.nativeimage.FoldNodePlugin; @NodeInfo(nameTemplate = "PluginReplacement/{p#pluginName}", cycles = NodeCycles.CYCLES_IGNORED, size = NodeSize.SIZE_IGNORED) public final class PluginReplacementNode extends FixedWithNextNode implements PluginReplacementInterface { @@ -56,7 +57,7 @@ public boolean replace(GraphBuilderContext b, Replacements injection) { return function.replace(b, injection, stamp, args); } - public interface ReplacementFunction { + public interface ReplacementFunction extends FoldNodePlugin { boolean replace(GraphBuilderContext b, Replacements injection, Stamp stamp, NodeInputList args); } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedFoldInvocationPlugin.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedFoldInvocationPlugin.java index 91a67e34a5d2..935c060bc9f4 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedFoldInvocationPlugin.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedFoldInvocationPlugin.java @@ -24,9 +24,11 @@ */ package jdk.graal.compiler.nodes.graphbuilderconf; +import jdk.graal.nativeimage.FoldNodePlugin; + import java.lang.reflect.Type; -public abstract class GeneratedFoldInvocationPlugin extends GeneratedInvocationPlugin { +public abstract class GeneratedFoldInvocationPlugin extends GeneratedInvocationPlugin implements FoldNodePlugin { public GeneratedFoldInvocationPlugin(String name, Type... argumentTypes) { super(name, argumentTypes); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java index ae32cd05c860..fe9f38d41487 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java @@ -30,14 +30,13 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Type; -import java.util.List; import jdk.graal.compiler.api.replacements.Fold; import jdk.graal.compiler.debug.GraalError; import jdk.graal.compiler.graph.Node.NodeIntrinsic; -import jdk.graal.compiler.nodes.PluginReplacementNode; import jdk.graal.compiler.nodes.ValueNode; import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInlineOnlyInvocationPlugin; +import jdk.graal.nativeimage.FoldNodePlugin; import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; @@ -48,16 +47,6 @@ */ public abstract class GeneratedInvocationPlugin extends RequiredInlineOnlyInvocationPlugin { - private static List> foldNodePluginClasses = List.of(GeneratedFoldInvocationPlugin.class, PluginReplacementNode.ReplacementFunction.class); - - public static void setFoldNodePluginClasses(List> customFoldNodePluginClasses) { - foldNodePluginClasses = customFoldNodePluginClasses; - } - - public static List> getFoldNodePluginClasses() { - return foldNodePluginClasses; - } - private ResolvedJavaMethod executeMethod; public GeneratedInvocationPlugin(String name, Type... argumentTypes) { @@ -100,11 +89,9 @@ protected boolean checkInjectedArgument(GraphBuilderContext b, ValueNode arg, Re if (inImageBuildtimeCode()) { // The use of this plugin in the plugin itself shouldn't be folded since that defeats // the purpose of the fold. - for (Class foldNodePluginClass : foldNodePluginClasses) { - ResolvedJavaType foldNodeClass = b.getMetaAccess().lookupJavaType(foldNodePluginClass); - if (foldNodeClass.isAssignableFrom(b.getMethod().getDeclaringClass())) { - return false; - } + ResolvedJavaType foldNodeClass = b.getMetaAccess().lookupJavaType(FoldNodePlugin.class); + if (foldNodeClass.isAssignableFrom(b.getMethod().getDeclaringClass())) { + return false; } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/InvocationPlugins.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/InvocationPlugins.java index 256b0c69b9da..6d65a1d083a4 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/InvocationPlugins.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/InvocationPlugins.java @@ -66,7 +66,6 @@ import jdk.graal.compiler.options.OptionValues; import jdk.graal.compiler.serviceprovider.GlobalAtomicLong; import jdk.graal.compiler.serviceprovider.IsolateUtil; -import jdk.vm.ci.common.NativeImageReinitialize; import jdk.vm.ci.meta.MetaUtil; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; @@ -983,7 +982,7 @@ public String toString() { * The intrinsic methods (in {@link Options#DisableIntrinsics} format) that have been printed by * {@link #maybePrintIntrinsics}. */ - @NativeImageReinitialize private static Set PrintedIntrinsics = new HashSet<>(); + private static Set PrintedIntrinsics = new HashSet<>(); /** * Determines if {@code plugin} is disabled by {@link Options#DisableIntrinsics}. diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/nodes/IntrinsicMethodNodeInterface.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/nodes/IntrinsicMethodNodeInterface.java index a756d9877d77..76f59ee9d2f3 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/nodes/IntrinsicMethodNodeInterface.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/nodes/IntrinsicMethodNodeInterface.java @@ -34,9 +34,9 @@ import jdk.graal.compiler.nodes.spi.LIRLowerable; import jdk.graal.compiler.nodes.spi.NodeLIRBuilderTool; -import jdk.graal.compiler.serviceprovider.GraalServices; import jdk.vm.ci.code.Architecture; import jdk.vm.ci.meta.Value; +import org.graalvm.nativeimage.ImageInfo; /** * Mixin for nodes that represent an entire custom assembly method. These nodes can either emit the @@ -69,7 +69,7 @@ default void generate(NodeLIRBuilderTool gen) { } } - if (GraalServices.isBuildingLibgraal() && !canBeEmitted(gen.getLIRGeneratorTool().target().arch)) { + if (ImageInfo.inImageBuildtimeCode() && !canBeEmitted(gen.getLIRGeneratorTool().target().arch)) { // When building libgraal, we unconditionally compile all stubs, including those not // supported. In such case, we will emit hlt instruction and let the invocation plugin // ensure the stub is not reachable. diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java index 070960219a11..9c110b56d5fb 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java @@ -30,38 +30,35 @@ import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Properties; import java.util.ServiceConfigurationError; import java.util.ServiceLoader; +import java.util.Set; +import jdk.graal.compiler.core.ArchitectureSpecific; +import jdk.graal.nativeimage.LibGraalLoader; +import jdk.vm.ci.code.Architecture; import org.graalvm.nativeimage.ImageInfo; -import org.graalvm.nativeimage.Platform; -import org.graalvm.nativeimage.Platforms; import jdk.graal.compiler.debug.GraalError; -import jdk.graal.compiler.options.ExcludeFromJacocoGeneratedReport; import jdk.internal.misc.VM; import jdk.vm.ci.meta.EncodedSpeculationReason; import jdk.vm.ci.meta.SpeculationLog.SpeculationReason; import jdk.vm.ci.runtime.JVMCI; import jdk.vm.ci.services.Services; +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; /** * Interface to functionality that abstracts over which JDK version Graal is running on. */ public final class GraalServices { - /** - * Returns true if code is executing in the context of building libgraal. Note that this is more - * specific than {@link ImageInfo#inImageBuildtimeCode()}. The latter will return true when - * building any native image, not just libgraal. - */ - public static boolean isBuildingLibgraal() { - return Services.IS_BUILDING_NATIVE_IMAGE; - } - /** * Returns true if code is executing in the context of executing libgraal. Note that this is * more specific than {@link ImageInfo#inImageRuntimeCode()}. The latter will return true when @@ -75,13 +72,62 @@ public static boolean isInLibgraal() { * The set of services available in libgraal. This field is only non-null when * {@link GraalServices} is loaded by the LibGraalClassLoader. */ - private static Map, List> libgraalServices; + private static final Map, List> libgraalServices; + + @Platforms(Platform.HOSTED_ONLY.class) + private static Class loadClassOrNull(String name) { + try { + return GraalServices.class.getClassLoader().loadClass(name); + } catch (Throwable e) { + return null; + } + } + + /** + * Gets a name for the current architecture that is compatible with + * {@link Architecture#getName()}. + */ + @Platforms(Platform.HOSTED_ONLY.class) + private static String getJVMCIArch() { + String rawArch = getSavedProperty("os.arch"); + return switch (rawArch) { + case "x86_64" -> "AMD64"; + case "amd64" -> "AMD64"; + case "aarch64" -> "aarch64"; + case "riscv64" -> "riscv64"; + default -> throw new GraalError("Unknown or unsupported arch: %s", rawArch); + }; + } @Platforms(Platform.HOSTED_ONLY.class) - @ExcludeFromJacocoGeneratedReport("only called when building libgraal") - public static void setLibgraalServices(Map, List> services) { - GraalError.guarantee(libgraalServices == null, "Libgraal services must be set exactly once"); - GraalServices.libgraalServices = services; + @SuppressWarnings("unchecked") + private static void addProviders(String arch, Class service) { + List providers = (List) GraalServices.libgraalServices.computeIfAbsent(service, key -> new ArrayList<>()); + for (Object provider : ServiceLoader.load(service, GraalServices.class.getClassLoader())) { + if (provider instanceof ArchitectureSpecific as && !as.getArchitecture().equals(arch)) { + // Skip provider for another architecture + continue; + } + providers.add(provider); + } + } + + static { + ClassLoader cl = GraalServices.class.getClassLoader(); + if (cl instanceof LibGraalLoader libgraalLoader) { + libgraalServices = new HashMap<>(); + Set libgraalServicesModules = libgraalLoader.getServicesModules(); + Map modules = libgraalLoader.getModuleMap(); + String arch = getJVMCIArch(); + modules.entrySet().stream()// + .filter(e -> libgraalServicesModules.contains(e.getValue())) + .map(Map.Entry::getKey)// + .map(GraalServices::loadClassOrNull)// + .filter(c -> c != null && c.getAnnotation(LibGraalService.class) != null)// + .forEach(service -> addProviders(arch, service)); + } else { + libgraalServices = null; + } } private GraalServices() { @@ -104,6 +150,19 @@ public static Iterable load(Class service) { return load0(service); } + /** + * An escape hatch for calling {@link System#getProperties()} without falling afoul of + * {@code VerifySystemPropertyUsage}. + * + * @param justification explains why {@link #getSavedProperties()} cannot be used + */ + public static Properties getSystemProperties(String justification) { + if (justification == null || justification.isEmpty()) { + throw new IllegalArgumentException("non-empty justification required"); + } + return System.getProperties(); + } + /** * Gets an unmodifiable copy of the system properties in their state at system initialization * time. This method must be used instead of calling {@link Services#getSavedProperties()} diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/VMSupport.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/VMSupport.java deleted file mode 100644 index e9c0e38156bf..000000000000 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/VMSupport.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 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 jdk.graal.compiler.serviceprovider; - -/** - * Interface between the compiler and its Native Image based runtime (i.e. libgraal). - * - * The methods of this class are substituted by the libgraal implementation. - */ -public final class VMSupport { - - /** - * Gets a scope that performs setup/cleanup actions around a libgraal compilation. - */ - public static AutoCloseable getCompilationRequestScope() { - return null; - } - - /** - * @param cbClassName name of class declaring the call back method - * @param cbMethodName name of the call back method - */ - public static void invokeShutdownCallback(String cbClassName, String cbMethodName) { - } -} diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/TruffleCompilerImpl.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/TruffleCompilerImpl.java index a227137e5f28..ee8fb43a1f9e 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/TruffleCompilerImpl.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/TruffleCompilerImpl.java @@ -103,7 +103,6 @@ import jdk.vm.ci.code.InstalledCode; import jdk.vm.ci.code.site.Infopoint; import jdk.vm.ci.meta.Assumptions.Assumption; -import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.ProfilingInfo; /** @@ -667,10 +666,6 @@ public TruffleTier getTruffleTier() { return truffleTier; } - public TruffleCompilable asCompilableTruffleAST(JavaConstant constant) { - return config.snippetReflection().asObject(TruffleCompilable.class, constant); - } - @Override public void onStuckCompilation(CompilationWatchDog watchDog, Thread watched, CompilationIdentifier compilation, StackTraceElement[] stackTrace, long stuckTime) { CompilationWatchDog.EventHandler.super.onStuckCompilation(watchDog, watched, compilation, stackTrace, stuckTime); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/hotspot/HotSpotTruffleSafepointLoweringSnippet.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/hotspot/HotSpotTruffleSafepointLoweringSnippet.java index 59ed27c9ada6..b2a3b2ec5dab 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/hotspot/HotSpotTruffleSafepointLoweringSnippet.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/hotspot/HotSpotTruffleSafepointLoweringSnippet.java @@ -60,7 +60,6 @@ import jdk.graal.compiler.truffle.nodes.TruffleSafepointNode; import jdk.graal.compiler.truffle.phases.TruffleSafepointInsertionPhase; import jdk.graal.compiler.word.Word; -import jdk.vm.ci.common.NativeImageReinitialize; import jdk.vm.ci.meta.ResolvedJavaMethod; /** @@ -124,14 +123,14 @@ public void lower(TruffleSafepointNode node, LoweringTool tool) { static class TruffleHotSpotSafepointLoweringExtension implements DefaultHotSpotLoweringProvider.Extension { - @NativeImageReinitialize private Templates templates; + private Templates templates; private final HotSpotKnownTruffleTypes types; /** * Initialization deferred until the first Truffle compilation starts. */ - @NativeImageReinitialize private volatile Runnable deferredInit; + private volatile Runnable deferredInit; TruffleHotSpotSafepointLoweringExtension(HotSpotKnownTruffleTypes types) { this.types = types; diff --git a/compiler/src/jdk.graal.nativeimage/snapshot.sigtest b/compiler/src/jdk.graal.nativeimage/snapshot.sigtest index 377308f93d8a..7080d7130ba0 100644 --- a/compiler/src/jdk.graal.nativeimage/snapshot.sigtest +++ b/compiler/src/jdk.graal.nativeimage/snapshot.sigtest @@ -5,6 +5,7 @@ CLSS public abstract interface jdk.graal.nativeimage.LibGraalFeatureComponent meth public abstract void duringAnalysis(org.graalvm.nativeimage.hosted.Feature$DuringAnalysisAccess) CLSS public abstract interface jdk.graal.nativeimage.LibGraalLoader +meth public abstract java.nio.file.Path getJavaHome() meth public abstract java.util.Set getServicesModules() meth public abstract java.lang.ClassLoader getRuntimeClassLoader() meth public abstract java.util.Map getModuleMap() @@ -18,6 +19,8 @@ meth public static void processReferences() meth public static void fatalError(java.lang.String) supr java.lang.Object +CLSS public jdk.graal.nativeimage.FoldNodePlugin + CLSS public final jdk.graal.nativeimage.hosted.GlobalData meth public static java.util.function.Supplier createGlobal(long) supr java.lang.Object diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/FoldNodePlugin.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/FoldNodePlugin.java new file mode 100644 index 000000000000..5c2db80ee5e8 --- /dev/null +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/FoldNodePlugin.java @@ -0,0 +1,10 @@ +package jdk.graal.nativeimage; + +/** + * A marker interface for generated classes that implement compile-time evaluation (i.e. folding) of + * certain method calls where the folding must be deferred to libgraal runtime. + * + * @since 25 + */ +public interface FoldNodePlugin { +} diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalLoader.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalLoader.java index e7cc443afe3d..12a63aa5c054 100644 --- a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalLoader.java +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalLoader.java @@ -24,6 +24,7 @@ */ package jdk.graal.nativeimage; +import java.nio.file.Path; import java.util.Map; import java.util.Set; @@ -32,6 +33,13 @@ * interface to provide extra information about the libgraal classes. */ public interface LibGraalLoader { + + /** + * Gets the {@code java.home} of the JDK whose runtime image contains the Graal and JVMCI + * classes from which libgraal will be built. + */ + Path getJavaHome(); + /** * @return ClassLoader that implements this interface. */ diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java index 4a011bbfae5d..2d69ce49f84c 100644 --- a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java @@ -30,6 +30,7 @@ import org.graalvm.nativeimage.ImageSingletons; import jdk.graal.nativeimage.impl.LibGraalRuntimeSupport; +import org.graalvm.nativeimage.hosted.RuntimeSystemProperties; /** * LibGraal specific extensions to {@link org.graalvm.nativeimage}. @@ -38,6 +39,13 @@ */ public final class LibGraalRuntime { + /** + * Prefix to be used when {@linkplain RuntimeSystemProperties#register registering} properties + * describing the image configuration for libgraal. This is analogous to the configuration info + * displayed by {@code -XshowSettings}. + */ + public static String NATIVE_IMAGE_SETTING_KEY_PREFIX = "org.graalvm.nativeimage.setting."; + /** * Enqueues pending {@link Reference}s into their corresponding {@link ReferenceQueue}s and * executes pending cleaners. diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/GenScavengeGCFeature.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/GenScavengeGCFeature.java index 14d45bfd9f64..c7e58359f57e 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/GenScavengeGCFeature.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/GenScavengeGCFeature.java @@ -28,6 +28,7 @@ import java.util.List; import java.util.Map; +import jdk.graal.nativeimage.LibGraalRuntime; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.Feature; @@ -67,6 +68,7 @@ import jdk.graal.compiler.graph.Node; import jdk.graal.compiler.options.OptionValues; import jdk.graal.compiler.phases.util.Providers; +import org.graalvm.nativeimage.hosted.RuntimeSystemProperties; @AutomaticallyRegisteredFeature class GenScavengeGCFeature implements InternalFeature { @@ -128,6 +130,9 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { ImageSingletons.add(CommittedMemoryProvider.class, createCommittedMemoryProvider()); } + String gcName = Heap.getHeap().getGC().getName(); + RuntimeSystemProperties.register(LibGraalRuntime.NATIVE_IMAGE_SETTING_KEY_PREFIX + "gc", gcName); + // Needed for the barrier set. access.registerAsUsed(Object[].class); } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JVMCISubstitutions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JVMCISubstitutions.java index 4ff7a612b638..4377b31bbd65 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JVMCISubstitutions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JVMCISubstitutions.java @@ -51,15 +51,6 @@ final class Target_jdk_vm_ci_services_Services { public static boolean IS_IN_NATIVE_IMAGE = true; // Checkstyle: resume - /** - * Ensure field returns false if seen by the analysis. - */ - // Checkstyle: stop - @Alias // - @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FromAlias, isFinal = true)// - public static boolean IS_BUILDING_NATIVE_IMAGE = false; - // Checkstyle: resume - /** * Redirect to {@link SystemPropertiesSupport#singleton()}. */ diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/runtimecompilation/GraalGraphObjectReplacer.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/runtimecompilation/GraalGraphObjectReplacer.java index a715e594f9b9..bc795d467d92 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/runtimecompilation/GraalGraphObjectReplacer.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/runtimecompilation/GraalGraphObjectReplacer.java @@ -166,11 +166,11 @@ public Object apply(Object source) { if (source instanceof MetaAccessProvider) { dest = sProviders.getMetaAccessProvider(); } else if (source instanceof JVMCIRuntime) { - throw new UnsupportedFeatureException("JVMCIRuntime should not appear in the image: " + source); + // throw new UnsupportedFeatureException("JVMCIRuntime should not appear in the image: " + // + source); } else if (source instanceof GraalHotSpotVMConfig) { throw new UnsupportedFeatureException("GraalHotSpotVMConfig should not appear in the image: " + source); - } else if (source instanceof HotSpotBackendFactory) { - HotSpotBackendFactory factory = (HotSpotBackendFactory) source; + } else if (source instanceof HotSpotBackendFactory factory) { Architecture hostArch = HotSpotJVMCIRuntime.runtime().getHostJVMCIBackend().getTarget().arch; if (!factory.getArchitecture().equals(hostArch.getName())) { throw new UnsupportedFeatureException("Non-host architecture HotSpotBackendFactory should not appear in the image: " + source); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageClassLoaderSupport.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageClassLoaderSupport.java index 442cd92e9fca..91bbd23df3b3 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageClassLoaderSupport.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageClassLoaderSupport.java @@ -573,8 +573,6 @@ private Stream processOption(OptionKey loaderClass = Class.forName(className, true, classLoader); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationSupport.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationSupport.java index 19f005c69186..d13e008a27a4 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationSupport.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationSupport.java @@ -44,6 +44,7 @@ import java.util.function.Function; import java.util.stream.Collectors; +import jdk.graal.nativeimage.LibGraalLoader; import org.graalvm.collections.EconomicSet; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport; @@ -189,6 +190,16 @@ public boolean maybeInitializeAtBuildTime(Class clazz) { * class initialization fails. */ InitKind ensureClassInitialized(Class clazz, boolean allowErrors) { + LibGraalLoader libGraalLoader = loader.classLoaderSupport.getLibGraalLoader(); + Thread thread = Thread.currentThread(); + ClassLoader restoreCCL = null; + ClassLoader clazzLoader = clazz.getClassLoader(); + if (libGraalLoader != null && libGraalLoader.getClassLoader() == clazzLoader) { + // Graal and JVMCI make use of ServiceLoader which uses the + // context class loader so it needs to be the libgraal loader. + restoreCCL = thread.getContextClassLoader(); + thread.setContextClassLoader(clazz.getClassLoader()); + } try { loader.watchdog.recordActivity(); /* @@ -234,6 +245,10 @@ InitKind ensureClassInitialized(Class clazz, boolean allowErrors) { throw UserError.abort(t, "%s", msg); } + } finally { + if (restoreCCL != null) { + thread.setContextClassLoader(restoreCCL); + } } } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/doc-files/LibGraalClassLoader.txt b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/doc-files/LibGraalClassLoader.txt index d843a040f927..040c6fbfa7c5 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/doc-files/LibGraalClassLoader.txt +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/doc-files/LibGraalClassLoader.txt @@ -1,12 +1,10 @@ -Specify the fully qualified class name of the LibGraalClassLoader implementation that gets used for building libgraal. +Specify the fully qualified name of a class that implements jdk.graal.nativeimage.LibGraalLoader. This option is only supported for building the libgraal shared library. -The given fully qualified class name has to be a subtype of -jdk.graal.compiler.hotspot.libgraal.LibGraalClassLoaderBase. -When building the libgraal shared library, this option is used to specify a custom loader -the builder instantiates via default constructor, that affects image building as follows: +The named class is instantiated via the default constructor. +It affects image building as follows: 1. The custom loader is used to lookup Feature implementations passed via the --features option. - 2. All @CEntryPoint definitions from classes managed by the custom loader are processed. - 3. All @TargetClass substitutions in classes managed by the custom loader are processed. + 2. All @CEntryPoint definitions in classes loaded by the custom loader are processed. + 3. All @TargetClass substitutions in classes loaded by the custom loader are processed. diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/UniverseBuilder.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/UniverseBuilder.java index 3b763ee5cf20..ed18a7a53898 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/UniverseBuilder.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/UniverseBuilder.java @@ -44,6 +44,7 @@ import java.util.function.Function; import java.util.stream.Collectors; +import org.graalvm.nativeimage.ImageInfo; import org.graalvm.nativeimage.c.function.CEntryPointLiteral; import org.graalvm.nativeimage.c.function.CFunction; import org.graalvm.nativeimage.c.function.CFunctionPointer; @@ -220,7 +221,7 @@ private HostedType makeType(AnalysisType aType) { String typeName = aType.getName(); - assert GraalServices.isBuildingLibgraal() || !typeName.contains("/hotspot/") || typeName.contains("/jtt/hotspot/") || typeName.contains("/hotspot/shared/") : "HotSpot object in image " + + assert ImageInfo.inImageBuildtimeCode() || !typeName.contains("/hotspot/") || typeName.contains("/jtt/hotspot/") || typeName.contains("/hotspot/shared/") : "HotSpot object in image " + typeName; assert !typeName.contains("/analysis/meta/") : "Analysis meta object in image " + typeName; assert !typeName.contains("/hosted/meta/") : "Hosted meta object in image " + typeName; diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/AnnotationSubstitutionProcessor.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/AnnotationSubstitutionProcessor.java index 04a015d7c329..70339d0e88d3 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/AnnotationSubstitutionProcessor.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/AnnotationSubstitutionProcessor.java @@ -88,7 +88,6 @@ import com.oracle.svm.util.ReflectionUtil; import com.oracle.svm.util.ReflectionUtil.ReflectionUtilError; -import jdk.vm.ci.common.NativeImageReinitialize; import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaField; import jdk.vm.ci.meta.ResolvedJavaMethod; @@ -314,11 +313,6 @@ public void init(FieldValueInterceptionSupport newFieldValueInterceptionSupport) for (Class annotatedClass : annotatedClasses) { handleClass(annotatedClass); } - - List annotatedFields = imageClassLoader.findAnnotatedFields(NativeImageReinitialize.class); - for (Field annotatedField : annotatedFields) { - reinitializeField(annotatedField); - } } protected List> findTargetClasses() { @@ -1048,11 +1042,6 @@ private static Field getField(ResolvedJavaField annotated, Class targetClass, } } - protected void reinitializeField(Field annotatedField) { - ResolvedJavaField annotated = metaAccess.lookupJavaField(annotatedField); - fieldValueInterceptionSupport.registerFieldValueTransformer(annotated, ConstantValueFieldValueTransformer.defaultValueForField(annotated)); - } - public Class getTargetClass(Class annotatedClass) { Class annotatedBaseClass = annotatedClass; int arrayDepth = 0; diff --git a/truffle/mx.truffle/suite.py b/truffle/mx.truffle/suite.py index eb9e834c9eec..6c0bb20babdd 100644 --- a/truffle/mx.truffle/suite.py +++ b/truffle/mx.truffle/suite.py @@ -1368,16 +1368,12 @@ "com.oracle.truffle.libgraal.processor" : { "subDir" : "src", "sourceDirs" : ["src"], - "dependencies" : [ - "truffle:ANTLR4" - ], "requires" : [ "java.compiler", "jdk.management" ], "checkstyle" : "com.oracle.truffle.api", "javaCompliance" : "17+", - "graalCompilerSourceEdition": "ignore", }, "org.graalvm.shadowed.org.json" : { @@ -2103,7 +2099,6 @@ "maven": { "tag": ["default", "public"], }, - "graalCompilerSourceEdition": "ignore", }, "TRUFFLE_SL" : { From c412d275b1e97690e65258d94ba5f72db6850365 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Sun, 29 Dec 2024 12:10:01 +0100 Subject: [PATCH 13/31] fix hotspot issue --- .../core/test/CompilationWatchDogTest.java | 2 +- .../compiler/core/CompilationWatchDog.java | 49 ++++++++--------- .../graal/compiler/debug/DebugContext.java | 10 ++-- .../hotspot/HotSpotBackendFactory.java | 5 +- .../hotspot/HotSpotGraalCompiler.java | 4 +- .../HotSpotGraalServiceThread.java} | 16 +++--- .../hotspot/HotSpotReplacementsImpl.java | 53 +++++++++---------- .../hotspot/SymbolicSnippetEncoder.java | 11 ++-- .../hotspot/debug/BenchmarkCounters.java | 4 +- .../graal/compiler/hotspot/stubs/Stub.java | 17 +++++- .../{JDK21.java => BeforeJDK8346781.java} | 13 +++-- .../compiler/libgraal/CompilerConfig.java | 38 ++++++------- .../compiler/libgraal/GetCompilerConfig.java | 7 ++- .../compiler/libgraal/LibGraalFeature.java | 7 +-- .../libgraal/LibGraalSubstitutions.java | 2 +- .../compiler/nodes/PluginReplacementNode.java | 7 +++ .../GeneratedFoldInvocationPlugin.java | 4 ++ .../GeneratedInvocationPlugin.java | 11 +++- .../nodes/spi/SnippetParameterInfo.java | 4 -- .../nodes/IntrinsicMethodNodeInterface.java | 8 --- .../compiler/truffle/TruffleCompilerImpl.java | 13 ++++- .../hotspot/HotSpotTruffleCompilerImpl.java | 7 +++ .../oracle/svm/graal/SubstrateGraalUtils.java | 2 +- .../GraalGraphObjectReplacer.java | 3 +- 24 files changed, 171 insertions(+), 126 deletions(-) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/{core/GraalServiceThread.java => hotspot/HotSpotGraalServiceThread.java} (85%) rename compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/{JDK21.java => BeforeJDK8346781.java} (79%) diff --git a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/CompilationWatchDogTest.java b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/CompilationWatchDogTest.java index 2d03881a91ca..0b71b4fd77f2 100644 --- a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/CompilationWatchDogTest.java +++ b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/CompilationWatchDogTest.java @@ -137,7 +137,7 @@ public void onStuckCompilation(CompilationWatchDog watchDog, Thread watched, Com }; - CompilationWatchDog watch = CompilationWatchDog.watch(compilation, options, false, longCompilationHandler); + CompilationWatchDog watch = CompilationWatchDog.watch(compilation, options, false, longCompilationHandler, null); try (CompilationWatchDog watchScope = watch) { event("start compiling"); try (TTY.Filter f = new TTY.Filter()) { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/CompilationWatchDog.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/CompilationWatchDog.java index 78e64afee3ed..1dc4e9a2e218 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/CompilationWatchDog.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/CompilationWatchDog.java @@ -181,19 +181,21 @@ public static class Options { private final ScheduledExecutorService singleShotExecutor; - CompilationWatchDog(CompilationIdentifier compilation, Thread watchedThread, int delay, int vmExitDelay, - boolean singleShotExecutor, EventHandler eventHandler) { + CompilationWatchDog(CompilationIdentifier compilation, + Thread watchedThread, int delay, int vmExitDelay, + boolean singleShotExecutor, EventHandler eventHandler, + ThreadFactory factory) { this.compilation = compilation; this.watchedThread = watchedThread; this.vmExitDelayNS = TimeUnit.SECONDS.toNanos(vmExitDelay); this.eventHandler = eventHandler == null ? EventHandler.DEFAULT : eventHandler; trace("started compiling %s", compilation); if (singleShotExecutor) { - this.singleShotExecutor = createExecutor(); + this.singleShotExecutor = createExecutor(factory); this.task = this.singleShotExecutor.schedule(this, delay, TimeUnit.SECONDS); } else { this.singleShotExecutor = null; - this.task = schedule(this, delay); + this.task = schedule(this, delay, factory); } } @@ -293,27 +295,24 @@ public void run() { private static ScheduledExecutorService watchDogService; - private static synchronized ScheduledFuture schedule(CompilationWatchDog watchdog, int delay) { + private static synchronized ScheduledFuture schedule(CompilationWatchDog watchdog, int delay, ThreadFactory factory) { if (watchDogService == null) { - watchDogService = createExecutor(); + watchDogService = createExecutor(factory); } return watchDogService.schedule(watchdog, delay, TimeUnit.SECONDS); } - private static ScheduledExecutorService createExecutor() { - ThreadFactory threadFactory = new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - Thread thread = new GraalServiceThread(CompilationWatchDog.class.getSimpleName(), r); - thread.setName("WatchDog-" + GraalServices.getThreadId(thread)); - thread.setPriority(Thread.MAX_PRIORITY); - thread.setDaemon(true); - return thread; - } + private static ScheduledExecutorService createExecutor(ThreadFactory factory) { + ThreadFactory watchDogThreadFactory = r -> { + Thread thread = factory == null ? new Thread(r) : factory.newThread(r); + thread.setName("WatchDog-" + GraalServices.getThreadId(thread)); + thread.setPriority(Thread.MAX_PRIORITY); + thread.setDaemon(true); + return thread; }; int poolSize = 1; - ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(poolSize, threadFactory); + ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(poolSize, watchDogThreadFactory); executor.setRemoveOnCancelPolicy(true); executor.allowCoreThreadTimeOut(true); return executor; @@ -323,16 +322,19 @@ public Thread newThread(Runnable r) { * Opens a scope for watching a compilation. * * @param compilation identifies the compilation being watched - * @param singleShotExecutor if true, then a dedicated executor is created for this task and it + * @param singleShotExecutor if true, then a dedicated executor is created for this task, and it * is shutdown once the compilation ends - * @param eventHandler notified of events like a compilation running long running or getting - * stuck. If {@code null}, {@link EventHandler#DEFAULT} is used. + * @param eventHandler notified of events like a compilation running long or getting stuck. If + * {@code null}, {@link EventHandler#DEFAULT} is used. + * @param factory factory to use for creating the watcher thread. If null, a default Thread + * object is used. * @return {@code null} if the compilation watch dog is disabled otherwise a new * {@link CompilationWatchDog} object. The returned value should be used in a * {@code try}-with-resources statement whose scope is the whole compilation so that * leaving the scope will cause {@link #close()} to be called. */ - public static CompilationWatchDog watch(CompilationIdentifier compilation, OptionValues options, boolean singleShotExecutor, EventHandler eventHandler) { + public static CompilationWatchDog watch(CompilationIdentifier compilation, OptionValues options, + boolean singleShotExecutor, EventHandler eventHandler, ThreadFactory factory) { int delay = Options.CompilationWatchDogStartDelay.getValue(options); if (ImageInfo.inImageBuildtimeCode() && !Options.CompilationWatchDogStartDelay.hasBeenSet(options)) { // Disable watch dog by default when building a native image @@ -341,9 +343,8 @@ public static CompilationWatchDog watch(CompilationIdentifier compilation, Optio if (delay > 0) { Thread watchedThread = Thread.currentThread(); int vmExitDelay = Options.CompilationWatchDogVMExitDelay.getValue(options); - CompilationWatchDog watchDog = new CompilationWatchDog(compilation, watchedThread, delay, - vmExitDelay, singleShotExecutor, eventHandler); - return watchDog; + return new CompilationWatchDog(compilation, watchedThread, delay, + vmExitDelay, singleShotExecutor, eventHandler, factory); } return null; } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/debug/DebugContext.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/debug/DebugContext.java index 5dd8b723e488..58198bbd8d3a 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/debug/DebugContext.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/debug/DebugContext.java @@ -86,6 +86,7 @@ public final class DebugContext implements AutoCloseable { */ public static final String DUMP_FILE_MESSAGE_REGEXP = "Dumping debug output to '(?[^']+)'"; + private static final Description DISABLED_DESCRIPTION = new Description(null, "DISABLED_DESCRIPTION"); public static final Description NO_DESCRIPTION = new Description(null, "NO_DESCRIPTION"); public static final GlobalMetrics NO_GLOBAL_METRIC_VALUES = null; public static final Iterable NO_CONFIG_CUSTOMIZERS = Collections.emptyList(); @@ -349,7 +350,7 @@ public Activation activate() { /** * Singleton used to represent a disabled debug context. */ - private static final DebugContext DISABLED = new DebugContext(NO_DESCRIPTION, null, NO_GLOBAL_METRIC_VALUES, getDefaultLogStream(), new Immutable(), NO_CONFIG_CUSTOMIZERS); + private static final DebugContext DISABLED = new DebugContext(DISABLED_DESCRIPTION, null, NO_GLOBAL_METRIC_VALUES, getDefaultLogStream(), new Immutable(), NO_CONFIG_CUSTOMIZERS); /** * Create a DebugContext with debugging disabled. @@ -638,6 +639,7 @@ private DebugContext(Description description, Immutable immutable, Iterable factories, boolean disableConfig) { this.immutable = immutable; + this.invariants = Assertions.assertionsEnabled() && description != DISABLED_DESCRIPTION ? new Invariants() : null; this.description = description; this.globalMetrics = globalMetrics; this.compilationListener = compilationListener; @@ -873,11 +875,7 @@ public DebugContext.Scope scope(Object name) { } } - /** - * Arbitrary threads cannot be in the image so null out {@code DebugContext.invariants} which - * holds onto a thread and is only used for assertions. - */ - private final Invariants invariants = Assertions.assertionsEnabled() ? new Invariants() : null; + private final Invariants invariants; static StackTraceElement[] getStackTrace(Thread thread) { return thread.getStackTrace(); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotBackendFactory.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotBackendFactory.java index c0841dc7d39e..ad5baecba878 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotBackendFactory.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotBackendFactory.java @@ -25,6 +25,7 @@ package jdk.graal.compiler.hotspot; import static jdk.vm.ci.common.InitTimer.timer; +import static org.graalvm.nativeimage.ImageInfo.inImageBuildtimeCode; import static org.graalvm.nativeimage.ImageInfo.inImageCode; import jdk.graal.compiler.bytecode.BytecodeProvider; @@ -201,7 +202,9 @@ public final HotSpotBackend createBackend(HotSpotGraalRuntimeProvider graalRunti try (InitTimer rt = timer("create Replacements provider")) { replacements = createReplacements(target, providers, bytecodeProvider); providers = replacements.getProviders(); - replacements.maybeInitializeEncoder(); + if (inImageBuildtimeCode()) { + replacements.maybeInitializeEncoder(); + } } GraphBuilderConfiguration.Plugins plugins; try (InitTimer rt = timer("create GraphBuilderPhase plugins")) { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalCompiler.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalCompiler.java index 7a0e7df0ad7b..83088874ec8f 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalCompiler.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalCompiler.java @@ -30,6 +30,7 @@ import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.concurrent.ThreadFactory; import jdk.graal.compiler.api.runtime.GraalJVMCICompiler; import jdk.graal.compiler.code.CompilationResult; @@ -207,7 +208,8 @@ public CompilationRequestResult compileMethod(CompilationRequest request, boolea boolean oneIsolatePerCompilation = ImageInfo.inImageRuntimeCode() && config.getFlag("JVMCIThreadsPerNativeLibraryRuntime", Integer.class, 0) == 1 && config.getFlag("JVMCICompilerIdleDelay", Integer.class, 1000) == 0; - try (CompilationWatchDog w1 = CompilationWatchDog.watch(task.getCompilationIdentifier(), options, oneIsolatePerCompilation, task); + ThreadFactory factory = ImageInfo.inImageRuntimeCode() ? HotSpotGraalServiceThread::new : null; + try (CompilationWatchDog w1 = CompilationWatchDog.watch(task.getCompilationIdentifier(), options, oneIsolatePerCompilation, task, factory); BootstrapWatchDog.Watch w2 = bootstrapWatchDog == null ? null : bootstrapWatchDog.watch(request); CompilationAlarm alarm = CompilationAlarm.trackCompilationPeriod(options);) { if (compilationCounters != null) { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/GraalServiceThread.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalServiceThread.java similarity index 85% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/GraalServiceThread.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalServiceThread.java index 34a0425e420a..ef87b6b285a2 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/GraalServiceThread.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotGraalServiceThread.java @@ -22,21 +22,19 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.compiler.core; +package jdk.graal.compiler.hotspot; import jdk.graal.compiler.serviceprovider.GraalServices; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; /** - * This is a utility class for Threads started by the compiler itself. In certain execution - * environments extra work must be done for these threads to execute correctly and this class - * provides hooks for this work. + * This is a utility class for Threads started by the compiler itself. In libgraal, such threads + * must be attached and detached to the host JVM process. */ -public class GraalServiceThread extends Thread { +public class HotSpotGraalServiceThread extends Thread { private final Runnable runnable; - public GraalServiceThread(String name, Runnable runnable) { - super(name); + public HotSpotGraalServiceThread(Runnable runnable) { this.runnable = runnable; } @@ -67,12 +65,12 @@ public final void run() { * Notifies of an error on attaching this thread to the libgraal peer runtime. * * The default implementation of this method is to print the stack trace for {@code error} if - * the {@code GraalServiceThread.verbose} system property is {@code "true"}. + * the {@code HotSpotGraalServiceThread.verbose} system property is {@code "true"}. * * @param error the error */ protected void onAttachError(InternalError error) { - if (Boolean.parseBoolean(GraalServices.getSavedProperty("GraalServiceThread.verbose", "false"))) { + if (Boolean.parseBoolean(GraalServices.getSavedProperty("HotSpotGraalServiceThread.verbose", "false"))) { error.printStackTrace(); } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotReplacementsImpl.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotReplacementsImpl.java index 8837119cc068..976ec5afc0d7 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotReplacementsImpl.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotReplacementsImpl.java @@ -63,6 +63,8 @@ import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; /** * Filters certain method substitutions based on whether there is underlying hardware support for @@ -71,11 +73,17 @@ public class HotSpotReplacementsImpl extends ReplacementsImpl { public HotSpotReplacementsImpl(HotSpotProviders providers, BytecodeProvider bytecodeProvider, TargetDescription target) { super(new GraalDebugHandlersFactory(providers.getSnippetReflection()), providers, bytecodeProvider, target); + if (inImageBuildtimeCode()) { + registeredSnippets = EconomicSet.create(); + } } HotSpotReplacementsImpl(HotSpotReplacementsImpl replacements, HotSpotProviders providers) { super(new GraalDebugHandlersFactory(replacements.getProviders().getSnippetReflection()), providers, replacements.getDefaultReplacementBytecodeProvider(), replacements.target); + if (inImageBuildtimeCode()) { + registeredSnippets = EconomicSet.create(); + } } @Override @@ -83,15 +91,11 @@ public HotSpotProviders getProviders() { return (HotSpotProviders) super.getProviders(); } + @Platforms(Platform.HOSTED_ONLY.class) public SymbolicSnippetEncoder maybeInitializeEncoder() { - if (inImageRuntimeCode()) { - return null; - } - if (inImageBuildtimeCode()) { - synchronized (HotSpotReplacementsImpl.class) { - if (snippetEncoder == null) { - snippetEncoder = new SymbolicSnippetEncoder(this); - } + synchronized (HotSpotReplacementsImpl.class) { + if (snippetEncoder == null) { + snippetEncoder = new SymbolicSnippetEncoder(this); } } return snippetEncoder; @@ -184,18 +188,18 @@ public StructuredGraph getInlineSubstitution(ResolvedJavaMethod method, int invo // When assertions are enabled, these fields are used to ensure all snippets are // registered during Graal initialization which in turn ensures that native image // building will not miss any snippets. - private EconomicSet registeredSnippets = EconomicSet.create(); + @Platforms(Platform.HOSTED_ONLY.class)// + private EconomicSet registeredSnippets; + @Platforms(Platform.HOSTED_ONLY.class)// private boolean snippetRegistrationClosed; @Override public void registerSnippet(ResolvedJavaMethod method, ResolvedJavaMethod original, Object receiver, boolean trackNodeSourcePosition, OptionValues options) { assert method.isStatic() || receiver != null : "must have a constant type for the receiver"; - if (!inImageRuntimeCode()) { + if (inImageBuildtimeCode()) { assert !snippetRegistrationClosed || System.getProperty("GraalUnitTest") != null : "Cannot register snippet after registration is closed: " + method.format("%H.%n(%p)"); if (registeredSnippets.add(method)) { - if (inImageBuildtimeCode()) { - snippetEncoder.registerSnippet(method, original, receiver, trackNodeSourcePosition); - } + snippetEncoder.registerSnippet(method, original, receiver, trackNodeSourcePosition); } } } @@ -218,7 +222,9 @@ public boolean isSnippet(ResolvedJavaMethod method) { @Override public void closeSnippetRegistration() { - snippetRegistrationClosed = true; + if (inImageBuildtimeCode()) { + snippetRegistrationClosed = true; + } } public static EncodedSnippets getEncodedSnippets() { @@ -228,29 +234,19 @@ public static EncodedSnippets getEncodedSnippets() { return encodedSnippets; } + @Platforms(Platform.HOSTED_ONLY.class)// public static boolean snippetsAreEncoded() { return encodedSnippets != null; } - public void clearSnippetParameterNames() { - assert snippetEncoder != null; - snippetEncoder.clearSnippetParameterNames(); - } - + @Platforms(Platform.HOSTED_ONLY.class)// public static void setEncodedSnippets(EncodedSnippets encodedSnippets) { HotSpotReplacementsImpl.encodedSnippets = encodedSnippets; } - public boolean encode(OptionValues options) { - SymbolicSnippetEncoder encoder = snippetEncoder; - if (encoder != null) { - return encoder.encode(options); - } - return false; - } - private static volatile EncodedSnippets encodedSnippets; + @Platforms(Platform.HOSTED_ONLY.class)// private static SymbolicSnippetEncoder snippetEncoder; @SuppressWarnings("try") @@ -269,7 +265,7 @@ public StructuredGraph getSnippet(ResolvedJavaMethod method, ResolvedJavaMethod } } - assert registeredSnippets == null || registeredSnippets.contains(method) : "Asking for snippet method that was never registered: " + method.format("%H.%n(%p)"); + assert !inImageBuildtimeCode() || registeredSnippets == null || registeredSnippets.contains(method) : "Asking for snippet method that was never registered: " + method.format("%H.%n(%p)"); return super.getSnippet(method, original, args, nonNullParameters, trackNodeSourcePosition, replaceePosition, options); } @@ -282,6 +278,7 @@ public T getInjectedArgument(Class capability) { return super.getInjectedArgument(capability); } + @Platforms(Platform.HOSTED_ONLY.class) public ResolvedJavaMethod findSnippetMethod(ResolvedJavaMethod thisMethod) { if (snippetEncoder == null) { throw new GraalError("findSnippetMethod called before initialization of Replacements"); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/SymbolicSnippetEncoder.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/SymbolicSnippetEncoder.java index c781d37f76f6..66ec39e0ba19 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/SymbolicSnippetEncoder.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/SymbolicSnippetEncoder.java @@ -136,6 +136,8 @@ import jdk.vm.ci.meta.Signature; import jdk.vm.ci.meta.SpeculationLog; import jdk.vm.ci.meta.UnresolvedJavaType; +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; /** * This class performs graph encoding using {@link GraphEncoder} but also converts JVMCI type and @@ -144,6 +146,7 @@ *

      * An instance of this class only exist when building libgraal. */ +@Platforms(Platform.HOSTED_ONLY.class) public class SymbolicSnippetEncoder { /** @@ -217,12 +220,6 @@ void addDelayedInvocationPluginMethod(ResolvedJavaMethod method) { delayedInvocationPluginMethods.add(method); } - public void clearSnippetParameterNames() { - for (SnippetParameterInfo info : snippetParameterInfos.getValues()) { - info.clearNames(); - } - } - protected class SnippetInlineInvokePlugin implements InlineInvokePlugin { @Override @@ -540,7 +537,7 @@ private synchronized EncodedSnippets encodeSnippets(DebugContext debug, Economic graphDatas.put(keyString, data); } - // Ensure a few types are available + // Ensure a few well known types are available lookupSnippetType(GraalHotSpotVMConfig.class); lookupSnippetType(NamedLocationIdentity.class); lookupSnippetType(SnippetTemplate.EagerSnippetInfo.class); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/debug/BenchmarkCounters.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/debug/BenchmarkCounters.java index cbc47d2d36b2..2f2bf07b1fce 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/debug/BenchmarkCounters.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/debug/BenchmarkCounters.java @@ -39,7 +39,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; -import jdk.graal.compiler.core.GraalServiceThread; import jdk.graal.compiler.core.common.SuppressFBWarnings; import jdk.graal.compiler.debug.CSVUtil; import jdk.graal.compiler.debug.GraalError; @@ -468,7 +467,7 @@ protected void patternFound(int index) { if (ImageInfo.inImageRuntimeCode()) { throw new GraalError("Use of %s is only supported in jargraal", Options.TimedDynamicCounters.getName()); } - Thread thread = new GraalServiceThread(BenchmarkCounters.class.getSimpleName(), new Runnable() { + Thread thread = new Thread(new Runnable() { long lastTime = System.nanoTime(); @Override @@ -486,6 +485,7 @@ public void run() { } } }); + thread.setName(BenchmarkCounters.class.getSimpleName()); thread.setDaemon(true); thread.setPriority(Thread.MAX_PRIORITY); thread.start(); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/stubs/Stub.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/stubs/Stub.java index ea38d909d002..9f4b69fa043f 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/stubs/Stub.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/stubs/Stub.java @@ -79,6 +79,8 @@ import jdk.vm.ci.meta.DefaultProfilingInfo; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.TriState; +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; //JaCoCo Exclude @@ -158,12 +160,25 @@ public RegisterConfig getRegisterConfig() { } /** - * Gets the graph that from which the code for this stub will be compiled. + * Gets the graph from which the code for this stub will be compiled. * * @param compilationId unique compilation id for the stub */ protected abstract StructuredGraph getGraph(DebugContext debug, CompilationIdentifier compilationId); + /** + * Calls {@link #getGraph} for the side effect of registering the types used in the graph with + * SymbolicSnippetEncoder.snippetTypes. + */ + @Platforms(Platform.HOSTED_ONLY.class) + public final void findTypesInGraph() { + try (DebugContext debug = DebugContext.disabled(options)) { + Stub stub = linkage.getStub(); + CompilationIdentifier compilationId = new StubCompilationIdentifier(stub); + stub.getGraph(debug, compilationId); + } + } + @Override public String toString() { return "Stub<" + linkage.getDescriptor().getSignature() + ">"; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/JDK21.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/BeforeJDK8346781.java similarity index 79% rename from compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/JDK21.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/BeforeJDK8346781.java index baba61097948..712913655a86 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/JDK21.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/BeforeJDK8346781.java @@ -25,12 +25,19 @@ package jdk.graal.compiler.libgraal; import java.util.function.BooleanSupplier; +import java.util.stream.Stream; -import jdk.graal.compiler.serviceprovider.JavaVersionUtil; +import jdk.vm.ci.services.Services; + +/** + * Determines if the JDK runtime does not include JDK-8346781. + */ +public class BeforeJDK8346781 implements BooleanSupplier { + + static final boolean VALUE = Stream.of(Services.class.getFields()).anyMatch(f -> f.getName().equals("IS_BUILDING_NATIVE_IMAGE")); -public class JDK21 implements BooleanSupplier { @Override public boolean getAsBoolean() { - return JavaVersionUtil.JAVA_SPEC == 21; + return VALUE; } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/CompilerConfig.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/CompilerConfig.java index 4577db416c59..168a093c8302 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/CompilerConfig.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/CompilerConfig.java @@ -24,6 +24,8 @@ */ package jdk.graal.compiler.libgraal; +import java.io.FileOutputStream; +import java.io.PrintStream; import java.lang.reflect.Field; import java.nio.file.Files; import java.nio.file.Path; @@ -85,20 +87,21 @@ public static void main(String[] args) throws Exception { encodedObjects.put("encodedSnippets", encodedSnippets); encodedObjects.put("foreignCallSignatures", foreignCallSignatures); - ObjectCopier.Encoder encoder = new ObjectCopier.Encoder(externalValueFields) { - @Override - protected ClassInfo makeClassInfo(Class declaringClass) { - ClassInfo ci = ClassInfo.of(declaringClass); - for (var f : ci.fields().values()) { - // Avoid problems with identity hash codes - GraalError.guarantee(!f.getName().toLowerCase(Locale.ROOT).contains("hash"), "Cannot serialize hash field: %s", f); + try (PrintStream debugStream = new PrintStream(new FileOutputStream(args[1]))) { + ObjectCopier.Encoder encoder = new ObjectCopier.Encoder(externalValueFields, debugStream) { + @Override + protected ClassInfo makeClassInfo(Class declaringClass) { + ClassInfo ci = ClassInfo.of(declaringClass); + for (var f : ci.fields().values()) { + // Avoid problems with identity hash codes + GraalError.guarantee(!f.getName().toLowerCase(Locale.ROOT).contains("hash"), "Cannot serialize hash field: %s", f); + } + return ci; } - return ci; - } - }; - byte[] encoded = ObjectCopier.encode(encoder, encodedObjects); - - Files.write(Path.of(args[0]), encoded); + }; + byte[] encoded = ObjectCopier.encode(encoder, encodedObjects); + Files.write(Path.of(args[0]), encoded); + } } private static EncodedSnippets getEncodedSnippets(HotSpotReplacementsImpl replacements, OptionValues options) { @@ -111,13 +114,12 @@ private static List getForeignCallSignatures(HotSpotReplac EconomicMap foreignCalls = collectForeignCalls(replacements, options); MapCursor cursor = foreignCalls.getEntries(); while (cursor.advance()) { - ForeignCallSignature sig = cursor.getKey(); + sigs.add(cursor.getKey()); HotSpotForeignCallLinkage linkage = cursor.getValue(); - sigs.add(sig); - if (linkage != null) { - // Construct the stub so that all types it uses are registered in + if (linkage != null && linkage.isCompiledStub()) { + // Construct the stub graph so that all types it uses are registered in // SymbolicSnippetEncoder.snippetTypes - linkage.finalizeAddress(graalRuntime.getHostBackend()); + linkage.getStub().findTypesInGraph(); } } return sigs; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetCompilerConfig.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetCompilerConfig.java index f89fbf2224da..76ef9b52fee3 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetCompilerConfig.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetCompilerConfig.java @@ -129,8 +129,11 @@ public static Result from(Path javaHome) { } command.add(CompilerConfig.class.getName()); - Path encodedConfigPath = Path.of(GetCompilerConfig.class.getSimpleName() + "_" + ProcessHandle.current().pid() + ".txt").toAbsolutePath(); + String base = GetCompilerConfig.class.getSimpleName() + "_" + ProcessHandle.current().pid(); + Path encodedConfigPath = Path.of(base + ".bin").toAbsolutePath(); + Path debugPath = Path.of(base + ".txt").toAbsolutePath(); command.add(encodedConfigPath.toString()); + command.add(debugPath.toString()); String quotedCommand = command.stream().map(e -> e.indexOf(' ') == -1 ? e : '\'' + e + '\'').collect(Collectors.joining(" ")); ProcessBuilder pb = new ProcessBuilder(command); @@ -155,8 +158,10 @@ public static Result from(Path javaHome) { if (DEBUG) { System.out.printf("[%d] Executed: %s%n", p.pid(), quotedCommand); System.out.printf("[%d] Output saved in %s%n", p.pid(), encodedConfigPath); + System.out.printf("[%d] Debug output saved in %s%n", p.pid(), debugPath); } else { Files.deleteIfExists(encodedConfigPath); + Files.deleteIfExists(debugPath); } return new Result(encodedConfig, opens); } catch (IOException e) { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java index b5993adf1d95..aa4be4203717 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java @@ -67,7 +67,6 @@ import org.graalvm.nativeimage.hosted.RuntimeReflection; import jdk.graal.compiler.core.common.Fields; -import jdk.graal.compiler.debug.DebugContext; import jdk.graal.compiler.debug.GraalError; import jdk.graal.compiler.graph.Edges; import jdk.graal.compiler.options.OptionDescriptor; @@ -309,8 +308,6 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { RuntimeClassInitialization.initializeAtRunTime(HotSpotModifiers.class); RuntimeClassInitialization.initializeAtRunTime(LibGraalUtil.lookupClass("jdk.vm.ci.hotspot.HotSpotCompiledCodeStream")); RuntimeClassInitialization.initializeAtRunTime(LibGraalUtil.lookupClass("jdk.vm.ci.hotspot.HotSpotCompiledCodeStream$Tag")); - /* ThreadLocal in static field jdk.graal.compiler.debug.DebugContext.activated */ - RuntimeClassInitialization.initializeAtRunTime(DebugContext.class); /* Needed for runtime calls to BoxingSnippets.Templates.getCacheClass(JavaKind) */ RuntimeReflection.registerAllDeclaredClasses(Character.class); @@ -356,7 +353,7 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { * JDK-8346781. */ private void doLegacyJVMCIInitialization() { - if (has8346781()) { + if (!BeforeJDK8346781.VALUE) { return; } try { @@ -395,7 +392,7 @@ private void doLegacyJVMCIInitialization() { * Determines if the JDK runtime includes JDK-8346781. Without it, initialization of some JVMCI * static cache fields must be done explicitly by {@link LibGraalFeature}. */ - private static boolean has8346781() { + static boolean has8346781() { try { Services.class.getField("IS_BUILDING_NATIVE_IMAGE"); return false; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java index f9592f6090e3..3f4c9667995f 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java @@ -39,7 +39,7 @@ static final class Target_jdk_vm_ci_services_Services { // Checkstyle: stop @Alias // @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FromAlias, isFinal = true)// - @TargetElement(onlyWith = JDK21.class)// + @TargetElement(onlyWith = BeforeJDK8346781.class)// public static boolean IS_BUILDING_NATIVE_IMAGE = false; // Checkstyle: resume diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PluginReplacementNode.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PluginReplacementNode.java index 9df63c222b0b..61a103a9602b 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PluginReplacementNode.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PluginReplacementNode.java @@ -33,10 +33,14 @@ import jdk.graal.compiler.nodeinfo.NodeInfo; import jdk.graal.compiler.nodeinfo.NodeSize; import jdk.graal.compiler.nodeinfo.Verbosity; +import jdk.graal.compiler.nodes.graphbuilderconf.GeneratedInvocationPlugin; import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderContext; import jdk.graal.compiler.nodes.spi.Replacements; import jdk.graal.nativeimage.FoldNodePlugin; +/** + * Used to defer the execution of a {@link GeneratedInvocationPlugin} until libgraal runtime. + */ @NodeInfo(nameTemplate = "PluginReplacement/{p#pluginName}", cycles = NodeCycles.CYCLES_IGNORED, size = NodeSize.SIZE_IGNORED) public final class PluginReplacementNode extends FixedWithNextNode implements PluginReplacementInterface { public static final NodeClass TYPE = NodeClass.create(PluginReplacementNode.class); @@ -57,6 +61,9 @@ public boolean replace(GraphBuilderContext b, Replacements injection) { return function.replace(b, injection, stamp, args); } + /** + * Functional interface for generated code that executes the plugin at libgraal runtime. + */ public interface ReplacementFunction extends FoldNodePlugin { boolean replace(GraphBuilderContext b, Replacements injection, Stamp stamp, NodeInputList args); } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedFoldInvocationPlugin.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedFoldInvocationPlugin.java index 935c060bc9f4..9da302b0683c 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedFoldInvocationPlugin.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedFoldInvocationPlugin.java @@ -24,10 +24,14 @@ */ package jdk.graal.compiler.nodes.graphbuilderconf; +import jdk.graal.compiler.api.replacements.Fold; import jdk.graal.nativeimage.FoldNodePlugin; import java.lang.reflect.Type; +/** + * Abstract class for a plugin generated for a method annotated by {@link Fold}. + */ public abstract class GeneratedFoldInvocationPlugin extends GeneratedInvocationPlugin implements FoldNodePlugin { public GeneratedFoldInvocationPlugin(String name, Type... argumentTypes) { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java index fe9f38d41487..134d3e064d67 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java @@ -32,6 +32,7 @@ import java.lang.reflect.Type; import jdk.graal.compiler.api.replacements.Fold; +import jdk.graal.compiler.api.replacements.Fold.InjectedParameter; import jdk.graal.compiler.debug.GraalError; import jdk.graal.compiler.graph.Node.NodeIntrinsic; import jdk.graal.compiler.nodes.ValueNode; @@ -72,6 +73,12 @@ public String getSourceLocation() { throw new GraalError("could not find method named \"execute\" in " + c.getName()); } + /** + * Determines if the {@linkplain InjectedParameter} value in {@code arg} allows folding of a + * call to {@code foldAnnotatedMethod} in the compilation context represented by {@code b}. + * + * @return true if the folding being attempted by the caller can proceed + */ protected boolean checkInjectedArgument(GraphBuilderContext b, ValueNode arg, ResolvedJavaMethod foldAnnotatedMethod) { if (arg.isNullConstant()) { return true; @@ -87,8 +94,8 @@ protected boolean checkInjectedArgument(GraphBuilderContext b, ValueNode arg, Re } if (inImageBuildtimeCode()) { - // The use of this plugin in the plugin itself shouldn't be folded since that defeats - // the purpose of the fold. + // The use of this plugin in the plugin itself shouldn't be folded since that + // defeats the purpose of the fold. ResolvedJavaType foldNodeClass = b.getMetaAccess().lookupJavaType(FoldNodePlugin.class); if (foldNodeClass.isAssignableFrom(b.getMethod().getDeclaringClass())) { return false; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/spi/SnippetParameterInfo.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/spi/SnippetParameterInfo.java index a312f77d3852..d6d86e3bdb86 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/spi/SnippetParameterInfo.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/spi/SnippetParameterInfo.java @@ -149,10 +149,6 @@ private boolean initNames(ResolvedJavaMethod method, int parameterCount) { return true; } - public void clearNames() { - names = null; - } - public static BitSet getNonNullParameters(SnippetParameterInfo info) { BitSet nonNullParameters = new BitSet(info.getParameterCount()); for (int i = 0; i < info.getParameterCount(); i++) { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/nodes/IntrinsicMethodNodeInterface.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/nodes/IntrinsicMethodNodeInterface.java index 76f59ee9d2f3..6366ed5623c6 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/nodes/IntrinsicMethodNodeInterface.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/nodes/IntrinsicMethodNodeInterface.java @@ -36,7 +36,6 @@ import jdk.vm.ci.code.Architecture; import jdk.vm.ci.meta.Value; -import org.graalvm.nativeimage.ImageInfo; /** * Mixin for nodes that represent an entire custom assembly method. These nodes can either emit the @@ -69,13 +68,6 @@ default void generate(NodeLIRBuilderTool gen) { } } - if (ImageInfo.inImageBuildtimeCode() && !canBeEmitted(gen.getLIRGeneratorTool().target().arch)) { - // When building libgraal, we unconditionally compile all stubs, including those not - // supported. In such case, we will emit hlt instruction and let the invocation plugin - // ensure the stub is not reachable. - gen.getLIRGeneratorTool().emitHalt(); - return; - } emitIntrinsic(gen); } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/TruffleCompilerImpl.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/TruffleCompilerImpl.java index ee8fb43a1f9e..cbe7fa1fc63e 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/TruffleCompilerImpl.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/TruffleCompilerImpl.java @@ -39,6 +39,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ThreadFactory; import java.util.function.Consumer; import org.graalvm.collections.EconomicMap; @@ -471,6 +472,15 @@ public void compileAST( compileAST(new TruffleCompilationWrapper(getOrCreateCompilerOptions(compilable), getDebugOutputDirectory(), Collections.emptyMap(), compilable, task, compilationId, listener), debug); } + /** + * Gets a factory to use for creating the {@link CompilationWatchDog} watcher thread. + * + * @see CompilationWatchDog#watch + */ + protected ThreadFactory getWatchDogThreadFactory() { + return null; + } + /** * Compiles a Truffle AST. If compilation succeeds, the AST will have compiled code associated * with it that can be executed instead of interpreting the AST. @@ -760,7 +770,8 @@ protected Void handleException(Throwable t) { @SuppressWarnings("try") @Override protected Void performCompilation(DebugContext debug) { - try (CompilationWatchDog watch = CompilationWatchDog.watch(compilationId, debug.getOptions(), false, TruffleCompilerImpl.this)) { + ThreadFactory factory = getWatchDogThreadFactory(); + try (CompilationWatchDog watch = CompilationWatchDog.watch(compilationId, debug.getOptions(), false, TruffleCompilerImpl.this, factory)) { compileAST(this, debug); return null; } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/hotspot/HotSpotTruffleCompilerImpl.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/hotspot/HotSpotTruffleCompilerImpl.java index 6edf08da1e48..81db62ebc7f3 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/hotspot/HotSpotTruffleCompilerImpl.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/hotspot/HotSpotTruffleCompilerImpl.java @@ -33,9 +33,11 @@ import java.util.List; import java.util.ListIterator; import java.util.Map; +import java.util.concurrent.ThreadFactory; import java.util.function.Supplier; import jdk.graal.compiler.core.GraalCompiler; +import jdk.graal.compiler.hotspot.HotSpotGraalServiceThread; import jdk.graal.compiler.truffle.host.TruffleHostEnvironment.TruffleRuntimeScope; import org.graalvm.collections.EconomicMap; @@ -141,6 +143,11 @@ protected void parseGraalOptions(String[] options, EconomicMap, Obj OptionsParser.parseOptions(options, values, OptionsParser.getOptionsLoader()); } + @Override + protected ThreadFactory getWatchDogThreadFactory() { + return HotSpotGraalServiceThread::new; + } + public static HotSpotTruffleCompilerImpl create(final TruffleCompilerRuntime runtime, Supplier openCanCallTruffleRuntimeScope) { OptionValues options = HotSpotGraalOptionValues.defaultOptions(); /* diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/SubstrateGraalUtils.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/SubstrateGraalUtils.java index 84adac791e33..d5112144f8a9 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/SubstrateGraalUtils.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/SubstrateGraalUtils.java @@ -121,7 +121,7 @@ protected void parseRetryOptions(String[] options, EconomicMap, Obj @SuppressWarnings("try") @Override protected CompilationResult performCompilation(DebugContext debug) { - try (CompilationWatchDog watchdog = CompilationWatchDog.watch(compilationId, debug.getOptions(), false, COMPILATION_WATCH_DOG_EVENT_HANDLER)) { + try (CompilationWatchDog watchdog = CompilationWatchDog.watch(compilationId, debug.getOptions(), false, COMPILATION_WATCH_DOG_EVENT_HANDLER, null)) { StructuredGraph graph = TruffleRuntimeCompilationSupport.decodeGraph(debug, null, compilationId, method, null); return compileGraph(runtimeConfig, TruffleRuntimeCompilationSupport.getMatchingSuitesForGraph(graph), lirSuites, method, graph); } diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/runtimecompilation/GraalGraphObjectReplacer.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/runtimecompilation/GraalGraphObjectReplacer.java index bc795d467d92..d4ad7e4fd2bd 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/runtimecompilation/GraalGraphObjectReplacer.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/runtimecompilation/GraalGraphObjectReplacer.java @@ -166,8 +166,7 @@ public Object apply(Object source) { if (source instanceof MetaAccessProvider) { dest = sProviders.getMetaAccessProvider(); } else if (source instanceof JVMCIRuntime) { - // throw new UnsupportedFeatureException("JVMCIRuntime should not appear in the image: " - // + source); + throw new UnsupportedFeatureException("JVMCIRuntime should not appear in the image: " + source); } else if (source instanceof GraalHotSpotVMConfig) { throw new UnsupportedFeatureException("GraalHotSpotVMConfig should not appear in the image: " + source); } else if (source instanceof HotSpotBackendFactory factory) { From cc5d56144902bf6453b55f2a1079e3ad7fd3a848 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Sun, 5 Jan 2025 20:30:44 +0100 Subject: [PATCH 14/31] putting jargraal on the --upgrade-module-path now also needs graal-nativeimage.jar and nativebridge.jar --- truffle/mx.truffle/mx_truffle.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/truffle/mx.truffle/mx_truffle.py b/truffle/mx.truffle/mx_truffle.py index 876fca040e27..048697f03668 100644 --- a/truffle/mx.truffle/mx_truffle.py +++ b/truffle/mx.truffle/mx_truffle.py @@ -735,11 +735,15 @@ def _sl_jvm_comiler_on_upgrade_module_path_gate_tests(jdk): # Ignore tests for Truffle LTS gate using GraalVM as a base JDK mx.log(f'Ignoring SL JVM Optimized with Compiler on Upgrade Module Path on {jdk.home} because JDK is GraalVM') return - compiler = mx.distribution('compiler:GRAAL') + compiler_cp = os.pathsep.join((mx.distribution(name).classpath_repr() for name in ( + 'compiler:GRAAL', + 'compiler:GRAAL_NATIVEIMAGE', + 'sdk:NATIVEBRIDGE' + ))) vm_args = [ '-XX:+UnlockExperimentalVMOptions', '-XX:+EnableJVMCI', - f'--upgrade-module-path={compiler.classpath_repr()}', + f'--upgrade-module-path={compiler_cp}', ] def run_jvm_optimized(test_file): From a68973a4ccadc1a41043e218f89b710dcfeed2ba Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Mon, 6 Jan 2025 18:55:46 +0100 Subject: [PATCH 15/31] fixed @since tags --- .../src/jdk/graal/nativeimage/LibGraalLoader.java | 2 ++ .../src/jdk/graal/nativeimage/LibGraalRuntime.java | 13 +++++++------ .../jdk/graal/nativeimage/hosted/GlobalData.java | 2 ++ .../jdk/graal/nativeimage/hosted/package-info.java | 2 +- .../src/jdk/graal/nativeimage/package-info.java | 2 +- .../nativeimage/hosted/FieldValueTransformer.java | 4 ++-- 6 files changed, 15 insertions(+), 10 deletions(-) diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalLoader.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalLoader.java index 12a63aa5c054..45218e18c02c 100644 --- a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalLoader.java +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalLoader.java @@ -31,6 +31,8 @@ /** * The class loader used to load the Graal and JVMCI classes compiled into libgraal implements this * interface to provide extra information about the libgraal classes. + * + * @since 25 */ public interface LibGraalLoader { diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java index 2d69ce49f84c..1e6d5ed70535 100644 --- a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java @@ -35,7 +35,7 @@ /** * LibGraal specific extensions to {@link org.graalvm.nativeimage}. * - * @since 24.2 + * @since 25 */ public final class LibGraalRuntime { @@ -43,6 +43,12 @@ public final class LibGraalRuntime { * Prefix to be used when {@linkplain RuntimeSystemProperties#register registering} properties * describing the image configuration for libgraal. This is analogous to the configuration info * displayed by {@code -XshowSettings}. + * + * For example: + * + *

      +     * RuntimeSystemProperties.register(NATIVE_IMAGE_SETTING_KEY_PREFIX + "gc", "serial");
      +     * 
      */ public static String NATIVE_IMAGE_SETTING_KEY_PREFIX = "org.graalvm.nativeimage.setting."; @@ -51,8 +57,6 @@ public final class LibGraalRuntime { * executes pending cleaners. * * If automatic reference handling is enabled, this method is a no-op. - * - * @since 24.2 */ public static void processReferences() { ImageSingletons.lookup(LibGraalRuntimeSupport.class).processReferences(); @@ -65,8 +69,6 @@ public static void processReferences() { * @param suggestFullGC if a GC is performed, then suggests a full GC is done. This is true when * the caller believes the heap occupancy is close to the minimal set of live objects * for Graal (e.g. after a compilation). - * - * @since 24.2 */ public static void notifyLowMemoryPoint(boolean suggestFullGC) { ImageSingletons.lookup(LibGraalRuntimeSupport.class).notifyLowMemoryPoint(suggestFullGC); @@ -77,7 +79,6 @@ public static void notifyLowMemoryPoint(boolean suggestFullGC) { * {@code 2^64 - 1} isolates in the process. * * @return a non-zero value - * @since 24.2 */ public static long getIsolateID() { return ImageSingletons.lookup(LibGraalRuntimeSupport.class).getIsolateID(); diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/hosted/GlobalData.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/hosted/GlobalData.java index 3fd6c9d045c7..d35682392d25 100644 --- a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/hosted/GlobalData.java +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/hosted/GlobalData.java @@ -33,6 +33,8 @@ /** * Methods for creating initialized, off-heap data that is shared across all isolates in a process. + * + * @since 25 */ @Platforms(Platform.HOSTED_ONLY.class) public final class GlobalData { diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/hosted/package-info.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/hosted/package-info.java index f345ee5c7e58..c7f9506b3e17 100644 --- a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/hosted/package-info.java +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/hosted/package-info.java @@ -30,6 +30,6 @@ /** * Extensions to the GraalVM SDK Native Image API to customize building libgraal. * - * @since 24.2 + * @since 25 */ package jdk.graal.nativeimage.hosted; diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/package-info.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/package-info.java index f13c28e44cd5..c0f173932130 100644 --- a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/package-info.java +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/package-info.java @@ -30,6 +30,6 @@ /** * Extensions to the GraalVM SDK Native Image API to customize building libgraal. * - * @since 24.2 + * @since 25 */ package jdk.graal.nativeimage; diff --git a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/FieldValueTransformer.java b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/FieldValueTransformer.java index a05d2b3c59a6..0b2c7f503a5b 100644 --- a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/FieldValueTransformer.java +++ b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/FieldValueTransformer.java @@ -86,8 +86,8 @@ public interface FieldValueTransformer { /** * Returns true when the value for this custom computation is available. - * - * @since 24.2 + * + * @since 25 */ default boolean isAvailable() { return true; From 8e423eff0482bcf6cdca451aac5592a9efbf19e4 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Tue, 7 Jan 2025 13:39:53 +0100 Subject: [PATCH 16/31] moved LibGraalFeatureComponent out of jdk.graal.nativeimage and renamed to FeatureComponent --- .../core/common/FeatureComponent.java} | 13 ++++-- .../graal/compiler/core/common/Fields.java | 40 ++++++------------- .../jdk/graal/compiler/graph/NodeClass.java | 20 ++++++---- .../compiler/libgraal/LibGraalFeature.java | 32 ++++++++++++--- .../jdk.graal.nativeimage/snapshot.sigtest | 3 -- 5 files changed, 60 insertions(+), 48 deletions(-) rename compiler/src/{jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalFeatureComponent.java => jdk.graal.compiler/src/jdk/graal/compiler/core/common/FeatureComponent.java} (77%) diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalFeatureComponent.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/FeatureComponent.java similarity index 77% rename from compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalFeatureComponent.java rename to compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/FeatureComponent.java index a3561b91b974..45d74f420bfc 100644 --- a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalFeatureComponent.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/FeatureComponent.java @@ -22,14 +22,19 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.graal.nativeimage; +package jdk.graal.compiler.core.common; import org.graalvm.nativeimage.hosted.Feature; /** - * A subset of {@link Feature} interception points specific to building LibGraal. + * Implemented by classes that have logic specific to a {@link Feature}s. */ -public interface LibGraalFeatureComponent { +public interface FeatureComponent { - void duringAnalysis(Feature.DuringAnalysisAccess access); + /** + * Called during analysis of {@code feature}. + * + * @see Feature#duringAnalysis(Feature.DuringAnalysisAccess) + */ + void duringAnalysis(Feature feature, Feature.DuringAnalysisAccess access); } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/Fields.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/Fields.java index cc4edb45c51a..96b8c2369550 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/Fields.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/Fields.java @@ -27,21 +27,20 @@ import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import jdk.graal.compiler.debug.GraalError; -import jdk.graal.compiler.options.ExcludeFromJacocoGeneratedReport; -import jdk.graal.nativeimage.LibGraalFeatureComponent; +import jdk.graal.compiler.libgraal.LibGraalFeature; import jdk.internal.misc.Unsafe; +import org.graalvm.nativeimage.ImageInfo; import org.graalvm.nativeimage.hosted.Feature; /** * Describes fields in a class, primarily for access via {@link Unsafe}. */ -public class Fields implements LibGraalFeatureComponent { +public class Fields implements FeatureComponent { private static final Unsafe UNSAFE = Unsafe.getUnsafe(); private static final Fields EMPTY_FIELDS = new Fields(Collections.emptyList()); @@ -63,24 +62,6 @@ public class Fields implements LibGraalFeatureComponent { private final Class[] declaringClasses; - @ExcludeFromJacocoGeneratedReport("only called when building libgraal") - public static void setLibGraalFeatureComponents(Collection components) { - GraalError.guarantee(libGraalFeatureComponents == null, "already initialized"); - Fields.libGraalFeatureComponents = components; - } - - /** - * Registers {@code c} if in a context where a registry - * {@linkplain #setLibGraalFeatureComponents exists}. - */ - public static void addLibGraalFeatureComponents(LibGraalFeatureComponent c) { - if (libGraalFeatureComponents != null) { - libGraalFeatureComponents.add(c); - } - } - - private static Collection libGraalFeatureComponents; - @SuppressWarnings("this-escape") protected Fields(List fields) { Collections.sort(fields); @@ -96,8 +77,9 @@ protected Fields(List fields) { declaringClasses[index] = f.declaringClass; index++; } - if (libGraalFeatureComponents != null) { - libGraalFeatureComponents.add(this); + + if (ImageInfo.inImageBuildtimeCode() && LibGraalFeature.singleton() != null) { + LibGraalFeature.singleton().addFeatureComponent(this); } } @@ -120,10 +102,12 @@ public Map.Entry recomputeOffsetsAndIterationMask(Feature.BeforeCo } @Override - public void duringAnalysis(Feature.DuringAnalysisAccess access) { - for (int i = 0; i < offsets.length; i++) { - Field field = getField(i); - access.registerAsUnsafeAccessed(field); + public void duringAnalysis(Feature feature, Feature.DuringAnalysisAccess access) { + if (feature == LibGraalFeature.singleton()) { + for (int i = 0; i < offsets.length; i++) { + Field field = getField(i); + access.registerAsUnsafeAccessed(field); + } } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graph/NodeClass.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graph/NodeClass.java index 9e3a201c2160..dbc43ddc6f83 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graph/NodeClass.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graph/NodeClass.java @@ -47,8 +47,9 @@ import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; +import jdk.graal.compiler.libgraal.LibGraalFeature; import jdk.graal.compiler.serviceprovider.GraalServices; -import jdk.graal.nativeimage.LibGraalFeatureComponent; +import jdk.graal.compiler.core.common.FeatureComponent; import org.graalvm.collections.EconomicMap; import org.graalvm.collections.Equivalence; @@ -76,6 +77,7 @@ import jdk.graal.compiler.nodeinfo.NodeSize; import jdk.graal.compiler.nodeinfo.Verbosity; import jdk.internal.misc.Unsafe; +import org.graalvm.nativeimage.ImageInfo; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; import org.graalvm.nativeimage.hosted.Feature; @@ -88,7 +90,7 @@ *
    • The identifier for an {@link IterableNodeType} class.
    • * */ -public final class NodeClass extends FieldIntrospection implements LibGraalFeatureComponent { +public final class NodeClass extends FieldIntrospection implements FeatureComponent { private static final Unsafe UNSAFE = Unsafe.getUnsafe(); // Timers for creation of a NodeClass instance @@ -284,7 +286,9 @@ private NodeClass(Class clazz, NodeClass superNodeClass, FieldsSca } assert verifyMemoryEdgeInvariant(fs) : "Nodes participating in the memory graph should have at most 1 optional memory input."; - Fields.addLibGraalFeatureComponents(this); + if (ImageInfo.inImageBuildtimeCode() && LibGraalFeature.singleton() != null) { + LibGraalFeature.singleton().addFeatureComponent(this); + } // All NodeClass instances must be constructed at libgraal build time GraalError.guarantee(!GraalServices.isInLibgraal(), getClazz().getName()); @@ -402,10 +406,12 @@ public EnumSet getAllowedUsageTypes() { } @Override - public void duringAnalysis(Feature.DuringAnalysisAccess access) { - if (!Modifier.isAbstract(getClazz().getModifiers())) { - /* Support for NodeClass.allocateInstance. */ - access.registerAsUnsafeAllocated(getClazz()); + public void duringAnalysis(Feature feature, Feature.DuringAnalysisAccess access) { + if (feature == LibGraalFeature.singleton()) { + if (!Modifier.isAbstract(getClazz().getModifiers())) { + /* Support for NodeClass.allocateInstance. */ + access.registerAsUnsafeAllocated(getClazz()); + } } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java index aa4be4203717..4b4f04862511 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java @@ -72,7 +72,7 @@ import jdk.graal.compiler.options.OptionDescriptor; import jdk.graal.compiler.options.OptionKey; import jdk.graal.compiler.serviceprovider.GlobalAtomicLong; -import jdk.graal.nativeimage.LibGraalFeatureComponent; +import jdk.graal.compiler.core.common.FeatureComponent; import jdk.graal.nativeimage.LibGraalLoader; import jdk.graal.nativeimage.hosted.GlobalData; import jdk.vm.ci.hotspot.HotSpotModifiers; @@ -83,6 +83,24 @@ @Platforms(Platform.HOSTED_ONLY.class) public final class LibGraalFeature implements Feature { + private static LibGraalFeature singleton; + + public LibGraalFeature() { + synchronized (LibGraalFeature.class) { + GraalError.guarantee(singleton == null, "only a single " + LibGraalFeature.class.getName() + " instance should be created"); + singleton = this; + } + } + + /** + * @return the singleton {@link LibGraalFeature} instance if called within the context of the + * class loader used to load the code being compiled into the libgraal image, otherwise + * null + */ + public static LibGraalFeature singleton() { + return singleton; + } + public static final class IsEnabled implements BooleanSupplier { @Override public boolean getAsBoolean() { @@ -101,9 +119,13 @@ public boolean getAsBoolean() { final LibGraalLoader libgraalLoader = (LibGraalLoader) getClass().getClassLoader(); /** - * Set of {@link LibGraalFeatureComponent}s created during analysis. + * Set of {@link FeatureComponent}s created during analysis. */ - private final Set libGraalFeatureComponents = ConcurrentHashMap.newKeySet(); + private final Set libGraalFeatureComponents = ConcurrentHashMap.newKeySet(); + + public void addFeatureComponent(FeatureComponent fc) { + libGraalFeatureComponents.add(fc); + } @Override public void afterRegistration(AfterRegistrationAccess access) { @@ -331,8 +353,6 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { } } - Fields.setLibGraalFeatureComponents(libGraalFeatureComponents); - EconomicMap libgraalObjects = (EconomicMap) ObjectCopier.decode(configResult.encodedConfig(), libgraalLoader.getClassLoader()); EncodedSnippets encodedSnippets = (EncodedSnippets) libgraalObjects.get("encodedSnippets"); @@ -404,7 +424,7 @@ static boolean has8346781() { @Override public void duringAnalysis(DuringAnalysisAccess access) { for (var c : libGraalFeatureComponents) { - c.duringAnalysis(access); + c.duringAnalysis(this, access); } } diff --git a/compiler/src/jdk.graal.nativeimage/snapshot.sigtest b/compiler/src/jdk.graal.nativeimage/snapshot.sigtest index 7080d7130ba0..a9fdb44fec41 100644 --- a/compiler/src/jdk.graal.nativeimage/snapshot.sigtest +++ b/compiler/src/jdk.graal.nativeimage/snapshot.sigtest @@ -1,9 +1,6 @@ #Signature file v4.1 #Version -CLSS public abstract interface jdk.graal.nativeimage.LibGraalFeatureComponent -meth public abstract void duringAnalysis(org.graalvm.nativeimage.hosted.Feature$DuringAnalysisAccess) - CLSS public abstract interface jdk.graal.nativeimage.LibGraalLoader meth public abstract java.nio.file.Path getJavaHome() meth public abstract java.util.Set getServicesModules() From f754d7613710573957756ecba8facf9f1ff4f37a Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Tue, 7 Jan 2025 14:33:49 +0100 Subject: [PATCH 17/31] moved NATIVE_IMAGE_SETTING_KEY_PREFIX from LibGraalRuntime to LibGraalFeature --- .../hotspot/CompilerConfigurationFactory.java | 2 +- .../graal/compiler/libgraal/LibGraalFeature.java | 15 +++++++++++++++ .../jdk/graal/nativeimage/LibGraalRuntime.java | 14 -------------- .../genscavenge/graal/GenScavengeGCFeature.java | 4 ++-- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/CompilerConfigurationFactory.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/CompilerConfigurationFactory.java index 19aec283db9b..20877b77eb81 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/CompilerConfigurationFactory.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/CompilerConfigurationFactory.java @@ -25,7 +25,7 @@ package jdk.graal.compiler.hotspot; import static jdk.vm.ci.common.InitTimer.timer; -import static jdk.graal.nativeimage.LibGraalRuntime.NATIVE_IMAGE_SETTING_KEY_PREFIX; +import static jdk.graal.compiler.libgraal.LibGraalFeature.NATIVE_IMAGE_SETTING_KEY_PREFIX; import java.util.ArrayList; import java.util.Collections; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java index 4b4f04862511..b57b2aeb0590 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java @@ -76,6 +76,7 @@ import jdk.graal.nativeimage.LibGraalLoader; import jdk.graal.nativeimage.hosted.GlobalData; import jdk.vm.ci.hotspot.HotSpotModifiers; +import org.graalvm.nativeimage.hosted.RuntimeSystemProperties; /** * This feature builds the libgraal shared library (e.g., libjvmcicompiler.so on linux). @@ -83,6 +84,19 @@ @Platforms(Platform.HOSTED_ONLY.class) public final class LibGraalFeature implements Feature { + /** + * Prefix to be used when {@linkplain RuntimeSystemProperties#register registering} properties + * describing the image configuration for libgraal. This is analogous to the configuration info + * displayed by {@code -XshowSettings}. + * + * For example: + * + *
      +     * RuntimeSystemProperties.register(NATIVE_IMAGE_SETTING_KEY_PREFIX + "gc", "serial");
      +     * 
      + */ + public static final String NATIVE_IMAGE_SETTING_KEY_PREFIX = "org.graalvm.nativeimage.setting."; + private static LibGraalFeature singleton; public LibGraalFeature() { @@ -98,6 +112,7 @@ public LibGraalFeature() { * null */ public static LibGraalFeature singleton() { + // Cannot use ImageSingletons here as it is not initialized early enough. return singleton; } diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java index 1e6d5ed70535..61f28fc32028 100644 --- a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java @@ -30,7 +30,6 @@ import org.graalvm.nativeimage.ImageSingletons; import jdk.graal.nativeimage.impl.LibGraalRuntimeSupport; -import org.graalvm.nativeimage.hosted.RuntimeSystemProperties; /** * LibGraal specific extensions to {@link org.graalvm.nativeimage}. @@ -39,19 +38,6 @@ */ public final class LibGraalRuntime { - /** - * Prefix to be used when {@linkplain RuntimeSystemProperties#register registering} properties - * describing the image configuration for libgraal. This is analogous to the configuration info - * displayed by {@code -XshowSettings}. - * - * For example: - * - *
      -     * RuntimeSystemProperties.register(NATIVE_IMAGE_SETTING_KEY_PREFIX + "gc", "serial");
      -     * 
      - */ - public static String NATIVE_IMAGE_SETTING_KEY_PREFIX = "org.graalvm.nativeimage.setting."; - /** * Enqueues pending {@link Reference}s into their corresponding {@link ReferenceQueue}s and * executes pending cleaners. diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/GenScavengeGCFeature.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/GenScavengeGCFeature.java index c7e58359f57e..0e56fc9dbac3 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/GenScavengeGCFeature.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/graal/GenScavengeGCFeature.java @@ -28,7 +28,7 @@ import java.util.List; import java.util.Map; -import jdk.graal.nativeimage.LibGraalRuntime; +import jdk.graal.compiler.libgraal.LibGraalFeature; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.Feature; @@ -131,7 +131,7 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { } String gcName = Heap.getHeap().getGC().getName(); - RuntimeSystemProperties.register(LibGraalRuntime.NATIVE_IMAGE_SETTING_KEY_PREFIX + "gc", gcName); + RuntimeSystemProperties.register(LibGraalFeature.NATIVE_IMAGE_SETTING_KEY_PREFIX + "gc", gcName); // Needed for the barrier set. access.registerAsUsed(Object[].class); From b9c2f4a7c0dbc0e96b1d61e99a654e67ac0f151a Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Wed, 8 Jan 2025 10:47:04 +0100 Subject: [PATCH 18/31] moved LibGraalFeatureComponent out of jdk.graal.nativeimage and renamed to FeatureComponent ++ --- .../src/jdk/graal/compiler/libgraal/LibGraalFeature.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java index b57b2aeb0590..565c5b58480c 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java @@ -101,7 +101,7 @@ public final class LibGraalFeature implements Feature { public LibGraalFeature() { synchronized (LibGraalFeature.class) { - GraalError.guarantee(singleton == null, "only a single " + LibGraalFeature.class.getName() + " instance should be created"); + GraalError.guarantee(singleton == null, "only a single %s instance should be created", LibGraalFeature.class.getName()); singleton = this; } } From 97af33c2a3b59948801a722f930a8d4172303002 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Wed, 8 Jan 2025 16:11:17 +0100 Subject: [PATCH 19/31] reduce and better document jdk.graal.nativeimage API --- .../loader/HostedLibGraalClassLoader.java | 5 ---- .../libgraal/loader/LibGraalClassLoader.java | 6 +++++ .../graal/compiler/libgraal/GetJNIConfig.java | 3 +-- .../compiler/libgraal/LibGraalFeature.java | 17 ++++---------- .../serviceprovider/GraalServices.java | 4 ++-- .../jdk.graal.nativeimage/snapshot.sigtest | 2 -- .../jdk/graal/nativeimage/LibGraalLoader.java | 23 ++++++------------- .../graal/nativeimage/LibGraalRuntime.java | 8 +++++++ .../hosted/FieldValueTransformer.java | 2 +- .../oracle/svm/hosted/ClassLoaderFeature.java | 2 +- .../hosted/NativeImageClassLoaderSupport.java | 6 ++--- .../ClassInitializationSupport.java | 2 +- .../svm/hosted/meta/UniverseBuilder.java | 1 - 13 files changed, 34 insertions(+), 47 deletions(-) diff --git a/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/HostedLibGraalClassLoader.java b/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/HostedLibGraalClassLoader.java index e2ee2524aa29..479b0bd64569 100644 --- a/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/HostedLibGraalClassLoader.java +++ b/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/HostedLibGraalClassLoader.java @@ -322,11 +322,6 @@ public String getContentType() { } } - @Override - public ClassLoader getClassLoader() { - return this; - } - @Override public ClassLoader getRuntimeClassLoader() { return LibGraalClassLoader.singleton; diff --git a/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/LibGraalClassLoader.java b/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/LibGraalClassLoader.java index 1c34e1d3d0ff..90df8b485bbe 100644 --- a/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/LibGraalClassLoader.java +++ b/compiler/src/jdk.graal.compiler.libgraal.loader/src/jdk/graal/compiler/libgraal/loader/LibGraalClassLoader.java @@ -24,6 +24,12 @@ */ package jdk.graal.compiler.libgraal.loader; +import org.graalvm.nativeimage.hosted.Feature.DuringSetupAccess; + +/** + * The image runtime class loader that {@linkplain DuringSetupAccess#registerObjectReplacer + * replaces} the build-time instance of {@link HostedLibGraalClassLoader}. + */ public final class LibGraalClassLoader extends ClassLoader { static final String LOADER_NAME = "LibGraalClassLoader"; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetJNIConfig.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetJNIConfig.java index 5deebf2c4435..6022ab0722ea 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetJNIConfig.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetJNIConfig.java @@ -95,8 +95,7 @@ private GetJNIConfig(ClassLoader loader) { } String nl = System.lineSeparator(); - String out = new BufferedReader(new InputStreamReader(p.getInputStream())) - .lines().collect(Collectors.joining(nl)); + String out = new BufferedReader(new InputStreamReader(p.getInputStream())).lines().collect(Collectors.joining(nl)); int exitValue; try { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java index 565c5b58480c..313198c7c6a0 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java @@ -120,12 +120,7 @@ public static final class IsEnabled implements BooleanSupplier { @Override public boolean getAsBoolean() { Class clazz = LibGraalFeature.class; - if (ImageSingletons.contains(clazz)) { - GraalError.guarantee("LibGraalClassLoader".equals(IsEnabled.class.getClassLoader().getName()), - "Only ever return true when LibGraalFeature got loaded by HostedLibGraalClassLoader"); - return true; - } - return false; + return ImageSingletons.contains(clazz); } } @@ -181,13 +176,9 @@ static Module getBootModule(String moduleName) { @Override public void duringSetup(DuringSetupAccess access) { - ClassLoader runtimeLoader = libgraalLoader.getRuntimeClassLoader(); - ClassLoader cl = libgraalLoader.getClassLoader(); - access.registerObjectReplacer(obj -> obj == cl ? runtimeLoader : obj); - optionCollector = new OptionCollector(); access.registerObjectReachabilityHandler(optionCollector::accept, OptionKey.class); - GetJNIConfig.register(cl); + GetJNIConfig.register((ClassLoader) libgraalLoader); } private OptionCollector optionCollector; @@ -368,7 +359,7 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { } } - EconomicMap libgraalObjects = (EconomicMap) ObjectCopier.decode(configResult.encodedConfig(), libgraalLoader.getClassLoader()); + EconomicMap libgraalObjects = (EconomicMap) ObjectCopier.decode(configResult.encodedConfig(), (ClassLoader) libgraalLoader); EncodedSnippets encodedSnippets = (EncodedSnippets) libgraalObjects.get("encodedSnippets"); // Mark all the Node classes as allocated so they are available during graph decoding. @@ -401,7 +392,7 @@ private void doLegacyJVMCIInitialization() { default -> throw new GraalError("Unknown or unsupported arch: %s", rawArch); }; - ClassLoader cl = libgraalLoader.getClassLoader(); + ClassLoader cl = (ClassLoader) libgraalLoader; Field cachedHotSpotJVMCIBackendFactoriesField = ObjectCopier.getField(HotSpotJVMCIRuntime.class, "cachedHotSpotJVMCIBackendFactories"); GraalError.guarantee(cachedHotSpotJVMCIBackendFactoriesField.get(null) == null, "Expect cachedHotSpotJVMCIBackendFactories to be null"); ServiceLoader load = ServiceLoader.load(HotSpotJVMCIBackendFactory.class, cl); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java index 9c110b56d5fb..b7fcb05b61c9 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java @@ -120,7 +120,7 @@ private static void addProviders(String arch, Class service) { Map modules = libgraalLoader.getModuleMap(); String arch = getJVMCIArch(); modules.entrySet().stream()// - .filter(e -> libgraalServicesModules.contains(e.getValue())) + .filter(e -> libgraalServicesModules.contains(e.getValue()))// .map(Map.Entry::getKey)// .map(GraalServices::loadClassOrNull)// .filter(c -> c != null && c.getAnnotation(LibGraalService.class) != null)// @@ -153,7 +153,7 @@ public static Iterable load(Class service) { /** * An escape hatch for calling {@link System#getProperties()} without falling afoul of * {@code VerifySystemPropertyUsage}. - * + * * @param justification explains why {@link #getSavedProperties()} cannot be used */ public static Properties getSystemProperties(String justification) { diff --git a/compiler/src/jdk.graal.nativeimage/snapshot.sigtest b/compiler/src/jdk.graal.nativeimage/snapshot.sigtest index a9fdb44fec41..b6a8776204af 100644 --- a/compiler/src/jdk.graal.nativeimage/snapshot.sigtest +++ b/compiler/src/jdk.graal.nativeimage/snapshot.sigtest @@ -6,8 +6,6 @@ meth public abstract java.nio.file.Path getJavaHome() meth public abstract java.util.Set getServicesModules() meth public abstract java.lang.ClassLoader getRuntimeClassLoader() meth public abstract java.util.Map getModuleMap() -meth public abstract java.lang.ClassLoader getClassLoader() -meth public java.util.Set getAllClassNames() CLSS public final jdk.graal.nativeimage.LibGraalRuntime meth public static long getIsolateID() diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalLoader.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalLoader.java index 45218e18c02c..28a9735b0998 100644 --- a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalLoader.java +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalLoader.java @@ -43,19 +43,17 @@ public interface LibGraalLoader { Path getJavaHome(); /** - * @return ClassLoader that implements this interface. - */ - ClassLoader getClassLoader(); - - /** - * @return loader that should be seen at image-runtime if a class was loaded at image-buildtime - * by {@link #getClassLoader()} + * Gets the ClassLoader that should be seen at image runtime if a class was loaded at image + * build-time by this loader. */ ClassLoader getRuntimeClassLoader(); /** - * Gets an unmodifiable map from the {@linkplain Class#forName(String) name} of a class to the - * name of its enclosing module. + * Gets a map from the {@linkplain Class#forName(String) name} of a class to the name of its + * enclosing module. There is one entry in the map for each class available for loading by this + * loader. + * + * @return an unmodifiable map */ Map getModuleMap(); @@ -64,11 +62,4 @@ public interface LibGraalLoader { * {@code LibGraalService}. */ Set getServicesModules(); - - /** - * Get unmodifiable set of fully qualified names of all classes this loader can load. - */ - default Set getAllClassNames() { - return getModuleMap().keySet(); - } } diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java index 61f28fc32028..435a53be6018 100644 --- a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalRuntime.java @@ -70,6 +70,14 @@ public static long getIsolateID() { return ImageSingletons.lookup(LibGraalRuntimeSupport.class).getIsolateID(); } + /** + * Called to signal a fatal, non-recoverable error. This method does not return or throw an + * exception. A typical implementation will delegate to an OS function that kills the process. + * In the context of libgraal, it will call the HotSpot fatal crash routine that produces an + * hs-err crash log. + * + * @param message a description of the error condition + */ public static void fatalError(String message) { ImageSingletons.lookup(LibGraalRuntimeSupport.class).fatalError(message); } diff --git a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/FieldValueTransformer.java b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/FieldValueTransformer.java index 0b2c7f503a5b..3a9f18bbb0a7 100644 --- a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/FieldValueTransformer.java +++ b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/FieldValueTransformer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ClassLoaderFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ClassLoaderFeature.java index e2c786004a52..64ade4c70f2e 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ClassLoaderFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ClassLoaderFeature.java @@ -123,7 +123,7 @@ public void duringSetup(DuringSetupAccess access) { if (ImageLayerBuildingSupport.firstImageBuild()) { LibGraalLoader libGraalLoader = ((DuringSetupAccessImpl) access).imageClassLoader.classLoaderSupport.getLibGraalLoader(); if (libGraalLoader != null) { - ClassLoader libGraalClassLoader = libGraalLoader.getClassLoader(); + ClassLoader libGraalClassLoader = (ClassLoader) libGraalLoader; ClassForNameSupport.singleton().setLibGraalLoader(libGraalClassLoader); ClassLoader runtimeLibGraalClassLoader = libGraalLoader.getRuntimeClassLoader(); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageClassLoaderSupport.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageClassLoaderSupport.java index 91bbd23df3b3..f3489ac0f83e 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageClassLoaderSupport.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageClassLoaderSupport.java @@ -274,9 +274,9 @@ public void loadAllClasses(ForkJoinPool executor, ImageClassLoader imageClassLoa LibGraalLoader loader = getLibGraalLoader(); if (loader != null) { /* If we have a LibGraalLoader, register its classes to the image builder */ - for (String fqn : loader.getAllClassNames()) { + for (String fqn : loader.getModuleMap().keySet()) { try { - var clazz = loader.getClassLoader().loadClass(fqn); + var clazz = ((ClassLoader) loader).loadClass(fqn); imageClassLoader.handleClass(clazz); } catch (ClassNotFoundException e) { throw GraalError.shouldNotReachHere(e, loader + " could not load class " + fqn); @@ -580,7 +580,7 @@ public void setupLibGraalClassLoader() { throw VMError.shouldNotReachHere("Class named by " + nameOption + " does not implement " + LibGraalLoader.class + '.'); } libGraalLoader = Optional.of((LibGraalLoader) ReflectionUtil.newInstance(loaderClass)); - classLoaders = List.of(libGraalLoader.get().getClassLoader(), getClassLoader()); + classLoaders = List.of((ClassLoader) libGraalLoader.get(), getClassLoader()); } catch (ClassNotFoundException e) { throw VMError.shouldNotReachHere("Class named by " + nameOption + " could not be found.", e); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationSupport.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationSupport.java index d13e008a27a4..f6991a0e8ff5 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationSupport.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationSupport.java @@ -194,7 +194,7 @@ InitKind ensureClassInitialized(Class clazz, boolean allowErrors) { Thread thread = Thread.currentThread(); ClassLoader restoreCCL = null; ClassLoader clazzLoader = clazz.getClassLoader(); - if (libGraalLoader != null && libGraalLoader.getClassLoader() == clazzLoader) { + if (libGraalLoader != null && (ClassLoader) libGraalLoader == clazzLoader) { // Graal and JVMCI make use of ServiceLoader which uses the // context class loader so it needs to be the libgraal loader. restoreCCL = thread.getContextClassLoader(); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/UniverseBuilder.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/UniverseBuilder.java index ed18a7a53898..f6ff1e7daed7 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/UniverseBuilder.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/UniverseBuilder.java @@ -107,7 +107,6 @@ import jdk.graal.compiler.core.common.NumUtil; import jdk.graal.compiler.debug.DebugContext; import jdk.graal.compiler.debug.Indent; -import jdk.graal.compiler.serviceprovider.GraalServices; import jdk.internal.vm.annotation.Contended; import jdk.vm.ci.meta.ConstantPool; import jdk.vm.ci.meta.ExceptionHandler; From 9793c0dc984830e3865e7bcdee9e0979097df609 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Wed, 8 Jan 2025 16:16:56 +0100 Subject: [PATCH 20/31] added missing headers --- .../LibGraalTruffleScopeEntryPoints.java | 24 +++++++++++++++++++ .../jdk/graal/nativeimage/FoldNodePlugin.java | 24 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleScopeEntryPoints.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleScopeEntryPoints.java index 8070b3ecc542..59c7add29c46 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleScopeEntryPoints.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleScopeEntryPoints.java @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2024, 2025, 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 jdk.graal.compiler.libgraal.truffle; import org.graalvm.nativeimage.Isolate; diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/FoldNodePlugin.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/FoldNodePlugin.java index 5c2db80ee5e8..dbdfd17e9647 100644 --- a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/FoldNodePlugin.java +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/FoldNodePlugin.java @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2025, 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 jdk.graal.nativeimage; /** From 7542c2f29eb22120a2ca600ee055fa34dd45f9aa Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Thu, 9 Jan 2025 12:10:20 +0100 Subject: [PATCH 21/31] added exception for importing libgraal into NodeClass and Fields --- compiler/mx.compiler/mx_compiler.py | 7 ++++++- truffle/mx.truffle/mx_truffle.py | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/compiler/mx.compiler/mx_compiler.py b/compiler/mx.compiler/mx_compiler.py index 982852a0e74b..4dc72abdb751 100644 --- a/compiler/mx.compiler/mx_compiler.py +++ b/compiler/mx.compiler/mx_compiler.py @@ -503,7 +503,12 @@ def _check_forbidden_imports(projects, package_substrings, exceptions=None): def compiler_gate_runner(suites, unit_test_runs, bootstrap_tests, tasks, extraVMarguments=None, extraUnitTestArguments=None): with Task('CheckForbiddenImports:Compiler', tasks, tags=['style']) as t: # Ensure HotSpot-independent compiler classes do not import HotSpot-specific classes - if t: _check_forbidden_imports([mx.project('jdk.graal.compiler')], ('hotspot', 'libgraal')) + if t: + exceptions = { + 'Fields.java': 'need to register libgraal feature components', + 'NodeClass.java': 'need to register libgraal feature components' + } + _check_forbidden_imports([mx.project('jdk.graal.compiler')], ('hotspot', 'libgraal'), exceptions) with Task('JDK_java_base_test', tasks, tags=['javabasetest'], report=True) as t: if t: java_base_unittest(_remove_empty_entries(extraVMarguments) + []) diff --git a/truffle/mx.truffle/mx_truffle.py b/truffle/mx.truffle/mx_truffle.py index 048697f03668..76485b27bb29 100644 --- a/truffle/mx.truffle/mx_truffle.py +++ b/truffle/mx.truffle/mx_truffle.py @@ -680,7 +680,7 @@ def sl_jvm_gate_tests(): _sl_jvm_gate_tests(mx.get_jdk(tag='default'), force_cp=False, supports_optimization=False) _sl_jvm_gate_tests(mx.get_jdk(tag='default'), force_cp=True, supports_optimization=False) - _sl_jvm_comiler_on_upgrade_module_path_gate_tests(mx.get_jdk(tag='default')) + _sl_jvm_compiler_on_upgrade_module_path_gate_tests(mx.get_jdk(tag='default')) def _sl_jvm_gate_tests(jdk, force_cp=False, supports_optimization=True): @@ -730,7 +730,7 @@ def run_jvm_no_enterprise_jvmci_disabled(test_file): _run_sl_tests(run_jvm_no_enterprise_jvmci_disabled) -def _sl_jvm_comiler_on_upgrade_module_path_gate_tests(jdk): +def _sl_jvm_compiler_on_upgrade_module_path_gate_tests(jdk): if mx_sdk.GraalVMJDKConfig.is_graalvm(jdk.home) or mx_sdk.GraalVMJDKConfig.is_libgraal_jdk(jdk.home): # Ignore tests for Truffle LTS gate using GraalVM as a base JDK mx.log(f'Ignoring SL JVM Optimized with Compiler on Upgrade Module Path on {jdk.home} because JDK is GraalVM') From 0a42666c29ad1bd81d2ae6c129e3b9c100cb5118 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Thu, 9 Jan 2025 16:47:17 +0100 Subject: [PATCH 22/31] added CHANGELOG entry --- compiler/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compiler/CHANGELOG.md b/compiler/CHANGELOG.md index b33a9cb1e440..3fbd1502e1c0 100644 --- a/compiler/CHANGELOG.md +++ b/compiler/CHANGELOG.md @@ -2,6 +2,12 @@ This changelog summarizes newly introduced optimizations and other compiler related changes. +## GraalVM for JDK 25 (Internal Version 25.0.0) +* (GR-60088): This PR adds the `jdk.graal.nativeimage` SDK module. With this module, all logic for building + libgraal has been moved into the core compiler. There is no dependency on Native Image internals. This + is required for Galahad CE where libgraal must be buildable from the Graal compiler sources in the OpenJDK + while using Native Image as an external tool. + ## GraalVM for JDK 24 (Internal Version 24.2.0) * (GR-57209): The default number of JVMCI threads is now the same as the number of C2 threads (`-XX:JVMCINativeLibraryThreadFraction=0.66`). This benefits the program warmup but could increase the maximum RSS. From 16d6066c8a51f37e08ad8e908bfb069e98e61dfe Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Thu, 9 Jan 2025 16:49:53 +0100 Subject: [PATCH 23/31] removed references to non-existing org.graalvm.libgraal package --- compiler/mx.compiler/suite.py | 1 - .../src/com/oracle/svm/configure/trace/AccessAdvisor.java | 1 - 2 files changed, 2 deletions(-) diff --git a/compiler/mx.compiler/suite.py b/compiler/mx.compiler/suite.py index c535387a507f..a60a1e7fd2f9 100644 --- a/compiler/mx.compiler/suite.py +++ b/compiler/mx.compiler/suite.py @@ -234,7 +234,6 @@ "jacoco" : "include", "jacocoExcludePackages" : [ "jdk.graal.compiler.test", - "org.graalvm.libgraal.jni", "jdk.graal.compiler.replacements", "jdk.graal.compiler.hotspot.test", "jdk.graal.compiler.replacements.test", diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/trace/AccessAdvisor.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/trace/AccessAdvisor.java index d947ba6b1b9b..d1610dcc9bf3 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/trace/AccessAdvisor.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/trace/AccessAdvisor.java @@ -148,7 +148,6 @@ private static void excludeInaccessiblePackages(HierarchyFilterNode rootNode) { rootNode.addOrGetChildren("com.oracle.truffle.**", ConfigurationFilter.Inclusion.Exclude); rootNode.addOrGetChildren("jdk.graal.compiler.**", ConfigurationFilter.Inclusion.Exclude); rootNode.addOrGetChildren("org.graalvm.compiler.**", ConfigurationFilter.Inclusion.Exclude); - rootNode.addOrGetChildren("org.graalvm.libgraal.**", ConfigurationFilter.Inclusion.Exclude); } public static HierarchyFilterNode copyBuiltinCallerFilterTree() { From 8de06d33e8d428e4b17ff6ea409aeec6e776cb53 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Thu, 9 Jan 2025 17:40:21 +0100 Subject: [PATCH 24/31] fixed checkstyle warnings and applied some ItelliJ tips --- .../core/common/FeatureComponent.java | 2 +- .../compiler/libgraal/BeforeJDK8346781.java | 2 +- .../compiler/libgraal/GetCompilerConfig.java | 2 +- .../graal/compiler/libgraal/GetJNIConfig.java | 33 ++++++++----------- .../graal/compiler/libgraal/JDKLatest.java | 2 +- .../libgraal/LibGraalEntryPoints.java | 4 +-- .../compiler/libgraal/LibGraalFeature.java | 2 +- .../libgraal/LibGraalNativeBridgeSupport.java | 2 +- .../libgraal/LibGraalSubstitutions.java | 2 +- .../truffle/HSTruffleCompilerRuntime.java | 2 +- .../truffle/LibGraalObjectHandleScope.java | 2 +- .../truffle/LibGraalTruffleEntryPoints.java | 2 +- .../truffle/TruffleFromLibGraalCalls.java | 2 +- .../TruffleFromLibGraalStartPoints.java | 2 +- .../GeneratedInvocationPlugin.java | 2 +- .../jdk/graal/nativeimage/FoldNodePlugin.java | 2 +- .../jdk/graal/nativeimage/LibGraalLoader.java | 2 +- .../graal/nativeimage/hosted/GlobalData.java | 2 +- 18 files changed, 31 insertions(+), 38 deletions(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/FeatureComponent.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/FeatureComponent.java index 45d74f420bfc..0a2ac2ae1310 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/FeatureComponent.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/FeatureComponent.java @@ -33,7 +33,7 @@ public interface FeatureComponent { /** * Called during analysis of {@code feature}. - * + * * @see Feature#duringAnalysis(Feature.DuringAnalysisAccess) */ void duringAnalysis(Feature feature, Feature.DuringAnalysisAccess access); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/BeforeJDK8346781.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/BeforeJDK8346781.java index 712913655a86..20a417c2431d 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/BeforeJDK8346781.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/BeforeJDK8346781.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetCompilerConfig.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetCompilerConfig.java index 76ef9b52fee3..1324f5f8a217 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetCompilerConfig.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetCompilerConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetJNIConfig.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetJNIConfig.java index 6022ab0722ea..81197af686a8 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetJNIConfig.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetJNIConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -109,8 +109,9 @@ private GetJNIConfig(ClassLoader loader) { try { lines = Files.readAllLines(configFilePath); } catch (IOException e) { + Path cfp = configFilePath; configFilePath = null; - throw new GraalError("Reading JNI config in %s dumped by command: %s%n%s", configFilePath, quotedCommand, out); + throw new GraalError("Reading JNI config in %s dumped by command: %s%n%s", cfp, quotedCommand, out); } } @@ -137,24 +138,15 @@ public void close() { public static Class forPrimitive(String name) { return switch (name) { - case "Z" -> boolean.class; - case "boolean" -> boolean.class; - case "C" -> char.class; - case "char" -> char.class; - case "F" -> float.class; - case "float" -> float.class; - case "D" -> double.class; - case "double" -> double.class; - case "B" -> byte.class; - case "byte" -> byte.class; - case "S" -> short.class; - case "short" -> short.class; - case "I" -> int.class; - case "int" -> int.class; - case "J" -> long.class; - case "long" -> long.class; - case "V" -> void.class; - case "void" -> void.class; + case "Z", "boolean" -> boolean.class; + case "C", "char" -> char.class; + case "F", "float" -> float.class; + case "D", "double" -> double.class; + case "B", "byte" -> byte.class; + case "S", "short" -> short.class; + case "I", "int" -> int.class; + case "J", "long" -> long.class; + case "V", "void" -> void.class; default -> null; }; } @@ -175,6 +167,7 @@ private Class findClass(String name) { try { return Class.forName(externalName, false, loader); } catch (ClassNotFoundException e3) { + // ignore } throw new GraalError(e, "Cannot find class %s during LibGraal JNIConfiguration registration", name); } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/JDKLatest.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/JDKLatest.java index c1fc04af3e67..cef8bbe6a07e 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/JDKLatest.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/JDKLatest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalEntryPoints.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalEntryPoints.java index 33a90ef043d6..bdf82f10205d 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalEntryPoints.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalEntryPoints.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -128,7 +128,7 @@ private static OptionValues decodeOptions(long address, int size, int hash) { * @param stackTraceAddress a native buffer in which a serialized stack trace can be returned. * The caller will only read from this buffer if this method returns 0. A returned * serialized stack trace is returned in this buffer with the following format: - * + * *
            *               struct {
            *                   int   length;
      diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java
      index 313198c7c6a0..eca869ab76f0 100644
      --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java
      +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 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
      diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalNativeBridgeSupport.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalNativeBridgeSupport.java
      index e06f4c085f2a..70bc289a54dd 100644
      --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalNativeBridgeSupport.java
      +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalNativeBridgeSupport.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 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
      diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java
      index 3f4c9667995f..a3296a3ec36e 100644
      --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java
      +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalSubstitutions.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 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
      diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilerRuntime.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilerRuntime.java
      index 81774682895a..33adf6247291 100644
      --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilerRuntime.java
      +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilerRuntime.java
      @@ -62,7 +62,7 @@ final class HSTruffleCompilerRuntime extends HSIndirectHandle implements Truffle
       
           private final ResolvedJavaType classLoaderDelegate;
       
      -    public HSTruffleCompilerRuntime(Object hsHandle, long runtimeClass) {
      +    HSTruffleCompilerRuntime(Object hsHandle, long runtimeClass) {
               super(hsHandle);
               this.classLoaderDelegate = HotSpotJVMCIRuntime.runtime().asResolvedJavaType(runtimeClass);
               if (this.classLoaderDelegate == null) {
      diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalObjectHandleScope.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalObjectHandleScope.java
      index bf7754171aa4..4f0d03adee62 100644
      --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalObjectHandleScope.java
      +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalObjectHandleScope.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 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
      diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleEntryPoints.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleEntryPoints.java
      index 454e83c61cfb..e62203ca048e 100644
      --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleEntryPoints.java
      +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleEntryPoints.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 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
      diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/TruffleFromLibGraalCalls.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/TruffleFromLibGraalCalls.java
      index 04e4c1484f67..f32440524246 100644
      --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/TruffleFromLibGraalCalls.java
      +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/TruffleFromLibGraalCalls.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2023, 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
      diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/TruffleFromLibGraalStartPoints.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/TruffleFromLibGraalStartPoints.java
      index 0c2890cf3b80..c74e3e1e48dd 100644
      --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/TruffleFromLibGraalStartPoints.java
      +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/TruffleFromLibGraalStartPoints.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 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
      diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java
      index 134d3e064d67..c5bb938b979c 100644
      --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java
      +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java
      @@ -76,7 +76,7 @@ public String getSourceLocation() {
           /**
            * Determines if the {@linkplain InjectedParameter} value in {@code arg} allows folding of a
            * call to {@code foldAnnotatedMethod} in the compilation context represented by {@code b}.
      -     * 
      +     *
            * @return true if the folding being attempted by the caller can proceed
            */
           protected boolean checkInjectedArgument(GraphBuilderContext b, ValueNode arg, ResolvedJavaMethod foldAnnotatedMethod) {
      diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/FoldNodePlugin.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/FoldNodePlugin.java
      index dbdfd17e9647..84f4cf24438d 100644
      --- a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/FoldNodePlugin.java
      +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/FoldNodePlugin.java
      @@ -27,7 +27,7 @@
       /**
        * A marker interface for generated classes that implement compile-time evaluation (i.e. folding) of
        * certain method calls where the folding must be deferred to libgraal runtime.
      - * 
      + *
        * @since 25
        */
       public interface FoldNodePlugin {
      diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalLoader.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalLoader.java
      index 28a9735b0998..a75d5753ce43 100644
      --- a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalLoader.java
      +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/LibGraalLoader.java
      @@ -31,7 +31,7 @@
       /**
        * The class loader used to load the Graal and JVMCI classes compiled into libgraal implements this
        * interface to provide extra information about the libgraal classes.
      - * 
      + *
        * @since 25
        */
       public interface LibGraalLoader {
      diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/hosted/GlobalData.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/hosted/GlobalData.java
      index d35682392d25..a83cdf980660 100644
      --- a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/hosted/GlobalData.java
      +++ b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/hosted/GlobalData.java
      @@ -33,7 +33,7 @@
       
       /**
        * Methods for creating initialized, off-heap data that is shared across all isolates in a process.
      - * 
      + *
        * @since 25
        */
       @Platforms(Platform.HOSTED_ONLY.class)
      
      From ab482b55e9ccf6a03126379bd947f9607ecd7cea Mon Sep 17 00:00:00 2001
      From: Doug Simon 
      Date: Thu, 9 Jan 2025 17:41:52 +0100
      Subject: [PATCH 25/31] removed unnecessary exporting of internal packages
      
      ---
       .../compiler/libgraal/GetCompilerConfig.java  |   2 +-
       .../graal/compiler/libgraal/GetJNIConfig.java |   3 -
       .../compiler/libgraal/LibGraalFeature.java    | 142 ++++-----
       .../graal/compiler/libgraal/LibGraalUtil.java | 278 ------------------
       .../truffle/HSTruffleCompilerRuntime.java     |   4 +-
       .../truffle/LibGraalTruffleEntryPoints.java   |   3 +-
       substratevm/mx.substratevm/mx_substratevm.py  |  32 +-
       7 files changed, 69 insertions(+), 395 deletions(-)
       delete mode 100644 compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalUtil.java
      
      diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetCompilerConfig.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetCompilerConfig.java
      index 1324f5f8a217..ede2b814f431 100644
      --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetCompilerConfig.java
      +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetCompilerConfig.java
      @@ -119,7 +119,7 @@ public static Result from(Path javaHome) {
                               // Required to use Modules class
                               "--add-exports=java.base/jdk.internal.module=jdk.graal.compiler",
                               addExports,
      -                        "-Djdk.vm.ci.services.aot=true",
      +                        "-Djdk.vm.ci.services.aot=true", // Remove after JDK-8346781
                               "-D%s=%s".formatted(ImageInfo.PROPERTY_IMAGE_CODE_KEY, ImageInfo.PROPERTY_IMAGE_CODE_VALUE_BUILDTIME)));
       
               for (var e : opens.entrySet()) {
      diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetJNIConfig.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetJNIConfig.java
      index 81197af686a8..7c36396663e0 100644
      --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetJNIConfig.java
      +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/GetJNIConfig.java
      @@ -197,9 +197,6 @@ private GraalError error(String format, Object... args) {
            */
           @SuppressWarnings("try")
           public static void register(ClassLoader loader) {
      -        // Export all JVMCI packages to this class
      -        LibGraalFeature.exportModulesToLibGraal("jdk.internal.vm.ci");
      -
               try (GetJNIConfig source = new GetJNIConfig(loader)) {
                   Map> classes = new HashMap<>();
                   for (String line : source.lines) {
      diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java
      index eca869ab76f0..9326776fde76 100644
      --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java
      +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java
      @@ -24,12 +24,8 @@
        */
       package jdk.graal.compiler.libgraal;
       
      -import static java.lang.invoke.MethodType.methodType;
      -
      -import java.lang.invoke.MethodHandle;
      -import java.lang.invoke.MethodHandles;
      +import java.lang.module.ModuleDescriptor;
       import java.lang.reflect.Field;
      -import java.lang.reflect.Method;
       import java.nio.file.Path;
       import java.util.ArrayList;
       import java.util.Collections;
      @@ -52,10 +48,10 @@
       import jdk.graal.compiler.serviceprovider.GraalServices;
       import jdk.graal.compiler.truffle.host.TruffleHostEnvironment;
       import jdk.graal.compiler.util.ObjectCopier;
      +import jdk.internal.module.Modules;
       import jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory;
       import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
       import jdk.vm.ci.services.JVMCIServiceLocator;
      -import jdk.vm.ci.services.Services;
       import org.graalvm.collections.EconomicMap;
       import org.graalvm.jniutils.NativeBridgeSupport;
       import org.graalvm.nativeimage.ImageSingletons;
      @@ -116,6 +112,35 @@ public static LibGraalFeature singleton() {
               return singleton;
           }
       
      +    /**
      +     * Looks up a class in the libgraal class loader.
      +     *
      +     * @throws Error if the lookup fails
      +     */
      +    public static Class lookupClass(String className) {
      +        try {
      +            return Class.forName(className, false, LibGraalFeature.class.getClassLoader());
      +        } catch (ClassNotFoundException ex) {
      +            throw new GraalError(ex);
      +        }
      +    }
      +
      +    /**
      +     * Looks up a field via reflection and makes it accessible for reading.
      +     *
      +     * @throws Error if the operation fails
      +     */
      +    public static Field lookupField(Class declaringClass, String fieldName) {
      +        try {
      +            Field result = declaringClass.getDeclaredField(fieldName);
      +            Modules.addOpensToAllUnnamed(declaringClass.getModule(), declaringClass.getPackageName());
      +            result.setAccessible(true);
      +            return result;
      +        } catch (ReflectiveOperationException ex) {
      +            throw new GraalError(ex);
      +        }
      +    }
      +
           public static final class IsEnabled implements BooleanSupplier {
               @Override
               public boolean getAsBoolean() {
      @@ -124,8 +149,6 @@ public boolean getAsBoolean() {
               }
           }
       
      -    final MethodHandles.Lookup mhl = MethodHandles.lookup();
      -
           final LibGraalLoader libgraalLoader = (LibGraalLoader) getClass().getClassLoader();
       
           /**
      @@ -139,41 +162,21 @@ public void addFeatureComponent(FeatureComponent fc) {
       
           @Override
           public void afterRegistration(AfterRegistrationAccess access) {
      -        // LibGraalEntryPoints uses a number of classes in org.graalvm.nativeimage.builder
      -        exportModulesToLibGraal("org.graalvm.nativeimage.builder");
      -
      -        // LibGraalFeature accesses a few Graal classes (see import statements above)
      -        exportModulesToLibGraal("jdk.graal.compiler");
      -
      -        // LibGraalTruffleToLibGraalEntryPoints access TruffleToLibGraal.Id
      -        exportModulesToLibGraal("org.graalvm.truffle.compiler");
      -
               ImageSingletons.add(NativeBridgeSupport.class, new LibGraalNativeBridgeSupport());
       
      -        // Guest JVMCI and Graal need access to some JDK internal packages
      -        String[] basePackages = {
      -                        "jdk.internal.misc",
      -                        "jdk.internal.util",
      -                        "jdk.internal.vm"};
      -        LibGraalUtil.accessPackagesToClass(LibGraalUtil.Access.EXPORT, null, false, "java.base", basePackages);
      -    }
      -
      -    static void exportModulesToLibGraal(String... moduleNames) {
      -        accessModulesToClass(LibGraalUtil.Access.EXPORT, LibGraalFeature.class, moduleNames);
      -    }
      -
      -    static void accessModulesToClass(LibGraalUtil.Access access, Class accessingClass, String... moduleNames) {
      -        for (String moduleName : moduleNames) {
      -            var module = getBootModule(moduleName);
      -            LibGraalUtil.accessPackagesToClass(access, accessingClass, false,
      -                            module.getName(), module.getPackages().toArray(String[]::new));
      +        // The qualified exports from java.base to jdk.internal.vm.ci
      +        // and jdk.graal.compiler need to be expressed as exports to
      +        // ALL-UNNAMED so that access is also possible when these classes
      +        // are loaded via the libgraal loader.
      +        Module javaBase = ModuleLayer.boot().findModule("java.base").orElseThrow();
      +        Set exports = javaBase.getDescriptor().exports();
      +        for (ModuleDescriptor.Exports e : exports) {
      +            if (e.targets().contains("jdk.internal.vm.ci") || e.targets().contains("jdk.graal.compiler")) {
      +                Modules.addExportsToAllUnnamed(javaBase, e.source());
      +            }
               }
           }
       
      -    static Module getBootModule(String moduleName) {
      -        return ModuleLayer.boot().findModule(moduleName).orElseThrow();
      -    }
      -
           @Override
           public void duringSetup(DuringSetupAccess access) {
               optionCollector = new OptionCollector();
      @@ -247,18 +250,12 @@ class FieldOffsetsTransformer implements FieldValueTransformer {
                */
               private final Map> replacements = new IdentityHashMap<>();
       
      -        final Class edgesClass;
      -        final Class fieldsClass;
               final Field fieldsOffsetsField;
               final Field edgesIterationMaskField;
      -        final Method recomputeOffsetsAndIterationMaskMethod;
       
               FieldOffsetsTransformer() {
      -            edgesClass = Edges.class;
      -            fieldsClass = Fields.class;
      -            fieldsOffsetsField = LibGraalUtil.lookupField(fieldsClass, "offsets");
      -            edgesIterationMaskField = LibGraalUtil.lookupField(edgesClass, "iterationMask");
      -            recomputeOffsetsAndIterationMaskMethod = LibGraalUtil.lookupMethod(fieldsClass, "recomputeOffsetsAndIterationMask", BeforeCompilationAccess.class);
      +            fieldsOffsetsField = lookupField(Fields.class, "offsets");
      +            edgesIterationMaskField = lookupField(Edges.class, "iterationMask");
               }
       
               void register(BeforeAnalysisAccess access) {
      @@ -286,13 +283,9 @@ private Map.Entry getReplacement(Object receiver) {
                   }
               }
       
      -        @SuppressWarnings("unchecked")
               private Map.Entry computeReplacement(Object receiver) {
      -            try {
      -                return (Map.Entry) recomputeOffsetsAndIterationMaskMethod.invoke(receiver, beforeCompilationAccess);
      -            } catch (Throwable e) {
      -                throw GraalError.shouldNotReachHere(e);
      -            }
      +            Fields fields = (Fields) receiver;
      +            return fields.recomputeOffsetsAndIterationMask(beforeCompilationAccess);
               }
           }
       
      @@ -300,24 +293,18 @@ private Map.Entry computeReplacement(Object receiver) {
            * Transforms {@code GlobalAtomicLong.addressSupplier} by replacing it with a {@link GlobalData}
            * backed address supplier.
            */
      -    class GlobalAtomicLongTransformer implements FieldValueTransformer {
      -        private MethodHandle globalAtomicLongGetInitialValue;
      +    static class GlobalAtomicLongTransformer implements FieldValueTransformer {
       
               void register(BeforeAnalysisAccess access) {
      -            Field addressSupplierField = LibGraalUtil.lookupField(GlobalAtomicLong.class, "addressSupplier");
      +            Field addressSupplierField = lookupField(GlobalAtomicLong.class, "addressSupplier");
                   access.registerFieldValueTransformer(addressSupplierField, this);
      -            try {
      -                globalAtomicLongGetInitialValue = mhl.findVirtual(GlobalAtomicLong.class, "getInitialValue", methodType(long.class));
      -            } catch (Throwable e) {
      -                GraalError.shouldNotReachHere(e);
      -            }
               }
       
               @Override
               public Object transform(Object receiver, Object originalValue) {
                   long initialValue;
                   try {
      -                initialValue = (long) globalAtomicLongGetInitialValue.invoke(receiver);
      +                initialValue = ((GlobalAtomicLong) receiver).getInitialValue();
                   } catch (Throwable e) {
                       throw GraalError.shouldNotReachHere(e);
                   }
      @@ -334,28 +321,29 @@ public void beforeAnalysis(BeforeAnalysisAccess access) {
       
               /* Contains static fields that depend on HotSpotJVMCIRuntime */
               RuntimeClassInitialization.initializeAtRunTime(HotSpotModifiers.class);
      -        RuntimeClassInitialization.initializeAtRunTime(LibGraalUtil.lookupClass("jdk.vm.ci.hotspot.HotSpotCompiledCodeStream"));
      -        RuntimeClassInitialization.initializeAtRunTime(LibGraalUtil.lookupClass("jdk.vm.ci.hotspot.HotSpotCompiledCodeStream$Tag"));
      +        RuntimeClassInitialization.initializeAtRunTime(lookupClass("jdk.vm.ci.hotspot.HotSpotCompiledCodeStream"));
      +        RuntimeClassInitialization.initializeAtRunTime(lookupClass("jdk.vm.ci.hotspot.HotSpotCompiledCodeStream$Tag"));
       
               /* Needed for runtime calls to BoxingSnippets.Templates.getCacheClass(JavaKind) */
               RuntimeReflection.registerAllDeclaredClasses(Character.class);
      -        RuntimeReflection.register(LibGraalUtil.lookupField(LibGraalUtil.lookupClass("java.lang.Character$CharacterCache"), "cache"));
      +        RuntimeReflection.register(lookupField(lookupClass("java.lang.Character$CharacterCache"), "cache"));
               RuntimeReflection.registerAllDeclaredClasses(Byte.class);
      -        RuntimeReflection.register(LibGraalUtil.lookupField(LibGraalUtil.lookupClass("java.lang.Byte$ByteCache"), "cache"));
      +        RuntimeReflection.register(lookupField(lookupClass("java.lang.Byte$ByteCache"), "cache"));
               RuntimeReflection.registerAllDeclaredClasses(Short.class);
      -        RuntimeReflection.register(LibGraalUtil.lookupField(LibGraalUtil.lookupClass("java.lang.Short$ShortCache"), "cache"));
      +        RuntimeReflection.register(lookupField(lookupClass("java.lang.Short$ShortCache"), "cache"));
               RuntimeReflection.registerAllDeclaredClasses(Integer.class);
      -        RuntimeReflection.register(LibGraalUtil.lookupField(LibGraalUtil.lookupClass("java.lang.Integer$IntegerCache"), "cache"));
      +        RuntimeReflection.register(lookupField(lookupClass("java.lang.Integer$IntegerCache"), "cache"));
               RuntimeReflection.registerAllDeclaredClasses(Long.class);
      -        RuntimeReflection.register(LibGraalUtil.lookupField(LibGraalUtil.lookupClass("java.lang.Long$LongCache"), "cache"));
      +        RuntimeReflection.register(lookupField(lookupClass("java.lang.Long$LongCache"), "cache"));
       
               doLegacyJVMCIInitialization();
       
               Path libGraalJavaHome = libgraalLoader.getJavaHome();
               GetCompilerConfig.Result configResult = GetCompilerConfig.from(libGraalJavaHome);
               for (var e : configResult.opens().entrySet()) {
      +            Module module = ModuleLayer.boot().findModule(e.getKey()).orElseThrow();
                   for (String source : e.getValue()) {
      -                LibGraalUtil.accessPackagesToClass(LibGraalUtil.Access.OPEN, getClass(), false, e.getKey(), source);
      +                Modules.addOpensToAllUnnamed(module, source);
                   }
               }
       
      @@ -385,8 +373,7 @@ private void doLegacyJVMCIInitialization() {
               try {
                   String rawArch = GraalServices.getSavedProperty("os.arch");
                   String arch = switch (rawArch) {
      -                case "x86_64" -> "AMD64";
      -                case "amd64" -> "AMD64";
      +                case "x86_64", "amd64" -> "AMD64";
                       case "aarch64" -> "aarch64";
                       case "riscv64" -> "riscv64";
                       default -> throw new GraalError("Unknown or unsupported arch: %s", rawArch);
      @@ -414,19 +401,6 @@ private void doLegacyJVMCIInitialization() {
               }
           }
       
      -    /**
      -     * Determines if the JDK runtime includes JDK-8346781. Without it, initialization of some JVMCI
      -     * static cache fields must be done explicitly by {@link LibGraalFeature}.
      -     */
      -    static boolean has8346781() {
      -        try {
      -            Services.class.getField("IS_BUILDING_NATIVE_IMAGE");
      -            return false;
      -        } catch (NoSuchFieldException e) {
      -            return true;
      -        }
      -    }
      -
           @Override
           public void duringAnalysis(DuringAnalysisAccess access) {
               for (var c : libGraalFeatureComponents) {
      diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalUtil.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalUtil.java
      deleted file mode 100644
      index 2dc6eef8cb35..000000000000
      --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalUtil.java
      +++ /dev/null
      @@ -1,278 +0,0 @@
      -/*
      - * Copyright (c) 2019, 2019, 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 jdk.graal.compiler.libgraal;
      -
      -import java.lang.reflect.Constructor;
      -import java.lang.reflect.Field;
      -import java.lang.reflect.Method;
      -import java.util.Locale;
      -import java.util.Objects;
      -import java.util.Optional;
      -import java.util.Set;
      -
      -import org.graalvm.nativeimage.Platform;
      -import org.graalvm.nativeimage.Platforms;
      -
      -import jdk.graal.compiler.debug.GraalError;
      -import jdk.internal.module.Modules;
      -
      -/**
      - * This is a copy of SVM internal classes such as {@code com.oracle.svm.util.ReflectionUtil} and
      - * {@code com.oracle.svm.util.ModuleSupport}.
      - */
      -public final class LibGraalUtil {
      -
      -    private LibGraalUtil() {
      -    }
      -
      -    //
      -    // com.oracle.svm.util.ClassUtil methods
      -    //
      -
      -    /**
      -     * Alternative to {@link Class#getSimpleName} that does not probe an enclosing class or method,
      -     * which can fail when they cannot be loaded.
      -     *
      -     * Note the differences to {@link Class#getName} and {@link Class#getSimpleName} (which might
      -     * actually be preferable):
      -     *
      -     * 
      -     * Class.getName()                              Class.getSimpleName()   ClassUtil.getUnqualifiedName()
      -     * ---------------------------------------------------------------------------------------------------
      -     * int                                          int                     int
      -     * java.lang.String                             String                  String
      -     * [Ljava.lang.String;                          String[]                String[]
      -     * java.util.HashMap$EntrySet                   EntrySet                HashMap$EntrySet
      -     * com.example.ClassWithAnonymousInnerClass$1   ""                      ClassWithAnonymousInnerClass$1
      -     * 
      - */ - public static String getUnqualifiedName(Class clazz) { - String name = clazz.getTypeName(); - return name.substring(name.lastIndexOf('.') + 1); // strip the package name - } - - // - // com.oracle.svm.util.ReflectionUtil methods - // - - /** - * Ensure that this class is allowed to call setAccessible for an element of the provided - * declaring class. - */ - private static void openModule(Class declaringClass) { - accessModuleByClass(Access.OPEN, LibGraalUtil.class, declaringClass); - } - - public static Class lookupClass(String className) { - return lookupClass(false, className); - } - - public static Class lookupClass(boolean optional, String className) { - return lookupClass(optional, className, LibGraalUtil.class.getClassLoader()); - } - - public static Class lookupClass(boolean optional, String className, ClassLoader loader) { - try { - return Class.forName(className, false, loader); - } catch (ClassNotFoundException ex) { - if (optional) { - return null; - } - throw new GraalError(ex); - } - } - - public static Method lookupMethod(Class declaringClass, String methodName, Class... parameterTypes) { - return lookupMethod(false, declaringClass, methodName, parameterTypes); - } - - public static Method lookupMethod(boolean optional, Class declaringClass, String methodName, Class... parameterTypes) { - try { - Method result = declaringClass.getDeclaredMethod(methodName, parameterTypes); - openModule(declaringClass); - result.setAccessible(true); - return result; - } catch (ReflectiveOperationException ex) { - if (optional) { - return null; - } - throw new GraalError(ex); - } - } - - public static Constructor lookupConstructor(Class declaringClass, Class... parameterTypes) { - return lookupConstructor(false, declaringClass, parameterTypes); - } - - public static Constructor lookupConstructor(boolean optional, Class declaringClass, Class... parameterTypes) { - try { - Constructor result = declaringClass.getDeclaredConstructor(parameterTypes); - openModule(declaringClass); - result.setAccessible(true); - return result; - } catch (ReflectiveOperationException ex) { - if (optional) { - return null; - } - throw new GraalError(ex); - } - } - - public static T newInstance(Class declaringClass) { - try { - return lookupConstructor(declaringClass).newInstance(); - } catch (ReflectiveOperationException ex) { - throw new GraalError(ex); - } - } - - public static Field lookupField(Class declaringClass, String fieldName) { - return lookupField(false, declaringClass, fieldName); - } - - private static final Method fieldGetDeclaredFields0 = lookupMethod(Class.class, "getDeclaredFields0", boolean.class); - - public static Field lookupField(boolean optional, Class declaringClass, String fieldName) { - try { - Field result = declaringClass.getDeclaredField(fieldName); - openModule(declaringClass); - result.setAccessible(true); - return result; - } catch (ReflectiveOperationException ex) { - /* Try to get hidden field */ - try { - Field[] allFields = (Field[]) fieldGetDeclaredFields0.invoke(declaringClass, false); - for (Field field : allFields) { - if (field.getName().equals(fieldName)) { - openModule(declaringClass); - field.setAccessible(true); - return field; - } - } - } catch (ReflectiveOperationException e) { - // ignore - } - if (optional) { - return null; - } - throw new GraalError(ex); - } - } - - @SuppressWarnings("unchecked") - public static T readField(Class declaringClass, String fieldName, Object receiver) { - try { - return (T) lookupField(declaringClass, fieldName).get(receiver); - } catch (ReflectiveOperationException ex) { - throw new GraalError(ex); - } - } - - // - // com.oracle.svm.util.ModuleSupport methods - // - - @Platforms(Platform.HOSTED_ONLY.class) - public enum Access { - OPEN { - @Override - void giveAccess(Module accessingModule, Module declaringModule, String packageName) { - if (accessingModule != null) { - if (declaringModule.isOpen(packageName, accessingModule)) { - return; - } - Modules.addOpens(declaringModule, packageName, accessingModule); - } else { - if (declaringModule.isOpen(packageName)) { - return; - } - Modules.addOpensToAllUnnamed(declaringModule, packageName); - } - } - }, - EXPORT { - @Override - void giveAccess(Module accessingModule, Module declaringModule, String packageName) { - if (accessingModule != null) { - if (declaringModule.isExported(packageName, accessingModule)) { - return; - } - Modules.addExports(declaringModule, packageName, accessingModule); - } else { - if (declaringModule.isExported(packageName)) { - return; - } - Modules.addExportsToAllUnnamed(declaringModule, packageName); - } - } - }; - - abstract void giveAccess(Module accessingModule, Module declaringModule, String packageName); - } - - @Platforms(Platform.HOSTED_ONLY.class) - public static void accessModuleByClass(Access access, Class accessingClass, Class declaringClass) { - accessModuleByClass(access, accessingClass, declaringClass.getModule(), declaringClass.getPackageName()); - } - - /** - * Open or export packages {@code packageNames} in the module named {@code moduleName} to module - * of given {@code accessingClass}. If {@code accessingClass} is null packages are opened or - * exported to ALL-UNNAMED. If no packages are given, all packages of the module are opened or - * exported. - */ - @Platforms(Platform.HOSTED_ONLY.class) - public static void accessPackagesToClass(Access access, Class accessingClass, boolean optional, String moduleName, String... packageNames) { - Objects.requireNonNull(moduleName); - Optional module = ModuleLayer.boot().findModule(moduleName); - if (module.isEmpty()) { - if (optional) { - return; - } - String accessor = accessingClass != null ? "class " + accessingClass.getTypeName() : "ALL-UNNAMED"; - String message = access.name().toLowerCase(Locale.ROOT) + " of packages from module " + moduleName + " to " + - accessor + " failed. No module named " + moduleName + " in boot layer."; - throw new GraalError(message); - } - Module declaringModule = module.get(); - Objects.requireNonNull(packageNames); - Set packages = packageNames.length > 0 ? Set.of(packageNames) : declaringModule.getPackages(); - for (String packageName : packages) { - accessModuleByClass(access, accessingClass, declaringModule, packageName); - } - } - - @Platforms(Platform.HOSTED_ONLY.class) - public static void accessModuleByClass(Access access, Class accessingClass, Module declaringModule, String packageName) { - Module namedAccessingModule = null; - if (accessingClass != null) { - Module accessingModule = accessingClass.getModule(); - if (accessingModule.isNamed()) { - namedAccessingModule = accessingModule; - } - } - access.giveAccess(namedAccessingModule, declaringModule, packageName); - } -} diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilerRuntime.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilerRuntime.java index 33adf6247291..98eb683f3174 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilerRuntime.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilerRuntime.java @@ -32,7 +32,7 @@ import com.oracle.truffle.compiler.TruffleCompilerRuntime; import jdk.graal.compiler.debug.GraalError; -import jdk.graal.compiler.libgraal.LibGraalUtil; +import jdk.graal.compiler.libgraal.LibGraalFeature; import jdk.graal.compiler.truffle.hotspot.HotSpotTruffleCompilationSupport; import jdk.graal.compiler.word.Word; import jdk.vm.ci.code.InstalledCode; @@ -58,7 +58,7 @@ final class HSTruffleCompilerRuntime extends HSIndirectHandle implements Truffle static final String COMPILER_VERSION = HotSpotTruffleCompilationSupport.readCompilerVersion(); // TranslatedException is package-private - private static final Class TRANSLATED_EXCEPTION = LibGraalUtil.lookupClass("jdk.internal.vm.TranslatedException"); + private static final Class TRANSLATED_EXCEPTION = LibGraalFeature.lookupClass("jdk.internal.vm.TranslatedException"); private final ResolvedJavaType classLoaderDelegate; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleEntryPoints.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleEntryPoints.java index e62203ca048e..4eeafde78472 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleEntryPoints.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleEntryPoints.java @@ -55,7 +55,6 @@ import jdk.graal.compiler.hotspot.HotSpotGraalServices; import jdk.graal.compiler.libgraal.LibGraalFeature; import jdk.graal.compiler.libgraal.LibGraalJNIMethodScope; -import jdk.graal.compiler.libgraal.LibGraalUtil; import jdk.graal.compiler.truffle.TruffleCompilerOptions; import jdk.graal.compiler.truffle.hotspot.HotSpotTruffleCompilationSupport; import jdk.graal.compiler.truffle.hotspot.HotSpotTruffleCompilerImpl; @@ -73,7 +72,7 @@ public class LibGraalTruffleEntryPoints { private static JNIMethodScope openScope(Enum id, JNIEnv env) { Objects.requireNonNull(id, "Id must be non null."); - String scopeName = LibGraalUtil.getUnqualifiedName(LibGraalTruffleEntryPoints.class) + "::" + id; + String scopeName = LibGraalTruffleEntryPoints.class.getSimpleName() + "::" + id; int offset = lastJavaPCOffset; if (offset == -1) { HotSpotVMConfigAccess configAccess = new HotSpotVMConfigAccess(HotSpotJVMCIRuntime.runtime().getConfigStore()); diff --git a/substratevm/mx.substratevm/mx_substratevm.py b/substratevm/mx.substratevm/mx_substratevm.py index 7de1354377fc..c77a6185a316 100644 --- a/substratevm/mx.substratevm/mx_substratevm.py +++ b/substratevm/mx.substratevm/mx_substratevm.py @@ -1493,34 +1493,15 @@ def prevent_build_path_in_libgraal(): return ['-H:NativeLinkerOption=-pdbaltpath:%_PDB%'] return [] -libgraal_features = [ - 'jdk.graal.compiler.libgraal.LibGraalFeature' -] - libgraal_build_args = [ - '--features=' + ','.join(libgraal_features), - - ## Pass via JVM args opening up of packages needed for image builder early on - '-J--add-exports=jdk.graal.compiler/jdk.graal.compiler.hotspot=ALL-UNNAMED', - '-J--add-exports=jdk.graal.compiler/jdk.graal.compiler.hotspot.libgraal=ALL-UNNAMED', - '-J--add-exports=jdk.graal.compiler/jdk.graal.compiler.options=ALL-UNNAMED', - '-J--add-exports=jdk.graal.compiler/jdk.graal.compiler.truffle=ALL-UNNAMED', - '-J--add-exports=jdk.graal.compiler/jdk.graal.compiler.truffle.hotspot=ALL-UNNAMED', - '-J--add-exports=org.graalvm.truffle.compiler/com.oracle.truffle.compiler.hotspot.libgraal=ALL-UNNAMED', - '-J--add-exports=org.graalvm.truffle.compiler/com.oracle.truffle.compiler.hotspot=ALL-UNNAMED', - '-J--add-exports=org.graalvm.truffle.compiler/com.oracle.truffle.compiler=ALL-UNNAMED', - '-J--add-exports=org.graalvm.nativeimage/com.oracle.svm.core.annotate=ALL-UNNAMED', - '-J--add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.option=ALL-UNNAMED', + '--features=jdk.graal.compiler.libgraal.LibGraalFeature', + + # Need jdk.internal.module.Modules to do exporting '-J--add-exports=java.base/jdk.internal.module=ALL-UNNAMED', - '-J--add-exports=org.graalvm.word/org.graalvm.word.impl=ALL-UNNAMED', - ## Packages used after option-processing can be opened by the builder (`-J`-prefix not needed) - '--add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.feature=ALL-UNNAMED', - # Make jdk.internal.module.Modules accessible to do the remaining opening-up in LibGraalFeature constructor - '--add-exports=java.base/jdk.internal.module=ALL-UNNAMED', - # TruffleLibGraalJVMCIServiceLocator needs access to JVMCIServiceLocator - '--add-exports=jdk.internal.vm.ci/jdk.vm.ci.services=ALL-UNNAMED', - '--initialize-at-build-time=jdk.graal.compiler,org.graalvm.libgraal,com.oracle.truffle', + # This is the truffle:TRUFFLE_COMPILER dependency that defines + # the Truffle compiler API. + '--initialize-at-build-time=com.oracle.truffle.compiler', '-H:+ReportExceptionStackTraces', @@ -1538,6 +1519,7 @@ def prevent_build_path_in_libgraal(): '-H:InitialCollectionPolicy=LibGraal', # Needed for initializing jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE. + # Remove after JDK-8346781. '-Djdk.vm.ci.services.aot=true', # These 2 arguments provide walkable call stacks for a crash in libgraal. From bbe988046783affbacd2b1b9e4e7f2dd586e0dd0 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Mon, 13 Jan 2025 23:57:50 +0900 Subject: [PATCH 26/31] move use of GlobalData to implement GlobalAtomicLong directly into the latter instead of using a FieldValueTransformer --- .../graal/compiler/core/common/Fields.java | 13 ++++++- .../jdk/graal/compiler/graph/NodeClass.java | 2 +- .../compiler/libgraal/LibGraalFeature.java | 33 ++---------------- .../graal/compiler/options/OptionsParser.java | 10 +++--- .../serviceprovider/GlobalAtomicLong.java | 34 ++++++++++++------- .../serviceprovider/GraalServices.java | 4 +-- 6 files changed, 43 insertions(+), 53 deletions(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/Fields.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/Fields.java index 96b8c2369550..95b443d4c97b 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/Fields.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/Fields.java @@ -32,10 +32,12 @@ import java.util.Map; import jdk.graal.compiler.debug.GraalError; +import jdk.graal.compiler.graph.Edges; import jdk.graal.compiler.libgraal.LibGraalFeature; import jdk.internal.misc.Unsafe; import org.graalvm.nativeimage.ImageInfo; import org.graalvm.nativeimage.hosted.Feature; +import org.graalvm.nativeimage.hosted.Feature.BeforeCompilationAccess; /** * Describes fields in a class, primarily for access via {@link Unsafe}. @@ -91,6 +93,15 @@ private Field getField(int i) { } } + /** + * Recomputes the {@link Unsafe} based field offsets and the {@link Edges#getIterationMask()} + * derived from them. + * + * @param access provides the new offsets via {@link BeforeCompilationAccess#objectFieldOffset} + * @return a pair (represented as a map entry) where the key is the new offsets and the value is + * the iteration mask + * + */ public Map.Entry recomputeOffsetsAndIterationMask(Feature.BeforeCompilationAccess access) { long[] newOffsets = new long[offsets.length]; for (int i = 0; i < offsets.length; i++) { @@ -293,7 +304,7 @@ public String getName(int index) { /** * Gets the type of a field. * - * @param index index of a field + * @param index index of the field */ public Class getType(int index) { return types[index]; diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graph/NodeClass.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graph/NodeClass.java index dbc43ddc6f83..983a60254ca8 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graph/NodeClass.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graph/NodeClass.java @@ -418,7 +418,7 @@ public void duringAnalysis(Feature feature, Feature.DuringAnalysisAccess access) /** * Describes a field representing an input or successor edge in a node. */ - protected static class EdgeInfo extends FieldsScanner.FieldInfo { + public static class EdgeInfo extends FieldsScanner.FieldInfo { public EdgeInfo(long offset, String name, Class type, Class declaringClass) { super(offset, name, type, declaringClass); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java index 9326776fde76..9c21e289e989 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java @@ -67,10 +67,8 @@ import jdk.graal.compiler.graph.Edges; import jdk.graal.compiler.options.OptionDescriptor; import jdk.graal.compiler.options.OptionKey; -import jdk.graal.compiler.serviceprovider.GlobalAtomicLong; import jdk.graal.compiler.core.common.FeatureComponent; import jdk.graal.nativeimage.LibGraalLoader; -import jdk.graal.nativeimage.hosted.GlobalData; import jdk.vm.ci.hotspot.HotSpotModifiers; import org.graalvm.nativeimage.hosted.RuntimeSystemProperties; @@ -187,11 +185,8 @@ public void duringSetup(DuringSetupAccess access) { private OptionCollector optionCollector; /** - * Collects all options that are reachable at run time. Reachable options are the - * {@link OptionKey} instances reached by the static analysis. The VM options are instances of - * {@link OptionKey} loaded by the {@code com.oracle.svm.hosted.NativeImageClassLoader} and - * compiler options are instances of {@link OptionKey} loaded by the - * {@code HostedLibGraalClassLoader}. + * Collects all instances of the LibGraalLoader loaded {@link OptionKey} class reached by the + * static analysis. */ private class OptionCollector implements Consumer> { private final Set> options = Collections.newSetFromMap(new ConcurrentHashMap<>()); @@ -289,35 +284,11 @@ private Map.Entry computeReplacement(Object receiver) { } } - /** - * Transforms {@code GlobalAtomicLong.addressSupplier} by replacing it with a {@link GlobalData} - * backed address supplier. - */ - static class GlobalAtomicLongTransformer implements FieldValueTransformer { - - void register(BeforeAnalysisAccess access) { - Field addressSupplierField = lookupField(GlobalAtomicLong.class, "addressSupplier"); - access.registerFieldValueTransformer(addressSupplierField, this); - } - - @Override - public Object transform(Object receiver, Object originalValue) { - long initialValue; - try { - initialValue = ((GlobalAtomicLong) receiver).getInitialValue(); - } catch (Throwable e) { - throw GraalError.shouldNotReachHere(e); - } - return GlobalData.createGlobal(initialValue); - } - } - @SuppressWarnings("unchecked") @Override public void beforeAnalysis(BeforeAnalysisAccess access) { new FieldOffsetsTransformer().register(access); - new GlobalAtomicLongTransformer().register(access); /* Contains static fields that depend on HotSpotJVMCIRuntime */ RuntimeClassInitialization.initializeAtRunTime(HotSpotModifiers.class); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/options/OptionsParser.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/options/OptionsParser.java index 4456fdebe1ee..7499a9186710 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/options/OptionsParser.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/options/OptionsParser.java @@ -54,8 +54,8 @@ public class OptionsParser { * * @param descriptors set of compiler options available in libgraal. These correspond to the * reachable {@link OptionKey}s discovered during Native Image static analysis. This - * field is only non-null when {@link OptionsParser} is loaded by the - * LibGraalClassLoader. + * field is only non-null when {@link OptionsParser} is loaded by a + * {@link jdk.graal.nativeimage.LibGraalLoader}. * @param enterpriseOptions {@linkplain OptionKey#getName() names} of enterprise options */ public record LibGraalOptionsInfo(EconomicMap descriptors, Set enterpriseOptions) { @@ -66,7 +66,7 @@ public static LibGraalOptionsInfo create() { /** * Compiler options info available in libgraal. This field is only non-null when - * {@link OptionsParser} is loaded by the LibGraalClassLoader. + * {@link OptionsParser} is loaded by a {@link jdk.graal.nativeimage.LibGraalLoader}. */ private static LibGraalOptionsInfo libgraalOptions; @@ -81,8 +81,8 @@ public static Iterable getOptionsLoader() { boolean inLibGraal = libgraalOptions != null; if (inLibGraal && inImageBuildtimeCode()) { /* - * Graal code is being run in the context of the LibGraalClassLoader while building - * libgraal so use the LibGraalClassLoader to load the OptionDescriptors. + * Graal code is being run is loaded by a LibGraalLoader while building libgraal so use + * the loader to load the OptionDescriptors. */ ClassLoader myCL = OptionsParser.class.getClassLoader(); return ServiceLoader.load(OptionDescriptors.class, myCL); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GlobalAtomicLong.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GlobalAtomicLong.java index 4ee016fccf54..089c0807c6a7 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GlobalAtomicLong.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GlobalAtomicLong.java @@ -29,9 +29,12 @@ import java.util.function.Supplier; import jdk.graal.compiler.debug.GraalError; +import jdk.graal.nativeimage.LibGraalLoader; import jdk.graal.nativeimage.hosted.GlobalData; import jdk.internal.misc.Unsafe; import org.graalvm.nativeimage.ImageInfo; +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; /** * A shareable long value in the JVM process that is updated atomically. The long value is stored in @@ -48,6 +51,7 @@ public class GlobalAtomicLong { /** * Cleaner for freeing {@link #address}. */ + @Platforms(Platform.HOSTED_ONLY.class) // private static Cleaner cleaner; /** @@ -83,20 +87,24 @@ public GlobalAtomicLong(String name, long initialValue) { if (ImageInfo.inImageRuntimeCode()) { throw GraalError.shouldNotReachHere("Cannot create " + getClass().getName() + " objects in native image runtime"); } else { - addressSupplier = () -> { - if (ImageInfo.inImageRuntimeCode()) { - throw GraalError.shouldNotReachHere("The addressSupplier field value should have been replaced at image build time"); - } - long addr = UNSAFE.allocateMemory(Long.BYTES); - synchronized (GlobalAtomicLong.class) { - if (cleaner == null) { - cleaner = Cleaner.create(); + if (ImageInfo.inImageBuildtimeCode() && GlobalAtomicLong.class.getClassLoader() instanceof LibGraalLoader) { + addressSupplier = GlobalData.createGlobal(initialValue); + } else { + addressSupplier = () -> { + if (ImageInfo.inImageRuntimeCode()) { + throw GraalError.shouldNotReachHere("The addressSupplier field value should have been replaced at image build time"); } - cleaner.register(GlobalAtomicLong.this, () -> UNSAFE.freeMemory(addr)); - } - UNSAFE.putLongVolatile(null, addr, initialValue); - return addr; - }; + long addr = UNSAFE.allocateMemory(Long.BYTES); + synchronized (GlobalAtomicLong.class) { + if (cleaner == null) { + cleaner = Cleaner.create(); + } + cleaner.register(GlobalAtomicLong.this, () -> UNSAFE.freeMemory(addr)); + } + UNSAFE.putLongVolatile(null, addr, initialValue); + return addr; + }; + } } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java index b7fcb05b61c9..f964ccec5e40 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java @@ -70,7 +70,7 @@ public static boolean isInLibgraal() { /** * The set of services available in libgraal. This field is only non-null when - * {@link GraalServices} is loaded by the LibGraalClassLoader. + * {@link GraalServices} is loaded by a {@link LibGraalLoader}. */ private static final Map, List> libgraalServices; @@ -173,7 +173,7 @@ public static Properties getSystemProperties(String justification) { public static Map getSavedProperties() { if (inImageBuildtimeCode()) { // Avoid calling down to JVMCI native methods as they will fail to - // link in a copy of JVMCI loaded by the LibGraalClassLoader. + // link in a copy of JVMCI loaded by a LibGraalLoader. return jdk.internal.misc.VM.getSavedProperties(); } return Services.getSavedProperties(); From 46bf4bbe506eff1e81ef6ee3da3cda4154c91c9e Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Tue, 14 Jan 2025 00:09:36 +0900 Subject: [PATCH 27/31] make OptionsParser#libgraalOptions final --- .../graal/compiler/libgraal/LibGraalFeature.java | 15 +++------------ .../jdk/graal/compiler/options/OptionsParser.java | 12 ++---------- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java index 9c21e289e989..0e95d5baa57a 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/libgraal/LibGraalFeature.java @@ -188,20 +188,11 @@ public void duringSetup(DuringSetupAccess access) { * Collects all instances of the LibGraalLoader loaded {@link OptionKey} class reached by the * static analysis. */ - private class OptionCollector implements Consumer> { + private final class OptionCollector implements Consumer> { private final Set> options = Collections.newSetFromMap(new ConcurrentHashMap<>()); - /** - * Libgraal compiler options info. - */ - private final OptionsParser.LibGraalOptionsInfo compilerOptionsInfo; - private boolean sealed; - OptionCollector() { - compilerOptionsInfo = OptionsParser.setLibgraalOptions(OptionsParser.LibGraalOptionsInfo.create()); - } - @Override public void accept(OptionKey option) { if (sealed) { @@ -221,11 +212,11 @@ void afterAnalysis(AfterAnalysisAccess access) { GraalError.guarantee(access.isReachable(descriptor.getClass()), "%s", descriptor.getClass()); String name = option.getName(); - compilerOptionsInfo.descriptors().put(name, descriptor); + OptionsParser.libgraalOptions.descriptors().put(name, descriptor); String module = modules.get(descriptor.getDeclaringClass().getName()); if (module.contains("enterprise")) { - compilerOptionsInfo.enterpriseOptions().add(name); + OptionsParser.libgraalOptions.enterpriseOptions().add(name); } } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/options/OptionsParser.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/options/OptionsParser.java index 7499a9186710..eb41fd021f92 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/options/OptionsParser.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/options/OptionsParser.java @@ -38,7 +38,7 @@ import java.util.Set; import java.util.regex.Pattern; -import jdk.graal.compiler.debug.GraalError; +import jdk.graal.nativeimage.LibGraalLoader; import org.graalvm.collections.EconomicMap; import org.graalvm.collections.EconomicSet; import org.graalvm.collections.MapCursor; @@ -68,7 +68,7 @@ public static LibGraalOptionsInfo create() { * Compiler options info available in libgraal. This field is only non-null when * {@link OptionsParser} is loaded by a {@link jdk.graal.nativeimage.LibGraalLoader}. */ - private static LibGraalOptionsInfo libgraalOptions; + public static final LibGraalOptionsInfo libgraalOptions = OptionsParser.class.getClassLoader() instanceof LibGraalLoader ? LibGraalOptionsInfo.create() : null; /** * Gets an iterable of available {@link OptionDescriptors}. @@ -97,14 +97,6 @@ public static Iterable getOptionsLoader() { } } - @ExcludeFromJacocoGeneratedReport("only called when building libgraal") - public static LibGraalOptionsInfo setLibgraalOptions(LibGraalOptionsInfo info) { - GraalError.guarantee(inImageBuildtimeCode(), "Can only set libgraal compiler options when building libgraal"); - GraalError.guarantee(libgraalOptions == null, "Libgraal compiler options must be set exactly once"); - OptionsParser.libgraalOptions = info; - return info; - } - /** * Parses a map representing assignments of values to options. * From 0fa27ca6ec4e235213d1cfbbcb6741a385a3fc88 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Wed, 15 Jan 2025 03:01:31 +0900 Subject: [PATCH 28/31] moved implementation of LibGraalRuntimeSupport into its own class --- .../oracle/svm/core/jdk/RuntimeSupport.java | 27 +-------- .../libgraal/LibGraalRuntimeSupportImpl.java | 58 +++++++++++++++++++ 2 files changed, 60 insertions(+), 25 deletions(-) create mode 100644 substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/libgraal/LibGraalRuntimeSupportImpl.java diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RuntimeSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RuntimeSupport.java index bbc6bc04e7b3..a07ad24ac362 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RuntimeSupport.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RuntimeSupport.java @@ -28,13 +28,10 @@ import java.util.Objects; import java.util.concurrent.atomic.AtomicReference; -import com.oracle.svm.core.heap.Heap; -import jdk.graal.nativeimage.impl.LibGraalRuntimeSupport; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; import org.graalvm.nativeimage.VMRuntime; -import org.graalvm.nativeimage.impl.IsolateSupport; import org.graalvm.nativeimage.impl.VMRuntimeSupport; import com.oracle.svm.core.IsolateArgumentParser; @@ -45,28 +42,8 @@ import jdk.graal.compiler.api.replacements.Fold; -@AutomaticallyRegisteredImageSingleton({VMRuntimeSupport.class, RuntimeSupport.class, LibGraalRuntimeSupport.class}) -public final class RuntimeSupport implements VMRuntimeSupport, LibGraalRuntimeSupport { - - @Override - public void processReferences() { - Heap.getHeap().doReferenceHandling(); - } - - @Override - public void notifyLowMemoryPoint(boolean suggestFullGC) { - Heap.getHeap().getGC().collectionHint(suggestFullGC); - } - - @Override - public long getIsolateID() { - return ImageSingletons.lookup(IsolateSupport.class).getIsolateID(); - } - - @Override - public void fatalError(String message) { - throw VMError.shouldNotReachHere(message); - } +@AutomaticallyRegisteredImageSingleton({VMRuntimeSupport.class, RuntimeSupport.class}) +public final class RuntimeSupport implements VMRuntimeSupport { @FunctionalInterface public interface Hook { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/libgraal/LibGraalRuntimeSupportImpl.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/libgraal/LibGraalRuntimeSupportImpl.java new file mode 100644 index 000000000000..be2c1dc81a26 --- /dev/null +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/libgraal/LibGraalRuntimeSupportImpl.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2025, 2025, 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.libgraal; + +import org.graalvm.nativeimage.ImageSingletons; +import org.graalvm.nativeimage.impl.IsolateSupport; + +import com.oracle.svm.core.feature.AutomaticallyRegisteredImageSingleton; +import com.oracle.svm.core.heap.Heap; +import com.oracle.svm.core.util.VMError; + +import jdk.graal.nativeimage.impl.LibGraalRuntimeSupport; + +@AutomaticallyRegisteredImageSingleton({LibGraalRuntimeSupport.class}) +public final class LibGraalRuntimeSupportImpl implements LibGraalRuntimeSupport { + + @Override + public void processReferences() { + Heap.getHeap().doReferenceHandling(); + } + + @Override + public void notifyLowMemoryPoint(boolean suggestFullGC) { + Heap.getHeap().getGC().collectionHint(suggestFullGC); + } + + @Override + public long getIsolateID() { + return ImageSingletons.lookup(IsolateSupport.class).getIsolateID(); + } + + @Override + public void fatalError(String message) { + throw VMError.shouldNotReachHere(message); + } +} From f3a994b3ae55c47225a555720fc4e04393fc4fd7 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Tue, 7 Jan 2025 11:10:03 -0800 Subject: [PATCH 29/31] Use plugin class name to filter fold plugin application --- .../processor/GeneratedFoldPlugin.java | 157 +++++++----------- .../GeneratedNodeIntrinsicPlugin.java | 22 ++- .../processor/GeneratedPlugin.java | 28 +--- .../processor/PluginGenerator.java | 3 - .../compiler/nodes/PluginReplacementNode.java | 17 +- .../PluginReplacementWithExceptionNode.java | 5 +- .../GeneratedFoldInvocationPlugin.java | 15 +- .../GeneratedInvocationPlugin.java | 40 ++--- ...eneratedNodeIntrinsicInvocationPlugin.java | 12 +- 9 files changed, 126 insertions(+), 173 deletions(-) diff --git a/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/replacements/processor/GeneratedFoldPlugin.java b/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/replacements/processor/GeneratedFoldPlugin.java index 9da4a75d9ac1..994035452e16 100644 --- a/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/replacements/processor/GeneratedFoldPlugin.java +++ b/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/replacements/processor/GeneratedFoldPlugin.java @@ -28,6 +28,7 @@ import static jdk.graal.compiler.replacements.processor.FoldHandler.INJECTED_PARAMETER_CLASS_NAME; import java.io.PrintWriter; +import java.io.StringWriter; import java.util.List; import java.util.Set; import java.util.TreeSet; @@ -66,138 +67,55 @@ public void extraImports(AbstractProcessor processor, Set imports) { imports.add("jdk.vm.ci.meta.JavaConstant"); imports.add("jdk.vm.ci.meta.JavaKind"); imports.add("jdk.graal.compiler.nodes.ConstantNode"); - imports.add("jdk.graal.compiler.core.common.type.Stamp"); } @Override protected void createExecute(AbstractProcessor processor, PrintWriter out, InjectedDependencies deps) { - List params = intrinsicMethod.getParameters(); - out.printf(" if (b.shouldDeferPlugin(this)) {\n"); out.printf(" b.replacePlugin%s(this, targetMethod, args, %s.FUNCTION);\n", getReplacementFunctionSuffix(processor), getReplacementName()); out.printf(" return true;\n"); out.printf(" }\n"); - int argCount = 0; - Object receiver; - if (intrinsicMethod.getModifiers().contains(Modifier.STATIC)) { - receiver = intrinsicMethod.getEnclosingElement(); - } else { - receiver = "arg0"; - TypeElement type = (TypeElement) intrinsicMethod.getEnclosingElement(); - constantArgument(processor, out, deps, argCount, type.asType(), argCount, false); - argCount++; - } - - int firstArg = argCount; - for (VariableElement param : params) { - if (processor.getAnnotation(param, processor.getType(INJECTED_PARAMETER_CLASS_NAME)) == null) { - constantArgument(processor, out, deps, argCount, param.asType(), argCount, false); - } else { + int argCount = intrinsicMethod.getModifiers().contains(Modifier.STATIC) ? 0 : 1; + for (VariableElement param : intrinsicMethod.getParameters()) { + if (processor.getAnnotation(param, processor.getType(INJECTED_PARAMETER_CLASS_NAME)) != null) { out.printf(" if (!checkInjectedArgument(b, args[%d], targetMethod)) {\n", argCount); out.printf(" return false;\n"); out.printf(" }\n"); - out.printf(" %s arg%d = %s;\n", param.asType(), argCount, deps.use(processor, (DeclaredType) param.asType())); } argCount++; } - Set suppressWarnings = new TreeSet<>(); - if (intrinsicMethod.getAnnotation(Deprecated.class) != null) { - suppressWarnings.add("deprecation"); - } - if (hasRawtypeWarning(intrinsicMethod.getReturnType())) { - suppressWarnings.add("rawtypes"); - } - for (VariableElement param : params) { - if (hasUncheckedWarning(param.asType())) { - suppressWarnings.add("unchecked"); - } - } - if (suppressWarnings.size() > 0) { - out.printf(" @SuppressWarnings({"); - String sep = ""; - for (String suppressWarning : suppressWarnings) { - out.printf("%s\"%s\"", sep, suppressWarning); - sep = ", "; - } - out.printf("})\n"); - } + // Exercise the emission (but swallow generated output) to populate the deps + emitReplace(processor, new PrintWriter(new StringWriter()), deps); - out.printf(" %s result = %s.%s(", getErasedType(intrinsicMethod.getReturnType()), receiver, intrinsicMethod.getSimpleName()); - if (argCount > firstArg) { - out.printf("arg%d", firstArg); - for (int i = firstArg + 1; i < argCount; i++) { - out.printf(", arg%d", i); - } + // Build the list of extra arguments to be passed + StringBuilder extraArguments = new StringBuilder(); + for (InjectedDependencies.Dependency dep : deps) { + extraArguments.append(", ").append(dep.getName(processor, intrinsicMethod)); } - out.printf(");\n"); - - TypeMirror returnType = intrinsicMethod.getReturnType(); - switch (returnType.getKind()) { - case BOOLEAN: - out.printf(" JavaConstant constant = JavaConstant.forInt(result ? 1 : 0);\n"); - break; - case BYTE: - case SHORT: - case CHAR: - case INT: - out.printf(" JavaConstant constant = JavaConstant.forInt(result);\n"); - break; - case LONG: - out.printf(" JavaConstant constant = JavaConstant.forLong(result);\n"); - break; - case FLOAT: - out.printf(" JavaConstant constant = JavaConstant.forFloat(result);\n"); - break; - case DOUBLE: - out.printf(" JavaConstant constant = JavaConstant.forDouble(result);\n"); - break; - case ARRAY: - case TYPEVAR: - case DECLARED: - if (returnType.equals(processor.getType("java.lang.String"))) { - out.printf(" JavaConstant constant = %s.forString(result);\n", deps.use(processor, WellKnownDependency.CONSTANT_REFLECTION)); - } else { - out.printf(" JavaConstant constant = %s.forObject(result);\n", deps.use(processor, WellKnownDependency.SNIPPET_REFLECTION)); - } - break; - default: - throw new IllegalArgumentException(returnType.toString()); - } - - out.printf(" ConstantNode node = ConstantNode.forConstant(constant, %s, %s);\n", deps.use(processor, WellKnownDependency.META_ACCESS), - deps.use(processor, WellKnownDependency.STRUCTURED_GRAPH)); - out.printf(" b.push(JavaKind.%s, node);\n", getReturnKind(intrinsicMethod)); - out.printf(" return true;\n"); + out.printf(" return doExecute(b, args%s);\n", extraArguments); } - @Override - protected void createHelpers(AbstractProcessor processor, PrintWriter out, InjectedDependencies deps) { - out.printf("\n"); - out.printf(" @Override\n"); - out.printf(" public boolean replace(GraphBuilderContext b, Replacements injection, Stamp stamp, NodeInputList args) {\n"); - + private void emitReplace(AbstractProcessor processor, PrintWriter out, InjectedDependencies deps) { List params = intrinsicMethod.getParameters(); - - int argCount = 0; + final int firstArg = intrinsicMethod.getModifiers().contains(Modifier.STATIC) ? 0 : 1; Object receiver; - if (intrinsicMethod.getModifiers().contains(Modifier.STATIC)) { + if (firstArg == 0) { receiver = intrinsicMethod.getEnclosingElement(); } else { receiver = "arg0"; TypeElement type = (TypeElement) intrinsicMethod.getEnclosingElement(); - constantArgument(processor, out, deps, argCount, type.asType(), argCount, true); - argCount++; + constantArgument(processor, out, deps, 0, type.asType(), 0, false); } - int firstArg = argCount; + int argCount = firstArg; for (VariableElement param : params) { if (processor.getAnnotation(param, processor.getType(INJECTED_PARAMETER_CLASS_NAME)) == null) { - constantArgument(processor, out, deps, argCount, param.asType(), argCount, true); + constantArgument(processor, out, deps, argCount, param.asType(), argCount, false); } else { - out.printf(" assert args.get(%d).isNullConstant() : \"Must be null constant \" + args.get(%d);\n", argCount, argCount); - out.printf(" %s arg%d = %s;\n", param.asType(), argCount, deps.find(processor, (DeclaredType) param.asType()).getExpression(processor, intrinsicMethod)); + out.printf(" assert args[%d].isNullConstant() : \"Must be null constant \" + args[%d];\n", argCount, argCount); + out.printf(" %s arg%d = %s;\n", param.asType(), argCount, deps.use(processor, (DeclaredType) param.asType())); } argCount++; } @@ -270,6 +188,43 @@ protected void createHelpers(AbstractProcessor processor, PrintWriter out, Injec deps.use(processor, WellKnownDependency.STRUCTURED_GRAPH)); out.printf(" b.push(JavaKind.%s, node);\n", getReturnKind(intrinsicMethod)); out.printf(" return true;\n"); + } + + @Override + protected void createPrivateMembersAndConstructor(AbstractProcessor processor, PrintWriter out, InjectedDependencies deps, String constructorName) { + // Add declarations for the extra arguments + StringBuilder extraArguments = new StringBuilder(); + for (InjectedDependencies.Dependency dep : deps) { + extraArguments.append(", ").append(dep.getType()).append(" ").append(dep.getName(processor, intrinsicMethod)); + } + out.printf("\n"); + out.printf(" @SuppressWarnings(\"unused\")\n"); + out.printf(" static boolean doExecute(GraphBuilderContext b, ValueNode[] args%s) {\n", extraArguments); + emitReplace(processor, out, deps); + out.printf(" }\n"); + + // This must be done after the code emission above to ensure that deps includes all required + // dependencies. + super.createPrivateMembersAndConstructor(processor, out, deps, constructorName); + } + + @Override + protected void createHelpers(AbstractProcessor processor, PrintWriter out, InjectedDependencies deps) { + out.printf("\n"); + out.printf(" @Override\n"); + out.printf(" public boolean replace(GraphBuilderContext b, GeneratedPluginInjectionProvider injection, ValueNode[] args) {\n"); + + // Create local declarations for all the injected arguments + for (InjectedDependencies.Dependency dep : deps) { + out.printf(" %s %s = %s;\n", dep.getType(), dep.getName(processor, intrinsicMethod), dep.getExpression(processor, intrinsicMethod)); + } + + // Build the list of extra arguments to be passed + StringBuilder extraArguments = new StringBuilder(); + for (InjectedDependencies.Dependency dep : deps) { + extraArguments.append(", ").append(dep.getName(processor, intrinsicMethod)); + } + out.printf(" return %s.doExecute(b, args%s);\n", getPluginName(), extraArguments); out.printf(" }\n"); } } diff --git a/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/replacements/processor/GeneratedNodeIntrinsicPlugin.java b/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/replacements/processor/GeneratedNodeIntrinsicPlugin.java index 830c2729c09d..b2b12b920b95 100644 --- a/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/replacements/processor/GeneratedNodeIntrinsicPlugin.java +++ b/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/replacements/processor/GeneratedNodeIntrinsicPlugin.java @@ -62,9 +62,6 @@ protected String pluginSuperclass() { @Override public void extraImports(AbstractProcessor processor, Set imports) { imports.add("jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderContext"); - if (needsReplacement(processor)) { - imports.add("jdk.graal.compiler.core.common.type.Stamp"); - } } protected abstract List getParameters(); @@ -87,7 +84,7 @@ protected void createExecute(AbstractProcessor processor, PrintWriter out, Injec for (int i = 0; i < signature.length; i++, idx++) { if (processor.getAnnotation(intrinsicMethod.getParameters().get(i), processor.getType(NodeIntrinsicHandler.CONSTANT_NODE_PARAMETER_CLASS_NAME)) != null) { - String argName = constantArgument(processor, out, deps, idx, signature[i], i, false); + String argName = constantArgument(processor, out, deps, idx, signature[i], i, true); verifyConstantArgument(out, argName, signature[i]); } else { if (signature[i].equals(processor.getType(NodeIntrinsicHandler.VALUE_NODE_CLASS_NAME))) { @@ -199,7 +196,7 @@ protected void verifyConstantArgument(PrintWriter out, String argName, TypeMirro } @Override - protected void createOtherClasses(AbstractProcessor processor, PrintWriter out) { + protected void createOtherClasses(AbstractProcessor processor, PrintWriter out, InjectedDependencies deps) { if (needsReplacement(processor)) { if (isWithExceptionReplacement(processor)) { /* @@ -212,11 +209,10 @@ protected void createOtherClasses(AbstractProcessor processor, PrintWriter out) out.printf("@ExcludeFromJacocoGeneratedReport(\"deferred plugin support that is only called in libgraal\")\n"); out.printf("final class %s implements PluginReplacementWithExceptionNode.ReplacementWithExceptionFunction {\n", name); out.printf(" static PluginReplacementWithExceptionNode.ReplacementWithExceptionFunction FUNCTION = new %s();\n", name); - InjectedDependencies deps = new InjectedDependencies(false, intrinsicMethod); createHelpers(processor, out, deps); out.printf("}\n"); } else { - super.createOtherClasses(processor, out); + super.createOtherClasses(processor, out, deps); } } } @@ -241,13 +237,15 @@ protected boolean needsReplacement(AbstractProcessor processor) { } @Override - protected void createHelpers(AbstractProcessor processor, PrintWriter out, InjectedDependencies deps) { + protected void createHelpers(AbstractProcessor processor, PrintWriter out, InjectedDependencies originalDeps) { if (!needsReplacement(processor)) { return; } + // In this context all values must be retrieved from the injection argument + InjectedDependencies deps = new InjectedDependencies(false, intrinsicMethod); out.printf("\n"); out.printf(" @Override\n"); - out.printf(" public boolean replace(GraphBuilderContext b, Replacements injection, Stamp stamp, NodeInputList args) {\n"); + out.printf(" public boolean replace(GraphBuilderContext b, GeneratedPluginInjectionProvider injection, ValueNode[] args) {\n"); List params = getParameters(); @@ -263,12 +261,12 @@ protected void createHelpers(AbstractProcessor processor, PrintWriter out, Injec for (int i = 0; i < signature.length; i++, idx++) { if (processor.getAnnotation(intrinsicMethod.getParameters().get(i), processor.getType(NodeIntrinsicHandler.CONSTANT_NODE_PARAMETER_CLASS_NAME)) != null) { - constantArgument(processor, out, deps, idx, signature[i], i, true); + constantArgument(processor, out, deps, idx, signature[i], i, false); } else { if (signature[i].equals(processor.getType(NodeIntrinsicHandler.VALUE_NODE_CLASS_NAME))) { - out.printf(" ValueNode arg%d = args.get(%d);\n", idx, i); + out.printf(" ValueNode arg%d = args[%d];\n", idx, i); } else { - out.printf(" %s arg%d = (%s) args.get(%d);\n", signature[i], idx, signature[i], i); + out.printf(" %s arg%d = (%s) args[%d];\n", signature[i], idx, signature[i], i); } } } diff --git a/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/replacements/processor/GeneratedPlugin.java b/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/replacements/processor/GeneratedPlugin.java index c21b28381794..aea8ffd96070 100644 --- a/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/replacements/processor/GeneratedPlugin.java +++ b/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/replacements/processor/GeneratedPlugin.java @@ -66,9 +66,7 @@ public void setPluginName(String pluginName) { this.pluginName = pluginName; } - protected String pluginSuperclass() { - return "GeneratedInvocationPlugin"; - } + protected abstract String pluginSuperclass(); public void generate(AbstractProcessor processor, PrintWriter out) { out.printf("// class: %s\n", intrinsicMethod.getEnclosingElement()); @@ -84,20 +82,15 @@ public void generate(AbstractProcessor processor, PrintWriter out) { InjectedDependencies deps = new InjectedDependencies(true, intrinsicMethod); createExecute(processor, out, deps); out.printf(" }\n"); - out.printf(" @Override\n"); - out.printf(" public Class getSource() {\n"); - out.printf(" return %s.class;\n", getAnnotationClass(processor).getQualifiedName().toString().replace('$', '.')); - out.printf(" }\n"); createPrivateMembersAndConstructor(processor, out, deps, pluginName); out.printf("}\n"); - createOtherClasses(processor, out); - + createOtherClasses(processor, out, deps); } - protected void createOtherClasses(AbstractProcessor processor, PrintWriter out) { + protected void createOtherClasses(AbstractProcessor processor, PrintWriter out, InjectedDependencies deps) { String name = getReplacementName(); out.printf("// class: %s\n", intrinsicMethod.getEnclosingElement()); out.printf("// method: %s\n", intrinsicMethod); @@ -105,7 +98,6 @@ protected void createOtherClasses(AbstractProcessor processor, PrintWriter out) out.printf("@ExcludeFromJacocoGeneratedReport(\"deferred plugin support that is only called in libgraal\")\n"); out.printf("final class %s implements PluginReplacementNode.ReplacementFunction {\n", name); out.printf(" static PluginReplacementNode.ReplacementFunction FUNCTION = new %s();\n", name); - InjectedDependencies deps = new InjectedDependencies(false, intrinsicMethod); createHelpers(processor, out, deps); out.printf("}\n"); } @@ -187,13 +179,12 @@ static boolean hasUncheckedWarning(TypeMirror type) { } } - protected void createPrivateMembersAndConstructor(AbstractProcessor processor, PrintWriter out, InjectedDependencies deps, String constructorName) { + protected void createPrivateMembersAndConstructor(@SuppressWarnings("unused") AbstractProcessor processor, PrintWriter out, InjectedDependencies deps, String constructorName) { if (!deps.isEmpty()) { out.printf("\n"); for (InjectedDependencies.Dependency dep : deps) { out.printf(" private final %s %s;\n", dep.getType(), dep.getName(processor, intrinsicMethod)); } - needInjectionProvider = true; } @@ -258,13 +249,8 @@ protected String constantArgument(AbstractProcessor processor, int argIdx, TypeMirror type, int nodeIdx, - boolean isReplacement) { - Function argFormatter; - if (isReplacement) { - argFormatter = (i) -> String.format("args.get(%d)", i); - } else { - argFormatter = (i) -> String.format("args[%d]", i); - } + boolean checkShouldDefer) { + Function argFormatter = (i) -> String.format("args[%d]", i); if (hasRawtypeWarning(type)) { out.printf(" @SuppressWarnings({\"rawtypes\"})\n"); } @@ -314,7 +300,7 @@ protected String constantArgument(AbstractProcessor processor, } } out.printf(" } else {\n"); - if (!isReplacement) { + if (checkShouldDefer) { out.printf(" if (b.shouldDeferPlugin(this)) {\n"); out.printf(" b.replacePlugin%s(this, targetMethod, args, %s.FUNCTION);\n", getReplacementFunctionSuffix(processor), getReplacementName()); out.printf(" return true;\n"); diff --git a/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/replacements/processor/PluginGenerator.java b/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/replacements/processor/PluginGenerator.java index 063fee39413a..d1afb1d52e3c 100644 --- a/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/replacements/processor/PluginGenerator.java +++ b/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/replacements/processor/PluginGenerator.java @@ -163,7 +163,6 @@ protected static void createImports(PrintWriter out, AbstractProcessor processor HashSet extra = new HashSet<>(); extra.add("jdk.vm.ci.meta.ResolvedJavaMethod"); - extra.add("java.lang.annotation.Annotation"); extra.add("jdk.graal.compiler.nodes.ValueNode"); extra.add("jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderContext"); extra.add("jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin"); @@ -176,8 +175,6 @@ protected static void createImports(PrintWriter out, AbstractProcessor processor extra.add("jdk.graal.compiler.nodes.graphbuilderconf." + plugin.pluginSuperclass()); if (plugin.needsReplacement(processor)) { extra.add("jdk.graal.compiler.options.ExcludeFromJacocoGeneratedReport"); - extra.add("jdk.graal.compiler.graph.NodeInputList"); - extra.add("jdk.graal.compiler.nodes.spi.Replacements"); if (plugin.isWithExceptionReplacement(processor)) { extra.add("jdk.graal.compiler.nodes.PluginReplacementWithExceptionNode"); } else { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PluginReplacementNode.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PluginReplacementNode.java index 61a103a9602b..b31779414ff5 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PluginReplacementNode.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PluginReplacementNode.java @@ -34,12 +34,15 @@ import jdk.graal.compiler.nodeinfo.NodeSize; import jdk.graal.compiler.nodeinfo.Verbosity; import jdk.graal.compiler.nodes.graphbuilderconf.GeneratedInvocationPlugin; +import jdk.graal.compiler.nodes.graphbuilderconf.GeneratedPluginInjectionProvider; import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderContext; import jdk.graal.compiler.nodes.spi.Replacements; -import jdk.graal.nativeimage.FoldNodePlugin; /** - * Used to defer the execution of a {@link GeneratedInvocationPlugin} until libgraal runtime. + * This node represents a {@link jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderPlugin + * plugin} which was deferred by + * {@link jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderTool#shouldDeferPlugin(GeneratedInvocationPlugin)} + * during graph encoding that must be replaced when the graph is decoded. */ @NodeInfo(nameTemplate = "PluginReplacement/{p#pluginName}", cycles = NodeCycles.CYCLES_IGNORED, size = NodeSize.SIZE_IGNORED) public final class PluginReplacementNode extends FixedWithNextNode implements PluginReplacementInterface { @@ -58,14 +61,16 @@ public PluginReplacementNode(Stamp stamp, ValueNode[] args, ReplacementFunction @Override public boolean replace(GraphBuilderContext b, Replacements injection) { - return function.replace(b, injection, stamp, args); + return function.replace(b, injection, args.toArray(ValueNode.EMPTY_ARRAY)); } /** - * Functional interface for generated code that executes the plugin at libgraal runtime. + * This is the work of the original + * {@link jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderPlugin} decoupled from the + * plugin. */ - public interface ReplacementFunction extends FoldNodePlugin { - boolean replace(GraphBuilderContext b, Replacements injection, Stamp stamp, NodeInputList args); + public interface ReplacementFunction { + boolean replace(GraphBuilderContext b, GeneratedPluginInjectionProvider injection, ValueNode[] args); } @Override diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PluginReplacementWithExceptionNode.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PluginReplacementWithExceptionNode.java index be00d675d320..8d9c902cf23e 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PluginReplacementWithExceptionNode.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PluginReplacementWithExceptionNode.java @@ -33,6 +33,7 @@ import jdk.graal.compiler.nodeinfo.NodeInfo; import jdk.graal.compiler.nodeinfo.NodeSize; import jdk.graal.compiler.nodeinfo.Verbosity; +import jdk.graal.compiler.nodes.graphbuilderconf.GeneratedPluginInjectionProvider; import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderContext; import jdk.graal.compiler.nodes.spi.Replacements; @@ -53,11 +54,11 @@ public PluginReplacementWithExceptionNode(Stamp stamp, ValueNode[] args, Replace @Override public boolean replace(GraphBuilderContext b, Replacements injection) { - return function.replace(b, injection, stamp, args); + return function.replace(b, injection, args.toArray(ValueNode.EMPTY_ARRAY)); } public interface ReplacementWithExceptionFunction { - boolean replace(GraphBuilderContext b, Replacements injection, Stamp stamp, NodeInputList args); + boolean replace(GraphBuilderContext b, GeneratedPluginInjectionProvider injection, ValueNode[] args); } @Override diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedFoldInvocationPlugin.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedFoldInvocationPlugin.java index 9da302b0683c..f082dedc27d9 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedFoldInvocationPlugin.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedFoldInvocationPlugin.java @@ -24,17 +24,22 @@ */ package jdk.graal.compiler.nodes.graphbuilderconf; -import jdk.graal.compiler.api.replacements.Fold; -import jdk.graal.nativeimage.FoldNodePlugin; - +import java.lang.annotation.Annotation; import java.lang.reflect.Type; +import jdk.graal.compiler.api.replacements.Fold; + /** - * Abstract class for a plugin generated for a method annotated by {@link Fold}. + * A plugin generated from an {@link Fold @Fold} annotation. */ -public abstract class GeneratedFoldInvocationPlugin extends GeneratedInvocationPlugin implements FoldNodePlugin { +public abstract class GeneratedFoldInvocationPlugin extends GeneratedInvocationPlugin { public GeneratedFoldInvocationPlugin(String name, Type... argumentTypes) { super(name, argumentTypes); } + + @Override + public final Class getSource() { + return Fold.class; + } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java index c5bb938b979c..d92afe26ac51 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java @@ -37,7 +37,6 @@ import jdk.graal.compiler.graph.Node.NodeIntrinsic; import jdk.graal.compiler.nodes.ValueNode; import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInlineOnlyInvocationPlugin; -import jdk.graal.nativeimage.FoldNodePlugin; import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; @@ -80,12 +79,13 @@ public String getSourceLocation() { * @return true if the folding being attempted by the caller can proceed */ protected boolean checkInjectedArgument(GraphBuilderContext b, ValueNode arg, ResolvedJavaMethod foldAnnotatedMethod) { - if (arg.isNullConstant()) { + if (inImageRuntimeCode()) { + // In native image runtime compilation, there is no later stage where execution of the + // plugin can be deferred. return true; } - if (inImageRuntimeCode()) { - // The reflection here is problematic for SVM. + if (arg.isNullConstant()) { return true; } @@ -93,40 +93,36 @@ protected boolean checkInjectedArgument(GraphBuilderContext b, ValueNode arg, Re return false; } + ResolvedJavaMethod thisExecuteMethod = getExecuteMethod(b); if (inImageBuildtimeCode()) { - // The use of this plugin in the plugin itself shouldn't be folded since that - // defeats the purpose of the fold. - ResolvedJavaType foldNodeClass = b.getMetaAccess().lookupJavaType(FoldNodePlugin.class); - if (foldNodeClass.isAssignableFrom(b.getMethod().getDeclaringClass())) { + // Calls to the @Fold method from the generated fold plugin shouldn't be folded. + ResolvedJavaType pluginClass = thisExecuteMethod.getDeclaringClass(); + if (pluginClass.getName().equals(b.getMethod().getDeclaringClass().getName())) { return false; } } - ResolvedJavaMethod thisExecuteMethod = getExecutedMethod(b); if (b.getMethod().equals(thisExecuteMethod)) { return true; } throw new AssertionError("must pass null to injected argument of " + foldAnnotatedMethod.format("%H.%n(%p)") + ", not " + arg + " in " + b.getMethod().format("%H.%n(%p)")); } - private ResolvedJavaMethod getExecutedMethod(GraphBuilderContext b) { + private ResolvedJavaMethod getExecuteMethod(GraphBuilderContext b) { if (executeMethod == null) { - MetaAccessProvider metaAccess = b.getMetaAccess(); - ResolvedJavaMethod baseMethod = metaAccess.lookupJavaMethod(getExecuteMethod()); - ResolvedJavaType thisClass = metaAccess.lookupJavaType(getClass()); - executeMethod = thisClass.resolveConcreteMethod(baseMethod, thisClass); + try { + MetaAccessProvider metaAccess = b.getMetaAccess(); + Method result = GeneratedInvocationPlugin.class.getMethod("execute", GraphBuilderContext.class, ResolvedJavaMethod.class, Receiver.class, ValueNode[].class); + ResolvedJavaMethod baseMethod = metaAccess.lookupJavaMethod(result); + ResolvedJavaType thisClass = metaAccess.lookupJavaType(getClass()); + executeMethod = thisClass.resolveConcreteMethod(baseMethod, thisClass); + } catch (NoSuchMethodException | SecurityException e) { + throw new GraalError(e); + } } return executeMethod; } - private static Method getExecuteMethod() { - try { - return GeneratedInvocationPlugin.class.getMethod("execute", GraphBuilderContext.class, ResolvedJavaMethod.class, InvocationPlugin.Receiver.class, ValueNode[].class); - } catch (NoSuchMethodException | SecurityException e) { - throw new GraalError(e); - } - } - public final boolean isGeneratedFromFoldOrNodeIntrinsic() { return getSource().equals(Fold.class) || getSource().equals(NodeIntrinsic.class); } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedNodeIntrinsicInvocationPlugin.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedNodeIntrinsicInvocationPlugin.java index ab156e6b72a3..30701b89851f 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedNodeIntrinsicInvocationPlugin.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GeneratedNodeIntrinsicInvocationPlugin.java @@ -24,20 +24,30 @@ */ package jdk.graal.compiler.nodes.graphbuilderconf; +import java.lang.annotation.Annotation; import java.lang.reflect.Type; import jdk.graal.compiler.core.common.spi.ForeignCallDescriptor; - +import jdk.graal.compiler.graph.Node; import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; +/** + * A plugin generated from an {@link jdk.graal.compiler.graph.Node.NodeIntrinsic @NodeIntrinsic} + * annotation. + */ public abstract class GeneratedNodeIntrinsicInvocationPlugin extends GeneratedInvocationPlugin { public GeneratedNodeIntrinsicInvocationPlugin(String name, Type... argumentTypes) { super(name, argumentTypes); } + @Override + public final Class getSource() { + return Node.NodeIntrinsic.class; + } + protected boolean verifyForeignCallDescriptor(GraphBuilderTool b, ResolvedJavaMethod targetMethod, ForeignCallDescriptor descriptor) { MetaAccessProvider metaAccess = b.getMetaAccess(); int parameters = 1; From 641df348497826c88e73cf90b0e1f6c3ed76b419 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Fri, 17 Jan 2025 22:49:39 +0900 Subject: [PATCH 30/31] make jdk.graal.nativeimage and org.graalvm.nativebridge optional dependencies of jdk.graal.compiler --- compiler/mx.compiler/suite.py | 7 +++++++ .../jdk/graal/compiler/options/OptionsParser.java | 13 ++++++++----- .../compiler/serviceprovider/GraalServices.java | 2 +- truffle/mx.truffle/mx_truffle.py | 9 +++------ 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/compiler/mx.compiler/suite.py b/compiler/mx.compiler/suite.py index a60a1e7fd2f9..6cbe20c6c663 100644 --- a/compiler/mx.compiler/suite.py +++ b/compiler/mx.compiler/suite.py @@ -597,6 +597,13 @@ # This distribution defines a module. "moduleInfo" : { "name" : "jdk.graal.compiler", + "requires" : [ + # These dependencies are only required when building libgraal. + # Running jargraal works without them so make them optional + # (i.e., "static") dependencies. + "static jdk.graal.nativeimage", + "static org.graalvm.nativebridge" + ], "exports" : [ """* to com.oracle.graal.graal_enterprise, org.graalvm.nativeimage.pointsto, diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/options/OptionsParser.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/options/OptionsParser.java index eb41fd021f92..7ef974b3f755 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/options/OptionsParser.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/options/OptionsParser.java @@ -42,6 +42,7 @@ import org.graalvm.collections.EconomicMap; import org.graalvm.collections.EconomicSet; import org.graalvm.collections.MapCursor; +import org.graalvm.nativeimage.ImageInfo; /** * This class contains methods for parsing Graal options and matching them against a set of @@ -66,9 +67,11 @@ public static LibGraalOptionsInfo create() { /** * Compiler options info available in libgraal. This field is only non-null when - * {@link OptionsParser} is loaded by a {@link jdk.graal.nativeimage.LibGraalLoader}. + * {@link OptionsParser} is loaded by a {@link jdk.graal.nativeimage.LibGraalLoader} and + * {@linkplain ImageInfo#inImageBuildtimeCode libgraal is being built}. */ - public static final LibGraalOptionsInfo libgraalOptions = OptionsParser.class.getClassLoader() instanceof LibGraalLoader ? LibGraalOptionsInfo.create() : null; + public static final LibGraalOptionsInfo libgraalOptions = inImageBuildtimeCode() && + OptionsParser.class.getClassLoader() instanceof LibGraalLoader ? LibGraalOptionsInfo.create() : null; /** * Gets an iterable of available {@link OptionDescriptors}. @@ -79,10 +82,10 @@ public static Iterable getOptionsLoader() { return List.of(new OptionDescriptorsMap(Objects.requireNonNull(libgraalOptions.descriptors, "missing options"))); } boolean inLibGraal = libgraalOptions != null; - if (inLibGraal && inImageBuildtimeCode()) { + if (inLibGraal) { /* - * Graal code is being run is loaded by a LibGraalLoader while building libgraal so use - * the loader to load the OptionDescriptors. + * Graal code being run is loaded by a LibGraalLoader while building libgraal so use the + * loader to load the OptionDescriptors. */ ClassLoader myCL = OptionsParser.class.getClassLoader(); return ServiceLoader.load(OptionDescriptors.class, myCL); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java index f964ccec5e40..f30eca33ff76 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/serviceprovider/GraalServices.java @@ -114,7 +114,7 @@ private static void addProviders(String arch, Class service) { static { ClassLoader cl = GraalServices.class.getClassLoader(); - if (cl instanceof LibGraalLoader libgraalLoader) { + if (inImageBuildtimeCode() && cl instanceof LibGraalLoader libgraalLoader) { libgraalServices = new HashMap<>(); Set libgraalServicesModules = libgraalLoader.getServicesModules(); Map modules = libgraalLoader.getModuleMap(); diff --git a/truffle/mx.truffle/mx_truffle.py b/truffle/mx.truffle/mx_truffle.py index 76485b27bb29..01a75a8d0748 100644 --- a/truffle/mx.truffle/mx_truffle.py +++ b/truffle/mx.truffle/mx_truffle.py @@ -735,15 +735,12 @@ def _sl_jvm_compiler_on_upgrade_module_path_gate_tests(jdk): # Ignore tests for Truffle LTS gate using GraalVM as a base JDK mx.log(f'Ignoring SL JVM Optimized with Compiler on Upgrade Module Path on {jdk.home} because JDK is GraalVM') return - compiler_cp = os.pathsep.join((mx.distribution(name).classpath_repr() for name in ( - 'compiler:GRAAL', - 'compiler:GRAAL_NATIVEIMAGE', - 'sdk:NATIVEBRIDGE' - ))) + compiler = mx.distribution('compiler:GRAAL') vm_args = [ '-XX:+UnlockExperimentalVMOptions', '-XX:+EnableJVMCI', - f'--upgrade-module-path={compiler_cp}', + '-Djdk.graal.CompilationFailureAction=ExitVM', + f'--upgrade-module-path={compiler.classpath_repr()}', ] def run_jvm_optimized(test_file): From 5c24a91e59da949fde766f4ea14c2a14bd327d84 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Fri, 17 Jan 2025 23:00:12 +0900 Subject: [PATCH 31/31] removed FoldNodePlugin --- .../jdk.graal.nativeimage/snapshot.sigtest | 4 +-- .../jdk/graal/nativeimage/FoldNodePlugin.java | 34 ------------------- 2 files changed, 1 insertion(+), 37 deletions(-) delete mode 100644 compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/FoldNodePlugin.java diff --git a/compiler/src/jdk.graal.nativeimage/snapshot.sigtest b/compiler/src/jdk.graal.nativeimage/snapshot.sigtest index b6a8776204af..1456a58e38cc 100644 --- a/compiler/src/jdk.graal.nativeimage/snapshot.sigtest +++ b/compiler/src/jdk.graal.nativeimage/snapshot.sigtest @@ -1,5 +1,5 @@ #Signature file v4.1 -#Version +#Version CLSS public abstract interface jdk.graal.nativeimage.LibGraalLoader meth public abstract java.nio.file.Path getJavaHome() @@ -14,8 +14,6 @@ meth public static void processReferences() meth public static void fatalError(java.lang.String) supr java.lang.Object -CLSS public jdk.graal.nativeimage.FoldNodePlugin - CLSS public final jdk.graal.nativeimage.hosted.GlobalData meth public static java.util.function.Supplier createGlobal(long) supr java.lang.Object diff --git a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/FoldNodePlugin.java b/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/FoldNodePlugin.java deleted file mode 100644 index 84f4cf24438d..000000000000 --- a/compiler/src/jdk.graal.nativeimage/src/jdk/graal/nativeimage/FoldNodePlugin.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2025, 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 jdk.graal.nativeimage; - -/** - * A marker interface for generated classes that implement compile-time evaluation (i.e. folding) of - * certain method calls where the folding must be deferred to libgraal runtime. - * - * @since 25 - */ -public interface FoldNodePlugin { -}