Skip to content

Commit

Permalink
Add libgraal tool
Browse files Browse the repository at this point in the history
  • Loading branch information
tkrodriguez committed Jan 29, 2019
1 parent db68412 commit e2ceb04
Show file tree
Hide file tree
Showing 51 changed files with 2,780 additions and 99 deletions.
7 changes: 7 additions & 0 deletions ci.hocon
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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"
Expand Down
43 changes: 42 additions & 1 deletion compiler/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
Expand Down Expand Up @@ -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.
Expand Down
32 changes: 19 additions & 13 deletions compiler/mx.compiler/mx_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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),
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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...]'],
Expand Down
9 changes: 6 additions & 3 deletions compiler/mx.compiler/mx_graal_benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -51,7 +52,7 @@ <T> T getProvider(Class<T> service, HotSpotGraalJVMCIServiceLocator locator) {
return null;
}

private HotSpotGraalRuntime graalRuntime;
@NativeImageReinitialize private HotSpotGraalRuntime graalRuntime;

/**
* Notifies this object of the compiler created via {@link HotSpotGraalJVMCIServiceLocator}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -63,7 +65,7 @@ protected boolean isStaticFieldConstant(ResolvedJavaField field, OptionValues op
private volatile List<ResolvedJavaField> 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<ResolvedJavaField> fields = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1721,7 +1722,6 @@ protected Invoke appendInvoke(InvokeKind initialInvokeKind, ResolvedJavaMethod i
}
}
if (invokeKind.isDirect()) {

inlineInfo = tryInline(args, targetMethod);
if (inlineInfo == SUCCESSFULLY_INLINED) {
return null;
Expand Down Expand Up @@ -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)).
Expand Down
Loading

0 comments on commit e2ceb04

Please sign in to comment.