--- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java 2017-03-20 17:37:25.000000000 -0700 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java 2017-03-20 17:37:25.000000000 -0700 @@ -44,12 +44,6 @@ import java.util.Set; import java.util.function.Supplier; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.internal.AssumptionViolatedException; - import org.graalvm.compiler.api.directives.GraalDirectives; import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; import org.graalvm.compiler.api.test.Graal; @@ -58,10 +52,12 @@ import org.graalvm.compiler.core.GraalCompiler.Request; import org.graalvm.compiler.core.common.CompilationIdentifier; import org.graalvm.compiler.core.common.type.StampFactory; +import org.graalvm.compiler.core.common.util.ModuleAPI; import org.graalvm.compiler.core.target.Backend; import org.graalvm.compiler.debug.Debug; import org.graalvm.compiler.debug.Debug.Scope; import org.graalvm.compiler.debug.DebugDumpScope; +import org.graalvm.compiler.debug.DebugEnvironment; import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.debug.TTY; import org.graalvm.compiler.graph.Node; @@ -98,7 +94,7 @@ import org.graalvm.compiler.nodes.spi.LoweringProvider; import org.graalvm.compiler.nodes.spi.Replacements; import org.graalvm.compiler.nodes.virtual.VirtualObjectNode; -import org.graalvm.compiler.options.DerivedOptionValue; +import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.phases.BasePhase; import org.graalvm.compiler.phases.OptimisticOptimizations; import org.graalvm.compiler.phases.Phase; @@ -112,9 +108,16 @@ import org.graalvm.compiler.phases.tiers.TargetProvider; import org.graalvm.compiler.phases.util.Providers; import org.graalvm.compiler.runtime.RuntimeProvider; +import org.graalvm.compiler.test.AddExports; import org.graalvm.compiler.test.GraalTest; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.internal.AssumptionViolatedException; import jdk.vm.ci.code.Architecture; +import jdk.vm.ci.code.BailoutException; import jdk.vm.ci.code.CodeCacheProvider; import jdk.vm.ci.code.InstalledCode; import jdk.vm.ci.code.TargetDescription; @@ -127,13 +130,15 @@ import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; import jdk.vm.ci.meta.SpeculationLog; +import jdk.vm.ci.meta.Assumptions.Assumption; +import jdk.vm.ci.services.Services; /** * Base class for Graal compiler unit tests. *

* White box tests for Graal compiler transformations use this pattern: *

    - *
  1. Create a graph by {@linkplain #parseEager(String, AllowAssumptions) parsing} a method.
  2. + *
  3. Create a graph by {@linkplain #parseEager parsing} a method.
  4. *
  5. Manually modify the graph (e.g. replace a parameter node with a constant).
  6. *
  7. Apply a transformation to the graph.
  8. *
  9. Assert that the transformed graph is equal to an expected graph.
  10. @@ -147,12 +152,46 @@ *

    * These tests will be run by the {@code mx unittest} command. */ +@AddExports({"jdk.internal.vm.ci/jdk.vm.ci.meta", + "jdk.internal.vm.ci/jdk.vm.ci.services", + "jdk.internal.vm.ci/jdk.vm.ci.code", + "jdk.internal.vm.ci/jdk.vm.ci.services", + "java.base/jdk.internal.org.objectweb.asm", + "java.base/jdk.internal.org.objectweb.asm.tree"}) public abstract class GraalCompilerTest extends GraalTest { + /** + * Gets the initial option values provided by the Graal runtime. These are option values + * typically parsed from the command line. + */ + public static OptionValues getInitialOptions() { + return Graal.getRequiredCapability(OptionValues.class); + } + + private static final int BAILOUT_RETRY_LIMIT = 1; private final Providers providers; private final Backend backend; - private final DerivedOptionValue suites; - private final DerivedOptionValue lirSuites; + + /** + * Representative class for the {@code java.base} module. + */ + public static final Class JAVA_BASE = Class.class; + + /** + * Representative class for the {@code jdk.vm.ci} module. + */ + public static final Class JDK_VM_CI = Services.class; + + /** + * Exports the package named {@code packageName} declared in {@code moduleMember}'s module to + * this object's module. This must be called before accessing packages that are no longer public + * as of JDK 9. + */ + protected final void exportPackage(Class moduleMember, String packageName) { + if (!Java8OrEarlier) { + ModuleAPI.exportPackageTo(moduleMember, packageName, getClass()); + } + } /** * Denotes a test method that must be inlined by the {@link BytecodeParser}. @@ -212,8 +251,8 @@ protected static void shouldBeOptimizedAway() { } - protected Suites createSuites() { - Suites ret = backend.getSuites().getDefaultSuites().copy(); + protected Suites createSuites(OptionValues opts) { + Suites ret = backend.getSuites().getDefaultSuites(opts).copy(); ListIterator> iter = ret.getHighTier().findPhase(ConvertDeoptimizeToGuardPhase.class, true); if (iter == null) { /* @@ -293,16 +332,14 @@ return ret; } - protected LIRSuites createLIRSuites() { - LIRSuites ret = backend.getSuites().getDefaultLIRSuites().copy(); + protected LIRSuites createLIRSuites(OptionValues opts) { + LIRSuites ret = backend.getSuites().getDefaultLIRSuites(opts).copy(); return ret; } public GraalCompilerTest() { this.backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend(); this.providers = getBackend().getProviders(); - this.suites = new DerivedOptionValue<>(this::createSuites); - this.lirSuites = new DerivedOptionValue<>(this::createLIRSuites); } /** @@ -321,8 +358,6 @@ this.backend = runtime.getHostBackend(); } this.providers = backend.getProviders(); - this.suites = new DerivedOptionValue<>(this::createSuites); - this.lirSuites = new DerivedOptionValue<>(this::createLIRSuites); } /** @@ -333,8 +368,6 @@ public GraalCompilerTest(Backend backend) { this.backend = backend; this.providers = backend.getProviders(); - this.suites = new DerivedOptionValue<>(this::createSuites); - this.lirSuites = new DerivedOptionValue<>(this::createLIRSuites); } private Scope debugScope; @@ -532,14 +565,6 @@ return backend; } - protected Suites getSuites() { - return suites.getValue(); - } - - protected LIRSuites getLIRSuites() { - return lirSuites.getValue(); - } - protected final Providers getProviders() { return providers; } @@ -621,7 +646,7 @@ return invoke(method, receiver, args); } - protected static class Result { + public static class Result { public final Object returnValue; public final Throwable exception; @@ -665,12 +690,16 @@ } protected Result executeActual(ResolvedJavaMethod method, Object receiver, Object... args) { + return executeActual(getInitialOptions(), method, receiver, args); + } + + protected Result executeActual(OptionValues options, ResolvedJavaMethod method, Object receiver, Object... args) { before(method); Object[] executeArgs = argsWithReceiver(receiver, args); checkArgs(method, executeArgs); - InstalledCode compiledMethod = getCode(method); + InstalledCode compiledMethod = getCode(method, options); try { return new Result(compiledMethod.executeVarargs(executeArgs), null); } catch (Throwable e) { @@ -718,14 +747,19 @@ return applyArgSuppliers(executeArgs); } - protected void test(String name, Object... args) { + protected final Result test(String name, Object... args) { + return test(getInitialOptions(), name, args); + } + + protected final Result test(OptionValues options, String name, Object... args) { try { ResolvedJavaMethod method = getResolvedJavaMethod(name); Object receiver = method.isStatic() ? null : this; - test(method, receiver, args); + return test(options, method, receiver, args); } catch (AssumptionViolatedException e) { // Suppress so that subsequent calls to this method within the // same Junit @Test annotated method can proceed. + return null; } } @@ -745,12 +779,16 @@ return supplier; } - protected void test(ResolvedJavaMethod method, Object receiver, Object... args) { + protected Result test(ResolvedJavaMethod method, Object receiver, Object... args) { + return test(getInitialOptions(), method, receiver, args); + } + + protected Result test(OptionValues options, ResolvedJavaMethod method, Object receiver, Object... args) { Result expect = executeExpected(method, receiver, args); - if (getCodeCache() == null) { - return; + if (getCodeCache() != null) { + testAgainstExpected(options, method, expect, receiver, args); } - testAgainstExpected(method, expect, receiver, args); + return expect; } /** @@ -770,17 +808,30 @@ return res; } - protected void testAgainstExpected(ResolvedJavaMethod method, Result expect, Object receiver, Object... args) { - testAgainstExpected(method, expect, Collections. emptySet(), receiver, args); + protected final void testAgainstExpected(ResolvedJavaMethod method, Result expect, Object receiver, Object... args) { + testAgainstExpected(getInitialOptions(), method, expect, Collections. emptySet(), receiver, args); + } + + protected void testAgainstExpected(ResolvedJavaMethod method, Result expect, Set shouldNotDeopt, Object receiver, Object... args) { + testAgainstExpected(getInitialOptions(), method, expect, shouldNotDeopt, receiver, args); + } + + protected final void testAgainstExpected(OptionValues options, ResolvedJavaMethod method, Result expect, Object receiver, Object... args) { + testAgainstExpected(options, method, expect, Collections. emptySet(), receiver, args); } - protected Result executeActualCheckDeopt(ResolvedJavaMethod method, Set shouldNotDeopt, Object receiver, Object... args) { + protected void testAgainstExpected(OptionValues options, ResolvedJavaMethod method, Result expect, Set shouldNotDeopt, Object receiver, Object... args) { + Result actual = executeActualCheckDeopt(options, method, shouldNotDeopt, receiver, args); + assertEquals(expect, actual); + } + + protected Result executeActualCheckDeopt(OptionValues options, ResolvedJavaMethod method, Set shouldNotDeopt, Object receiver, Object... args) { Map deoptCounts = new EnumMap<>(DeoptimizationReason.class); ProfilingInfo profile = method.getProfilingInfo(); for (DeoptimizationReason reason : shouldNotDeopt) { deoptCounts.put(reason, profile.getDeoptimizationCount(reason)); } - Result actual = executeActual(method, receiver, args); + Result actual = executeActual(options, method, receiver, args); profile = method.getProfilingInfo(); // profile can change after execution for (DeoptimizationReason reason : shouldNotDeopt) { Assert.assertEquals((int) deoptCounts.get(reason), profile.getDeoptimizationCount(reason)); @@ -801,19 +852,18 @@ } } - protected void testAgainstExpected(ResolvedJavaMethod method, Result expect, Set shouldNotDeopt, Object receiver, Object... args) { - Result actual = executeActualCheckDeopt(method, shouldNotDeopt, receiver, args); - assertEquals(expect, actual); - } - private Map cache = new HashMap<>(); /** * Gets installed code for a given method, compiling it first if necessary. The graph is parsed - * {@link #parseEager(ResolvedJavaMethod, AllowAssumptions) eagerly}. + * {@link #parseEager eagerly}. */ - protected InstalledCode getCode(ResolvedJavaMethod method) { - return getCode(method, null); + protected final InstalledCode getCode(ResolvedJavaMethod method) { + return getCode(method, null, false, false, getInitialOptions()); + } + + protected final InstalledCode getCode(ResolvedJavaMethod method, OptionValues options) { + return getCode(method, null, false, false, options); } /** @@ -823,12 +873,21 @@ * @param graph the graph to be compiled. If null, a graph will be obtained from * {@code installedCodeOwner} via {@link #parseForCompile(ResolvedJavaMethod)}. */ - protected InstalledCode getCode(ResolvedJavaMethod installedCodeOwner, StructuredGraph graph) { - return getCode(installedCodeOwner, graph, false); + protected final InstalledCode getCode(ResolvedJavaMethod installedCodeOwner, StructuredGraph graph) { + return getCode(installedCodeOwner, graph, false, false, graph == null ? getInitialOptions() : graph.getOptions()); } - protected InstalledCode getCode(final ResolvedJavaMethod installedCodeOwner, StructuredGraph graph0, boolean forceCompile) { - return getCode(installedCodeOwner, graph0, forceCompile, false); + /** + * Gets installed code for a given method and graph, compiling it first if necessary. + * + * @param installedCodeOwner the method the compiled code will be associated with when installed + * @param graph the graph to be compiled. If null, a graph will be obtained from + * {@code installedCodeOwner} via {@link #parseForCompile(ResolvedJavaMethod)}. + * @param forceCompile specifies whether to ignore any previous code cached for the (method, + * key) pair + */ + protected final InstalledCode getCode(final ResolvedJavaMethod installedCodeOwner, StructuredGraph graph, boolean forceCompile) { + return getCode(installedCodeOwner, graph, forceCompile, false, graph == null ? getInitialOptions() : graph.getOptions()); } /** @@ -839,10 +898,11 @@ * {@code installedCodeOwner} via {@link #parseForCompile(ResolvedJavaMethod)}. * @param forceCompile specifies whether to ignore any previous code cached for the (method, * key) pair - * @param installDefault specifies whether to install as the default implementation + * @param installAsDefault specifies whether to install as the default implementation + * @param options the options that will be used in {@link #parseForCompile(ResolvedJavaMethod)} */ @SuppressWarnings("try") - protected InstalledCode getCode(final ResolvedJavaMethod installedCodeOwner, StructuredGraph graph, boolean forceCompile, boolean installDefault) { + protected InstalledCode getCode(final ResolvedJavaMethod installedCodeOwner, StructuredGraph graph, boolean forceCompile, boolean installAsDefault, OptionValues options) { if (!forceCompile) { InstalledCode cached = cache.get(installedCodeOwner); if (cached != null) { @@ -851,41 +911,54 @@ } } } - - final CompilationIdentifier id = getOrCreateCompilationId(installedCodeOwner, graph); - - InstalledCode installedCode = null; - try (AllocSpy spy = AllocSpy.open(installedCodeOwner); Scope ds = Debug.scope("Compiling", new DebugDumpScope(id.toString(CompilationIdentifier.Verbosity.ID), true))) { - final boolean printCompilation = PrintCompilation.getValue() && !TTY.isSuppressed(); - if (printCompilation) { - TTY.println(String.format("@%-6s Graal %-70s %-45s %-50s ...", id, installedCodeOwner.getDeclaringClass().getName(), installedCodeOwner.getName(), installedCodeOwner.getSignature())); - } - long start = System.currentTimeMillis(); - CompilationResult compResult = compile(installedCodeOwner, graph, id); - if (printCompilation) { - TTY.println(String.format("@%-6s Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize())); - } - - try (Scope s = Debug.scope("CodeInstall", getCodeCache(), installedCodeOwner, compResult)) { - if (installDefault) { - installedCode = addDefaultMethod(installedCodeOwner, compResult); - } else { - installedCode = addMethod(installedCodeOwner, compResult); + // loop for retrying compilation + for (int retry = 0; retry <= BAILOUT_RETRY_LIMIT; retry++) { + final CompilationIdentifier id = getOrCreateCompilationId(installedCodeOwner, graph); + + InstalledCode installedCode = null; + try (AllocSpy spy = AllocSpy.open(installedCodeOwner); Scope ds = Debug.scope("Compiling", new DebugDumpScope(id.toString(CompilationIdentifier.Verbosity.ID), true))) { + final boolean printCompilation = PrintCompilation.getValue(options) && !TTY.isSuppressed(); + if (printCompilation) { + TTY.println(String.format("@%-6s Graal %-70s %-45s %-50s ...", id, installedCodeOwner.getDeclaringClass().getName(), installedCodeOwner.getName(), + installedCodeOwner.getSignature())); } - if (installedCode == null) { - throw new GraalError("Could not install code for " + installedCodeOwner.format("%H.%n(%p)")); + long start = System.currentTimeMillis(); + CompilationResult compResult = compile(installedCodeOwner, graph, new CompilationResult(), id, options); + if (printCompilation) { + TTY.println(String.format("@%-6s Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize())); + } + + try (Scope s = Debug.scope("CodeInstall", getCodeCache(), installedCodeOwner, compResult)) { + try { + if (installAsDefault) { + installedCode = addDefaultMethod(installedCodeOwner, compResult); + } else { + installedCode = addMethod(installedCodeOwner, compResult); + } + if (installedCode == null) { + throw new GraalError("Could not install code for " + installedCodeOwner.format("%H.%n(%p)")); + } + } catch (BailoutException e) { + if (retry <= BAILOUT_RETRY_LIMIT && graph == null && !e.isPermanent()) { + // retry (if there is no predefined graph) + TTY.println(String.format("Restart compilation %s (%s) due to a non-permanent bailout!", installedCodeOwner, id)); + continue; + } + throw e; + } + } catch (Throwable e) { + throw Debug.handle(e); } } catch (Throwable e) { throw Debug.handle(e); } - } catch (Throwable e) { - throw Debug.handle(e); - } - if (!forceCompile) { - cache.put(installedCodeOwner, installedCode); + if (!forceCompile) { + cache.put(installedCodeOwner, installedCode); + } + return installedCode; } - return installedCode; + throw GraalError.shouldNotReachHere(); } /** @@ -893,15 +966,18 @@ * {@link #compile(ResolvedJavaMethod, StructuredGraph)} if the second parameter to that method * is null. * - * The default implementation in {@link GraalCompilerTest} is to call - * {@link #parseEager(ResolvedJavaMethod, AllowAssumptions)}. + * The default implementation in {@link GraalCompilerTest} is to call {@link #parseEager}. */ + protected StructuredGraph parseForCompile(ResolvedJavaMethod method, OptionValues options) { + return parseEager(method, AllowAssumptions.YES, getCompilationId(method), options); + } + protected final StructuredGraph parseForCompile(ResolvedJavaMethod method) { - return parseEager(method, AllowAssumptions.YES); + return parseEager(method, AllowAssumptions.YES, getCompilationId(method), getInitialOptions()); } - protected StructuredGraph parseForCompile(ResolvedJavaMethod method, CompilationIdentifier compilationId) { - return parseEager(method, AllowAssumptions.YES, compilationId); + protected StructuredGraph parseForCompile(ResolvedJavaMethod method, CompilationIdentifier compilationId, OptionValues options) { + return parseEager(method, AllowAssumptions.YES, compilationId, options); } /** @@ -913,11 +989,18 @@ * {@link #parseForCompile(ResolvedJavaMethod)}. */ protected final CompilationResult compile(ResolvedJavaMethod installedCodeOwner, StructuredGraph graph) { - return compile(installedCodeOwner, graph, getOrCreateCompilationId(installedCodeOwner, graph)); + OptionValues options = graph == null ? getInitialOptions() : graph.getOptions(); + return compile(installedCodeOwner, graph, new CompilationResult(), getOrCreateCompilationId(installedCodeOwner, graph), options); + } + + protected final CompilationResult compile(ResolvedJavaMethod installedCodeOwner, StructuredGraph graph, CompilationIdentifier compilationId) { + OptionValues options = graph == null ? getInitialOptions() : graph.getOptions(); + return compile(installedCodeOwner, graph, new CompilationResult(), compilationId, options); } - protected CompilationResult compile(ResolvedJavaMethod installedCodeOwner, StructuredGraph graph, CompilationIdentifier compilationId) { - return compile(installedCodeOwner, graph, new CompilationResult(), compilationId); + protected final CompilationResult compile(ResolvedJavaMethod installedCodeOwner, StructuredGraph graph, OptionValues options) { + assert graph == null || graph.getOptions() == options; + return compile(installedCodeOwner, graph, new CompilationResult(), getOrCreateCompilationId(installedCodeOwner, graph), options); } /** @@ -927,16 +1010,16 @@ * @param graph the graph to be compiled for {@code installedCodeOwner}. If null, a graph will * be obtained from {@code installedCodeOwner} via * {@link #parseForCompile(ResolvedJavaMethod)}. - * @param compilationResult * @param compilationId */ @SuppressWarnings("try") - protected CompilationResult compile(ResolvedJavaMethod installedCodeOwner, StructuredGraph graph, CompilationResult compilationResult, CompilationIdentifier compilationId) { - StructuredGraph graphToCompile = graph == null ? parseForCompile(installedCodeOwner, compilationId) : graph; + protected CompilationResult compile(ResolvedJavaMethod installedCodeOwner, StructuredGraph graph, CompilationResult compilationResult, CompilationIdentifier compilationId, OptionValues options) { + StructuredGraph graphToCompile = graph == null ? parseForCompile(installedCodeOwner, compilationId, options) : graph; lastCompiledGraph = graphToCompile; try (Scope s = Debug.scope("Compile", graphToCompile)) { + assert options != null; Request request = new Request<>(graphToCompile, installedCodeOwner, getProviders(), getBackend(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, - graphToCompile.getProfilingInfo(), getSuites(), getLIRSuites(), compilationResult, CompilationResultBuilderFactory.Default); + graphToCompile.getProfilingInfo(), createSuites(options), createLIRSuites(options), compilationResult, CompilationResultBuilderFactory.Default); return GraalCompiler.compile(request); } catch (Throwable e) { throw Debug.handle(e); @@ -1002,21 +1085,32 @@ * produce a graph. * * @param methodName the name of the method in {@code this.getClass()} to be parsed + * @param allowAssumptions specifies if {@link Assumption}s can be made compiling the graph */ - protected StructuredGraph parseProfiled(String methodName, AllowAssumptions allowAssumptions) { + protected final StructuredGraph parseProfiled(String methodName, AllowAssumptions allowAssumptions) { return parseProfiled(getResolvedJavaMethod(methodName), allowAssumptions); } /** * Parses a Java method in {@linkplain GraphBuilderConfiguration#getDefault default} mode to * produce a graph. + * + * @param method the method to be parsed + * @param allowAssumptions specifies if {@link Assumption}s can be made compiling the graph */ - protected final StructuredGraph parseProfiled(ResolvedJavaMethod m, AllowAssumptions allowAssumptions) { - return parseProfiled(m, allowAssumptions, getCompilationId(m)); + protected final StructuredGraph parseProfiled(ResolvedJavaMethod method, AllowAssumptions allowAssumptions) { + return parse1(method, getDefaultGraphBuilderSuite(), allowAssumptions, getCompilationId(method), getInitialOptions()); } - protected StructuredGraph parseProfiled(ResolvedJavaMethod m, AllowAssumptions allowAssumptions, CompilationIdentifier compilationId) { - return parse1(m, getDefaultGraphBuilderSuite(), allowAssumptions, compilationId); + /** + * Parses a Java method with {@linkplain GraphBuilderConfiguration#withEagerResolving(boolean)} + * set to true to produce a graph. + * + * @param methodName the name of the method in {@code this.getClass()} to be parsed + * @param allowAssumptions specifies if {@link Assumption}s can be made compiling the graph + */ + protected final StructuredGraph parseEager(String methodName, AllowAssumptions allowAssumptions) { + return parseEager(getResolvedJavaMethod(methodName), allowAssumptions, getInitialOptions()); } /** @@ -1024,39 +1118,67 @@ * set to true to produce a graph. * * @param methodName the name of the method in {@code this.getClass()} to be parsed + * @param allowAssumptions specifies if {@link Assumption}s can be made compiling the graph + * @param options the option values to be used when compiling the graph */ - protected final StructuredGraph parseEager(String methodName, AllowAssumptions allowAssumptions) { - return parseEager(getResolvedJavaMethod(methodName), allowAssumptions); + protected final StructuredGraph parseEager(String methodName, AllowAssumptions allowAssumptions, OptionValues options) { + return parseEager(getResolvedJavaMethod(methodName), allowAssumptions, options); } /** * Parses a Java method with {@linkplain GraphBuilderConfiguration#withEagerResolving(boolean)} * set to true to produce a graph. + * + * @param method the method to be parsed + * @param allowAssumptions specifies if {@link Assumption}s can be made compiling the graph */ - protected final StructuredGraph parseEager(ResolvedJavaMethod m, AllowAssumptions allowAssumptions) { - return parseEager(m, allowAssumptions, getCompilationId(m)); + protected final StructuredGraph parseEager(ResolvedJavaMethod method, AllowAssumptions allowAssumptions) { + return parseEager(method, allowAssumptions, getCompilationId(method), getInitialOptions()); } - protected StructuredGraph parseEager(ResolvedJavaMethod m, AllowAssumptions allowAssumptions, CompilationIdentifier compilationId) { - return parse1(m, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getDefault(getDefaultGraphBuilderPlugins()).withEagerResolving(true)), allowAssumptions, compilationId); + /** + * Parses a Java method with {@linkplain GraphBuilderConfiguration#withEagerResolving(boolean)} + * set to true to produce a graph. + * + * @param method the method to be parsed + * @param allowAssumptions specifies if {@link Assumption}s can be made compiling the graph + * @param options the option values to be used when compiling the graph + */ + protected final StructuredGraph parseEager(ResolvedJavaMethod method, AllowAssumptions allowAssumptions, OptionValues options) { + return parseEager(method, allowAssumptions, getCompilationId(method), options); } /** - * Parses a Java method using {@linkplain GraphBuilderConfiguration#withFullInfopoints(boolean) - * full debug} set to true to produce a graph. + * Parses a Java method with {@linkplain GraphBuilderConfiguration#withEagerResolving(boolean)} + * set to true to produce a graph. + * + * @param method the method to be parsed + * @param allowAssumptions specifies if {@link Assumption}s can be made compiling the graph + * @param compilationId the compilation identifier to be associated with the graph + * @param options the option values to be used when compiling the graph */ - protected final StructuredGraph parseDebug(ResolvedJavaMethod m, AllowAssumptions allowAssumptions) { - return parseDebug(m, allowAssumptions, getCompilationId(m)); + protected StructuredGraph parseEager(ResolvedJavaMethod method, AllowAssumptions allowAssumptions, CompilationIdentifier compilationId, OptionValues options) { + return parse1(method, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getDefault(getDefaultGraphBuilderPlugins()).withEagerResolving(true)), allowAssumptions, compilationId, options); } - protected StructuredGraph parseDebug(ResolvedJavaMethod m, AllowAssumptions allowAssumptions, CompilationIdentifier compilationId) { - return parse1(m, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getDefault(getDefaultGraphBuilderPlugins()).withFullInfopoints(true)), allowAssumptions, compilationId); + /** + * Parses a Java method using {@linkplain GraphBuilderConfiguration#withFullInfopoints(boolean) + * full debug} set to true to produce a graph. + * + * @param method the method to be parsed + * @param allowAssumptions specifies if {@link Assumption}s can be made compiling the graph + */ + protected StructuredGraph parseDebug(ResolvedJavaMethod method, AllowAssumptions allowAssumptions) { + return parse1(method, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getDefault(getDefaultGraphBuilderPlugins()).withFullInfopoints(true)), allowAssumptions, getCompilationId(method), + getInitialOptions()); } @SuppressWarnings("try") - private StructuredGraph parse1(ResolvedJavaMethod javaMethod, PhaseSuite graphBuilderSuite, AllowAssumptions allowAssumptions, CompilationIdentifier compilationId) { + private StructuredGraph parse1(ResolvedJavaMethod javaMethod, PhaseSuite graphBuilderSuite, AllowAssumptions allowAssumptions, CompilationIdentifier compilationId, + OptionValues options) { assert javaMethod.getAnnotation(Test.class) == null : "shouldn't parse method with @Test annotation: " + javaMethod; - StructuredGraph graph = new StructuredGraph(javaMethod, allowAssumptions, getSpeculationLog(), compilationId); + StructuredGraph graph = new StructuredGraph.Builder(options, allowAssumptions).method(javaMethod).speculationLog(getSpeculationLog()).useProfilingInfo(true).compilationId( + compilationId).build(); try (Scope ds = Debug.scope("Parsing", javaMethod, graph)) { graphBuilderSuite.apply(graph, getDefaultHighTierContext()); return graph; @@ -1186,4 +1308,13 @@ protected boolean isArchitecture(String name) { return name.equals(backend.getTarget().arch.getName()); } + + /** + * This method should be called in "timeout" tests which JUnit runs in a different thread. + */ + public static void initializeForTimeout() { + // timeout tests run in a separate thread which needs the DebugEnvironment to be + // initialized + DebugEnvironment.ensureInitialized(getInitialOptions()); + } }