diff --git a/ci.hocon b/ci.hocon index 34d0531d372b..d68c28fdded0 100644 --- a/ci.hocon +++ b/ci.hocon @@ -11,8 +11,11 @@ include "truffle/ci.hocon" #Compiler compiler-suite-root = "./compiler" +substrate-suite-root = "./substratevm" logPatterns = ["*.bgv"] +native-graal-config = "native-graal-core" + #Tools include "tools/ci.hocon" @@ -52,6 +55,10 @@ include "compiler/ci_includes/gate_tasks.hocon" # ------------------ SVM ---------------------- include "substratevm/ci_includes/gate.hocon" +include "substratevm/ci_common/native-bench.hocon" +include "substratevm/ci_common/x52-native.hocon" +include "substratevm/ci_common/x32-native.hocon" +include "substratevm/ci_common/x4150-native.hocon" # Maven deploy dry-run include "substratevm/ci_includes/deploy.hocon" diff --git a/compiler/README.md b/compiler/README.md index f919f27a069e..871d8b3c3595 100644 --- a/compiler/README.md +++ b/compiler/README.md @@ -55,7 +55,6 @@ If you omit `EXTRA_JAVA_HOMES` in the above examples, versioned projects dependi Note that `JAVA_HOME` defines the *primary* JDK for development. For instance, when running `mx vm`, this is the JDK that will be used so if you want to run on JDK 11, swap JDK 8 and JDK 11 in `JAVA_HOME` and `EXTRA_JAVA_HOMES`. Now change to the `graal/compiler` directory: - ``` cd graal/compiler ``` @@ -104,6 +103,48 @@ The former are those with a prefix in the UI denoting the compiler thread and id Further information can be found on the [Debugging](docs/Debugging.md) page. +## libgraal + +Building Graal as described above enables it to be used in HotSpot as Java code +called from the VM. In this mode, Graal is executed in the same way as any +other Java code in the VM; it allocates in the HotSpot heap and it starts execution +in the interpreter with hot parts being subsequently JIT compiled. +The advantage of this mode is that Graal can be debugged with a Java debugger. + +However, it has some disadvantages. Firstly, since Graal uses the object heap, it can +reduce application object locality and increase GC pause times. Additionally, it can +complicate fine tuning options such as `-Xmx` and `Xms` which now need to take the +heap usage of Graal needs to be taken into account. Secondly, Graal will initially be executed +in the interpreter and only get faster over time as its hot methods are JIT +compiled. This is mitigated to some degree by forcing Graal (and JVMCI) +to only be compiled by C1 but this comes at the cost of lower peak performance for Graal. + +To address these issues, Graal can be deployed as a native shared library. The shared +library is produced using [SubstrateVM](../substratevm/README.md) to ahead-of-time compile Graal. In this mode, +Graal uses memory separate from the HotSpot heap and it runs compiled +from the start. That is, it has execution properties similar to other native HotSpot +compilers such as C1 and C2. + +To build libgraal, you need to use the `native-image` tool in the `substratevm` suite. + +``` +cd graal/substratevm +mx build +./native-image -shared -no-server --tool.libgraal +``` + +This will produce a shared library in the current working directory whose name is +compliant with the shared library naming conventions for the platform; +`libgraal.dylib` (macOS), `libgraal.so` (Linux, Solaris, etc), `graal.dll` (Windows). + +To use this library, copy it to the same directory as `libjava.dylib`/`libjava.so`/`java.dll` +in your JVMCI JDK8 installation and use the option `-XX:JVMCIJavaMode=SVM`. Alternatively, +you can directly specify the path to the library as the value to `JVMCIJavaMode`. +For example: +``` +mx vm -XX:JVMCIJavaMode=/path/to/libgraal.dylib -XX:+UseJVMCICompiler ... +``` + ## Publications and Presentations For video tutorials, presentations and publications on Graal visit the [Publications](../docs/Publications.md) page. diff --git a/compiler/mx.compiler/mx_compiler.py b/compiler/mx.compiler/mx_compiler.py index b165a9dd5f03..0a22a5468622 100644 --- a/compiler/mx.compiler/mx_compiler.py +++ b/compiler/mx.compiler/mx_compiler.py @@ -541,6 +541,14 @@ def compiler_gate_runner(suites, unit_test_runs, bootstrap_tests, tasks, extraVM for b in bootstrap_tests: b.run(tasks, extraVMarguments) + with Task('Javadoc', tasks, tags=GraalTags.doc) as t: + # metadata package was deprecated, exclude it + if t: mx.javadoc(['--exclude-packages', 'com.oracle.truffle.dsl.processor.java'], quietForNoPackages=True) + + +def compiler_gate_benchmark_runner(tasks, extraVMarguments=None, libgraal=False): + prefix = 'libgraal ' if libgraal else '' + # run selected DaCapo benchmarks # DaCapo benchmarks that can run with system assertions enabled dacapos_with_sa = { @@ -552,7 +560,7 @@ def compiler_gate_runner(suites, unit_test_runs, bootstrap_tests, tasks, extraVM 'xalan': 1, } for name, iterations in sorted(dacapos_with_sa.iteritems()): - with Task('DaCapo:' + name, tasks, tags=GraalTags.benchmarktest) as t: + with Task(prefix + 'DaCapo:' + name, tasks, tags=GraalTags.benchmarktest) as t: if t: _gate_dacapo(name, iterations, _remove_empty_entries(extraVMarguments) + ['-XX:+UseJVMCICompiler', '-Dgraal.TrackNodeSourcePosition=true', '-esa']) # DaCapo benchmarks for which system assertions cannot be enabled because of benchmark failures @@ -563,7 +571,7 @@ def compiler_gate_runner(suites, unit_test_runs, bootstrap_tests, tasks, extraVM 'sunflow': 2, } for name, iterations in sorted(dacapos_without_sa.iteritems()): - with Task('DaCapo:' + name, tasks, tags=GraalTags.benchmarktest) as t: + with Task(prefix + 'DaCapo:' + name, tasks, tags=GraalTags.benchmarktest) as t: if t: _gate_dacapo(name, iterations, _remove_empty_entries(extraVMarguments) + ['-XX:+UseJVMCICompiler']) # run selected Scala DaCapo benchmarks @@ -581,7 +589,7 @@ def compiler_gate_runner(suites, unit_test_runs, bootstrap_tests, tasks, extraVM 'tmt': 1 } for name, iterations in sorted(scala_dacapos_with_sa.iteritems()): - with Task('ScalaDaCapo:' + name, tasks, tags=GraalTags.benchmarktest) as t: + with Task(prefix + 'ScalaDaCapo:' + name, tasks, tags=GraalTags.benchmarktest) as t: if t: _gate_scala_dacapo(name, iterations, _remove_empty_entries(extraVMarguments) + ['-XX:+UseJVMCICompiler', '-Dgraal.TrackNodeSourcePosition=true', '-esa']) # Scala DaCapo benchmarks for which system assertions cannot be enabled because of benchmark failures @@ -593,36 +601,34 @@ def compiler_gate_runner(suites, unit_test_runs, bootstrap_tests, tasks, extraVM del scala_dacapos_without_sa['actors'] for name, iterations in sorted(scala_dacapos_without_sa.iteritems()): - with Task('ScalaDaCapo:' + name, tasks, tags=GraalTags.benchmarktest) as t: + with Task(prefix + 'ScalaDaCapo:' + name, tasks, tags=GraalTags.benchmarktest) as t: if t: _gate_scala_dacapo(name, iterations, _remove_empty_entries(extraVMarguments) + ['-XX:+UseJVMCICompiler']) # ensure -Xbatch still works - with Task('DaCapo_pmd:BatchMode', tasks, tags=GraalTags.test) as t: + with Task(prefix + 'DaCapo_pmd:BatchMode', tasks, tags=GraalTags.test) as t: if t: _gate_dacapo('pmd', 1, _remove_empty_entries(extraVMarguments) + ['-XX:+UseJVMCICompiler', '-Xbatch']) # ensure benchmark counters still work if mx.get_arch() != 'aarch64': # GR-8364 Exclude benchmark counters on AArch64 - with Task('DaCapo_pmd:BenchmarkCounters', tasks, tags=GraalTags.test) as t: + with Task(prefix + 'DaCapo_pmd:BenchmarkCounters', tasks, tags=GraalTags.test) as t: if t: _gate_dacapo('pmd', 1, _remove_empty_entries(extraVMarguments) + ['-XX:+UseJVMCICompiler', '-Dgraal.LIRProfileMoves=true', '-Dgraal.GenericDynamicCounters=true', '-XX:JVMCICounterSize=10']) # ensure -Xcomp still works - with Task('XCompMode:product', tasks, tags=GraalTags.test) as t: + with Task(prefix + 'XCompMode:product', tasks, tags=GraalTags.test) as t: if t: run_vm(_remove_empty_entries(extraVMarguments) + ['-XX:+UseJVMCICompiler', '-Xcomp', '-version']) if isJDK8: # temporarily isolate those test (GR-10990) cms = ['cms'] # ensure CMS still works - with Task('DaCapo_pmd:CMS', tasks, tags=cms) as t: + with Task(prefix + 'DaCapo_pmd:CMS', tasks, tags=cms) as t: if t: _gate_dacapo('pmd', 4, _remove_empty_entries(extraVMarguments) + ['-XX:+UseJVMCICompiler', '-Xmx256M', '-XX:+UseConcMarkSweepGC'], threads=4, force_serial_gc=False, set_start_heap_size=False) # ensure CMSIncrementalMode still works - with Task('DaCapo_pmd:CMSIncrementalMode', tasks, tags=cms) as t: + with Task(prefix + 'DaCapo_pmd:CMSIncrementalMode', tasks, tags=cms) as t: if t: _gate_dacapo('pmd', 4, _remove_empty_entries(extraVMarguments) + ['-XX:+UseJVMCICompiler', '-Xmx256M', '-XX:+UseConcMarkSweepGC', '-XX:+CMSIncrementalMode'], threads=4, force_serial_gc=False, set_start_heap_size=False) - with Task('Javadoc', tasks, tags=GraalTags.doc) as t: - # metadata package was deprecated, exclude it - if t: mx.javadoc(['--exclude-packages', 'com.oracle.truffle.dsl.processor.java'], quietForNoPackages=True) + graal_unit_test_runs = [ UnitTestRun('UnitTests', [], tags=GraalTags.test + GraalTags.coverage), @@ -662,6 +668,7 @@ def compiler_gate_runner(suites, unit_test_runs, bootstrap_tests, tasks, extraVM def _graal_gate_runner(args, tasks): compiler_gate_runner(['compiler', 'truffle'], graal_unit_test_runs, graal_bootstrap_tests, tasks, args.extra_vm_argument) + compiler_gate_benchmark_runner(tasks, args.extra_vm_argument) jvmci_ci_version_gate_runner(tasks) mx_jaotc.jaotc_gate_runner(tasks) @@ -1173,7 +1180,6 @@ def makegraaljdk(args): graal_compiler='graal', )) - mx.update_commands(_suite, { 'sl' : [sl, '[SL args|@VM options]'], 'vm': [run_vm, '[-options] class [args...]'], diff --git a/compiler/mx.compiler/mx_graal_benchmark.py b/compiler/mx.compiler/mx_graal_benchmark.py index bc4001f32656..75f0834f6852 100644 --- a/compiler/mx.compiler/mx_graal_benchmark.py +++ b/compiler/mx.compiler/mx_graal_benchmark.py @@ -113,7 +113,7 @@ def config_name(self): return self.raw_config_name def post_process_command_line_args(self, args): - return self.extra_args + args + return [arg if not callable(arg) else arg() for arg in self.extra_args] + args def run_java(self, args, out=None, err=None, cwd=None, nonZeroIsFatal=False): tag = mx.get_jdk_option().tag @@ -147,8 +147,11 @@ def rules(self, output, benchmarks, bmSuiteArgs): mx_benchmark.add_java_vm(JvmciJdkVm('server', 'default', ['-server', '-XX:-EnableJVMCI']), _suite, 2) mx_benchmark.add_java_vm(JvmciJdkVm('server', 'hosted', ['-server', '-XX:+EnableJVMCI']), _suite, 3) -def build_jvmci_vm_variants(raw_name, raw_config_name, extra_args, variants, include_default=True, suite=None, priority=0): - for prefix, args in [('', ['-XX:+UseJVMCICompiler']), ('hosted-', ['-XX:-UseJVMCICompiler'])]: +def build_jvmci_vm_variants(raw_name, raw_config_name, extra_args, variants, include_default=True, suite=None, priority=0, hosted=True): + prefixes = [('', ['-XX:+UseJVMCICompiler'])] + if hosted: + prefixes.append(('hosted-', ['-XX:-UseJVMCICompiler'])) + for prefix, args in prefixes: extended_raw_config_name = prefix + raw_config_name extended_extra_args = extra_args + args if include_default: diff --git a/compiler/src/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyDebugUsage.java b/compiler/src/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyDebugUsage.java index 56ddafee2878..1543e001eff5 100644 --- a/compiler/src/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyDebugUsage.java +++ b/compiler/src/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyDebugUsage.java @@ -150,7 +150,8 @@ private void verifyParameters(MethodCallTargetNode callTarget, StructuredGraph c "org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl.compilePEGraph", "org.graalvm.compiler.core.test.VerifyDebugUsageTest$ValidDumpUsagePhase.run", "org.graalvm.compiler.core.test.VerifyDebugUsageTest$InvalidConcatDumpUsagePhase.run", - "org.graalvm.compiler.core.test.VerifyDebugUsageTest$InvalidDumpUsagePhase.run")); + "org.graalvm.compiler.core.test.VerifyDebugUsageTest$InvalidDumpUsagePhase.run", + "org.graalvm.compiler.hotspot.SymbolicSnippetEncoder.verifySnippetEncodeDecode")); /** * The set of methods allowed to call a {@code Debug.dump(...)} method with the {@code level} diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java index 6ef54ffe1319..8b87341ba8b9 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java @@ -196,6 +196,10 @@ public CompilationResult compile(ResolvedJavaMethod method, int entryBCI, boolea StructuredGraph graph = createGraph(method, entryBCI, useProfilingInfo, compilationId, options, debug); CompilationResult result = new CompilationResult(compilationId); return compileHelper(CompilationResultBuilderFactory.Default, result, graph, method, entryBCI, useProfilingInfo, options); + // this isn't quite right yet. method substitutions are normally parsed into the + // graph + // but we need to stitch the snippet graph into the current graph instead. Method + // substitutions are currently disabled over in lookupInvocation. } protected OptimisticOptimizations getOptimisticOpts(ProfilingInfo profilingInfo, OptionValues options) { diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java index 289f3fff8420..9367d1427c17 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java @@ -25,6 +25,7 @@ package org.graalvm.compiler.hotspot; import static jdk.vm.ci.common.InitTimer.timer; +import static jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE; import static org.graalvm.compiler.hotspot.HotSpotGraalOptionValues.GRAAL_OPTION_PROPERTY_PREFIX; import java.io.PrintStream; @@ -80,6 +81,10 @@ public void onSelection() { */ adjustCompilationLevelInternal(Object.class, "hashCode", "()I", CompilationLevel.FullOptimization); adjustCompilationLevelInternal(Object.class, "hashCode", "()I", CompilationLevel.Simple); + if (IS_BUILDING_NATIVE_IMAGE) { + // Triggers initialization of all option descriptors + Options.CompileGraalWithC1Only.getName(); + } } private static void initializeGraalCompilePolicyFields(OptionValues options) { diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalJVMCIServiceLocator.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalJVMCIServiceLocator.java index 2a918eb1e85e..22954c87ea95 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalJVMCIServiceLocator.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalJVMCIServiceLocator.java @@ -26,6 +26,7 @@ import org.graalvm.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; @@ -51,7 +52,7 @@ T getProvider(Class service, HotSpotGraalJVMCIServiceLocator locator) { return null; } - private HotSpotGraalRuntime graalRuntime; + @NativeImageReinitialize private HotSpotGraalRuntime graalRuntime; /** * Notifies this object of the compiler created via {@link HotSpotGraalJVMCIServiceLocator}. diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java index d21b0902ef10..14a94618562d 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java @@ -39,7 +39,7 @@ class JVMCIVersionCheck { private static final int JVMCI8_MIN_MAJOR_VERSION = 0; - private static final int JVMCI8_MIN_MINOR_VERSION = 46; + private static final int JVMCI8_MIN_MINOR_VERSION = 54; private static void failVersionCheck(boolean exit, String reason, Object... args) { Formatter errorMessage = new Formatter().format(reason, args); diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java index 23a7bd603a31..9ffa4292f36b 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java @@ -24,6 +24,7 @@ */ package org.graalvm.compiler.hotspot.meta; +import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; import static org.graalvm.compiler.core.common.GraalOptions.AlwaysInlineVTableStubs; import static org.graalvm.compiler.core.common.GraalOptions.InlineVTableStubs; import static org.graalvm.compiler.core.common.GraalOptions.OmitHotExceptionStacktrace; @@ -686,6 +687,9 @@ public static final class RuntimeCalls { } private void throwCachedException(BytecodeExceptionNode node) { + if (IS_IN_NATIVE_IMAGE) { + throw new InternalError("Can't throw exception from SVM object"); + } Throwable exception = Exceptions.cachedExceptions.get(node.getExceptionKind()); assert exception != null; diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraalConstantFieldProvider.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraalConstantFieldProvider.java index 4c9b6e0d2789..e60051b47e79 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraalConstantFieldProvider.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraalConstantFieldProvider.java @@ -24,6 +24,8 @@ */ package org.graalvm.compiler.hotspot.meta; +import static jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE; +import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode; import java.util.ArrayList; @@ -63,7 +65,7 @@ protected boolean isStaticFieldConstant(ResolvedJavaField field, OptionValues op private volatile List nonEmbeddableFields; protected boolean isEmbeddableField(ResolvedJavaField field) { - if (nonEmbeddableFields == null) { + if (!IS_IN_NATIVE_IMAGE && (IS_BUILDING_NATIVE_IMAGE || nonEmbeddableFields == null)) { synchronized (this) { if (nonEmbeddableFields == null) { List fields = new ArrayList<>(); diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java index 57405753ebce..3a11b53ceabf 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java @@ -24,6 +24,7 @@ */ package org.graalvm.compiler.hotspot.meta; +import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC; import static org.graalvm.compiler.hotspot.HotSpotBackend.GHASH_PROCESS_BLOCKS; import static org.graalvm.compiler.hotspot.meta.HotSpotAOTProfilingPlugin.Options.TieredAOT; @@ -142,7 +143,9 @@ public static Plugins create(CompilerConfiguration compilerConfiguration, GraalH plugins.appendInlineInvokePlugin(new InlineDuringParsingPlugin()); } - if (GeneratePIC.getValue(options)) { + // The use of MethodHandles to access HotSpotConstantPool in + // HotSpotClassInitializationPlugin is problematic for SVM. + if (!IS_IN_NATIVE_IMAGE && GeneratePIC.getValue(options)) { plugins.setClassInitializationPlugin(new HotSpotClassInitializationPlugin()); if (TieredAOT.getValue(options)) { plugins.setProfilingPlugin(new HotSpotAOTProfilingPlugin()); diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotClassSubstitutions.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotClassSubstitutions.java index d7775d47bbf8..73b5745a1d2a 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotClassSubstitutions.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotClassSubstitutions.java @@ -38,6 +38,7 @@ import java.lang.reflect.Modifier; import org.graalvm.compiler.api.replacements.ClassSubstitution; +import org.graalvm.compiler.api.replacements.Fold; import org.graalvm.compiler.api.replacements.MethodSubstitution; import org.graalvm.compiler.hotspot.word.KlassPointer; import org.graalvm.compiler.nodes.PiNode; @@ -92,6 +93,13 @@ public static boolean isPrimitive(final Class thisObj) { return klass.isNull(); } + @Fold + public static Class getObjectClass() { + // XXX SVM this must a ConstantNode wrapping the HotSpotObjectConstant for + // java.lang.Class.class + return Object.class; + } + @MethodSubstitution(isStatic = false) public static Class getSuperclass(final Class thisObj) { KlassPointer klass = ClassGetHubNode.readClass(thisObj); @@ -100,7 +108,7 @@ public static Class getSuperclass(final Class thisObj) { int accessFlags = klassNonNull.readInt(klassAccessFlagsOffset(INJECTED_VMCONFIG), KLASS_ACCESS_FLAGS_LOCATION); if ((accessFlags & Modifier.INTERFACE) == 0) { if (klassIsArray(klassNonNull)) { - return Object.class; + return getObjectClass(); } else { KlassPointer superKlass = klassNonNull.readKlassPointer(klassSuperKlassOffset(INJECTED_VMCONFIG), KLASS_SUPER_KLASS_LOCATION); if (superKlass.isNull()) { diff --git a/compiler/src/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java b/compiler/src/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java index eb3cc54f72a6..f5ade53a3eee 100644 --- a/compiler/src/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java +++ b/compiler/src/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java @@ -38,6 +38,7 @@ import static jdk.vm.ci.meta.DeoptimizationReason.UnreachedCode; import static jdk.vm.ci.meta.DeoptimizationReason.Unresolved; import static jdk.vm.ci.runtime.JVMCICompiler.INVOCATION_ENTRY_BCI; +import static jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE; import static org.graalvm.compiler.bytecode.Bytecodes.AALOAD; import static org.graalvm.compiler.bytecode.Bytecodes.AASTORE; import static org.graalvm.compiler.bytecode.Bytecodes.ACONST_NULL; @@ -1721,7 +1722,6 @@ protected Invoke appendInvoke(InvokeKind initialInvokeKind, ResolvedJavaMethod i } } if (invokeKind.isDirect()) { - inlineInfo = tryInline(args, targetMethod); if (inlineInfo == SUCCESSFULLY_INLINED) { return null; @@ -2321,7 +2321,7 @@ private boolean inline(ResolvedJavaMethod targetMethod, ResolvedJavaMethod inlin } return false; } - if (canInlinePartialIntrinsicExit() && InlinePartialIntrinsicExitDuringParsing.getValue(options)) { + if (canInlinePartialIntrinsicExit() && InlinePartialIntrinsicExitDuringParsing.getValue(options) && !IS_BUILDING_NATIVE_IMAGE) { // Otherwise inline the original method. Any frame state created // during the inlining will exclude frame(s) in the // intrinsic method (see FrameStateBuilder.create(int bci)). diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java index b5ce86c9b14e..c282d1ea9965 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GeneratedInvocationPlugin.java @@ -24,6 +24,8 @@ */ package org.graalvm.compiler.nodes.graphbuilderconf; +import static jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE; +import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; import java.lang.annotation.Annotation; import java.lang.reflect.Method; @@ -66,6 +68,11 @@ protected boolean checkInjectedArgument(GraphBuilderContext b, ValueNode arg, Re return true; } + if (IS_IN_NATIVE_IMAGE) { + // The reflection here is problematic for SVM. + return true; + } + MetaAccessProvider metaAccess = b.getMetaAccess(); ResolvedJavaMethod executeMethod = metaAccess.lookupJavaMethod(getExecuteMethod()); ResolvedJavaType thisClass = metaAccess.lookupJavaType(getClass()); @@ -75,6 +82,9 @@ protected boolean checkInjectedArgument(GraphBuilderContext b, ValueNode arg, Re // the injected argument of the call to the @Fold annotated method will be non-null. return true; } + if (IS_BUILDING_NATIVE_IMAGE) { + return true; + } throw new AssertionError("must pass null to injected argument of " + foldAnnotatedMethod.format("%H.%n(%p)") + ", not " + arg); } diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InvocationPlugins.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InvocationPlugins.java index a27358ef24a8..f4dc7ca0693d 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InvocationPlugins.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InvocationPlugins.java @@ -25,6 +25,8 @@ package org.graalvm.compiler.nodes.graphbuilderconf; import static java.lang.String.format; +import static jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE; +import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; import static org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.LateClassPlugins.CLOSED_LATE_CLASS_PLUGIN; import java.lang.reflect.Constructor; @@ -144,6 +146,9 @@ static class OptionalLazySymbol implements Type { OptionalLazySymbol(String name) { this.name = name; + if (IS_BUILDING_NATIVE_IMAGE) { + resolve(); + } } @Override @@ -156,7 +161,7 @@ public String getTypeName() { * resolution fails. */ public Class resolve() { - if (resolved == null) { + if (!IS_IN_NATIVE_IMAGE && resolved == null) { Class resolvedOrNull = resolveClass(name, true); resolved = resolvedOrNull == null ? MASK_NULL : resolvedOrNull; } @@ -466,8 +471,8 @@ public void register(InvocationPlugin plugin, String name, Type... argumentTypes Binding binding = new Binding(plugin, isStatic, name, argumentTypes); bindings.add(binding); - assert Checks.check(this.plugins, declaringType, binding); - assert Checks.checkResolvable(false, declaringType, binding); + assert IS_IN_NATIVE_IMAGE || Checks.check(this.plugins, declaringType, binding); + assert IS_IN_NATIVE_IMAGE || Checks.checkResolvable(false, declaringType, binding); } @Override @@ -974,8 +979,8 @@ protected void register(InvocationPlugin plugin, boolean isOptional, boolean all argumentTypes[0] = declaringClass; } Binding binding = put(plugin, isStatic, allowOverwrite, declaringClass, name, argumentTypes); - assert Checks.check(this, declaringClass, binding); - assert Checks.checkResolvable(isOptional, declaringClass, binding); + assert IS_IN_NATIVE_IMAGE || Checks.check(this, declaringClass, binding); + assert IS_IN_NATIVE_IMAGE || Checks.checkResolvable(isOptional, declaringClass, binding); } /** @@ -1018,10 +1023,19 @@ public InvocationPlugin lookupInvocation(ResolvedJavaMethod method) { if (parent != null) { InvocationPlugin plugin = parent.lookupInvocation(method); if (plugin != null) { + if (IS_IN_NATIVE_IMAGE && plugin instanceof MethodSubstitutionPlugin) { + // Disable method substitutions for now + return null; + } return plugin; } } - return get(method); + InvocationPlugin invocationPlugin = get(method); + if (IS_IN_NATIVE_IMAGE && invocationPlugin instanceof MethodSubstitutionPlugin) { + // Disable method substitutions for now + return null; + } + return invocationPlugin; } /** @@ -1155,25 +1169,27 @@ private static class Checks { static final Class[][] SIGS; static { - if (!Assertions.assertionsEnabled()) { + if (!Assertions.assertionsEnabled() && !IS_BUILDING_NATIVE_IMAGE) { throw new GraalError("%s must only be used in assertions", Checks.class.getName()); } ArrayList[]> sigs = new ArrayList<>(MAX_ARITY); - for (Method method : InvocationPlugin.class.getDeclaredMethods()) { - if (!Modifier.isStatic(method.getModifiers()) && method.getName().equals("apply")) { - Class[] sig = method.getParameterTypes(); - assert sig[0] == GraphBuilderContext.class; - assert sig[1] == ResolvedJavaMethod.class; - assert sig[2] == InvocationPlugin.Receiver.class; - assert Arrays.asList(sig).subList(3, sig.length).stream().allMatch(c -> c == ValueNode.class); - while (sigs.size() < sig.length - 2) { - sigs.add(null); + if (!IS_IN_NATIVE_IMAGE) { + for (Method method : InvocationPlugin.class.getDeclaredMethods()) { + if (!Modifier.isStatic(method.getModifiers()) && method.getName().equals("apply")) { + Class[] sig = method.getParameterTypes(); + assert sig[0] == GraphBuilderContext.class; + assert sig[1] == ResolvedJavaMethod.class; + assert sig[2] == InvocationPlugin.Receiver.class; + assert Arrays.asList(sig).subList(3, sig.length).stream().allMatch(c -> c == ValueNode.class); + while (sigs.size() < sig.length - 2) { + sigs.add(null); + } + sigs.set(sig.length - 3, sig); } - sigs.set(sig.length - 3, sig); } + assert sigs.indexOf(null) == -1 : format("need to add an apply() method to %s that takes %d %s arguments ", InvocationPlugin.class.getName(), sigs.indexOf(null), + ValueNode.class.getSimpleName()); } - assert sigs.indexOf(null) == -1 : format("need to add an apply() method to %s that takes %d %s arguments ", InvocationPlugin.class.getName(), sigs.indexOf(null), - ValueNode.class.getSimpleName()); SIGS = sigs.toArray(new Class[sigs.size()][]); } @@ -1290,6 +1306,9 @@ public static Class resolveType(Type type, boolean optional) { if (type instanceof OptionalLazySymbol) { return ((OptionalLazySymbol) type).resolve(); } + if (IS_IN_NATIVE_IMAGE) { + throw new GraalError("Unresolved type in SVM image."); + } return resolveClass(type.getTypeName(), optional); } diff --git a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/MethodSubstitutionPlugin.java b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/MethodSubstitutionPlugin.java index 75e513f2eed1..5b610f34b3d3 100644 --- a/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/MethodSubstitutionPlugin.java +++ b/compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/MethodSubstitutionPlugin.java @@ -24,6 +24,7 @@ */ package org.graalvm.compiler.nodes.graphbuilderconf; +import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; import static org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.resolveType; import java.lang.reflect.Method; @@ -177,6 +178,10 @@ private Method lookupSubstitute() { @Override public boolean execute(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin.Receiver receiver, ValueNode[] argsIncludingReceiver) { + if (IS_IN_NATIVE_IMAGE) { + // these are currently unimplemented + return false; + } ResolvedJavaMethod subst = getSubstitute(b.getMetaAccess()); return b.intrinsify(bytecodeProvider, targetMethod, subst, receiver, argsIncludingReceiver); } diff --git a/compiler/src/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionsParser.java b/compiler/src/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionsParser.java index acfea471d3cd..cc004066de31 100644 --- a/compiler/src/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionsParser.java +++ b/compiler/src/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionsParser.java @@ -24,6 +24,9 @@ */ package org.graalvm.compiler.options; +import static jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE; +import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; + import java.util.ArrayList; import java.util.Collection; import java.util.Formatter; @@ -39,11 +42,15 @@ */ public class OptionsParser { + private static volatile List cachedOptionDescriptors; + /** - * Gets an iterable composed of the {@link ServiceLoader}s to be used when looking for - * {@link OptionDescriptors} providers. + * Gets an iterable of available {@link OptionDescriptors}. */ public static Iterable getOptionsLoader() { + if (IS_IN_NATIVE_IMAGE || cachedOptionDescriptors != null) { + return cachedOptionDescriptors; + } boolean java8OrEarlier = System.getProperty("java.specification.version").compareTo("1.9") < 0; ClassLoader loader; if (java8OrEarlier) { @@ -58,7 +65,17 @@ public static Iterable getOptionsLoader() { */ loader = ClassLoader.getSystemClassLoader(); } - return ServiceLoader.load(OptionDescriptors.class, loader); + Iterable result = ServiceLoader.load(OptionDescriptors.class, loader); + if (IS_BUILDING_NATIVE_IMAGE) { + ArrayList optionDescriptors = new ArrayList<>(); + for (OptionDescriptors descriptors : result) { + if (!descriptors.getClass().getName().contains(".svm.hosted.snippets.")) { + optionDescriptors.add(descriptors); + } + } + OptionsParser.cachedOptionDescriptors = optionDescriptors; + } + return result; } /** diff --git a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java index 5f596fef2a26..ee7412279019 100644 --- a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java +++ b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java @@ -24,6 +24,7 @@ */ package org.graalvm.compiler.replacements; +import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; import static org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.CompilationContext.INLINE_AFTER_PARSING; import java.lang.reflect.Method; @@ -358,13 +359,18 @@ public void inline(InvokeNode invoke, String reason, String phase) { Plugins plugins = new Plugins(graphBuilderPlugins); GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(plugins); - StructuredGraph calleeGraph = new StructuredGraph.Builder(invoke.getOptions(), invoke.getDebug()).method(method).trackNodeSourcePosition( - invoke.graph().trackNodeSourcePosition()).setIsSubstitution(true).build(); - IntrinsicContext initialReplacementContext = new IntrinsicContext(method, method, providers.getReplacements().getDefaultReplacementBytecodeProvider(), INLINE_AFTER_PARSING); - GraphBuilderPhase.Instance instance = createGraphBuilderInstance(metaAccess, providers.getStampProvider(), providers.getConstantReflection(), providers.getConstantFieldProvider(), config, - OptimisticOptimizations.NONE, - initialReplacementContext); - instance.apply(calleeGraph); + StructuredGraph calleeGraph; + if (IS_IN_NATIVE_IMAGE) { + calleeGraph = providers.getReplacements().getSnippet(method, null, false, null); + } else { + calleeGraph = new StructuredGraph.Builder(invoke.getOptions(), invoke.getDebug()).method(method).trackNodeSourcePosition(invoke.graph().trackNodeSourcePosition()).setIsSubstitution( + true).build(); + IntrinsicContext initialReplacementContext = new IntrinsicContext(method, method, providers.getReplacements().getDefaultReplacementBytecodeProvider(), INLINE_AFTER_PARSING); + GraphBuilderPhase.Instance instance = createGraphBuilderInstance(metaAccess, providers.getStampProvider(), providers.getConstantReflection(), providers.getConstantFieldProvider(), config, + OptimisticOptimizations.NONE, + initialReplacementContext); + instance.apply(calleeGraph); + } // Remove all frame states from inlinee calleeGraph.clearAllStateAfter(); diff --git a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java index 2d513cd018b9..b00879391b5e 100644 --- a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java +++ b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java @@ -752,6 +752,10 @@ protected boolean tryInvocationPlugin(PEMethodScope methodScope, LoopScope loopS return false; } + if (loopScope.methodScope.encodedGraph.isCallToOriginal(targetMethod)) { + return false; + } + ValueNode[] arguments = callTarget.arguments().toArray(new ValueNode[0]); FixedWithNextNode invokePredecessor = (FixedWithNextNode) invoke.asNode().predecessor(); diff --git a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounter.java b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounter.java index e42f3277d987..438251a96ef0 100644 --- a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounter.java +++ b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounter.java @@ -133,7 +133,7 @@ public Group getGroup() { * compile-time constant {@link SnippetCounter} object. */ public void inc() { - if (group != null) { + if (getGroup() != null) { SnippetCounterNode.increment(this); } } @@ -143,7 +143,7 @@ public void inc() { * compile-time constant {@link SnippetCounter} object. */ public void add(int increment) { - if (group != null) { + if (getGroup() != null) { SnippetCounterNode.add(this, increment); } } diff --git a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java index 2f19334ba80b..cded158a1579 100644 --- a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java +++ b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java @@ -25,6 +25,7 @@ package org.graalvm.compiler.replacements; import static java.util.FormattableFlags.ALTERNATE; +import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; import static org.graalvm.compiler.debug.DebugContext.DEFAULT_LOG_STREAM; import static org.graalvm.compiler.debug.DebugContext.applyFormattingFlagsAndWidth; import static org.graalvm.compiler.debug.DebugOptions.DebugStubsAndSnippets; @@ -212,8 +213,9 @@ static class Lazy { constantParameters[0] = true; } - // Retrieve the names only when assertions are turned on. - assert initNames(method, count); + // Retrieve the names only when assertions are turned on. Parameter annotations are + // unsupported in the native image. + assert IS_IN_NATIVE_IMAGE || initNames(method, count); } final boolean[] constantParameters; diff --git a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java index 4a3e7bdb5eaa..edfb2173e1ca 100644 --- a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java +++ b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java @@ -202,8 +202,10 @@ private static void registerStringPlugins(InvocationPlugins plugins, BytecodePro public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { if (receiver.isConstant()) { String s = snippetReflection.asObject(String.class, (JavaConstant) receiver.get().asConstant()); - b.addPush(JavaKind.Int, b.add(ConstantNode.forInt(s.hashCode()))); - return true; + if (s != null) { + b.addPush(JavaKind.Int, b.add(ConstantNode.forInt(s.hashCode()))); + return true; + } } return false; } diff --git a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/ArrayCopySnippets.java b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/ArrayCopySnippets.java index bf311d5527db..50c0b997fa2d 100644 --- a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/ArrayCopySnippets.java +++ b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/arraycopy/ArrayCopySnippets.java @@ -24,6 +24,7 @@ */ package org.graalvm.compiler.replacements.arraycopy; +import static jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE; import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.FREQUENT_PROBABILITY; import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.LIKELY_PROBABILITY; import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.NOT_FREQUENT_PROBABILITY; @@ -251,7 +252,9 @@ public void genericArraycopyWithSlowPathWork(Object src, int srcPos, Object dest } private static void incrementLengthCounter(int length, Counters counters) { - counters.lengthHistogram.inc(length); + if (!IS_BUILDING_NATIVE_IMAGE) { + counters.lengthHistogram.inc(length); + } } private static void checkLimits(Object src, int srcPos, Object dest, int destPos, int length, Counters counters) { diff --git a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java index 20f7cd2ce2a8..ddcdea327e1b 100644 --- a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java +++ b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java @@ -40,6 +40,7 @@ import jdk.vm.ci.meta.ResolvedJavaField; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.services.Services; /** * A {@link BytecodeProvider} that provides bytecode properties of a {@link ResolvedJavaMethod} as @@ -72,7 +73,11 @@ public ClassfileBytecodeProvider(MetaAccessProvider metaAccess, SnippetReflectio this.metaAccess = metaAccess; this.snippetReflection = snippetReflection; ClassLoader cl = getClass().getClassLoader(); - this.loader = cl == null ? ClassLoader.getSystemClassLoader() : cl; + if (Services.IS_IN_NATIVE_IMAGE) { + this.loader = null; + } else { + this.loader = cl == null ? ClassLoader.getSystemClassLoader() : cl; + } } public ClassfileBytecodeProvider(MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection, ClassLoader loader) { diff --git a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java index 843c976913cc..988b62795947 100644 --- a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java +++ b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java @@ -25,6 +25,7 @@ package org.graalvm.compiler.replacements.nodes; import static jdk.vm.ci.code.BytecodeFrame.isPlaceholderBci; +import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_UNKNOWN; @@ -205,13 +206,15 @@ public void lower(LoweringTool tool) { if (invoke.stateAfter() == null) { ResolvedJavaMethod method = graph().method(); - if (method.getAnnotation(MethodSubstitution.class) != null || method.getAnnotation(Snippet.class) != null) { - // One cause for this is that a MacroNode is created for a method that - // no longer needs a MacroNode. For example, Class.getComponentType() - // only needs a MacroNode prior to JDK9 as it was given a non-native - // implementation in JDK9. - throw new GraalError("%s macro created for call to %s in %s must be lowerable to a snippet or intrinsic graph. " + - "Maybe a macro node is not needed for this method in the current JDK?", getClass().getSimpleName(), targetMethod.format("%h.%n(%p)"), graph()); + if (!IS_IN_NATIVE_IMAGE) { + if (method.getAnnotation(MethodSubstitution.class) != null || method.getAnnotation(Snippet.class) != null) { + // One cause for this is that a MacroNode is created for a method that + // no longer needs a MacroNode. For example, Class.getComponentType() + // only needs a MacroNode prior to JDK9 as it was given a non-native + // implementation in JDK9. + throw new GraalError("%s macro created for call to %s in %s must be lowerable to a snippet or intrinsic graph. " + + "Maybe a macro node is not needed for this method in the current JDK?", getClass().getSimpleName(), targetMethod.format("%h.%n(%p)"), graph()); + } } throw new GraalError("%s: cannot lower to invoke without state: %s", graph(), this); } diff --git a/substratevm/ci_common/m7_eighth-native.hocon b/substratevm/ci_common/m7_eighth-native.hocon new file mode 100644 index 000000000000..b321b842ccbe --- /dev/null +++ b/substratevm/ci_common/m7_eighth-native.hocon @@ -0,0 +1,36 @@ +# Eigth of a M7 processor with 4 cores, 8 threads each + +m7_eighth-native.default : ${solaris-sparcv9} { + capabilities: ${solaris-sparcv9.capabilities} [m7_eighth] + environment : { + XMX : "16g" + XMS : "16g" + JVM_CONFIG : ${native-graal-config} + JVM : "server" + MACHINE_NAME: "m7_eighth" + } +} + +m7_eighth-native.default-g1gc : ${m7_eighth-native.default} { + environment : { + JVM_CONFIG : ${native-graal-config}"-g1gc" + } +} + + +builds += [ + ${m7_eighth-native.default} ${native-bench-dacapo} ${labsjdk8} { name: "bench-substratevm-dacapo-solaris-m7_eighth", timelimit: "1:00:00" } + ${m7_eighth-native.default} ${native-bench-dacapo-timing} ${labsjdk8} { name: "bench-substratevm-dacapo-timing-solaris-m7_eighth", timelimit: "1:00:00" } + ${m7_eighth-native.default} ${native-bench-scala-dacapo} ${labsjdk8} { name: "bench-substratevm-scala-dacapo-solaris-m7_eighth", timelimit: "1:00:00" } + ${m7_eighth-native.default} ${native-bench-scala-dacapo-timing} ${labsjdk8} { name: "bench-substratevm-scala-dacapo-timing-solaris-m7_eighth", timelimit: "1:00:00" } + ${m7_eighth-native.default} ${native-bench-specjvm2008-Single} ${labsjdk8} { name: "bench-substratevm-specjvm2008-Single-solaris-m7_eighth" } + ${m7_eighth-native.default} ${native-bench-specjvm2008-OneVM} ${labsjdk8} { name: "bench-substratevm-specjvm2008-OneVM-solaris-m7_eighth" } + ${m7_eighth-native.default} ${native-bench-specjbb2015} ${labsjdk8} { name: "bench-substratevm-specjbb2015-solaris-m7_eighth" } + ${m7_eighth-native.default} ${native-bench-micros-graal-whitebox} ${labsjdk8} { name: "bench-substratevm-jmh-micros-graal-whitebox-solaris-m7_eighth" } + ${m7_eighth-native.default} ${native-bench-micros-graal-dist} ${labsjdk8} { name: "bench-substratevm-jmh-micros-graal-dist-solaris-m7_eighth" } + + ${m7_eighth-native.default-g1gc} ${native-bench-dacapo} ${labsjdk8} { targets : [weekly, bench], name: "bench-substratevm-dacapo-g1gc-solaris-m7_eighth", timelimit: "1:00:00" } + ${m7_eighth-native.default-g1gc} ${native-bench-scala-dacapo} ${labsjdk8} { targets : [weekly, bench], name: "bench-substratevm-scala-dacapo-g1gc-solaris-m7_eighth", timelimit: "1:00:00" } + ${m7_eighth-native.default-g1gc} ${native-bench-specjvm2008-Single} ${labsjdk8} { targets : [weekly, bench], name: "bench-substratevm-specjvm2008-g1gc-Single-solaris-m7_eighth" } + ${m7_eighth-native.default-g1gc} ${native-bench-specjbb2015} ${labsjdk8} { targets : [weekly, bench], name: "bench-substratevm-specjbb2015-g1gc-solaris-m7_eighth" } +] diff --git a/substratevm/ci_common/native-bench.hocon b/substratevm/ci_common/native-bench.hocon new file mode 100644 index 000000000000..7d25a46174f9 --- /dev/null +++ b/substratevm/ci_common/native-bench.hocon @@ -0,0 +1,23 @@ +substrate-setup : { + setup : [ + [cd, ${substrate-suite-root}], + [mx, build] + ] +} + +# this is a workaround for a pyhocon bug where expansion doens't happen properly +native-bench-specjbb2015 : ${bench-specjbb2015} ${labsjdk8} ${substrate-setup} {} +native-bench-specjvm2008-Single : ${bench-specjvm2008-Single} ${labsjdk8} ${substrate-setup} {} +native-bench-dacapo-hwloc : ${bench-dacapo-hwloc} ${labsjdk8} ${substrate-setup} {} +native-bench-dacapo-timing-hwloc : ${bench-dacapo-timing-hwloc} ${labsjdk8} ${substrate-setup} {} +native-bench-dacapo-move-profiling-hwloc : ${bench-dacapo-move-profiling-hwloc} ${labsjdk8} ${substrate-setup} {} +native-bench-scala-dacapo-hwloc : ${bench-scala-dacapo-hwloc} ${labsjdk8} ${substrate-setup} {} +native-bench-scala-dacapo-timing-hwloc : ${bench-scala-dacapo-timing-hwloc} ${labsjdk8} ${substrate-setup} {} +native-bench-scala-dacapo-move-profiling-hwloc : ${bench-scala-dacapo-move-profiling-hwloc} ${labsjdk8} ${substrate-setup} {} +native-bench-specjvm2008-Single : ${bench-specjvm2008-Single} ${labsjdk8} ${substrate-setup} {} +native-bench-specjvm2008-OneVM : ${bench-specjvm2008-OneVM} ${labsjdk8} ${substrate-setup} {} +native-bench-micros-graal-whitebox : ${bench-micros-graal-whitebox} ${labsjdk8} ${substrate-setup} {} +native-bench-micros-graal-dist : ${bench-micros-graal-dist} ${labsjdk8} ${substrate-setup} {} +native-bench-dacapo-hwloc : ${bench-dacapo-hwloc} ${labsjdk8} ${substrate-setup} {} +native-bench-scala-dacapo-hwloc : ${bench-scala-dacapo-hwloc} ${labsjdk8} ${substrate-setup} {} +native-bench-renaissance-hwloc : ${bench-renaissance-hwloc} ${labsjdk8} ${substrate-setup} {} diff --git a/substratevm/ci_common/x32-native.hocon b/substratevm/ci_common/x32-native.hocon new file mode 100644 index 000000000000..31c4331fe23f --- /dev/null +++ b/substratevm/ci_common/x32-native.hocon @@ -0,0 +1,22 @@ +x32_native.default : ${linux-amd64} { + capabilities: ${linux-amd64.capabilities} [x32, no_frequency_scaling, tmpfs25g] + environment : { + XMX : "8g" + XMS : "8g" + JVM_CONFIG : ${native-graal-config} + JVM : "server" + MACHINE_NAME: "x32" + } +} + +x32_native.default-g1gc : ${x32_native.default} { + environment : { + JVM_CONFIG : ${native-graal-config}"-g1gc" + } +} + +builds += [ + ${x32_native.default} ${native-bench-renaissance-hwloc} ${labsjdk8} { name: "bench-substratevm-renaissance-linux-x32" } + + ${x32_native.default-g1gc} ${native-bench-renaissance-hwloc} ${labsjdk8} { targets : [weekly, bench], name: "bench-substratevm-renaissance-g1gc-linux-x32" } +] diff --git a/substratevm/ci_common/x4150-native.hocon b/substratevm/ci_common/x4150-native.hocon new file mode 100644 index 000000000000..3335a1fb13e7 --- /dev/null +++ b/substratevm/ci_common/x4150-native.hocon @@ -0,0 +1,25 @@ +x4150-native.default : ${linux-amd64} { + capabilities: ${linux-amd64.capabilities} [x4150, no_frequency_scaling] + environment : { + XMX : "32g" + XMS : "32g" + JVM_CONFIG : ${native-graal-config} + JVM : "server" + MACHINE_NAME: "x4150" + } +} + +x4150-native.default-g1gc : ${x4150-native.default} { + environment : { + JVM_CONFIG : ${native-graal-config}"-g1gc" + } +} + +# this is a workaround for a pyhocon bug where expansion doens't happen properly +native-bench-specjbb2005 : ${bench-specjbb2005} ${labsjdk8} ${substrate-setup} {} + +builds += [ + ${x4150-native.default} ${native-bench-specjbb2005} ${labsjdk8} { name: "bench-substratevm-specjbb2005-linux-x4150"} + + ${x4150-native.default-g1gc} ${native-bench-specjbb2005} ${labsjdk8} { targets : [weekly, bench], name: "bench-substratevm-specjbb2005-g1gc-linux-x4150"} +] diff --git a/substratevm/ci_common/x52-native.hocon b/substratevm/ci_common/x52-native.hocon new file mode 100644 index 000000000000..dda201c50672 --- /dev/null +++ b/substratevm/ci_common/x52-native.hocon @@ -0,0 +1,38 @@ +x52_native.default : ${linux-amd64} { + capabilities: ${linux-amd64.capabilities} [x52, no_frequency_scaling] + environment : { + XMX : "64g" + XMS : "64g" + JVM_CONFIG : ${native-graal-config} + JVM : "server" + MACHINE_NAME: "x52" + } +} + +x52_native.tmpfs10g : ${x52_native.default} { + capabilities: ${x52.default.capabilities} [tmpfs10g] +} + +x52_native.tmpfs10g-g1gc: ${x52_native.tmpfs10g} { + environment : { + JVM_CONFIG : ${native-graal-config}"-g1gc" + } +} + +builds += [ + ${x52_native.tmpfs10g} ${native-bench-dacapo-hwloc} { name: "bench-substratevm-dacapo-linux-x52" } + ${x52_native.tmpfs10g} ${native-bench-dacapo-timing-hwloc} { name: "bench-substratevm-dacapo-timing-linux-x52" } + ${x52_native.tmpfs10g} ${native-bench-dacapo-move-profiling-hwloc} { name: "bench-substratevm-dacapo-move-profiling-linux-x52" } + ${x52_native.tmpfs10g} ${native-bench-scala-dacapo-hwloc} { name: "bench-substratevm-scala-dacapo-linux-x52" } + ${x52_native.tmpfs10g} ${native-bench-scala-dacapo-timing-hwloc} { name: "bench-substratevm-scala-dacapo-timing-linux-x52" } + ${x52_native.tmpfs10g} ${native-bench-scala-dacapo-move-profiling-hwloc} { name: "bench-substratevm-scala-dacapo-move-profiling-linux-x52" } + ${x52_native.default} ${native-bench-specjvm2008-Single} { name: "bench-substratevm-specjvm2008-Single-linux-x52" } + ${x52_native.default} ${native-bench-specjvm2008-OneVM} { name: "bench-substratevm-specjvm2008-OneVM-linux-x52" } + ${x52_native.default} ${native-bench-specjbb2015} { name: "bench-substratevm-specjbb2015-linux-x52" } + ${x52_native.default} ${native-bench-micros-graal-whitebox} { name: "bench-substratevm-jmh-micros-graal-whitebox-linux-x52" } + ${x52_native.default} ${native-bench-micros-graal-dist} { name: "bench-substratevm-jmh-micros-graal-dist-linux-x52" } + ${x52_native.tmpfs10g-g1gc} ${native-bench-dacapo-hwloc} { targets : [weekly, bench], name: "bench-substratevm-dacapo-g1gc-linux-x52" } + ${x52_native.tmpfs10g-g1gc} ${native-bench-scala-dacapo-hwloc} { targets : [weekly, bench], name: "bench-substratevm-scala-dacapo-g1gc-linux-x52" } + ${x52_native.tmpfs10g-g1gc} ${native-bench-specjvm2008-Single} { targets : [weekly, bench], name: "bench-substratevm-specjvm2008-g1gc-Single-linux-x52" } + ${x52_native.tmpfs10g-g1gc} ${native-bench-specjbb2015} { targets : [weekly, bench], name: "bench-substratevm-specjbb2015-g1gc-linux-x52" } +] diff --git a/substratevm/mx.substratevm/mx_substratevm.py b/substratevm/mx.substratevm/mx_substratevm.py index b026047641d9..d9899f8dcb40 100644 --- a/substratevm/mx.substratevm/mx_substratevm.py +++ b/substratevm/mx.substratevm/mx_substratevm.py @@ -44,12 +44,19 @@ from argparse import ArgumentParser import fnmatch +def find_libgraal_path(): + for p in svm_suite().projects: + if p.name == libgraal_name: + return '-XX:JVMCILibPath=' + p.get_output_root() + mx.abort("Can't find libgraal") + import mx import mx_compiler import mx_gate import mx_unittest import mx_urlrewrites import mx_sdk +import mx_subst from mx_compiler import GraalArchiveParticipant from mx_compiler import run_java from mx_gate import Task @@ -97,6 +104,7 @@ def add_opens_to_all_unnamed(packageName): 'jdk.internal.vm.ci/jdk.vm.ci.amd64', 'jdk.internal.vm.ci/jdk.vm.ci.meta', 'jdk.internal.vm.ci/jdk.vm.ci.hotspot', + 'jdk.internal.vm.ci/jdk.vm.ci.services', 'jdk.internal.vm.ci/jdk.vm.ci.common', 'jdk.internal.vm.ci/jdk.vm.ci.code.site'] GRAAL_COMPILER_FLAGS_MAP['11'].extend(add_exports_from_packages(graal_compiler_export_packages)) @@ -149,6 +157,7 @@ def svm_java80(): IMAGE_ASSERTION_FLAGS = ['-H:+VerifyGraalGraphs', '-H:+VerifyGraalGraphEdges', '-H:+VerifyPhases'] suite = mx.suite('substratevm') svmSuites = [suite] +libgraal_name = 'libgraal' def _host_os_supported(): @@ -322,11 +331,19 @@ def __init__(self, image_deps=None, builder_deps=None, native_deps=None): self.builder_deps = builder_deps if builder_deps else [] self.native_deps = native_deps if native_deps else [] + def missingDependencies(self): + allDeps = self.image_deps + self.builder_deps + self.native_deps + return [dist_name for dist_name in allDeps if mx.dependency(dist_name, fatalIfMissing=False) == None] + + def allDepsAvailable(self): + return not self.missingDependencies() + tools_map = { 'truffle' : ToolDescriptor(), 'native-image' : ToolDescriptor(), 'junit' : ToolDescriptor(builder_deps=['mx:JUNIT_TOOL', 'JUNIT', 'HAMCREST']), 'regex' : ToolDescriptor(image_deps=['regex:TREGEX']), + 'libgraal' : ToolDescriptor(image_deps=['substratevm:GRAAL_HOTSPOT_LIBRARY']) } def native_image_path(native_image_root): @@ -396,10 +413,13 @@ def native_image_extract_dists(subdir, dist_names): # Create native-image layout for tools parts for tool_name in tools_map: tool_descriptor = tools_map[tool_name] - native_image_layout_dists(join('tools', tool_name, 'builder'), tool_descriptor.builder_deps) - native_image_layout_dists(join('tools', tool_name), tool_descriptor.image_deps) - native_image_extract_dists(join('tools', tool_name), tool_descriptor.native_deps) - native_image_option_properties('tools', tool_name, native_image_root) + if tool_descriptor.allDepsAvailable(): + native_image_layout_dists(join('tools', tool_name, 'builder'), tool_descriptor.builder_deps) + native_image_layout_dists(join('tools', tool_name), tool_descriptor.image_deps) + native_image_extract_dists(join('tools', tool_name), tool_descriptor.native_deps) + native_image_option_properties('tools', tool_name, native_image_root) + else: + mx.log('Tool {} is not available because of missing dependencies: {}'.format(tool_name, ', '.join(tool_descriptor.missingDependencies()))) # Create native-image layout for svm parts svm_subdir = join('lib', 'svm') @@ -409,6 +429,68 @@ def native_image_extract_dists(subdir, dist_names): for clibrary_path in clibrary_paths(): copy_tree(clibrary_path, clibraries_dest) +class NativeImageToolTask(mx.Project): + def __init__(self, suite, name, deps, workingSets, theLicense=None, **kwargs): + super(NativeImageToolTask, self).__init__(suite, name, "", [], deps, workingSets, suite.dir, theLicense) + self.toolArgs = kwargs.pop('toolArgs', []) + self.tool = kwargs.pop('tool') + self.output = mx_subst.results_substitutions.substitute(kwargs.pop('output')) + self.buildDependencies = ['substratevm:GRAAL_HOTSPOT_LIBRARY'] + + def getResults(self): + return None + + def getBuildTask(self, args): + if self.suite == svm_suite(): + return NativeImageToolBuildTask(args, self) + else: + return mx.NoOpTask(self, args) + +class NativeImageToolBuildTask(mx.ProjectBuildTask): + def __init__(self, args, project): + super(NativeImageToolBuildTask, self).__init__(args, min(8, mx.cpu_count()), project) + self._newestOutput = None + + def __str__(self): + return "Building tool " + self.subject.name + + def build(self): + mx.ensure_dir_exists(self.subject.get_output_root()) + args = self.subject.toolArgs + ['--tool:' + self.subject.tool] + ['-H:Path=' + self.subject.get_output_root()] + java_dbg_port = mx.get_opts().java_dbg_port + # If -d or --dbg is on the command line, we want to debug the com.oracle.svm.hosted.NativeImageGeneratorRunner + # process, not the com.oracle.svm.driver.NativeImage process that launches it + if java_dbg_port: + args.append('--debug-attach=' + str(java_dbg_port)) + if mx.get_opts().verbose: + args.append('--verbose') + with mx.DisableJavaDebugging(): + native_image_on_jvm(args) + + def clean(self, forBuild=False): + if forBuild: + return + + if exists(self.subject.get_output_root()): + remove_tree(self.subject.get_output_root()) + + def needsBuild(self, newestInput): + sup = super(NativeImageToolBuildTask, self).needsBuild(newestInput) + if sup[0]: + return sup + witness = self.newestOutput() + if not self._newestOutput or witness.isNewerThan(self._newestOutput): + self._newestOutput = witness + if not witness.exists(): + return True, witness.path + ' does not exist' + if newestInput and witness.isOlderThan(newestInput): + return True, '{} is older than {}'.format(witness, newestInput) + return False, 'output is up to date' + + def newestOutput(self): + return mx.TimeStampFile(join(self.subject.get_output_root(), self.subject.output)) + + def truffle_language_ensure(language_flag, version=None, native_image_root=None, early_exit=False, extract=True): """ Ensures that we have a valid suite for the given language_flag, by downloading a binary if necessary @@ -504,6 +586,9 @@ def __getattr__(self, name): 'test', 'maven', 'js', + 'build', + 'test', + 'benchmarktest' ]) @contextmanager @@ -556,7 +641,8 @@ def native_image_func(args, **kwargs): native_image_context.hosted_assertions = ['-J-ea', '-J-esa'] def svm_gate_body(args, tasks): - build_native_image_image() + with Task('Build native-image image', tasks, tags=[GraalTags.build, GraalTags.helloworld]) as t: + if t: build_native_image_image() with native_image_context(IMAGE_ASSERTION_FLAGS) as native_image: with Task('image demos', tasks, tags=[GraalTags.helloworld]) as t: if t: @@ -581,6 +667,27 @@ def svm_gate_body(args, tasks): maven_plugin_test([]) +def libgraal_gate_body(args, tasks): + if mx.get_os() == 'windows': + return + + if not tools_map['libgraal'].allDepsAvailable(): + return + + with Task('Build libgraal', tasks, tags=[GraalTags.build, GraalTags.benchmarktest, GraalTags.test]) as t: + if t: + native_image_on_jvm(['--tool:libgraal', '-ea']) + extra_vm_argument = args.extra_vm_argument + print(extra_vm_argument) + if extra_vm_argument: + extra_vm_argument = extra_vm_argument + ['-XX:+UseJVMCINativeLibrary', '-XX:JVMCILibPath=' + os.getcwd()] + else: + extra_vm_argument = ['-XX:+UseJVMCINativeLibrary', '-XX:JVMCILibPath=' + os.getcwd()] + + mx_compiler.compiler_gate_benchmark_runner(tasks, extra_vm_argument, libgraal=True) + +mx_gate.add_gate_runner(suite, libgraal_gate_body) + def javac_image_command(javac_path): return [join(javac_path, 'javac'), "-proc:none", "-bootclasspath", join(mx_compiler.jdk.home, "jre", "lib", "rt.jar")] @@ -1054,6 +1161,11 @@ def maven_plugin_install(args): ] mx.log('\n'.join(success_message)) +@mx.command(suite.name, 'vm', '[-options] class [args...]') +def run_vm(args, nonZeroIsFatal=True, out=None, err=None, cwd=None, timeout=None, debugLevel=None, vmbuild=None): + """run a Java program by executing the java executable in a JVMCI JDK""" + libgraal_args = [find_libgraal_path()] + return mx_compiler.run_java(libgraal_args + args, nonZeroIsFatal=nonZeroIsFatal, out=out, err=err, cwd=cwd, timeout=timeout) @mx.command(suite.name, 'maven-plugin-test') def maven_plugin_test(args): diff --git a/substratevm/mx.substratevm/mx_substratevm_benchmark.py b/substratevm/mx.substratevm/mx_substratevm_benchmark.py index 0c181f198b79..7eb1ab62da27 100644 --- a/substratevm/mx.substratevm/mx_substratevm_benchmark.py +++ b/substratevm/mx.substratevm/mx_substratevm_benchmark.py @@ -38,6 +38,7 @@ import functools import mx +import mx_graal_benchmark import mx_substratevm _default_image_options = ['-R:+PrintGCSummary', '-R:+PrintGC', '-H:+PrintImageHeapPartitionSizes', @@ -298,3 +299,8 @@ def run_js(vmArgs, jsArgs, nonZeroIsFatal, out, err, cwd): if nonZeroIsFatal: mx.abort('Javascript image building for js-benchmarks failed') return -1 + +mx_graal_benchmark.build_jvmci_vm_variants('server', 'native-graal-core', + ['-server', '-XX:+EnableJVMCI', '-XX:JVMCILibArgs=-Dgraal.CompilerConfiguration=community', '-Djvmci.Compiler=graal', + mx_substratevm.find_libgraal_path, '-XX:+UseJVMCINativeLibrary'], + mx_graal_benchmark._graal_variants, suite=mx.suite('substratevm'), priority=16, hosted=False) diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py index 639dd6eb0484..073b1f7eed19 100644 --- a/substratevm/mx.substratevm/suite.py +++ b/substratevm/mx.substratevm/suite.py @@ -576,6 +576,36 @@ }, }, }, + + "libgraal" : { + "class" : "NativeImageToolTask", + "dependencies": [ + "SVM_DRIVER", + "SVM_HOSTED_NATIVE", + "compiler:GRAAL" + ], + "tool" : "libgraal", + "toolArgs" : ['--shared'], + "output" : "", + "defaultBuild": False + }, + + "com.oracle.svm.graal.hotspot.nativelib" : { + "subDir": "src", + "sourceDirs": ["src"], + "dependencies": [ + "com.oracle.svm.jni", + "com.oracle.svm.graal", + "compiler:GRAAL" + ], + "checkstyle" : "com.oracle.svm.hosted", + "javaCompliance": "1.8", + "annotationProcessors": [ + "compiler:GRAAL_NODEINFO_PROCESSOR", + "compiler:GRAAL_REPLACEMENTS_PROCESSOR", + "compiler:GRAAL_OPTIONS_PROCESSOR", + ], + }, }, "distributions": { @@ -678,6 +708,19 @@ ], }, + "GRAAL_HOTSPOT_LIBRARY": { + "description" : "SubstrateVM HotSpot Graal library support", + "dependencies": [ + "com.oracle.svm.graal.hotspot.nativelib", + ], + "overlaps" : [ + "LIBRARY_SUPPORT" + ], + "distDependencies": [ + "SVM", + ], + }, + # # Native Projects # diff --git a/substratevm/mx.substratevm/tools-libgraal.properties b/substratevm/mx.substratevm/tools-libgraal.properties new file mode 100644 index 000000000000..b09871009104 --- /dev/null +++ b/substratevm/mx.substratevm/tools-libgraal.properties @@ -0,0 +1,15 @@ +# Continuation backslashes must have whitespace before them or there will be no space between arguments +Requires = tool:truffle + +ImageName = libjvmcicompiler + +Args = --shared \ + -cp ${.}/../../tools/libgraal/graal-hotspot-library.jar \ + -H:Features=com.oracle.svm.graal.hotspot.nativelib.HotSpotGraalLibraryFeature \ + -H:+MultiThreaded \ + -H:-UseServiceLoaderFeature \ + -H:+AllowFoldMethods \ + -H:JNIConfigurationResources=com/oracle/svm/graal/hotspot/nativelib/HotSpotGraalLibrary.json + +JavaArgs = -Djdk.vm.ci.services.aot=true \ + -ea diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java index 9ca8b3cb0896..f9cf67781e7e 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java @@ -28,12 +28,15 @@ import static jdk.vm.ci.common.JVMCIError.shouldNotReachHere; import java.lang.reflect.Modifier; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Optional; +import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; +import org.graalvm.compiler.api.runtime.GraalJVMCICompiler; import org.graalvm.compiler.bytecode.Bytecode; import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode; import org.graalvm.compiler.core.common.PermanentBailoutException; @@ -41,6 +44,7 @@ import org.graalvm.compiler.core.common.type.ObjectStamp; import org.graalvm.compiler.core.common.type.TypeReference; import org.graalvm.compiler.debug.DebugContext; +import org.graalvm.compiler.debug.DebugContext.Description; import org.graalvm.compiler.debug.Indent; import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.Node.NodeIntrinsic; @@ -140,6 +144,7 @@ import jdk.vm.ci.common.JVMCIError; import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.runtime.JVMCI; public class MethodTypeFlowBuilder { @@ -170,7 +175,11 @@ public MethodTypeFlowBuilder(BigBang bb, StructuredGraph graph) { @SuppressWarnings("try") private boolean parse() { OptionValues options = bb.getOptions(); - DebugContext debug = DebugContext.create(options, new GraalDebugHandlersFactory(bb.getProviders().getSnippetReflection())); + GraalJVMCICompiler compiler = (GraalJVMCICompiler) JVMCI.getRuntime().getCompiler(); + SnippetReflectionProvider snippetReflection = compiler.getGraalRuntime().getRequiredCapability(SnippetReflectionProvider.class); + // Use the real SnippetReflectionProvider for dumping + Description description = new Description(method, toString()); + DebugContext debug = DebugContext.create(options, description, Collections.singletonList(new GraalDebugHandlersFactory(snippetReflection))); try (Indent indent = debug.logAndIndent("parse graph %s", method)) { boolean needParsing = false; diff --git a/substratevm/src/com.oracle.svm.core.graal/src/com/oracle/svm/core/graal/snippets/SubstrateTemplates.java b/substratevm/src/com.oracle.svm.core.graal/src/com/oracle/svm/core/graal/snippets/SubstrateTemplates.java index 878c8d90ec9f..f2ce79b642d5 100644 --- a/substratevm/src/com.oracle.svm.core.graal/src/com/oracle/svm/core/graal/snippets/SubstrateTemplates.java +++ b/substratevm/src/com.oracle.svm.core.graal/src/com/oracle/svm/core/graal/snippets/SubstrateTemplates.java @@ -36,10 +36,10 @@ import org.graalvm.compiler.phases.util.Providers; import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates; import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo; +import org.graalvm.compiler.replacements.Snippets; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; import org.graalvm.word.LocationIdentity; -import org.graalvm.compiler.replacements.Snippets; import com.oracle.svm.core.config.ConfigurationValues; import com.oracle.svm.core.graal.nodes.SubstrateFieldLocationIdentity; @@ -47,6 +47,7 @@ import com.oracle.svm.core.util.VMError; import jdk.vm.ci.meta.MetaAccessProvider; +import jdk.vm.ci.meta.ResolvedJavaMethod; public class SubstrateTemplates extends AbstractTemplates { @@ -57,13 +58,23 @@ protected SubstrateTemplates(OptionValues options, Iterable declaringClass, String methodName, LocationIdentity... privateLocations) { - return snippet(declaringClass, methodName, (Object[]) privateLocations); + protected SnippetInfo snippet(Class declaringClass, String methodName, ResolvedJavaMethod original, Object receiver, LocationIdentity... privateLocations) { + return snippet(declaringClass, methodName, original, receiver, (Object[]) privateLocations); + } + + @Platforms(Platform.HOSTED_ONLY.class) + protected SnippetInfo snippet(Class declaringClass, String methodName, Object receiver, Object[] privateLocations) { + return snippet(declaringClass, methodName, null, receiver, privateLocations); } @Platforms(Platform.HOSTED_ONLY.class) protected SnippetInfo snippet(Class declaringClass, String methodName, Object[] privateLocations) { - return super.snippet(declaringClass, methodName, toLocationIdentity(providers.getMetaAccess(), privateLocations)); + return snippet(declaringClass, methodName, null, null, privateLocations); + } + + @Platforms(Platform.HOSTED_ONLY.class) + protected SnippetInfo snippet(Class declaringClass, String methodName, ResolvedJavaMethod original, Object receiver, Object[] privateLocations) { + return super.snippet(declaringClass, methodName, original, receiver, toLocationIdentity(providers.getMetaAccess(), privateLocations)); } @Platforms(Platform.HOSTED_ONLY.class) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateUtil.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateUtil.java index c0681f4f1c9d..fe51f781bc50 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateUtil.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateUtil.java @@ -83,6 +83,7 @@ import com.oracle.svm.core.util.VMError; import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.services.Services; public class SubstrateUtil { @@ -113,6 +114,20 @@ public static String getArchitectureName() { return arch; } + /** + * @return true if the standalone libgraal is being built instead of a normal SVM image. + */ + public static boolean isBuildingLibgraal() { + return Services.IS_BUILDING_NATIVE_IMAGE; + } + + /** + * @return true if running in the standalone libgraal image. + */ + public static boolean isInLibgraal() { + return Services.IS_IN_NATIVE_IMAGE; + } + @TargetClass(com.oracle.svm.core.SubstrateUtil.class) static final class Target_com_oracle_svm_core_SubstrateUtil { @Alias @RecomputeFieldValue(kind = Kind.FromAlias, isFinal = true)// diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/meta/SubstrateObjectConstant.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/meta/SubstrateObjectConstant.java index d9507ef2eaae..4760132aafcd 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/meta/SubstrateObjectConstant.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/meta/SubstrateObjectConstant.java @@ -29,6 +29,7 @@ import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; +import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.snippets.KnownIntrinsics; import jdk.vm.ci.meta.Constant; @@ -78,7 +79,7 @@ public static T asObject(Class type, JavaConstant constant) { } public static Object asObject(ResolvedJavaType type, JavaConstant constant) { - if (constant.isNonNull()) { + if (constant.isNonNull() && constant instanceof SubstrateObjectConstant) { Object object = ((SubstrateObjectConstant) constant).object; if (type.isInstance(constant)) { return object; @@ -113,6 +114,9 @@ private SubstrateObjectConstant(Object object, boolean compressed) { this.object = object; this.compressed = compressed; assert object != null; + if (SubstrateUtil.isInLibgraal()) { + throw new InternalError(); + } } public Object getObject() { diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.nativelib/src/com/oracle/svm/graal/hotspot/nativelib/HotSpotGraalLibrary.java b/substratevm/src/com.oracle.svm.graal.hotspot.nativelib/src/com/oracle/svm/graal/hotspot/nativelib/HotSpotGraalLibrary.java new file mode 100644 index 000000000000..0bfe89392163 --- /dev/null +++ b/substratevm/src/com.oracle.svm.graal.hotspot.nativelib/src/com/oracle/svm/graal/hotspot/nativelib/HotSpotGraalLibrary.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2017, 2018, 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.nativelib; + +import org.graalvm.nativeimage.IsolateThread; +import org.graalvm.nativeimage.c.function.CEntryPoint; + +import jdk.vm.ci.hotspot.HotSpotCompilationRequest; +import jdk.vm.ci.runtime.JVMCI; +import jdk.vm.ci.runtime.JVMCICompiler; +import jdk.vm.ci.runtime.JVMCIRuntime; + +public final class HotSpotGraalLibrary { + + @CEntryPoint(name = "graal_compile_method", documentation = { + "Compiles a method using Graal" + }) + public static int graalCompileMethod(@SuppressWarnings("unused") IsolateThread isolateThread) { + try { + run(getRequest()); + } catch (Throwable e) { + // e.printStackTrace(); + } + return 0; + } + + /** + * Temporary workaround for inability to pass a HotSpotCompilationRequest in to + * {@link #graalCompileMethod(IsolateThread)}. + */ + private static native HotSpotCompilationRequest getRequest(); + + protected static void run(HotSpotCompilationRequest request) { + JVMCICompiler compiler = getCompiler(); + compiler.compileMethod(request); + } + + protected static JVMCICompiler getCompiler() { + JVMCIRuntime runtime = JVMCI.getRuntime(); + JVMCICompiler compiler = runtime.getCompiler(); + return compiler; + } +} diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.nativelib/src/com/oracle/svm/graal/hotspot/nativelib/HotSpotGraalLibrary.json b/substratevm/src/com.oracle.svm.graal.hotspot.nativelib/src/com/oracle/svm/graal/hotspot/nativelib/HotSpotGraalLibrary.json new file mode 100644 index 000000000000..251914369d4c --- /dev/null +++ b/substratevm/src/com.oracle.svm.graal.hotspot.nativelib/src/com/oracle/svm/graal/hotspot/nativelib/HotSpotGraalLibrary.json @@ -0,0 +1,1670 @@ +[ + { + "name": "[Ljava.lang.ArrayIndexOutOfBoundsException;" + }, + { + "name": "[Ljava.lang.Boolean;" + }, + { + "name": "[Ljava.lang.Byte;" + }, + { + "name": "[Ljava.lang.Character;" + }, + { + "name": "[Ljava.lang.Class;" + }, + { + "name": "[Ljava.lang.Double;" + }, + { + "name": "[Ljava.lang.Float;" + }, + { + "name": "[Ljava.lang.IllegalArgumentException;" + }, + { + "name": "[Ljava.lang.IllegalStateException;" + }, + { + "name": "[Ljava.lang.Integer;" + }, + { + "name": "[Ljava.lang.InternalError;" + }, + { + "name": "[Ljava.lang.Long;" + }, + { + "name": "[Ljava.lang.NullPointerException;" + }, + { + "name": "[Ljava.lang.Object;" + }, + { + "name": "[Ljava.lang.Short;" + }, + { + "name": "[Ljava.lang.StackTraceElement;" + }, + { + "name": "[Ljava.lang.String;" + }, + { + "name": "[Ljava.lang.Throwable;" + }, + { + "name": "[Ljava.lang.UnsatisfiedLinkError;" + }, + { + "name": "[Ljdk.vm.ci.code.Architecture;" + }, + { + "name": "[Ljdk.vm.ci.code.BytecodeFrame;" + }, + { + "name": "[Ljdk.vm.ci.code.BytecodePosition;" + }, + { + "name": "[Ljdk.vm.ci.code.DebugInfo;" + }, + { + "name": "[Ljdk.vm.ci.code.InstalledCode;" + }, + { + "name": "[Ljdk.vm.ci.code.InvalidInstalledCodeException;" + }, + { + "name": "[Ljdk.vm.ci.code.Location;" + }, + { + "name": "[Ljdk.vm.ci.code.Register;" + }, + { + "name": "[Ljdk.vm.ci.code.RegisterSaveLayout;" + }, + { + "name": "[Ljdk.vm.ci.code.RegisterValue;" + }, + { + "name": "[Ljdk.vm.ci.code.StackLockValue;" + }, + { + "name": "[Ljdk.vm.ci.code.StackSlot;" + }, + { + "name": "[Ljdk.vm.ci.code.TargetDescription;" + }, + { + "name": "[Ljdk.vm.ci.code.VirtualObject;" + }, + { + "name": "[Ljdk.vm.ci.code.site.Call;" + }, + { + "name": "[Ljdk.vm.ci.code.site.ConstantReference;" + }, + { + "name": "[Ljdk.vm.ci.code.site.DataPatch;" + }, + { + "name": "[Ljdk.vm.ci.code.site.DataSectionReference;" + }, + { + "name": "[Ljdk.vm.ci.code.site.ExceptionHandler;" + }, + { + "name": "[Ljdk.vm.ci.code.site.Infopoint;" + }, + { + "name": "[Ljdk.vm.ci.code.site.InfopointReason;" + }, + { + "name": "[Ljdk.vm.ci.code.site.Mark;" + }, + { + "name": "[Ljdk.vm.ci.code.site.Site;" + }, + { + "name": "[Ljdk.vm.ci.code.stack.InspectedFrameVisitor;" + }, + { + "name": "[Ljdk.vm.ci.common.JVMCIError;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.CompilerToVM;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.DirectHotSpotObjectConstantImpl;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotCompilationRequestResult;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotCompiledCode$Comment;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotCompiledCode;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotCompiledNmethod;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotCompressedNullConstant;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotConstantPool;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotForeignCallTarget;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotInstalledCode;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotJVMCIRuntime;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotMetaData;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotMetaspaceConstantImpl;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotNmethod;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotNmethodHandle;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotObjectConstantImpl;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotReferenceMap;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotResolvedJavaFieldImpl;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotResolvedPrimitiveType;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotSentinelConstant;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotSpeculationLog;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.HotSpotStackFrameReference;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.IndirectHotSpotObjectConstantImpl;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.VMField;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.VMFlag;" + }, + { + "name": "[Ljdk.vm.ci.hotspot.VMIntrinsicMethod;" + }, + { + "name": "[Ljdk.vm.ci.meta.Assumptions$CallSiteTargetValue;" + }, + { + "name": "[Ljdk.vm.ci.meta.Assumptions$ConcreteMethod;" + }, + { + "name": "[Ljdk.vm.ci.meta.Assumptions$ConcreteSubtype;" + }, + { + "name": "[Ljdk.vm.ci.meta.Assumptions$LeafType;" + }, + { + "name": "[Ljdk.vm.ci.meta.Assumptions$NoFinalizableSubclass;" + }, + { + "name": "[Ljdk.vm.ci.meta.JavaConstant;" + }, + { + "name": "[Ljdk.vm.ci.meta.JavaKind;" + }, + { + "name": "[Ljdk.vm.ci.meta.NullConstant;" + }, + { + "name": "[Ljdk.vm.ci.meta.PrimitiveConstant;" + }, + { + "name": "[Ljdk.vm.ci.meta.RawConstant;" + }, + { + "name": "[Ljdk.vm.ci.meta.ResolvedJavaMethod;" + }, + { + "name": "[Ljdk.vm.ci.meta.Value;" + }, + { + "name": "[Ljdk.vm.ci.meta.ValueKind;" + }, + { + "name": "[Ljdk.vm.ci.runtime.JVMCI;" + }, + { + "name": "[Ljdk.vm.ci.services.JVMCIClassLoaderFactory;" + }, + { + "methods": [ + { + "name": "" + } + ], + "name": "java.lang.ArrayIndexOutOfBoundsException" + }, + { + "fields": [ + { + "name": "value" + } + ], + "methods": [ + { + "name": "" + } + ], + "name": "java.lang.Boolean" + }, + { + "fields": [ + { + "name": "value" + } + ], + "methods": [ + { + "name": "" + } + ], + "name": "java.lang.Byte" + }, + { + "fields": [ + { + "name": "value" + } + ], + "methods": [ + { + "name": "" + } + ], + "name": "java.lang.Character" + }, + { + "methods": [ + { + "name": "getName" + } + ], + "name": "java.lang.Class" + }, + { + "fields": [ + { + "name": "value" + } + ], + "methods": [ + { + "name": "" + } + ], + "name": "java.lang.Double" + }, + { + "fields": [ + { + "name": "value" + } + ], + "methods": [ + { + "name": "" + } + ], + "name": "java.lang.Float" + }, + { + "methods": [ + { + "name": "" + } + ], + "name": "java.lang.IllegalArgumentException" + }, + { + "methods": [ + { + "name": "" + } + ], + "name": "java.lang.IllegalStateException" + }, + { + "fields": [ + { + "name": "value" + } + ], + "methods": [ + { + "name": "" + } + ], + "name": "java.lang.Integer" + }, + { + "methods": [ + { + "name": "" + } + ], + "name": "java.lang.InternalError" + }, + { + "fields": [ + { + "name": "value" + } + ], + "methods": [ + { + "name": "" + } + ], + "name": "java.lang.Long" + }, + { + "methods": [ + { + "name": "" + } + ], + "name": "java.lang.NullPointerException" + }, + { + "name": "java.lang.Object" + }, + { + "fields": [ + { + "name": "value" + } + ], + "methods": [ + { + "name": "" + } + ], + "name": "java.lang.Short" + }, + { + "fields": [ + { + "name": "declaringClass" + }, + { + "name": "fileName" + }, + { + "name": "lineNumber" + }, + { + "name": "methodName" + } + ], + "methods": [ + { + "name": "" + } + ], + "name": "java.lang.StackTraceElement" + }, + { + "name": "java.lang.String" + }, + { + "fields": [ + { + "name": "detailMessage" + } + ], + "name": "java.lang.Throwable" + }, + { + "methods": [ + { + "name": "" + } + ], + "name": "java.lang.UnsatisfiedLinkError" + }, + { + "fields": [ + { + "name": "wordKind" + } + ], + "name": "jdk.vm.ci.code.Architecture" + }, + { + "fields": [ + { + "name": "AFTER_BCI" + }, + { + "name": "AFTER_EXCEPTION_BCI" + }, + { + "name": "BEFORE_BCI" + }, + { + "name": "INVALID_FRAMESTATE_BCI" + }, + { + "name": "UNKNOWN_BCI" + }, + { + "name": "UNWIND_BCI" + }, + { + "name": "duringCall" + }, + { + "name": "numLocals" + }, + { + "name": "numLocks" + }, + { + "name": "numStack" + }, + { + "name": "rethrowException" + }, + { + "name": "slotKinds" + }, + { + "name": "values" + } + ], + "name": "jdk.vm.ci.code.BytecodeFrame" + }, + { + "fields": [ + { + "name": "bci" + }, + { + "name": "caller" + }, + { + "name": "method" + } + ], + "name": "jdk.vm.ci.code.BytecodePosition" + }, + { + "fields": [ + { + "name": "bytecodePosition" + }, + { + "name": "calleeSaveInfo" + }, + { + "name": "referenceMap" + }, + { + "name": "virtualObjectMapping" + } + ], + "name": "jdk.vm.ci.code.DebugInfo" + }, + { + "fields": [ + { + "name": "address" + }, + { + "name": "entryPoint" + }, + { + "name": "name" + }, + { + "name": "version" + } + ], + "name": "jdk.vm.ci.code.InstalledCode" + }, + { + "methods": [ + { + "name": "" + } + ], + "name": "jdk.vm.ci.code.InvalidInstalledCodeException" + }, + { + "fields": [ + { + "name": "offset" + }, + { + "name": "reg" + } + ], + "name": "jdk.vm.ci.code.Location" + }, + { + "fields": [ + { + "name": "encoding" + }, + { + "name": "number" + } + ], + "name": "jdk.vm.ci.code.Register" + }, + { + "fields": [ + { + "name": "registers" + }, + { + "name": "slots" + } + ], + "name": "jdk.vm.ci.code.RegisterSaveLayout" + }, + { + "fields": [ + { + "name": "reg" + } + ], + "name": "jdk.vm.ci.code.RegisterValue" + }, + { + "fields": [ + { + "name": "eliminated" + }, + { + "name": "owner" + }, + { + "name": "slot" + } + ], + "name": "jdk.vm.ci.code.StackLockValue" + }, + { + "fields": [ + { + "name": "addFrameSize" + }, + { + "name": "offset" + } + ], + "name": "jdk.vm.ci.code.StackSlot" + }, + { + "fields": [ + { + "name": "arch" + } + ], + "name": "jdk.vm.ci.code.TargetDescription" + }, + { + "fields": [ + { + "name": "baseObject" + }, + { + "name": "id" + }, + { + "name": "slotKinds" + }, + { + "name": "type" + }, + { + "name": "values" + } + ], + "name": "jdk.vm.ci.code.VirtualObject" + }, + { + "fields": [ + { + "name": "target" + } + ], + "name": "jdk.vm.ci.code.site.Call" + }, + { + "fields": [ + { + "name": "constant" + } + ], + "name": "jdk.vm.ci.code.site.ConstantReference" + }, + { + "fields": [ + { + "name": "reference" + } + ], + "name": "jdk.vm.ci.code.site.DataPatch" + }, + { + "fields": [ + { + "name": "offset" + } + ], + "name": "jdk.vm.ci.code.site.DataSectionReference" + }, + { + "fields": [ + { + "name": "handlerPos" + } + ], + "name": "jdk.vm.ci.code.site.ExceptionHandler" + }, + { + "fields": [ + { + "name": "debugInfo" + }, + { + "name": "reason" + } + ], + "name": "jdk.vm.ci.code.site.Infopoint" + }, + { + "fields": [ + { + "name": "CALL" + }, + { + "name": "IMPLICIT_EXCEPTION" + }, + { + "name": "SAFEPOINT" + } + ], + "name": "jdk.vm.ci.code.site.InfopointReason" + }, + { + "fields": [ + { + "name": "id" + } + ], + "name": "jdk.vm.ci.code.site.Mark" + }, + { + "fields": [ + { + "name": "pcOffset" + } + ], + "name": "jdk.vm.ci.code.site.Site" + }, + { + "name": "jdk.vm.ci.code.stack.InspectedFrameVisitor" + }, + { + "methods": [ + { + "name": "" + } + ], + "name": "jdk.vm.ci.common.JVMCIError" + }, + { + "methods": [ + { + "name": "allocateCompileId" + }, + { + "name": "arrayBaseOffset" + }, + { + "name": "arrayIndexScale" + }, + { + "name": "asJavaType" + }, + { + "name": "asResolvedJavaMethod" + }, + { + "name": "asString" + }, + { + "name": "boxPrimitive" + }, + { + "name": "collectCounters" + }, + { + "name": "compileToBytecode" + }, + { + "name": "constantPoolRemapInstructionOperandFromCache" + }, + { + "name": "disassembleCodeBlob" + }, + { + "name": "ensureInitialized" + }, + { + "name": "equals" + }, + { + "name": "executeHotSpotNmethod" + }, + { + "name": "findUniqueConcreteMethod" + }, + { + "name": "flushCompileLogOutput" + }, + { + "name": "flushDebugOutput" + }, + { + "name": "getArrayLength" + }, + { + "name": "getByte" + }, + { + "name": "getBytecode" + }, + { + "name": "getClassInitializer" + }, + { + "name": "getCode" + }, + { + "name": "getComponentType" + }, + { + "name": "getConstantPool" + }, + { + "name": "getDeclaredConstructors" + }, + { + "name": "getDeclaredMethods" + }, + { + "name": "getExceptionTableLength" + }, + { + "name": "getExceptionTableStart" + }, + { + "name": "getFingerprint" + }, + { + "name": "getFlagValue" + }, + { + "name": "getHostClass" + }, + { + "name": "getIdentityHashCode" + }, + { + "name": "getImplementor" + }, + { + "name": "getInt" + }, + { + "name": "getInterfaces" + }, + { + "name": "getJavaMirror" + }, + { + "name": "getLineNumberTable" + }, + { + "name": "getLocalVariableTableLength" + }, + { + "name": "getLocalVariableTableStart" + }, + { + "name": "getLong" + }, + { + "name": "getMaxCallTargetOffset" + }, + { + "name": "getMetadata" + }, + { + "name": "getObject" + }, + { + "name": "getObjectAtAddress" + }, + { + "name": "getResolvedJavaMethod" + }, + { + "name": "getResolvedJavaType0" + }, + { + "name": "getShort" + }, + { + "name": "getSignaturePolymorphicHolders" + }, + { + "name": "getStackTraceElement" + }, + { + "name": "getSymbol" + }, + { + "name": "getVtableIndexForInterfaceMethod" + }, + { + "name": "hasCompiledCodeForOSR" + }, + { + "name": "hasFinalizableSubclass" + }, + { + "name": "hasNeverInlineDirective" + }, + { + "name": "installCode" + }, + { + "name": "interpreterFrameSize" + }, + { + "name": "invalidateHotSpotNmethod" + }, + { + "name": "isAssignableFrom" + }, + { + "name": "isCompilable" + }, + { + "name": "isInstance" + }, + { + "name": "isInternedString" + }, + { + "name": "isMature" + }, + { + "name": "isResolvedInvokeHandleInPool" + }, + { + "name": "iterateFrames" + }, + { + "name": "lookupAppendixInPool" + }, + { + "name": "lookupClass" + }, + { + "name": "lookupKlassInPool" + }, + { + "name": "lookupKlassRefIndexInPool" + }, + { + "name": "lookupMethodInPool" + }, + { + "name": "lookupNameAndTypeRefIndexInPool" + }, + { + "name": "lookupNameInPool" + }, + { + "name": "lookupSignatureInPool" + }, + { + "name": "lookupType" + }, + { + "name": "materializeVirtualObjects" + }, + { + "name": "methodDataProfileDataSize" + }, + { + "name": "methodIsIgnoredBySecurityStackWalk" + }, + { + "name": "readArrayElement" + }, + { + "name": "readConfiguration" + }, + { + "name": "readFieldValue" + }, + { + "name": "readUncompressedOop" + }, + { + "name": "registerNativeMethods" + }, + { + "name": "registerNatives" + }, + { + "name": "reprofile" + }, + { + "name": "resetCompilationStatistics" + }, + { + "name": "resolveConstantInPool" + }, + { + "name": "resolveFieldInPool" + }, + { + "name": "resolveInvokeDynamicInPool" + }, + { + "name": "resolveInvokeHandleInPool" + }, + { + "name": "resolveMethod" + }, + { + "name": "resolvePossiblyCachedConstantInPool" + }, + { + "name": "resolveTypeInPool" + }, + { + "name": "setNotInlinableOrCompilable" + }, + { + "name": "shouldDebugNonSafepoints" + }, + { + "name": "shouldInlineMethod" + }, + { + "name": "translate" + }, + { + "name": "unboxPrimitive" + }, + { + "name": "unhand" + }, + { + "name": "updateHotSpotNmethodHandle" + }, + { + "name": "writeCompileLogOutput" + }, + { + "name": "writeDebugOutput" + }, + { + "name": "asReflectionExecutable" + }, + { + "name": "asReflectionField" + } + ], + "name": "jdk.vm.ci.hotspot.CompilerToVM" + }, + { + "fields": [ + { + "name": "object" + } + ], + "methods": [ + { + "name": "" + } + ], + "name": "jdk.vm.ci.hotspot.DirectHotSpotObjectConstantImpl" + }, + { + "fields": [ + { + "name": "failureMessage" + }, + { + "name": "inlinedBytecodes" + }, + { + "name": "retry" + } + ], + "name": "jdk.vm.ci.hotspot.HotSpotCompilationRequestResult" + }, + { + "fields": [ + { + "name": "assumptions" + }, + { + "name": "comments" + }, + { + "name": "dataSection" + }, + { + "name": "dataSectionAlignment" + }, + { + "name": "dataSectionPatches" + }, + { + "name": "deoptRescueSlot" + }, + { + "name": "isImmutablePIC" + }, + { + "name": "methods" + }, + { + "name": "name" + }, + { + "name": "sites" + }, + { + "name": "targetCode" + }, + { + "name": "targetCodeSize" + }, + { + "name": "totalFrameSize" + } + ], + "name": "jdk.vm.ci.hotspot.HotSpotCompiledCode" + }, + { + "fields": [ + { + "name": "pcOffset" + }, + { + "name": "text" + } + ], + "name": "jdk.vm.ci.hotspot.HotSpotCompiledCode$Comment" + }, + { + "fields": [ + { + "name": "compileTask" + }, + { + "name": "entryBCI" + }, + { + "name": "hasUnsafeAccess" + }, + { + "name": "id" + }, + { + "name": "installationFailureMessage" + }, + { + "name": "method" + } + ], + "name": "jdk.vm.ci.hotspot.HotSpotCompiledNmethod" + }, + { + "name": "jdk.vm.ci.hotspot.HotSpotCompressedNullConstant" + }, + { + "fields": [ + { + "name": "metadataHandle" + } + ], + "methods": [ + { + "name": "fromMetaspace" + } + ], + "name": "jdk.vm.ci.hotspot.HotSpotConstantPool" + }, + { + "fields": [ + { + "name": "address" + } + ], + "name": "jdk.vm.ci.hotspot.HotSpotForeignCallTarget" + }, + { + "fields": [ + { + "name": "codeSize" + }, + { + "name": "codeStart" + }, + { + "name": "size" + } + ], + "name": "jdk.vm.ci.hotspot.HotSpotInstalledCode" + }, + { + "fields": [ + { + "name": "compilationLevelAdjustment" + } + ], + "methods": [ + { + "name": "adjustCompilationLevel" + }, + { + "name": "bootstrapFinished" + }, + { + "name": "callToString" + }, + { + "name": "compileMethod" + }, + { + "name": "decodeThrowable" + }, + { + "name": "encodeThrowable" + }, + { + "name": "getCompiler" + }, + { + "name": "runtime" + }, + { + "name": "shutdown" + } + ], + "name": "jdk.vm.ci.hotspot.HotSpotJVMCIRuntime" + }, + { + "fields": [ + { + "name": "exceptionBytes" + }, + { + "name": "metadata" + }, + { + "name": "oopMaps" + }, + { + "name": "pcDescBytes" + }, + { + "name": "relocBytes" + }, + { + "name": "scopesDescBytes" + } + ], + "name": "jdk.vm.ci.hotspot.HotSpotMetaData" + }, + { + "fields": [ + { + "name": "compressed" + }, + { + "name": "metaspaceObject" + } + ], + "name": "jdk.vm.ci.hotspot.HotSpotMetaspaceConstantImpl" + }, + { + "fields": [ + { + "name": "isDefault" + }, + { + "name": "method" + } + ], + "methods": [ + { + "name": "" + } + ], + "name": "jdk.vm.ci.hotspot.HotSpotNmethod" + }, + { + "fields": [ + { + "name": "compileId" + } + ], + "methods": [ + { + "name": "" + } + ], + "name": "jdk.vm.ci.hotspot.HotSpotNmethodHandle" + }, + { + "fields": [ + { + "name": "compressed" + } + ], + "name": "jdk.vm.ci.hotspot.HotSpotObjectConstantImpl" + }, + { + "fields": [ + { + "name": "derivedBase" + }, + { + "name": "maxRegisterSize" + }, + { + "name": "objects" + }, + { + "name": "sizeInBytes" + } + ], + "name": "jdk.vm.ci.hotspot.HotSpotReferenceMap" + }, + { + "fields": [ + { + "name": "holder" + }, + { + "name": "modifiers" + }, + { + "name": "offset" + }, + { + "name": "type" + } + ], + "name": "jdk.vm.ci.hotspot.HotSpotResolvedJavaFieldImpl" + }, + { + "fields": [ + { + "name": "metadataHandle" + } + ], + "methods": [ + { + "name": "fromMetaspace" + } + ], + "name": "jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl" + }, + { + "fields": [ + { + "name": "metadataPointer" + } + ], + "methods": [ + { + "name": "fromMetaspace" + } + ], + "name": "jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl" + }, + { + "fields": [ + { + "name": "kind" + }, + { + "name": "mirror" + }, + { + "name": "primitives" + } + ], + "methods": [ + { + "name": "fromMetaspace" + } + ], + "name": "jdk.vm.ci.hotspot.HotSpotResolvedPrimitiveType" + }, + { + "name": "jdk.vm.ci.hotspot.HotSpotSentinelConstant" + }, + { + "fields": [ + { + "name": "lastFailed" + } + ], + "name": "jdk.vm.ci.hotspot.HotSpotSpeculationLog" + }, + { + "fields": [ + { + "name": "bci" + }, + { + "name": "compilerToVM" + }, + { + "name": "frameNumber" + }, + { + "name": "localIsVirtual" + }, + { + "name": "locals" + }, + { + "name": "method" + }, + { + "name": "objectsMaterialized" + }, + { + "name": "stackPointer" + } + ], + "name": "jdk.vm.ci.hotspot.HotSpotStackFrameReference" + }, + { + "fields": [ + { + "name": "objectHandle" + } + ], + "methods": [ + { + "name": "" + } + ], + "name": "jdk.vm.ci.hotspot.IndirectHotSpotObjectConstantImpl" + }, + { + "fields": [ + { + "name": "address" + }, + { + "name": "name" + }, + { + "name": "offset" + }, + { + "name": "type" + }, + { + "name": "value" + } + ], + "methods": [ + { + "name": "" + } + ], + "name": "jdk.vm.ci.hotspot.VMField" + }, + { + "fields": [ + { + "name": "name" + }, + { + "name": "type" + }, + { + "name": "value" + } + ], + "methods": [ + { + "name": "" + } + ], + "name": "jdk.vm.ci.hotspot.VMFlag" + }, + { + "fields": [ + { + "name": "declaringClass" + }, + { + "name": "descriptor" + }, + { + "name": "id" + }, + { + "name": "name" + } + ], + "methods": [ + { + "name": "" + } + ], + "name": "jdk.vm.ci.hotspot.VMIntrinsicMethod" + }, + { + "fields": [ + { + "name": "callSite" + }, + { + "name": "methodHandle" + } + ], + "name": "jdk.vm.ci.meta.Assumptions$CallSiteTargetValue" + }, + { + "fields": [ + { + "name": "context" + }, + { + "name": "impl" + }, + { + "name": "method" + } + ], + "name": "jdk.vm.ci.meta.Assumptions$ConcreteMethod" + }, + { + "fields": [ + { + "name": "context" + }, + { + "name": "subtype" + } + ], + "name": "jdk.vm.ci.meta.Assumptions$ConcreteSubtype" + }, + { + "fields": [ + { + "name": "context" + } + ], + "name": "jdk.vm.ci.meta.Assumptions$LeafType" + }, + { + "fields": [ + { + "name": "receiverType" + } + ], + "name": "jdk.vm.ci.meta.Assumptions$NoFinalizableSubclass" + }, + { + "fields": [ + { + "name": "NULL_POINTER" + } + ], + "methods": [ + { + "name": "forDouble" + }, + { + "name": "forFloat" + } + ], + "name": "jdk.vm.ci.meta.JavaConstant" + }, + { + "fields": [ + { + "name": "Boolean" + }, + { + "name": "Byte" + }, + { + "name": "Char" + }, + { + "name": "Int" + }, + { + "name": "Long" + }, + { + "name": "Short" + }, + { + "name": "typeChar" + } + ], + "name": "jdk.vm.ci.meta.JavaKind" + }, + { + "name": "jdk.vm.ci.meta.NullConstant" + }, + { + "fields": [ + { + "name": "kind" + }, + { + "name": "primitive" + } + ], + "methods": [ + { + "name": "forTypeChar" + } + ], + "name": "jdk.vm.ci.meta.PrimitiveConstant" + }, + { + "name": "jdk.vm.ci.meta.RawConstant" + }, + { + "name": "jdk.vm.ci.meta.ResolvedJavaMethod" + }, + { + "fields": [ + { + "name": "ILLEGAL" + }, + { + "name": "valueKind" + } + ], + "name": "jdk.vm.ci.meta.Value" + }, + { + "fields": [ + { + "name": "platformKind" + } + ], + "name": "jdk.vm.ci.meta.ValueKind" + }, + { + "methods": [ + { + "name": "getRuntime" + }, + { + "name": "initializeRuntime" + } + ], + "name": "jdk.vm.ci.runtime.JVMCI" + }, + { + "methods": [ + { + "name": "init" + } + ], + "name": "jdk.vm.ci.services.JVMCIClassLoaderFactory" + } +] diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.nativelib/src/com/oracle/svm/graal/hotspot/nativelib/HotSpotGraalLibraryFeature.java b/substratevm/src/com.oracle.svm.graal.hotspot.nativelib/src/com/oracle/svm/graal/hotspot/nativelib/HotSpotGraalLibraryFeature.java new file mode 100644 index 000000000000..971af9b342c1 --- /dev/null +++ b/substratevm/src/com.oracle.svm.graal.hotspot.nativelib/src/com/oracle/svm/graal/hotspot/nativelib/HotSpotGraalLibraryFeature.java @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2017, 2018, 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.nativelib; + +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.BooleanSupplier; + +import org.graalvm.collections.EconomicSet; +import org.graalvm.collections.MapCursor; +import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; +import org.graalvm.compiler.debug.DebugContext; +import org.graalvm.compiler.debug.DebugHandlersFactory; +import org.graalvm.compiler.debug.GraalError; +import org.graalvm.compiler.graph.Node; +import org.graalvm.compiler.hotspot.HotSpotCodeCacheListener; +import org.graalvm.compiler.hotspot.HotSpotGraalCompiler; +import org.graalvm.compiler.hotspot.HotSpotReplacementsImpl; +import org.graalvm.compiler.hotspot.meta.HotSpotProviders; +import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins; +import org.graalvm.compiler.nodes.graphbuilderconf.MethodSubstitutionPlugin; +import org.graalvm.compiler.options.OptionValues; +import org.graalvm.compiler.phases.util.Providers; +import org.graalvm.compiler.serviceprovider.GraalServices; +import org.graalvm.compiler.truffle.common.TruffleCompilerRuntime; +import org.graalvm.compiler.truffle.compiler.hotspot.TruffleCallBoundaryInstrumentationFactory; +import org.graalvm.compiler.truffle.compiler.substitutions.TruffleInvocationPluginProvider; +import org.graalvm.nativeimage.Feature; +import org.graalvm.nativeimage.ImageSingletons; +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; + +import com.oracle.graal.pointsto.meta.AnalysisType; +import com.oracle.graal.pointsto.meta.AnalysisUniverse; +import com.oracle.svm.core.annotate.Alias; +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.graal.meta.RuntimeConfiguration; +import com.oracle.svm.core.graal.snippets.NodeLoweringProvider; +import com.oracle.svm.core.option.RuntimeOptionValues; +import com.oracle.svm.core.snippets.KnownIntrinsics; +import com.oracle.svm.graal.hosted.GraalFeature; +import com.oracle.svm.hosted.FeatureImpl; +import com.oracle.svm.hosted.FeatureImpl.DuringAnalysisAccessImpl; +import com.oracle.svm.jni.hosted.JNIFeature; + +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; +import jdk.vm.ci.meta.MetaAccessProvider; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; + +public final class HotSpotGraalLibraryFeature implements com.oracle.svm.core.graal.GraalFeature { + + private HotSpotReplacementsImpl hotSpotSubstrateReplacements; + + @Override + public void afterImageWrite(AfterImageWriteAccess access) { + } + + @Override + public List> getRequiredFeatures() { + return Arrays.asList(JNIFeature.class, GraalFeature.class); + } + + public static final class IsEnabled implements BooleanSupplier { + @Override + public boolean getAsBoolean() { + return ImageSingletons.contains(HotSpotGraalLibraryFeature.class); + } + } + + private EconomicSet visitedElements = EconomicSet.create(); + + @Override + public void afterRegistration(AfterRegistrationAccess access) { + ImageSingletons.add(MethodAnnotationSupport.class, new MethodAnnotationSupport()); + } + + @Override + public void registerLowerings(RuntimeConfiguration runtimeConfig, OptionValues options, Iterable factories, Providers substrateProviders, + SnippetReflectionProvider substrateSnippetReflection, + Map, NodeLoweringProvider> lowerings, boolean hosted) { + hotSpotSubstrateReplacements = getReplacements(); + } + + @SuppressWarnings("try") + @Override + public void beforeAnalysis(BeforeAnalysisAccess access) { + + // Services that will not be loaded if native-image is run + // with -XX:-UseJVMCICompiler. + GraalServices.load(TruffleCallBoundaryInstrumentationFactory.class); + GraalServices.load(TruffleInvocationPluginProvider.class); + GraalServices.load(HotSpotCodeCacheListener.class); + + FeatureImpl.BeforeAnalysisAccessImpl impl = (FeatureImpl.BeforeAnalysisAccessImpl) access; + DebugContext debug = impl.getBigBang().getDebug(); + try (DebugContext.Scope scope = debug.scope("SnippetSupportEncode")) { + + MapCursor> cursor = hotSpotSubstrateReplacements.getGraphBuilderPlugins().getInvocationPlugins().getBindings(true).getEntries(); + Providers providers = hotSpotSubstrateReplacements.getProviders(); + MetaAccessProvider metaAccess = providers.getMetaAccess(); + while (cursor.advance()) { + String className = cursor.getKey(); + ResolvedJavaType type = null; + try { + String typeName = className.substring(1, className.length() - 1).replace('/', '.'); + ClassLoader cl = ClassLoader.getSystemClassLoader(); + Class clazz = Class.forName(typeName, true, cl); + type = metaAccess.lookupJavaType(clazz); + } catch (ClassNotFoundException e) { + debug.log("Can't find original type for %s%n", className); + // throw new GraalError(e); + } + + for (InvocationPlugins.Binding binding : cursor.getValue()) { + if (binding.plugin instanceof MethodSubstitutionPlugin) { + MethodSubstitutionPlugin plugin = (MethodSubstitutionPlugin) binding.plugin; + ResolvedJavaMethod method = plugin.getSubstitute(metaAccess); + + ResolvedJavaMethod original = null; + for (ResolvedJavaMethod declared : type.getDeclaredMethods()) { + if (declared.getName().equals(binding.name)) { + if (declared.isStatic() == binding.isStatic) { + if (declared.getSignature().toMethodDescriptor().startsWith(binding.argumentsDescriptor)) { + original = declared; + break; + } + } + } + } + if (original != null) { + debug.log("Method substitution %s %s", method, original); + hotSpotSubstrateReplacements.registerMethodSubstitution(method, original); + } else { + throw new GraalError("Can't find original for " + method); + } + } + } + } + } catch (Throwable t) { + throw debug.handle(t); + } + } + + @SuppressWarnings("try") + @Override + public void duringAnalysis(DuringAnalysisAccess access) { + DuringAnalysisAccessImpl accessImpl = (DuringAnalysisAccessImpl) access; + AnalysisUniverse universe = accessImpl.getUniverse(); + + int numTypes = universe.getTypes().size(); + int numMethods = universe.getMethods().size(); + int numFields = universe.getFields().size(); + + /* + * JDK implementation of repeatable annotations always instantiates an array of a requested + * annotation. We need to mark arrays of all reachable annotations as in heap. + */ + universe.getTypes().stream() + .filter(AnalysisType::isAnnotation) + .filter(AnalysisType::isInTypeCheck) + .map(type -> universe.lookup(type.getWrapped()).getArrayClass()) + .filter(annotationArray -> !annotationArray.isInstantiated()) + .forEach(annotationArray -> { + accessImpl.registerAsInHeap(annotationArray); + access.requireAnalysisIteration(); + }); + + // Capture annotations for all Snippets + for (ResolvedJavaMethod method : hotSpotSubstrateReplacements.getSnippetMethods()) { + if (visitedElements.add(method)) { + ImageSingletons.lookup(MethodAnnotationSupport.class).setParameterAnnotations(method, method.getParameterAnnotations()); + ImageSingletons.lookup(MethodAnnotationSupport.class).setMethodAnnotation(method, method.getAnnotations()); + } + } + + // Rerun the iteration is new things have been seen. + if (numTypes != universe.getTypes().size() || numMethods != universe.getMethods().size() || numFields != universe.getFields().size()) { + access.requireAnalysisIteration(); + } + + // Ensure all known snippets and method subsitutions are encoded and rerun the iteration if + // new encoding is done. + if (hotSpotSubstrateReplacements.encode()) { + access.requireAnalysisIteration(); + } + } + + @Override + public void afterAnalysis(AfterAnalysisAccess access) { + visitedElements.clear(); + } + + static class MethodAnnotationSupport { + private Map classAnnotationMap = new HashMap<>(); + + private Map parameterAnnotationMap = new HashMap<>(); + private Map methodAnnotationMap = new HashMap<>(); + + static final Annotation[][] NO_PARAMETER_ANNOTATIONS = new Annotation[0][]; + static final Annotation[] NO_ANNOTATIONS = new Annotation[0]; + + @Platforms(Platform.HOSTED_ONLY.class) + void setParameterAnnotations(ResolvedJavaMethod element, Annotation[][] parameterAnnotations) { + String name = element.getDeclaringClass().getName() + " " + element.getName(); + if (parameterAnnotations.length == 0) { + parameterAnnotationMap.put(name, NO_PARAMETER_ANNOTATIONS); + } else { + parameterAnnotationMap.put(name, parameterAnnotations); + } + } + + @Platforms(Platform.HOSTED_ONLY.class) + void setMethodAnnotation(ResolvedJavaMethod javaMethod, Annotation[] annotations) { + String name = javaMethod.format("%R %H.%n%P"); + if (annotations.length == 0) { + methodAnnotationMap.put(name, NO_ANNOTATIONS); + } else { + methodAnnotationMap.put(name, annotations); + } + } + + public Annotation[] getClassAnnotations(String className) { + return classAnnotationMap.get(className); + } + + public Annotation[][] getParameterAnnotations(String className, String methodName) { + String name = className + " " + methodName; + return parameterAnnotationMap.get(name); + } + + public Annotation[] getMethodAnnotations(ResolvedJavaMethod javaMethod) { + String name = javaMethod.format("%R %H.%n%P"); + return methodAnnotationMap.get(name); + + } + } + + static HotSpotReplacementsImpl getReplacements() { + HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) HotSpotJVMCIRuntime.runtime().getCompiler(); + HotSpotProviders originalProvider = compiler.getGraalRuntime().getHostProviders(); + return (HotSpotReplacementsImpl) originalProvider.getReplacements(); + } + +} + +@TargetClass(className = "jdk.vm.ci.hotspot.SharedLibraryJVMCIReflection", onlyWith = HotSpotGraalLibraryFeature.IsEnabled.class) +final class Target_jdk_vm_ci_hotspot_SharedLibraryJVMCIReflection { + + @Substitute + static Annotation[] getClassAnnotations(String className) { + return ImageSingletons.lookup(HotSpotGraalLibraryFeature.MethodAnnotationSupport.class).getClassAnnotations(className); + } + + @Substitute + static Annotation[][] getParameterAnnotations(String className, String methodName) { + return ImageSingletons.lookup(HotSpotGraalLibraryFeature.MethodAnnotationSupport.class).getParameterAnnotations(className, methodName); + } + + @Substitute + static Annotation[] getMethodAnnotationsInternal(ResolvedJavaMethod javaMethod) { + return ImageSingletons.lookup(HotSpotGraalLibraryFeature.MethodAnnotationSupport.class).getMethodAnnotations(javaMethod); + } + + @Substitute + static Object convertUnknownValue(Object object) { + return KnownIntrinsics.convertUnknownValue(object, Object.class); + } +} + +@TargetClass(className = "org.graalvm.compiler.hotspot.HotSpotGraalOptionValues", onlyWith = HotSpotGraalLibraryFeature.IsEnabled.class) +final class Target_org_graalvm_compiler_hotspot_HotSpotGraalOptionValues { + @Substitute + private static OptionValues initializeOptions() { + return RuntimeOptionValues.singleton(); + } +} + +@TargetClass(className = "org.graalvm.compiler.truffle.common.TruffleCompilerRuntimeInstance", onlyWith = HotSpotGraalLibraryFeature.IsEnabled.class) +final class Target_org_graalvm_compiler_truffle_common_TruffleCompilerRuntimeInstance { + // Checkstyle: stop + @Alias @RecomputeFieldValue(kind = Kind.Reset, isFinal = true) static Object TRUFFLE_RUNTIME; + // Checkstyle: resume + @Alias @RecomputeFieldValue(kind = Kind.Reset) static TruffleCompilerRuntime truffleCompilerRuntime; +} diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.nativelib/src/com/oracle/svm/graal/hotspot/nativelib/HotSpotGraalSubstitutions.java b/substratevm/src/com.oracle.svm.graal.hotspot.nativelib/src/com/oracle/svm/graal/hotspot/nativelib/HotSpotGraalSubstitutions.java new file mode 100644 index 000000000000..f9b256c7897b --- /dev/null +++ b/substratevm/src/com.oracle.svm.graal.hotspot.nativelib/src/com/oracle/svm/graal/hotspot/nativelib/HotSpotGraalSubstitutions.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017, 2018, 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.nativelib; + +import com.oracle.svm.core.annotate.Alias; +import com.oracle.svm.core.annotate.RecomputeFieldValue; +import com.oracle.svm.core.annotate.TargetClass; + +import jdk.vm.ci.services.Services; + +/** Dummy class to have a class with the file's name. Do not remove. */ +public final class HotSpotGraalSubstitutions { + // Dummy +} + +@TargetClass(value = Services.class, onlyWith = HotSpotGraalLibraryFeature.IsEnabled.class) +final class Target_jdk_vm_ci_services_Services { + // Checkstyle: stop + @Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FromAlias, isFinal = true)// + public static boolean IS_IN_NATIVE_IMAGE = true; + // Checkstyle: resume +} + +@TargetClass(className = "jdk.vm.ci.hotspot.HotSpotJDKReflection", onlyWith = HotSpotGraalLibraryFeature.IsEnabled.class) +final class Target_jdk_vm_ci_hotspot_HotSpotJDKReflection { + + @Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.None)// + private long oopSizeOffset; +} diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/GraalSubstitutions.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/GraalSubstitutions.java index f800acf97114..a3c3d6f3315a 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/GraalSubstitutions.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/GraalSubstitutions.java @@ -81,7 +81,7 @@ // Checkstyle: stop -@TargetClass(value = org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.class, onlyWith = GraalFeature.IsEnabled.class) +@TargetClass(value = org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.class, onlyWith = GraalFeature.IsPureSVMEnabled.class) final class Target_org_graalvm_compiler_nodes_graphbuilderconf_InvocationPlugins { @Alias// @@ -95,7 +95,7 @@ private void flushDeferrables() { } } -@TargetClass(value = org.graalvm.compiler.phases.common.inlining.info.elem.InlineableGraph.class, onlyWith = GraalFeature.IsEnabled.class) +@TargetClass(value = org.graalvm.compiler.phases.common.inlining.info.elem.InlineableGraph.class, onlyWith = GraalFeature.IsPureSVMEnabled.class) @SuppressWarnings({"unused"}) final class Target_org_graalvm_compiler_phases_common_inlining_info_elem_InlineableGraph { @@ -109,7 +109,7 @@ private static StructuredGraph parseBytecodes(ResolvedJavaMethod method, HighTie } } -@TargetClass(value = org.graalvm.compiler.phases.common.inlining.walker.ComputeInliningRelevance.class, onlyWith = GraalFeature.IsEnabled.class) +@TargetClass(value = org.graalvm.compiler.phases.common.inlining.walker.ComputeInliningRelevance.class, onlyWith = GraalFeature.IsPureSVMEnabled.class) @SuppressWarnings({"static-method", "unused"}) final class Target_org_graalvm_compiler_phases_common_inlining_walker_ComputeInliningRelevance { @@ -248,7 +248,7 @@ final class Target_org_graalvm_compiler_debug_KeyRegistry { private static List keys = new ArrayList<>(); } -@TargetClass(value = org.graalvm.compiler.core.match.MatchRuleRegistry.class, onlyWith = GraalFeature.IsEnabled.class) +@TargetClass(value = org.graalvm.compiler.core.match.MatchRuleRegistry.class, onlyWith = GraalFeature.IsPureSVMEnabled.class) final class Target_org_graalvm_compiler_core_match_MatchRuleRegistry { @Substitute @@ -278,7 +278,7 @@ void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { } } -@TargetClass(value = org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.class, onlyWith = GraalFeature.IsEnabled.class) +@TargetClass(value = org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.class, onlyWith = GraalFeature.IsPureSVMEnabled.class) @SuppressWarnings({"unused", "static-method"}) final class Target_org_graalvm_compiler_replacements_nodes_UnaryMathIntrinsicNode { diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/GraalFeature.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/GraalFeature.java index 09d6f11f07ff..f423ab3080fe 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/GraalFeature.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/GraalFeature.java @@ -52,6 +52,7 @@ import org.graalvm.compiler.java.BytecodeParser; import org.graalvm.compiler.java.GraphBuilderPhase; import org.graalvm.compiler.lir.phases.LIRSuites; +import org.graalvm.compiler.loop.phases.ConvertDeoptimizeToGuardPhase; import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind; import org.graalvm.compiler.nodes.FixedGuardNode; import org.graalvm.compiler.nodes.FrameState; @@ -69,7 +70,6 @@ import org.graalvm.compiler.options.Option; import org.graalvm.compiler.phases.OptimisticOptimizations; import org.graalvm.compiler.phases.common.CanonicalizerPhase; -import org.graalvm.compiler.loop.phases.ConvertDeoptimizeToGuardPhase; import org.graalvm.compiler.phases.common.inlining.InliningUtil; import org.graalvm.compiler.phases.tiers.PhaseContext; import org.graalvm.compiler.phases.tiers.Suites; @@ -87,6 +87,7 @@ import com.oracle.graal.pointsto.meta.AnalysisType; import com.oracle.graal.pointsto.meta.HostedProviders; import com.oracle.svm.core.SubstrateOptions; +import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.config.ConfigurationValues; import com.oracle.svm.core.graal.GraalConfiguration; import com.oracle.svm.core.graal.code.SubstrateBackend; @@ -162,6 +163,18 @@ public boolean getAsBoolean() { } } + /** + * This predicate is used to distinguish between building a Graal native image as a shared + * library for HotSpot (non-pure) or Graal as a compiler used only for a runtime in the same + * image (pure). + */ + public static final class IsPureSVMEnabled implements BooleanSupplier { + @Override + public boolean getAsBoolean() { + return ImageSingletons.contains(GraalFeature.class) && !SubstrateUtil.isBuildingLibgraal(); + } + } + public interface IncludeCalleePredicate { boolean includeCallee(CallTreeNode calleeNode, List implementationMethods); } diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/GraalObjectReplacer.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/GraalObjectReplacer.java index 619f726c72ba..920c8195501a 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/GraalObjectReplacer.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/GraalObjectReplacer.java @@ -38,11 +38,13 @@ import org.graalvm.nativeimage.Feature.CompilationAccess; import org.graalvm.nativeimage.c.function.RelocatedPointer; +import com.oracle.graal.pointsto.constraints.UnsupportedFeatureException; import com.oracle.graal.pointsto.meta.AnalysisField; import com.oracle.graal.pointsto.meta.AnalysisMetaAccess; import com.oracle.graal.pointsto.meta.AnalysisMethod; import com.oracle.graal.pointsto.meta.AnalysisType; import com.oracle.graal.pointsto.meta.AnalysisUniverse; +import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.graal.nodes.SubstrateFieldLocationIdentity; import com.oracle.svm.core.hub.DynamicHub; import com.oracle.svm.core.meta.ReadableJavaField; @@ -67,6 +69,11 @@ import com.oracle.svm.hosted.meta.HostedType; import com.oracle.svm.hosted.meta.HostedUniverse; +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; +import jdk.vm.ci.hotspot.HotSpotResolvedJavaField; +import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; +import jdk.vm.ci.hotspot.HotSpotResolvedJavaType; +import jdk.vm.ci.hotspot.HotSpotSignature; import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaField; @@ -124,6 +131,8 @@ public Object apply(Object source) { if (source instanceof MetaAccessProvider) { dest = sMetaAccess; + } else if (source instanceof HotSpotJVMCIRuntime) { + throw new UnsupportedFeatureException(source.toString()); } else if (source instanceof GraalRuntime) { dest = sGraalRuntime; } else if (source instanceof AnalysisConstantReflectionProvider) { @@ -141,7 +150,15 @@ public Object apply(Object source) { * BigBang.finish(), which is multi-threaded. */ synchronized (this) { - if (source instanceof ResolvedJavaMethod) { + if (source instanceof HotSpotResolvedJavaMethod) { + throw new UnsupportedFeatureException(source.toString()); + } else if (source instanceof HotSpotResolvedJavaField) { + throw new UnsupportedFeatureException(source.toString()); + } else if (source instanceof HotSpotResolvedJavaType) { + throw new UnsupportedFeatureException(source.toString()); + } else if (source instanceof HotSpotSignature) { + throw new UnsupportedFeatureException(source.toString()); + } else if (source instanceof ResolvedJavaMethod) { dest = createMethod((ResolvedJavaMethod) source); } else if (source instanceof ResolvedJavaField) { dest = createField((ResolvedJavaField) source); @@ -162,9 +179,10 @@ public Object apply(Object source) { assert dest != null; String className = dest.getClass().getName(); - assert !className.contains(".hotspot.") || className.contains(".svm.jtt.hotspot.") : "HotSpot object in image " + className; + assert SubstrateUtil.isBuildingLibgraal() || !className.contains(".hotspot.") || className.contains(".svm.jtt.hotspot.") : "HotSpot object in image " + className; assert !className.contains(".analysis.meta.") : "Analysis meta object in image " + className; assert !className.contains(".hosted.meta.") : "Hosted meta object in image " + className; + assert !SubstrateUtil.isBuildingLibgraal() || !className.contains(".svm.hosted.snippets.") : "Hosted snippet object in image " + className; return dest; } diff --git a/substratevm/src/com.oracle.svm.hosted/.checkstyle_checks.xml b/substratevm/src/com.oracle.svm.hosted/.checkstyle_checks.xml index d3612201bd04..87cc3167b88e 100644 --- a/substratevm/src/com.oracle.svm.hosted/.checkstyle_checks.xml +++ b/substratevm/src/com.oracle.svm.hosted/.checkstyle_checks.xml @@ -42,8 +42,8 @@ - - + + diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ClassValueFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ClassValueFeature.java index bbab04eb98da..20370e47d2a5 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ClassValueFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ClassValueFeature.java @@ -24,16 +24,18 @@ */ package com.oracle.svm.hosted; -import com.oracle.graal.pointsto.meta.AnalysisType; -import com.oracle.svm.core.annotate.AutomaticFeature; -import com.oracle.svm.core.jdk.JavaLangSubstitutions.ClassValueSupport; -import com.oracle.svm.core.util.VMError; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; + import org.graalvm.nativeimage.Feature; import org.graalvm.nativeimage.ImageSingletons; +import com.oracle.graal.pointsto.meta.AnalysisType; +import com.oracle.svm.core.annotate.AutomaticFeature; +import com.oracle.svm.core.jdk.JavaLangSubstitutions.ClassValueSupport; +import com.oracle.svm.core.util.VMError; + @AutomaticFeature public final class ClassValueFeature implements Feature { private final Map, Map, Object>> values = new ConcurrentHashMap<>(); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java index 656d1924a358..184b98f10aff 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java @@ -73,6 +73,10 @@ import org.graalvm.compiler.debug.DebugHandlersFactory; import org.graalvm.compiler.debug.Indent; import org.graalvm.compiler.graph.Node; +import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; +import org.graalvm.compiler.hotspot.HotSpotGraalCompiler; +import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider; +import org.graalvm.compiler.hotspot.word.HotSpotWordTypes; import org.graalvm.compiler.lir.phases.LIRSuites; import org.graalvm.compiler.loop.phases.ConvertDeoptimizeToGuardPhase; import org.graalvm.compiler.nodes.StructuredGraph; @@ -146,6 +150,7 @@ import com.oracle.svm.core.OS; import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.SubstrateTargetDescription; +import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.c.function.CEntryPointOptions; import com.oracle.svm.core.config.ConfigurationValues; import com.oracle.svm.core.deopt.DeoptTester; @@ -256,6 +261,7 @@ import jdk.vm.ci.amd64.AMD64; import jdk.vm.ci.code.Architecture; import jdk.vm.ci.code.TargetDescription; +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; import jdk.vm.ci.meta.ConstantReflectionProvider; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.MetaAccessProvider; @@ -794,7 +800,8 @@ private void setupNativeImage(String imageName, OptionValues options, Map feature.registerNodePlugins(analysis ? aMetaAccess : hMetaAccess, plugins, analysis, hosted)); HostedSnippetReflectionProvider hostedSnippetReflection = new HostedSnippetReflectionProvider((SVMHost) aUniverse.hostVM(), new WordTypes(aMetaAccess, FrameAccess.getWordKind())); - NodeIntrinsificationProvider nodeIntrinsificationProvider = new NodeIntrinsificationProvider(providers.getMetaAccess(), hostedSnippetReflection, providers.getForeignCalls(), - providers.getWordTypes()); + HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) HotSpotJVMCIRuntime.runtime().getCompiler(); + + NodeIntrinsificationProvider nodeIntrinsificationProvider; + if (!SubstrateUtil.isBuildingLibgraal()) { + nodeIntrinsificationProvider = new NodeIntrinsificationProvider(providers.getMetaAccess(), hostedSnippetReflection, providers.getForeignCalls(), + providers.getWordTypes()); + + } else { + nodeIntrinsificationProvider = new NodeIntrinsificationProvider(providers.getMetaAccess(), hostedSnippetReflection, + providers.getForeignCalls(), providers.getWordTypes()) { + @Override + public T getInjectedArgument(Class type) { + if (type.isAssignableFrom(GraalHotSpotVMConfig.class)) { + return type.cast(compiler.getGraalRuntime().getVMConfig()); + } + if (type.isAssignableFrom(HotSpotGraalRuntimeProvider.class)) { + return type.cast(compiler.getGraalRuntime()); + } + return super.getInjectedArgument(type); + } + }; + } for (Class factoryClass : loader.findSubclasses(NodeIntrinsicPluginFactory.class)) { if (!Modifier.isAbstract(factoryClass.getModifiers()) && !factoryClass.getName().contains("hotspot")) { NodeIntrinsicPluginFactory factory; @@ -1384,7 +1411,7 @@ private void checkName(String name, AnalysisMethod method) { String lname = name.toLowerCase(); if (lname.contains("hosted")) { bigbang.getUnsupportedFeatures().addMessage(name, method, "Hosted element used at run time: " + name); - } else if ((!name.startsWith("jdk.internal")) && (lname.contains("hotspot"))) { + } else if (SubstrateUtil.isBuildingLibgraal() && (!name.startsWith("jdk.internal")) && (lname.contains("hotspot"))) { bigbang.getUnsupportedFeatures().addMessage(name, method, "HotSpot element used at run time: " + name); } } 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 7a281aab3a6e..05fa33ba5df0 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 @@ -172,7 +172,7 @@ private HostedType makeType(AnalysisType aType) { String typeName = aType.getName(); - assert !typeName.contains("/hotspot/") || typeName.contains("/jtt/hotspot/") : "HotSpot object in image " + typeName; + assert SubstrateUtil.isBuildingLibgraal() || !typeName.contains("/hotspot/") || typeName.contains("/jtt/hotspot/") : "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.jni/src/com/oracle/svm/jni/functions/JNIInvocationInterface.java b/substratevm/src/com.oracle.svm.jni/src/com/oracle/svm/jni/functions/JNIInvocationInterface.java index 99503c0205cc..6644946ded76 100644 --- a/substratevm/src/com.oracle.svm.jni/src/com/oracle/svm/jni/functions/JNIInvocationInterface.java +++ b/substratevm/src/com.oracle.svm.jni/src/com/oracle/svm/jni/functions/JNIInvocationInterface.java @@ -46,6 +46,7 @@ import com.oracle.svm.core.MonitorSupport; import com.oracle.svm.core.SubstrateOptions; +import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.annotate.Uninterruptible; import com.oracle.svm.core.c.function.CEntryPointActions; import com.oracle.svm.core.c.function.CEntryPointErrors;