src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java

Print this page




  27 import static org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo.DO_NOT_INLINE_NO_EXCEPTION;
  28 import static org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo.DO_NOT_INLINE_WITH_EXCEPTION;
  29 
  30 import java.lang.annotation.ElementType;
  31 import java.lang.annotation.Retention;
  32 import java.lang.annotation.RetentionPolicy;
  33 import java.lang.annotation.Target;
  34 import java.lang.reflect.InvocationTargetException;
  35 import java.lang.reflect.Method;
  36 import java.util.ArrayList;
  37 import java.util.Arrays;
  38 import java.util.Collections;
  39 import java.util.EnumMap;
  40 import java.util.HashMap;
  41 import java.util.List;
  42 import java.util.ListIterator;
  43 import java.util.Map;
  44 import java.util.Set;
  45 import java.util.function.Supplier;
  46 
  47 import org.junit.After;
  48 import org.junit.Assert;
  49 import org.junit.Before;
  50 import org.junit.Test;
  51 import org.junit.internal.AssumptionViolatedException;
  52 
  53 import org.graalvm.compiler.api.directives.GraalDirectives;
  54 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
  55 import org.graalvm.compiler.api.test.Graal;
  56 import org.graalvm.compiler.code.CompilationResult;
  57 import org.graalvm.compiler.core.GraalCompiler;
  58 import org.graalvm.compiler.core.GraalCompiler.Request;
  59 import org.graalvm.compiler.core.common.CompilationIdentifier;
  60 import org.graalvm.compiler.core.common.type.StampFactory;

  61 import org.graalvm.compiler.core.target.Backend;
  62 import org.graalvm.compiler.debug.Debug;
  63 import org.graalvm.compiler.debug.Debug.Scope;
  64 import org.graalvm.compiler.debug.DebugDumpScope;

  65 import org.graalvm.compiler.debug.GraalError;
  66 import org.graalvm.compiler.debug.TTY;
  67 import org.graalvm.compiler.graph.Node;
  68 import org.graalvm.compiler.graph.NodeClass;
  69 import org.graalvm.compiler.graph.NodeMap;
  70 import org.graalvm.compiler.java.BytecodeParser;
  71 import org.graalvm.compiler.java.ComputeLoopFrequenciesClosure;
  72 import org.graalvm.compiler.java.GraphBuilderPhase;
  73 import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory;
  74 import org.graalvm.compiler.lir.phases.LIRSuites;
  75 import org.graalvm.compiler.nodeinfo.NodeInfo;
  76 import org.graalvm.compiler.nodeinfo.NodeSize;
  77 import org.graalvm.compiler.nodeinfo.Verbosity;
  78 import org.graalvm.compiler.nodes.BreakpointNode;
  79 import org.graalvm.compiler.nodes.ConstantNode;
  80 import org.graalvm.compiler.nodes.FixedWithNextNode;
  81 import org.graalvm.compiler.nodes.FrameState;
  82 import org.graalvm.compiler.nodes.FullInfopointNode;
  83 import org.graalvm.compiler.nodes.InvokeNode;
  84 import org.graalvm.compiler.nodes.InvokeWithExceptionNode;
  85 import org.graalvm.compiler.nodes.ProxyNode;
  86 import org.graalvm.compiler.nodes.ReturnNode;
  87 import org.graalvm.compiler.nodes.StructuredGraph;
  88 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
  89 import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
  90 import org.graalvm.compiler.nodes.ValueNode;
  91 import org.graalvm.compiler.nodes.cfg.Block;
  92 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
  93 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
  94 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
  95 import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin;
  96 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
  97 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
  98 import org.graalvm.compiler.nodes.spi.LoweringProvider;
  99 import org.graalvm.compiler.nodes.spi.Replacements;
 100 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
 101 import org.graalvm.compiler.options.DerivedOptionValue;
 102 import org.graalvm.compiler.phases.BasePhase;
 103 import org.graalvm.compiler.phases.OptimisticOptimizations;
 104 import org.graalvm.compiler.phases.Phase;
 105 import org.graalvm.compiler.phases.PhaseSuite;
 106 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 107 import org.graalvm.compiler.phases.common.ConvertDeoptimizeToGuardPhase;
 108 import org.graalvm.compiler.phases.schedule.SchedulePhase;
 109 import org.graalvm.compiler.phases.schedule.SchedulePhase.SchedulingStrategy;
 110 import org.graalvm.compiler.phases.tiers.HighTierContext;
 111 import org.graalvm.compiler.phases.tiers.Suites;
 112 import org.graalvm.compiler.phases.tiers.TargetProvider;
 113 import org.graalvm.compiler.phases.util.Providers;
 114 import org.graalvm.compiler.runtime.RuntimeProvider;

 115 import org.graalvm.compiler.test.GraalTest;





 116 
 117 import jdk.vm.ci.code.Architecture;

 118 import jdk.vm.ci.code.CodeCacheProvider;
 119 import jdk.vm.ci.code.InstalledCode;
 120 import jdk.vm.ci.code.TargetDescription;
 121 import jdk.vm.ci.meta.ConstantReflectionProvider;
 122 import jdk.vm.ci.meta.DeoptimizationReason;
 123 import jdk.vm.ci.meta.JavaKind;
 124 import jdk.vm.ci.meta.JavaType;
 125 import jdk.vm.ci.meta.MetaAccessProvider;
 126 import jdk.vm.ci.meta.ProfilingInfo;
 127 import jdk.vm.ci.meta.ResolvedJavaMethod;
 128 import jdk.vm.ci.meta.ResolvedJavaType;
 129 import jdk.vm.ci.meta.SpeculationLog;


 130 
 131 /**
 132  * Base class for Graal compiler unit tests.
 133  * <p>
 134  * White box tests for Graal compiler transformations use this pattern:
 135  * <ol>
 136  * <li>Create a graph by {@linkplain #parseEager(String, AllowAssumptions) parsing} a method.</li>
 137  * <li>Manually modify the graph (e.g. replace a parameter node with a constant).</li>
 138  * <li>Apply a transformation to the graph.</li>
 139  * <li>Assert that the transformed graph is equal to an expected graph.</li>
 140  * </ol>
 141  * <p>
 142  * See {@link InvokeHintsTest} as an example of a white box test.
 143  * <p>
 144  * Black box tests use the {@link #test(String, Object...)} or
 145  * {@link #testN(int, String, Object...)} to execute some method in the interpreter and compare its
 146  * result against that produced by a Graal compiled version of the method.
 147  * <p>
 148  * These tests will be run by the {@code mx unittest} command.
 149  */






 150 public abstract class GraalCompilerTest extends GraalTest {
 151 









 152     private final Providers providers;
 153     private final Backend backend;
 154     private final DerivedOptionValue<Suites> suites;
 155     private final DerivedOptionValue<LIRSuites> lirSuites;



















 156 
 157     /**
 158      * Denotes a test method that must be inlined by the {@link BytecodeParser}.
 159      */
 160     @Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
 161     @Retention(RetentionPolicy.RUNTIME)
 162     public @interface BytecodeParserForceInline {
 163     }
 164 
 165     /**
 166      * Denotes a test method that must never be inlined by the {@link BytecodeParser}.
 167      */
 168     @Retention(RetentionPolicy.RUNTIME)
 169     @Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
 170     public @interface BytecodeParserNeverInline {
 171         /**
 172          * Specifies if the call should be implemented with {@link InvokeWithExceptionNode} instead
 173          * of {@link InvokeNode}.
 174          */
 175         boolean invokeWithException() default false;


 195 
 196     /**
 197      * Can be overridden by unit tests to verify properties of the graph.
 198      *
 199      * @param graph the graph at the end of LowTier
 200      */
 201     protected boolean checkLowTierGraph(StructuredGraph graph) {
 202         return true;
 203     }
 204 
 205     protected static void breakpoint() {
 206     }
 207 
 208     @SuppressWarnings("unused")
 209     protected static void breakpoint(int arg0) {
 210     }
 211 
 212     protected static void shouldBeOptimizedAway() {
 213     }
 214 
 215     protected Suites createSuites() {
 216         Suites ret = backend.getSuites().getDefaultSuites().copy();
 217         ListIterator<BasePhase<? super HighTierContext>> iter = ret.getHighTier().findPhase(ConvertDeoptimizeToGuardPhase.class, true);
 218         if (iter == null) {
 219             /*
 220              * in the economy configuration, we don't have the ConvertDeoptimizeToGuard phase, so we
 221              * just select the first CanonicalizerPhase in HighTier
 222              */
 223             iter = ret.getHighTier().findPhase(CanonicalizerPhase.class);
 224         }
 225         iter.add(new Phase() {
 226 
 227             @Override
 228             protected void run(StructuredGraph graph) {
 229                 ComputeLoopFrequenciesClosure.compute(graph);
 230             }
 231 
 232             @Override
 233             public float codeSizeIncrease() {
 234                 return NodeSize.IGNORE_SIZE_CONTRACT_FACTOR;
 235             }
 236 


 276         ret.getLowTier().appendPhase(new Phase() {
 277 
 278             @Override
 279             protected void run(StructuredGraph graph) {
 280                 assert checkLowTierGraph(graph) : "failed LowTier graph check";
 281             }
 282 
 283             @Override
 284             public float codeSizeIncrease() {
 285                 return NodeSize.IGNORE_SIZE_CONTRACT_FACTOR;
 286             }
 287 
 288             @Override
 289             protected CharSequence getName() {
 290                 return "CheckGraphPhase";
 291             }
 292         });
 293         return ret;
 294     }
 295 
 296     protected LIRSuites createLIRSuites() {
 297         LIRSuites ret = backend.getSuites().getDefaultLIRSuites().copy();
 298         return ret;
 299     }
 300 
 301     public GraalCompilerTest() {
 302         this.backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend();
 303         this.providers = getBackend().getProviders();
 304         this.suites = new DerivedOptionValue<>(this::createSuites);
 305         this.lirSuites = new DerivedOptionValue<>(this::createLIRSuites);
 306     }
 307 
 308     /**
 309      * Set up a test for a non-default backend. The test should check (via {@link #getBackend()} )
 310      * whether the desired backend is available.
 311      *
 312      * @param arch the name of the desired backend architecture
 313      */
 314     public GraalCompilerTest(Class<? extends Architecture> arch) {
 315         RuntimeProvider runtime = Graal.getRequiredCapability(RuntimeProvider.class);
 316         Backend b = runtime.getBackend(arch);
 317         if (b != null) {
 318             this.backend = b;
 319         } else {
 320             // Fall back to the default/host backend
 321             this.backend = runtime.getHostBackend();
 322         }
 323         this.providers = backend.getProviders();
 324         this.suites = new DerivedOptionValue<>(this::createSuites);
 325         this.lirSuites = new DerivedOptionValue<>(this::createLIRSuites);
 326     }
 327 
 328     /**
 329      * Set up a test for a non-default backend.
 330      *
 331      * @param backend the desired backend
 332      */
 333     public GraalCompilerTest(Backend backend) {
 334         this.backend = backend;
 335         this.providers = backend.getProviders();
 336         this.suites = new DerivedOptionValue<>(this::createSuites);
 337         this.lirSuites = new DerivedOptionValue<>(this::createLIRSuites);
 338     }
 339 
 340     private Scope debugScope;
 341 
 342     @Before
 343     public void beforeTest() {
 344         assert debugScope == null;
 345         debugScope = Debug.scope(getClass());
 346     }
 347 
 348     @After
 349     public void afterTest() {
 350         if (debugScope != null) {
 351             debugScope.close();
 352         }
 353         debugScope = null;
 354     }
 355 
 356     protected void assertEquals(StructuredGraph expected, StructuredGraph graph) {
 357         assertEquals(expected, graph, false, true);


 515             result.append("Block " + block + " ");
 516             if (block == scheduleResult.getCFG().getStartBlock()) {
 517                 result.append("* ");
 518             }
 519             result.append("-> ");
 520             for (Block succ : block.getSuccessors()) {
 521                 result.append(succ + " ");
 522             }
 523             result.append("\n");
 524             for (Node node : scheduleResult.getBlockToNodesMap().get(block)) {
 525                 result.append(String.format("%1S\n", node));
 526             }
 527         }
 528         return result.toString();
 529     }
 530 
 531     protected Backend getBackend() {
 532         return backend;
 533     }
 534 
 535     protected Suites getSuites() {
 536         return suites.getValue();
 537     }
 538 
 539     protected LIRSuites getLIRSuites() {
 540         return lirSuites.getValue();
 541     }
 542 
 543     protected final Providers getProviders() {
 544         return providers;
 545     }
 546 
 547     protected HighTierContext getDefaultHighTierContext() {
 548         return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
 549     }
 550 
 551     protected SnippetReflectionProvider getSnippetReflection() {
 552         return Graal.getRequiredCapability(SnippetReflectionProvider.class);
 553     }
 554 
 555     protected TargetDescription getTarget() {
 556         return getTargetProvider().getTarget();
 557     }
 558 
 559     protected TargetProvider getTargetProvider() {
 560         return getBackend();
 561     }
 562 


 604             };
 605             threads[i] = t;
 606             t.start();
 607         }
 608         for (int i = 0; i < n; i++) {
 609             try {
 610                 threads[i].join();
 611             } catch (InterruptedException e) {
 612                 errors.add(e);
 613             }
 614         }
 615         if (!errors.isEmpty()) {
 616             throw new MultiCauseAssertionError(errors.size() + " failures", errors.toArray(new Throwable[errors.size()]));
 617         }
 618     }
 619 
 620     protected Object referenceInvoke(ResolvedJavaMethod method, Object receiver, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
 621         return invoke(method, receiver, args);
 622     }
 623 
 624     protected static class Result {
 625 
 626         public final Object returnValue;
 627         public final Throwable exception;
 628 
 629         public Result(Object returnValue, Throwable exception) {
 630             this.returnValue = returnValue;
 631             this.exception = exception;
 632         }
 633 
 634         @Override
 635         public String toString() {
 636             return exception == null ? returnValue == null ? "null" : returnValue.toString() : "!" + exception;
 637         }
 638     }
 639 
 640     /**
 641      * Called before a test is executed.
 642      */
 643     protected void before(@SuppressWarnings("unused") ResolvedJavaMethod method) {
 644     }


 648      */
 649     protected void after() {
 650     }
 651 
 652     protected Result executeExpected(ResolvedJavaMethod method, Object receiver, Object... args) {
 653         before(method);
 654         try {
 655             // This gives us both the expected return value as well as ensuring that the method to
 656             // be compiled is fully resolved
 657             return new Result(referenceInvoke(method, receiver, args), null);
 658         } catch (InvocationTargetException e) {
 659             return new Result(null, e.getTargetException());
 660         } catch (Exception e) {
 661             throw new RuntimeException(e);
 662         } finally {
 663             after();
 664         }
 665     }
 666 
 667     protected Result executeActual(ResolvedJavaMethod method, Object receiver, Object... args) {




 668         before(method);
 669         Object[] executeArgs = argsWithReceiver(receiver, args);
 670 
 671         checkArgs(method, executeArgs);
 672 
 673         InstalledCode compiledMethod = getCode(method);
 674         try {
 675             return new Result(compiledMethod.executeVarargs(executeArgs), null);
 676         } catch (Throwable e) {
 677             return new Result(null, e);
 678         } finally {
 679             after();
 680         }
 681     }
 682 
 683     protected void checkArgs(ResolvedJavaMethod method, Object[] args) {
 684         JavaType[] sig = method.toParameterTypes();
 685         Assert.assertEquals(sig.length, args.length);
 686         for (int i = 0; i < args.length; i++) {
 687             JavaType javaType = sig[i];
 688             JavaKind kind = javaType.getJavaKind();
 689             Object arg = args[i];
 690             if (kind == JavaKind.Object) {
 691                 if (arg != null && javaType instanceof ResolvedJavaType) {
 692                     ResolvedJavaType resolvedJavaType = (ResolvedJavaType) javaType;
 693                     Assert.assertTrue(resolvedJavaType + " from " + getMetaAccess().lookupJavaType(arg.getClass()), resolvedJavaType.isAssignableFrom(getMetaAccess().lookupJavaType(arg.getClass())));


 701 
 702     /**
 703      * Prepends a non-null receiver argument to a given list or args.
 704      *
 705      * @param receiver the receiver argument to prepend if it is non-null
 706      */
 707     protected Object[] argsWithReceiver(Object receiver, Object... args) {
 708         Object[] executeArgs;
 709         if (receiver == null) {
 710             executeArgs = args;
 711         } else {
 712             executeArgs = new Object[args.length + 1];
 713             executeArgs[0] = receiver;
 714             for (int i = 0; i < args.length; i++) {
 715                 executeArgs[i + 1] = args[i];
 716             }
 717         }
 718         return applyArgSuppliers(executeArgs);
 719     }
 720 
 721     protected void test(String name, Object... args) {




 722         try {
 723             ResolvedJavaMethod method = getResolvedJavaMethod(name);
 724             Object receiver = method.isStatic() ? null : this;
 725             test(method, receiver, args);
 726         } catch (AssumptionViolatedException e) {
 727             // Suppress so that subsequent calls to this method within the
 728             // same Junit @Test annotated method can proceed.

 729         }
 730     }
 731 
 732     /**
 733      * Type denoting a lambda that supplies a fresh value each time it is called. This is useful
 734      * when supplying an argument to {@link GraalCompilerTest#test(String, Object...)} where the
 735      * test modifies the state of the argument (e.g., updates a field).
 736      */
 737     @FunctionalInterface
 738     public interface ArgSupplier extends Supplier<Object> {
 739     }
 740 
 741     /**
 742      * Convenience method for using an {@link ArgSupplier} lambda in a varargs list.
 743      */
 744     public static Object supply(ArgSupplier supplier) {
 745         return supplier;
 746     }
 747 
 748     protected void test(ResolvedJavaMethod method, Object receiver, Object... args) {




 749         Result expect = executeExpected(method, receiver, args);
 750         if (getCodeCache() == null) {
 751             return;
 752         }
 753         testAgainstExpected(method, expect, receiver, args);
 754     }
 755 
 756     /**
 757      * Process a given set of arguments, converting any {@link ArgSupplier} argument to the argument
 758      * it supplies.
 759      */
 760     protected Object[] applyArgSuppliers(Object... args) {
 761         Object[] res = args;
 762         for (int i = 0; i < args.length; i++) {
 763             if (args[i] instanceof ArgSupplier) {
 764                 if (res == args) {
 765                     res = args.clone();
 766                 }
 767                 res[i] = ((ArgSupplier) args[i]).get();
 768             }
 769         }
 770         return res;
 771     }
 772 
 773     protected void testAgainstExpected(ResolvedJavaMethod method, Result expect, Object receiver, Object... args) {
 774         testAgainstExpected(method, expect, Collections.<DeoptimizationReason> emptySet(), receiver, args);
 775     }
 776 
 777     protected Result executeActualCheckDeopt(ResolvedJavaMethod method, Set<DeoptimizationReason> shouldNotDeopt, Object receiver, Object... args) {













 778         Map<DeoptimizationReason, Integer> deoptCounts = new EnumMap<>(DeoptimizationReason.class);
 779         ProfilingInfo profile = method.getProfilingInfo();
 780         for (DeoptimizationReason reason : shouldNotDeopt) {
 781             deoptCounts.put(reason, profile.getDeoptimizationCount(reason));
 782         }
 783         Result actual = executeActual(method, receiver, args);
 784         profile = method.getProfilingInfo(); // profile can change after execution
 785         for (DeoptimizationReason reason : shouldNotDeopt) {
 786             Assert.assertEquals((int) deoptCounts.get(reason), profile.getDeoptimizationCount(reason));
 787         }
 788         return actual;
 789     }
 790 
 791     protected void assertEquals(Result expect, Result actual) {
 792         if (expect.exception != null) {
 793             Assert.assertTrue("expected " + expect.exception, actual.exception != null);
 794             Assert.assertEquals("Exception class", expect.exception.getClass(), actual.exception.getClass());
 795             Assert.assertEquals("Exception message", expect.exception.getMessage(), actual.exception.getMessage());
 796         } else {
 797             if (actual.exception != null) {
 798                 throw new AssertionError("expected " + expect.returnValue + " but got an exception", actual.exception);
 799             }
 800             assertDeepEquals(expect.returnValue, actual.returnValue);
 801         }
 802     }
 803 
 804     protected void testAgainstExpected(ResolvedJavaMethod method, Result expect, Set<DeoptimizationReason> shouldNotDeopt, Object receiver, Object... args) {
 805         Result actual = executeActualCheckDeopt(method, shouldNotDeopt, receiver, args);
 806         assertEquals(expect, actual);
 807     }
 808 
 809     private Map<ResolvedJavaMethod, InstalledCode> cache = new HashMap<>();
 810 
 811     /**
 812      * Gets installed code for a given method, compiling it first if necessary. The graph is parsed
 813      * {@link #parseEager(ResolvedJavaMethod, AllowAssumptions) eagerly}.
 814      */
 815     protected InstalledCode getCode(ResolvedJavaMethod method) {
 816         return getCode(method, null);




 817     }
 818 
 819     /**
 820      * Gets installed code for a given method, compiling it first if necessary.
 821      *
 822      * @param installedCodeOwner the method the compiled code will be associated with when installed
 823      * @param graph the graph to be compiled. If null, a graph will be obtained from
 824      *            {@code installedCodeOwner} via {@link #parseForCompile(ResolvedJavaMethod)}.
 825      */
 826     protected InstalledCode getCode(ResolvedJavaMethod installedCodeOwner, StructuredGraph graph) {
 827         return getCode(installedCodeOwner, graph, false);
 828     }
 829 
 830     protected InstalledCode getCode(final ResolvedJavaMethod installedCodeOwner, StructuredGraph graph0, boolean forceCompile) {
 831         return getCode(installedCodeOwner, graph0, forceCompile, false);









 832     }
 833 
 834     /**
 835      * Gets installed code for a given method and graph, compiling it first if necessary.
 836      *
 837      * @param installedCodeOwner the method the compiled code will be associated with when installed
 838      * @param graph the graph to be compiled. If null, a graph will be obtained from
 839      *            {@code installedCodeOwner} via {@link #parseForCompile(ResolvedJavaMethod)}.
 840      * @param forceCompile specifies whether to ignore any previous code cached for the (method,
 841      *            key) pair
 842      * @param installDefault specifies whether to install as the default implementation

 843      */
 844     @SuppressWarnings("try")
 845     protected InstalledCode getCode(final ResolvedJavaMethod installedCodeOwner, StructuredGraph graph, boolean forceCompile, boolean installDefault) {
 846         if (!forceCompile) {
 847             InstalledCode cached = cache.get(installedCodeOwner);
 848             if (cached != null) {
 849                 if (cached.isValid()) {
 850                     return cached;
 851                 }
 852             }
 853         }
 854 

 855         final CompilationIdentifier id = getOrCreateCompilationId(installedCodeOwner, graph);
 856 
 857         InstalledCode installedCode = null;
 858         try (AllocSpy spy = AllocSpy.open(installedCodeOwner); Scope ds = Debug.scope("Compiling", new DebugDumpScope(id.toString(CompilationIdentifier.Verbosity.ID), true))) {
 859             final boolean printCompilation = PrintCompilation.getValue() && !TTY.isSuppressed();
 860             if (printCompilation) {
 861                 TTY.println(String.format("@%-6s Graal %-70s %-45s %-50s ...", id, installedCodeOwner.getDeclaringClass().getName(), installedCodeOwner.getName(), installedCodeOwner.getSignature()));

 862             }
 863             long start = System.currentTimeMillis();
 864             CompilationResult compResult = compile(installedCodeOwner, graph, id);
 865             if (printCompilation) {
 866                 TTY.println(String.format("@%-6s Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize()));
 867             }
 868 
 869             try (Scope s = Debug.scope("CodeInstall", getCodeCache(), installedCodeOwner, compResult)) {
 870                 if (installDefault) {

 871                     installedCode = addDefaultMethod(installedCodeOwner, compResult);
 872                 } else {
 873                     installedCode = addMethod(installedCodeOwner, compResult);
 874                 }
 875                 if (installedCode == null) {
 876                     throw new GraalError("Could not install code for " + installedCodeOwner.format("%H.%n(%p)"));
 877                 }








 878             } catch (Throwable e) {
 879                 throw Debug.handle(e);
 880             }
 881         } catch (Throwable e) {
 882             throw Debug.handle(e);
 883         }
 884 
 885         if (!forceCompile) {
 886             cache.put(installedCodeOwner, installedCode);
 887         }
 888         return installedCode;
 889     }


 890 
 891     /**
 892      * Used to produce a graph for a method about to be compiled by
 893      * {@link #compile(ResolvedJavaMethod, StructuredGraph)} if the second parameter to that method
 894      * is null.
 895      *
 896      * The default implementation in {@link GraalCompilerTest} is to call
 897      * {@link #parseEager(ResolvedJavaMethod, AllowAssumptions)}.
 898      */




 899     protected final StructuredGraph parseForCompile(ResolvedJavaMethod method) {
 900         return parseEager(method, AllowAssumptions.YES);
 901     }
 902 
 903     protected StructuredGraph parseForCompile(ResolvedJavaMethod method, CompilationIdentifier compilationId) {
 904         return parseEager(method, AllowAssumptions.YES, compilationId);
 905     }
 906 
 907     /**
 908      * Compiles a given method.
 909      *
 910      * @param installedCodeOwner the method the compiled code will be associated with when installed
 911      * @param graph the graph to be compiled for {@code installedCodeOwner}. If null, a graph will
 912      *            be obtained from {@code installedCodeOwner} via
 913      *            {@link #parseForCompile(ResolvedJavaMethod)}.
 914      */
 915     protected final CompilationResult compile(ResolvedJavaMethod installedCodeOwner, StructuredGraph graph) {
 916         return compile(installedCodeOwner, graph, getOrCreateCompilationId(installedCodeOwner, graph));






 917     }
 918 
 919     protected CompilationResult compile(ResolvedJavaMethod installedCodeOwner, StructuredGraph graph, CompilationIdentifier compilationId) {
 920         return compile(installedCodeOwner, graph, new CompilationResult(), compilationId);

 921     }
 922 
 923     /**
 924      * Compiles a given method.
 925      *
 926      * @param installedCodeOwner the method the compiled code will be associated with when installed
 927      * @param graph the graph to be compiled for {@code installedCodeOwner}. If null, a graph will
 928      *            be obtained from {@code installedCodeOwner} via
 929      *            {@link #parseForCompile(ResolvedJavaMethod)}.
 930      * @param compilationResult
 931      * @param compilationId
 932      */
 933     @SuppressWarnings("try")
 934     protected CompilationResult compile(ResolvedJavaMethod installedCodeOwner, StructuredGraph graph, CompilationResult compilationResult, CompilationIdentifier compilationId) {
 935         StructuredGraph graphToCompile = graph == null ? parseForCompile(installedCodeOwner, compilationId) : graph;
 936         lastCompiledGraph = graphToCompile;
 937         try (Scope s = Debug.scope("Compile", graphToCompile)) {

 938             Request<CompilationResult> request = new Request<>(graphToCompile, installedCodeOwner, getProviders(), getBackend(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL,
 939                             graphToCompile.getProfilingInfo(), getSuites(), getLIRSuites(), compilationResult, CompilationResultBuilderFactory.Default);
 940             return GraalCompiler.compile(request);
 941         } catch (Throwable e) {
 942             throw Debug.handle(e);
 943         }
 944     }
 945 
 946     protected StructuredGraph lastCompiledGraph;
 947 
 948     protected SpeculationLog getSpeculationLog() {
 949         return null;
 950     }
 951 
 952     protected InstalledCode addMethod(final ResolvedJavaMethod method, final CompilationResult compilationResult) {
 953         return backend.addInstalledCode(method, null, compilationResult);
 954     }
 955 
 956     protected InstalledCode addDefaultMethod(final ResolvedJavaMethod method, final CompilationResult compilationResult) {
 957         return backend.createDefaultInstalledCode(method, compilationResult);
 958     }
 959 


 985      * or null if {@code javaMethod} does not correspond to a reflection method.
 986      */
 987     protected Method lookupMethod(ResolvedJavaMethod javaMethod) {
 988         return methodMap.get(javaMethod);
 989     }
 990 
 991     protected Object invoke(ResolvedJavaMethod javaMethod, Object receiver, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
 992         Method method = lookupMethod(javaMethod);
 993         Assert.assertTrue(method != null);
 994         if (!method.isAccessible()) {
 995             method.setAccessible(true);
 996         }
 997         return method.invoke(receiver, applyArgSuppliers(args));
 998     }
 999 
1000     /**
1001      * Parses a Java method in {@linkplain GraphBuilderConfiguration#getDefault default} mode to
1002      * produce a graph.
1003      *
1004      * @param methodName the name of the method in {@code this.getClass()} to be parsed

1005      */
1006     protected StructuredGraph parseProfiled(String methodName, AllowAssumptions allowAssumptions) {
1007         return parseProfiled(getResolvedJavaMethod(methodName), allowAssumptions);
1008     }
1009 
1010     /**
1011      * Parses a Java method in {@linkplain GraphBuilderConfiguration#getDefault default} mode to
1012      * produce a graph.



1013      */
1014     protected final StructuredGraph parseProfiled(ResolvedJavaMethod m, AllowAssumptions allowAssumptions) {
1015         return parseProfiled(m, allowAssumptions, getCompilationId(m));
1016     }
1017 
1018     protected StructuredGraph parseProfiled(ResolvedJavaMethod m, AllowAssumptions allowAssumptions, CompilationIdentifier compilationId) {
1019         return parse1(m, getDefaultGraphBuilderSuite(), allowAssumptions, compilationId);







1020     }
1021 
1022     /**
1023      * Parses a Java method with {@linkplain GraphBuilderConfiguration#withEagerResolving(boolean)}
1024      * set to true to produce a graph.
1025      *
1026      * @param methodName the name of the method in {@code this.getClass()} to be parsed


1027      */
1028     protected final StructuredGraph parseEager(String methodName, AllowAssumptions allowAssumptions) {
1029         return parseEager(getResolvedJavaMethod(methodName), allowAssumptions);
1030     }
1031 
1032     /**
1033      * Parses a Java method with {@linkplain GraphBuilderConfiguration#withEagerResolving(boolean)}
1034      * set to true to produce a graph.



1035      */
1036     protected final StructuredGraph parseEager(ResolvedJavaMethod m, AllowAssumptions allowAssumptions) {
1037         return parseEager(m, allowAssumptions, getCompilationId(m));
1038     }
1039 
1040     protected StructuredGraph parseEager(ResolvedJavaMethod m, AllowAssumptions allowAssumptions, CompilationIdentifier compilationId) {
1041         return parse1(m, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getDefault(getDefaultGraphBuilderPlugins()).withEagerResolving(true)), allowAssumptions, compilationId);








1042     }
1043 
1044     /**
1045      * Parses a Java method using {@linkplain GraphBuilderConfiguration#withFullInfopoints(boolean)
1046      * full debug} set to true to produce a graph.





1047      */
1048     protected final StructuredGraph parseDebug(ResolvedJavaMethod m, AllowAssumptions allowAssumptions) {
1049         return parseDebug(m, allowAssumptions, getCompilationId(m));
1050     }
1051 
1052     protected StructuredGraph parseDebug(ResolvedJavaMethod m, AllowAssumptions allowAssumptions, CompilationIdentifier compilationId) {
1053         return parse1(m, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getDefault(getDefaultGraphBuilderPlugins()).withFullInfopoints(true)), allowAssumptions, compilationId);








1054     }
1055 
1056     @SuppressWarnings("try")
1057     private StructuredGraph parse1(ResolvedJavaMethod javaMethod, PhaseSuite<HighTierContext> graphBuilderSuite, AllowAssumptions allowAssumptions, CompilationIdentifier compilationId) {

1058         assert javaMethod.getAnnotation(Test.class) == null : "shouldn't parse method with @Test annotation: " + javaMethod;
1059         StructuredGraph graph = new StructuredGraph(javaMethod, allowAssumptions, getSpeculationLog(), compilationId);

1060         try (Scope ds = Debug.scope("Parsing", javaMethod, graph)) {
1061             graphBuilderSuite.apply(graph, getDefaultHighTierContext());
1062             return graph;
1063         } catch (Throwable e) {
1064             throw Debug.handle(e);
1065         }
1066     }
1067 
1068     protected Plugins getDefaultGraphBuilderPlugins() {
1069         PhaseSuite<HighTierContext> suite = backend.getSuites().getDefaultGraphBuilderSuite();
1070         Plugins defaultPlugins = ((GraphBuilderPhase) suite.findPhase(GraphBuilderPhase.class).previous()).getGraphBuilderConfig().getPlugins();
1071         // defensive copying
1072         return new Plugins(defaultPlugins);
1073     }
1074 
1075     protected PhaseSuite<HighTierContext> getDefaultGraphBuilderSuite() {
1076         // defensive copying
1077         return backend.getSuites().getDefaultGraphBuilderSuite().copy();
1078     }
1079 


1169      * case.
1170      *
1171      * @param i the iteration count of the loop
1172      * @param cond the condition of the loop
1173      * @return cond
1174      */
1175     protected static boolean iterationCount(double i, boolean cond) {
1176         return GraalDirectives.injectIterationCount(i, cond);
1177     }
1178 
1179     /**
1180      * Test if the current test runs on the given platform. The name must match the name given in
1181      * the {@link Architecture#getName()}.
1182      *
1183      * @param name The name to test
1184      * @return true if we run on the architecture given by name
1185      */
1186     protected boolean isArchitecture(String name) {
1187         return name.equals(backend.getTarget().arch.getName());
1188     }









1189 }


  27 import static org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo.DO_NOT_INLINE_NO_EXCEPTION;
  28 import static org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo.DO_NOT_INLINE_WITH_EXCEPTION;
  29 
  30 import java.lang.annotation.ElementType;
  31 import java.lang.annotation.Retention;
  32 import java.lang.annotation.RetentionPolicy;
  33 import java.lang.annotation.Target;
  34 import java.lang.reflect.InvocationTargetException;
  35 import java.lang.reflect.Method;
  36 import java.util.ArrayList;
  37 import java.util.Arrays;
  38 import java.util.Collections;
  39 import java.util.EnumMap;
  40 import java.util.HashMap;
  41 import java.util.List;
  42 import java.util.ListIterator;
  43 import java.util.Map;
  44 import java.util.Set;
  45 import java.util.function.Supplier;
  46 






  47 import org.graalvm.compiler.api.directives.GraalDirectives;
  48 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
  49 import org.graalvm.compiler.api.test.Graal;
  50 import org.graalvm.compiler.code.CompilationResult;
  51 import org.graalvm.compiler.core.GraalCompiler;
  52 import org.graalvm.compiler.core.GraalCompiler.Request;
  53 import org.graalvm.compiler.core.common.CompilationIdentifier;
  54 import org.graalvm.compiler.core.common.type.StampFactory;
  55 import org.graalvm.compiler.core.common.util.ModuleAPI;
  56 import org.graalvm.compiler.core.target.Backend;
  57 import org.graalvm.compiler.debug.Debug;
  58 import org.graalvm.compiler.debug.Debug.Scope;
  59 import org.graalvm.compiler.debug.DebugDumpScope;
  60 import org.graalvm.compiler.debug.DebugEnvironment;
  61 import org.graalvm.compiler.debug.GraalError;
  62 import org.graalvm.compiler.debug.TTY;
  63 import org.graalvm.compiler.graph.Node;
  64 import org.graalvm.compiler.graph.NodeClass;
  65 import org.graalvm.compiler.graph.NodeMap;
  66 import org.graalvm.compiler.java.BytecodeParser;
  67 import org.graalvm.compiler.java.ComputeLoopFrequenciesClosure;
  68 import org.graalvm.compiler.java.GraphBuilderPhase;
  69 import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory;
  70 import org.graalvm.compiler.lir.phases.LIRSuites;
  71 import org.graalvm.compiler.nodeinfo.NodeInfo;
  72 import org.graalvm.compiler.nodeinfo.NodeSize;
  73 import org.graalvm.compiler.nodeinfo.Verbosity;
  74 import org.graalvm.compiler.nodes.BreakpointNode;
  75 import org.graalvm.compiler.nodes.ConstantNode;
  76 import org.graalvm.compiler.nodes.FixedWithNextNode;
  77 import org.graalvm.compiler.nodes.FrameState;
  78 import org.graalvm.compiler.nodes.FullInfopointNode;
  79 import org.graalvm.compiler.nodes.InvokeNode;
  80 import org.graalvm.compiler.nodes.InvokeWithExceptionNode;
  81 import org.graalvm.compiler.nodes.ProxyNode;
  82 import org.graalvm.compiler.nodes.ReturnNode;
  83 import org.graalvm.compiler.nodes.StructuredGraph;
  84 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
  85 import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
  86 import org.graalvm.compiler.nodes.ValueNode;
  87 import org.graalvm.compiler.nodes.cfg.Block;
  88 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
  89 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
  90 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
  91 import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin;
  92 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
  93 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
  94 import org.graalvm.compiler.nodes.spi.LoweringProvider;
  95 import org.graalvm.compiler.nodes.spi.Replacements;
  96 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
  97 import org.graalvm.compiler.options.OptionValues;
  98 import org.graalvm.compiler.phases.BasePhase;
  99 import org.graalvm.compiler.phases.OptimisticOptimizations;
 100 import org.graalvm.compiler.phases.Phase;
 101 import org.graalvm.compiler.phases.PhaseSuite;
 102 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 103 import org.graalvm.compiler.phases.common.ConvertDeoptimizeToGuardPhase;
 104 import org.graalvm.compiler.phases.schedule.SchedulePhase;
 105 import org.graalvm.compiler.phases.schedule.SchedulePhase.SchedulingStrategy;
 106 import org.graalvm.compiler.phases.tiers.HighTierContext;
 107 import org.graalvm.compiler.phases.tiers.Suites;
 108 import org.graalvm.compiler.phases.tiers.TargetProvider;
 109 import org.graalvm.compiler.phases.util.Providers;
 110 import org.graalvm.compiler.runtime.RuntimeProvider;
 111 import org.graalvm.compiler.test.AddExports;
 112 import org.graalvm.compiler.test.GraalTest;
 113 import org.junit.After;
 114 import org.junit.Assert;
 115 import org.junit.Before;
 116 import org.junit.Test;
 117 import org.junit.internal.AssumptionViolatedException;
 118 
 119 import jdk.vm.ci.code.Architecture;
 120 import jdk.vm.ci.code.BailoutException;
 121 import jdk.vm.ci.code.CodeCacheProvider;
 122 import jdk.vm.ci.code.InstalledCode;
 123 import jdk.vm.ci.code.TargetDescription;
 124 import jdk.vm.ci.meta.ConstantReflectionProvider;
 125 import jdk.vm.ci.meta.DeoptimizationReason;
 126 import jdk.vm.ci.meta.JavaKind;
 127 import jdk.vm.ci.meta.JavaType;
 128 import jdk.vm.ci.meta.MetaAccessProvider;
 129 import jdk.vm.ci.meta.ProfilingInfo;
 130 import jdk.vm.ci.meta.ResolvedJavaMethod;
 131 import jdk.vm.ci.meta.ResolvedJavaType;
 132 import jdk.vm.ci.meta.SpeculationLog;
 133 import jdk.vm.ci.meta.Assumptions.Assumption;
 134 import jdk.vm.ci.services.Services;
 135 
 136 /**
 137  * Base class for Graal compiler unit tests.
 138  * <p>
 139  * White box tests for Graal compiler transformations use this pattern:
 140  * <ol>
 141  * <li>Create a graph by {@linkplain #parseEager parsing} a method.</li>
 142  * <li>Manually modify the graph (e.g. replace a parameter node with a constant).</li>
 143  * <li>Apply a transformation to the graph.</li>
 144  * <li>Assert that the transformed graph is equal to an expected graph.</li>
 145  * </ol>
 146  * <p>
 147  * See {@link InvokeHintsTest} as an example of a white box test.
 148  * <p>
 149  * Black box tests use the {@link #test(String, Object...)} or
 150  * {@link #testN(int, String, Object...)} to execute some method in the interpreter and compare its
 151  * result against that produced by a Graal compiled version of the method.
 152  * <p>
 153  * These tests will be run by the {@code mx unittest} command.
 154  */
 155 @AddExports({"jdk.internal.vm.ci/jdk.vm.ci.meta",
 156                 "jdk.internal.vm.ci/jdk.vm.ci.services",
 157                 "jdk.internal.vm.ci/jdk.vm.ci.code",
 158                 "jdk.internal.vm.ci/jdk.vm.ci.services",
 159                 "java.base/jdk.internal.org.objectweb.asm",
 160                 "java.base/jdk.internal.org.objectweb.asm.tree"})
 161 public abstract class GraalCompilerTest extends GraalTest {
 162 
 163     /**
 164      * Gets the initial option values provided by the Graal runtime. These are option values
 165      * typically parsed from the command line.
 166      */
 167     public static OptionValues getInitialOptions() {
 168         return Graal.getRequiredCapability(OptionValues.class);
 169     }
 170 
 171     private static final int BAILOUT_RETRY_LIMIT = 1;
 172     private final Providers providers;
 173     private final Backend backend;
 174 
 175     /**
 176      * Representative class for the {@code java.base} module.
 177      */
 178     public static final Class<?> JAVA_BASE = Class.class;
 179 
 180     /**
 181      * Representative class for the {@code jdk.vm.ci} module.
 182      */
 183     public static final Class<?> JDK_VM_CI = Services.class;
 184 
 185     /**
 186      * Exports the package named {@code packageName} declared in {@code moduleMember}'s module to
 187      * this object's module. This must be called before accessing packages that are no longer public
 188      * as of JDK 9.
 189      */
 190     protected final void exportPackage(Class<?> moduleMember, String packageName) {
 191         if (!Java8OrEarlier) {
 192             ModuleAPI.exportPackageTo(moduleMember, packageName, getClass());
 193         }
 194     }
 195 
 196     /**
 197      * Denotes a test method that must be inlined by the {@link BytecodeParser}.
 198      */
 199     @Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
 200     @Retention(RetentionPolicy.RUNTIME)
 201     public @interface BytecodeParserForceInline {
 202     }
 203 
 204     /**
 205      * Denotes a test method that must never be inlined by the {@link BytecodeParser}.
 206      */
 207     @Retention(RetentionPolicy.RUNTIME)
 208     @Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
 209     public @interface BytecodeParserNeverInline {
 210         /**
 211          * Specifies if the call should be implemented with {@link InvokeWithExceptionNode} instead
 212          * of {@link InvokeNode}.
 213          */
 214         boolean invokeWithException() default false;


 234 
 235     /**
 236      * Can be overridden by unit tests to verify properties of the graph.
 237      *
 238      * @param graph the graph at the end of LowTier
 239      */
 240     protected boolean checkLowTierGraph(StructuredGraph graph) {
 241         return true;
 242     }
 243 
 244     protected static void breakpoint() {
 245     }
 246 
 247     @SuppressWarnings("unused")
 248     protected static void breakpoint(int arg0) {
 249     }
 250 
 251     protected static void shouldBeOptimizedAway() {
 252     }
 253 
 254     protected Suites createSuites(OptionValues opts) {
 255         Suites ret = backend.getSuites().getDefaultSuites(opts).copy();
 256         ListIterator<BasePhase<? super HighTierContext>> iter = ret.getHighTier().findPhase(ConvertDeoptimizeToGuardPhase.class, true);
 257         if (iter == null) {
 258             /*
 259              * in the economy configuration, we don't have the ConvertDeoptimizeToGuard phase, so we
 260              * just select the first CanonicalizerPhase in HighTier
 261              */
 262             iter = ret.getHighTier().findPhase(CanonicalizerPhase.class);
 263         }
 264         iter.add(new Phase() {
 265 
 266             @Override
 267             protected void run(StructuredGraph graph) {
 268                 ComputeLoopFrequenciesClosure.compute(graph);
 269             }
 270 
 271             @Override
 272             public float codeSizeIncrease() {
 273                 return NodeSize.IGNORE_SIZE_CONTRACT_FACTOR;
 274             }
 275 


 315         ret.getLowTier().appendPhase(new Phase() {
 316 
 317             @Override
 318             protected void run(StructuredGraph graph) {
 319                 assert checkLowTierGraph(graph) : "failed LowTier graph check";
 320             }
 321 
 322             @Override
 323             public float codeSizeIncrease() {
 324                 return NodeSize.IGNORE_SIZE_CONTRACT_FACTOR;
 325             }
 326 
 327             @Override
 328             protected CharSequence getName() {
 329                 return "CheckGraphPhase";
 330             }
 331         });
 332         return ret;
 333     }
 334 
 335     protected LIRSuites createLIRSuites(OptionValues opts) {
 336         LIRSuites ret = backend.getSuites().getDefaultLIRSuites(opts).copy();
 337         return ret;
 338     }
 339 
 340     public GraalCompilerTest() {
 341         this.backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend();
 342         this.providers = getBackend().getProviders();


 343     }
 344 
 345     /**
 346      * Set up a test for a non-default backend. The test should check (via {@link #getBackend()} )
 347      * whether the desired backend is available.
 348      *
 349      * @param arch the name of the desired backend architecture
 350      */
 351     public GraalCompilerTest(Class<? extends Architecture> arch) {
 352         RuntimeProvider runtime = Graal.getRequiredCapability(RuntimeProvider.class);
 353         Backend b = runtime.getBackend(arch);
 354         if (b != null) {
 355             this.backend = b;
 356         } else {
 357             // Fall back to the default/host backend
 358             this.backend = runtime.getHostBackend();
 359         }
 360         this.providers = backend.getProviders();


 361     }
 362 
 363     /**
 364      * Set up a test for a non-default backend.
 365      *
 366      * @param backend the desired backend
 367      */
 368     public GraalCompilerTest(Backend backend) {
 369         this.backend = backend;
 370         this.providers = backend.getProviders();


 371     }
 372 
 373     private Scope debugScope;
 374 
 375     @Before
 376     public void beforeTest() {
 377         assert debugScope == null;
 378         debugScope = Debug.scope(getClass());
 379     }
 380 
 381     @After
 382     public void afterTest() {
 383         if (debugScope != null) {
 384             debugScope.close();
 385         }
 386         debugScope = null;
 387     }
 388 
 389     protected void assertEquals(StructuredGraph expected, StructuredGraph graph) {
 390         assertEquals(expected, graph, false, true);


 548             result.append("Block " + block + " ");
 549             if (block == scheduleResult.getCFG().getStartBlock()) {
 550                 result.append("* ");
 551             }
 552             result.append("-> ");
 553             for (Block succ : block.getSuccessors()) {
 554                 result.append(succ + " ");
 555             }
 556             result.append("\n");
 557             for (Node node : scheduleResult.getBlockToNodesMap().get(block)) {
 558                 result.append(String.format("%1S\n", node));
 559             }
 560         }
 561         return result.toString();
 562     }
 563 
 564     protected Backend getBackend() {
 565         return backend;
 566     }
 567 








 568     protected final Providers getProviders() {
 569         return providers;
 570     }
 571 
 572     protected HighTierContext getDefaultHighTierContext() {
 573         return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
 574     }
 575 
 576     protected SnippetReflectionProvider getSnippetReflection() {
 577         return Graal.getRequiredCapability(SnippetReflectionProvider.class);
 578     }
 579 
 580     protected TargetDescription getTarget() {
 581         return getTargetProvider().getTarget();
 582     }
 583 
 584     protected TargetProvider getTargetProvider() {
 585         return getBackend();
 586     }
 587 


 629             };
 630             threads[i] = t;
 631             t.start();
 632         }
 633         for (int i = 0; i < n; i++) {
 634             try {
 635                 threads[i].join();
 636             } catch (InterruptedException e) {
 637                 errors.add(e);
 638             }
 639         }
 640         if (!errors.isEmpty()) {
 641             throw new MultiCauseAssertionError(errors.size() + " failures", errors.toArray(new Throwable[errors.size()]));
 642         }
 643     }
 644 
 645     protected Object referenceInvoke(ResolvedJavaMethod method, Object receiver, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
 646         return invoke(method, receiver, args);
 647     }
 648 
 649     public static class Result {
 650 
 651         public final Object returnValue;
 652         public final Throwable exception;
 653 
 654         public Result(Object returnValue, Throwable exception) {
 655             this.returnValue = returnValue;
 656             this.exception = exception;
 657         }
 658 
 659         @Override
 660         public String toString() {
 661             return exception == null ? returnValue == null ? "null" : returnValue.toString() : "!" + exception;
 662         }
 663     }
 664 
 665     /**
 666      * Called before a test is executed.
 667      */
 668     protected void before(@SuppressWarnings("unused") ResolvedJavaMethod method) {
 669     }


 673      */
 674     protected void after() {
 675     }
 676 
 677     protected Result executeExpected(ResolvedJavaMethod method, Object receiver, Object... args) {
 678         before(method);
 679         try {
 680             // This gives us both the expected return value as well as ensuring that the method to
 681             // be compiled is fully resolved
 682             return new Result(referenceInvoke(method, receiver, args), null);
 683         } catch (InvocationTargetException e) {
 684             return new Result(null, e.getTargetException());
 685         } catch (Exception e) {
 686             throw new RuntimeException(e);
 687         } finally {
 688             after();
 689         }
 690     }
 691 
 692     protected Result executeActual(ResolvedJavaMethod method, Object receiver, Object... args) {
 693         return executeActual(getInitialOptions(), method, receiver, args);
 694     }
 695 
 696     protected Result executeActual(OptionValues options, ResolvedJavaMethod method, Object receiver, Object... args) {
 697         before(method);
 698         Object[] executeArgs = argsWithReceiver(receiver, args);
 699 
 700         checkArgs(method, executeArgs);
 701 
 702         InstalledCode compiledMethod = getCode(method, options);
 703         try {
 704             return new Result(compiledMethod.executeVarargs(executeArgs), null);
 705         } catch (Throwable e) {
 706             return new Result(null, e);
 707         } finally {
 708             after();
 709         }
 710     }
 711 
 712     protected void checkArgs(ResolvedJavaMethod method, Object[] args) {
 713         JavaType[] sig = method.toParameterTypes();
 714         Assert.assertEquals(sig.length, args.length);
 715         for (int i = 0; i < args.length; i++) {
 716             JavaType javaType = sig[i];
 717             JavaKind kind = javaType.getJavaKind();
 718             Object arg = args[i];
 719             if (kind == JavaKind.Object) {
 720                 if (arg != null && javaType instanceof ResolvedJavaType) {
 721                     ResolvedJavaType resolvedJavaType = (ResolvedJavaType) javaType;
 722                     Assert.assertTrue(resolvedJavaType + " from " + getMetaAccess().lookupJavaType(arg.getClass()), resolvedJavaType.isAssignableFrom(getMetaAccess().lookupJavaType(arg.getClass())));


 730 
 731     /**
 732      * Prepends a non-null receiver argument to a given list or args.
 733      *
 734      * @param receiver the receiver argument to prepend if it is non-null
 735      */
 736     protected Object[] argsWithReceiver(Object receiver, Object... args) {
 737         Object[] executeArgs;
 738         if (receiver == null) {
 739             executeArgs = args;
 740         } else {
 741             executeArgs = new Object[args.length + 1];
 742             executeArgs[0] = receiver;
 743             for (int i = 0; i < args.length; i++) {
 744                 executeArgs[i + 1] = args[i];
 745             }
 746         }
 747         return applyArgSuppliers(executeArgs);
 748     }
 749 
 750     protected final Result test(String name, Object... args) {
 751         return test(getInitialOptions(), name, args);
 752     }
 753 
 754     protected final Result test(OptionValues options, String name, Object... args) {
 755         try {
 756             ResolvedJavaMethod method = getResolvedJavaMethod(name);
 757             Object receiver = method.isStatic() ? null : this;
 758             return test(options, method, receiver, args);
 759         } catch (AssumptionViolatedException e) {
 760             // Suppress so that subsequent calls to this method within the
 761             // same Junit @Test annotated method can proceed.
 762             return null;
 763         }
 764     }
 765 
 766     /**
 767      * Type denoting a lambda that supplies a fresh value each time it is called. This is useful
 768      * when supplying an argument to {@link GraalCompilerTest#test(String, Object...)} where the
 769      * test modifies the state of the argument (e.g., updates a field).
 770      */
 771     @FunctionalInterface
 772     public interface ArgSupplier extends Supplier<Object> {
 773     }
 774 
 775     /**
 776      * Convenience method for using an {@link ArgSupplier} lambda in a varargs list.
 777      */
 778     public static Object supply(ArgSupplier supplier) {
 779         return supplier;
 780     }
 781 
 782     protected Result test(ResolvedJavaMethod method, Object receiver, Object... args) {
 783         return test(getInitialOptions(), method, receiver, args);
 784     }
 785 
 786     protected Result test(OptionValues options, ResolvedJavaMethod method, Object receiver, Object... args) {
 787         Result expect = executeExpected(method, receiver, args);
 788         if (getCodeCache() != null) {
 789             testAgainstExpected(options, method, expect, receiver, args);
 790         }
 791         return expect;
 792     }
 793 
 794     /**
 795      * Process a given set of arguments, converting any {@link ArgSupplier} argument to the argument
 796      * it supplies.
 797      */
 798     protected Object[] applyArgSuppliers(Object... args) {
 799         Object[] res = args;
 800         for (int i = 0; i < args.length; i++) {
 801             if (args[i] instanceof ArgSupplier) {
 802                 if (res == args) {
 803                     res = args.clone();
 804                 }
 805                 res[i] = ((ArgSupplier) args[i]).get();
 806             }
 807         }
 808         return res;
 809     }
 810 
 811     protected final void testAgainstExpected(ResolvedJavaMethod method, Result expect, Object receiver, Object... args) {
 812         testAgainstExpected(getInitialOptions(), method, expect, Collections.<DeoptimizationReason> emptySet(), receiver, args);
 813     }
 814 
 815     protected void testAgainstExpected(ResolvedJavaMethod method, Result expect, Set<DeoptimizationReason> shouldNotDeopt, Object receiver, Object... args) {
 816         testAgainstExpected(getInitialOptions(), method, expect, shouldNotDeopt, receiver, args);
 817     }
 818 
 819     protected final void testAgainstExpected(OptionValues options, ResolvedJavaMethod method, Result expect, Object receiver, Object... args) {
 820         testAgainstExpected(options, method, expect, Collections.<DeoptimizationReason> emptySet(), receiver, args);
 821     }
 822 
 823     protected void testAgainstExpected(OptionValues options, ResolvedJavaMethod method, Result expect, Set<DeoptimizationReason> shouldNotDeopt, Object receiver, Object... args) {
 824         Result actual = executeActualCheckDeopt(options, method, shouldNotDeopt, receiver, args);
 825         assertEquals(expect, actual);
 826     }
 827 
 828     protected Result executeActualCheckDeopt(OptionValues options, ResolvedJavaMethod method, Set<DeoptimizationReason> shouldNotDeopt, Object receiver, Object... args) {
 829         Map<DeoptimizationReason, Integer> deoptCounts = new EnumMap<>(DeoptimizationReason.class);
 830         ProfilingInfo profile = method.getProfilingInfo();
 831         for (DeoptimizationReason reason : shouldNotDeopt) {
 832             deoptCounts.put(reason, profile.getDeoptimizationCount(reason));
 833         }
 834         Result actual = executeActual(options, method, receiver, args);
 835         profile = method.getProfilingInfo(); // profile can change after execution
 836         for (DeoptimizationReason reason : shouldNotDeopt) {
 837             Assert.assertEquals((int) deoptCounts.get(reason), profile.getDeoptimizationCount(reason));
 838         }
 839         return actual;
 840     }
 841 
 842     protected void assertEquals(Result expect, Result actual) {
 843         if (expect.exception != null) {
 844             Assert.assertTrue("expected " + expect.exception, actual.exception != null);
 845             Assert.assertEquals("Exception class", expect.exception.getClass(), actual.exception.getClass());
 846             Assert.assertEquals("Exception message", expect.exception.getMessage(), actual.exception.getMessage());
 847         } else {
 848             if (actual.exception != null) {
 849                 throw new AssertionError("expected " + expect.returnValue + " but got an exception", actual.exception);
 850             }
 851             assertDeepEquals(expect.returnValue, actual.returnValue);
 852         }
 853     }
 854 





 855     private Map<ResolvedJavaMethod, InstalledCode> cache = new HashMap<>();
 856 
 857     /**
 858      * Gets installed code for a given method, compiling it first if necessary. The graph is parsed
 859      * {@link #parseEager eagerly}.
 860      */
 861     protected final InstalledCode getCode(ResolvedJavaMethod method) {
 862         return getCode(method, null, false, false, getInitialOptions());
 863     }
 864 
 865     protected final InstalledCode getCode(ResolvedJavaMethod method, OptionValues options) {
 866         return getCode(method, null, false, false, options);
 867     }
 868 
 869     /**
 870      * Gets installed code for a given method, compiling it first if necessary.
 871      *
 872      * @param installedCodeOwner the method the compiled code will be associated with when installed
 873      * @param graph the graph to be compiled. If null, a graph will be obtained from
 874      *            {@code installedCodeOwner} via {@link #parseForCompile(ResolvedJavaMethod)}.
 875      */
 876     protected final InstalledCode getCode(ResolvedJavaMethod installedCodeOwner, StructuredGraph graph) {
 877         return getCode(installedCodeOwner, graph, false, false, graph == null ? getInitialOptions() : graph.getOptions());
 878     }
 879 
 880     /**
 881      * Gets installed code for a given method and graph, compiling it first if necessary.
 882      *
 883      * @param installedCodeOwner the method the compiled code will be associated with when installed
 884      * @param graph the graph to be compiled. If null, a graph will be obtained from
 885      *            {@code installedCodeOwner} via {@link #parseForCompile(ResolvedJavaMethod)}.
 886      * @param forceCompile specifies whether to ignore any previous code cached for the (method,
 887      *            key) pair
 888      */
 889     protected final InstalledCode getCode(final ResolvedJavaMethod installedCodeOwner, StructuredGraph graph, boolean forceCompile) {
 890         return getCode(installedCodeOwner, graph, forceCompile, false, graph == null ? getInitialOptions() : graph.getOptions());
 891     }
 892 
 893     /**
 894      * Gets installed code for a given method and graph, compiling it first if necessary.
 895      *
 896      * @param installedCodeOwner the method the compiled code will be associated with when installed
 897      * @param graph the graph to be compiled. If null, a graph will be obtained from
 898      *            {@code installedCodeOwner} via {@link #parseForCompile(ResolvedJavaMethod)}.
 899      * @param forceCompile specifies whether to ignore any previous code cached for the (method,
 900      *            key) pair
 901      * @param installAsDefault specifies whether to install as the default implementation
 902      * @param options the options that will be used in {@link #parseForCompile(ResolvedJavaMethod)}
 903      */
 904     @SuppressWarnings("try")
 905     protected InstalledCode getCode(final ResolvedJavaMethod installedCodeOwner, StructuredGraph graph, boolean forceCompile, boolean installAsDefault, OptionValues options) {
 906         if (!forceCompile) {
 907             InstalledCode cached = cache.get(installedCodeOwner);
 908             if (cached != null) {
 909                 if (cached.isValid()) {
 910                     return cached;
 911                 }
 912             }
 913         }
 914         // loop for retrying compilation
 915         for (int retry = 0; retry <= BAILOUT_RETRY_LIMIT; retry++) {
 916             final CompilationIdentifier id = getOrCreateCompilationId(installedCodeOwner, graph);
 917 
 918             InstalledCode installedCode = null;
 919             try (AllocSpy spy = AllocSpy.open(installedCodeOwner); Scope ds = Debug.scope("Compiling", new DebugDumpScope(id.toString(CompilationIdentifier.Verbosity.ID), true))) {
 920                 final boolean printCompilation = PrintCompilation.getValue(options) && !TTY.isSuppressed();
 921                 if (printCompilation) {
 922                     TTY.println(String.format("@%-6s Graal %-70s %-45s %-50s ...", id, installedCodeOwner.getDeclaringClass().getName(), installedCodeOwner.getName(),
 923                                     installedCodeOwner.getSignature()));
 924                 }
 925                 long start = System.currentTimeMillis();
 926                 CompilationResult compResult = compile(installedCodeOwner, graph, new CompilationResult(), id, options);
 927                 if (printCompilation) {
 928                     TTY.println(String.format("@%-6s Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize()));
 929                 }
 930 
 931                 try (Scope s = Debug.scope("CodeInstall", getCodeCache(), installedCodeOwner, compResult)) {
 932                     try {
 933                         if (installAsDefault) {
 934                             installedCode = addDefaultMethod(installedCodeOwner, compResult);
 935                         } else {
 936                             installedCode = addMethod(installedCodeOwner, compResult);
 937                         }
 938                         if (installedCode == null) {
 939                             throw new GraalError("Could not install code for " + installedCodeOwner.format("%H.%n(%p)"));
 940                         }
 941                     } catch (BailoutException e) {
 942                         if (retry <= BAILOUT_RETRY_LIMIT && graph == null && !e.isPermanent()) {
 943                             // retry (if there is no predefined graph)
 944                             TTY.println(String.format("Restart compilation %s (%s) due to a non-permanent bailout!", installedCodeOwner, id));
 945                             continue;
 946                         }
 947                         throw e;
 948                     }
 949                 } catch (Throwable e) {
 950                     throw Debug.handle(e);
 951                 }
 952             } catch (Throwable e) {
 953                 throw Debug.handle(e);
 954             }
 955 
 956             if (!forceCompile) {
 957                 cache.put(installedCodeOwner, installedCode);
 958             }
 959             return installedCode;
 960         }
 961         throw GraalError.shouldNotReachHere();
 962     }
 963 
 964     /**
 965      * Used to produce a graph for a method about to be compiled by
 966      * {@link #compile(ResolvedJavaMethod, StructuredGraph)} if the second parameter to that method
 967      * is null.
 968      *
 969      * The default implementation in {@link GraalCompilerTest} is to call {@link #parseEager}.

 970      */
 971     protected StructuredGraph parseForCompile(ResolvedJavaMethod method, OptionValues options) {
 972         return parseEager(method, AllowAssumptions.YES, getCompilationId(method), options);
 973     }
 974 
 975     protected final StructuredGraph parseForCompile(ResolvedJavaMethod method) {
 976         return parseEager(method, AllowAssumptions.YES, getCompilationId(method), getInitialOptions());
 977     }
 978 
 979     protected StructuredGraph parseForCompile(ResolvedJavaMethod method, CompilationIdentifier compilationId, OptionValues options) {
 980         return parseEager(method, AllowAssumptions.YES, compilationId, options);
 981     }
 982 
 983     /**
 984      * Compiles a given method.
 985      *
 986      * @param installedCodeOwner the method the compiled code will be associated with when installed
 987      * @param graph the graph to be compiled for {@code installedCodeOwner}. If null, a graph will
 988      *            be obtained from {@code installedCodeOwner} via
 989      *            {@link #parseForCompile(ResolvedJavaMethod)}.
 990      */
 991     protected final CompilationResult compile(ResolvedJavaMethod installedCodeOwner, StructuredGraph graph) {
 992         OptionValues options = graph == null ? getInitialOptions() : graph.getOptions();
 993         return compile(installedCodeOwner, graph, new CompilationResult(), getOrCreateCompilationId(installedCodeOwner, graph), options);
 994     }
 995 
 996     protected final CompilationResult compile(ResolvedJavaMethod installedCodeOwner, StructuredGraph graph, CompilationIdentifier compilationId) {
 997         OptionValues options = graph == null ? getInitialOptions() : graph.getOptions();
 998         return compile(installedCodeOwner, graph, new CompilationResult(), compilationId, options);
 999     }
1000 
1001     protected final CompilationResult compile(ResolvedJavaMethod installedCodeOwner, StructuredGraph graph, OptionValues options) {
1002         assert graph == null || graph.getOptions() == options;
1003         return compile(installedCodeOwner, graph, new CompilationResult(), getOrCreateCompilationId(installedCodeOwner, graph), options);
1004     }
1005 
1006     /**
1007      * Compiles a given method.
1008      *
1009      * @param installedCodeOwner the method the compiled code will be associated with when installed
1010      * @param graph the graph to be compiled for {@code installedCodeOwner}. If null, a graph will
1011      *            be obtained from {@code installedCodeOwner} via
1012      *            {@link #parseForCompile(ResolvedJavaMethod)}.

1013      * @param compilationId
1014      */
1015     @SuppressWarnings("try")
1016     protected CompilationResult compile(ResolvedJavaMethod installedCodeOwner, StructuredGraph graph, CompilationResult compilationResult, CompilationIdentifier compilationId, OptionValues options) {
1017         StructuredGraph graphToCompile = graph == null ? parseForCompile(installedCodeOwner, compilationId, options) : graph;
1018         lastCompiledGraph = graphToCompile;
1019         try (Scope s = Debug.scope("Compile", graphToCompile)) {
1020             assert options != null;
1021             Request<CompilationResult> request = new Request<>(graphToCompile, installedCodeOwner, getProviders(), getBackend(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL,
1022                             graphToCompile.getProfilingInfo(), createSuites(options), createLIRSuites(options), compilationResult, CompilationResultBuilderFactory.Default);
1023             return GraalCompiler.compile(request);
1024         } catch (Throwable e) {
1025             throw Debug.handle(e);
1026         }
1027     }
1028 
1029     protected StructuredGraph lastCompiledGraph;
1030 
1031     protected SpeculationLog getSpeculationLog() {
1032         return null;
1033     }
1034 
1035     protected InstalledCode addMethod(final ResolvedJavaMethod method, final CompilationResult compilationResult) {
1036         return backend.addInstalledCode(method, null, compilationResult);
1037     }
1038 
1039     protected InstalledCode addDefaultMethod(final ResolvedJavaMethod method, final CompilationResult compilationResult) {
1040         return backend.createDefaultInstalledCode(method, compilationResult);
1041     }
1042 


1068      * or null if {@code javaMethod} does not correspond to a reflection method.
1069      */
1070     protected Method lookupMethod(ResolvedJavaMethod javaMethod) {
1071         return methodMap.get(javaMethod);
1072     }
1073 
1074     protected Object invoke(ResolvedJavaMethod javaMethod, Object receiver, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
1075         Method method = lookupMethod(javaMethod);
1076         Assert.assertTrue(method != null);
1077         if (!method.isAccessible()) {
1078             method.setAccessible(true);
1079         }
1080         return method.invoke(receiver, applyArgSuppliers(args));
1081     }
1082 
1083     /**
1084      * Parses a Java method in {@linkplain GraphBuilderConfiguration#getDefault default} mode to
1085      * produce a graph.
1086      *
1087      * @param methodName the name of the method in {@code this.getClass()} to be parsed
1088      * @param allowAssumptions specifies if {@link Assumption}s can be made compiling the graph
1089      */
1090     protected final StructuredGraph parseProfiled(String methodName, AllowAssumptions allowAssumptions) {
1091         return parseProfiled(getResolvedJavaMethod(methodName), allowAssumptions);
1092     }
1093 
1094     /**
1095      * Parses a Java method in {@linkplain GraphBuilderConfiguration#getDefault default} mode to
1096      * produce a graph.
1097      *
1098      * @param method the method to be parsed
1099      * @param allowAssumptions specifies if {@link Assumption}s can be made compiling the graph
1100      */
1101     protected final StructuredGraph parseProfiled(ResolvedJavaMethod method, AllowAssumptions allowAssumptions) {
1102         return parse1(method, getDefaultGraphBuilderSuite(), allowAssumptions, getCompilationId(method), getInitialOptions());
1103     }
1104 
1105     /**
1106      * Parses a Java method with {@linkplain GraphBuilderConfiguration#withEagerResolving(boolean)}
1107      * set to true to produce a graph.
1108      *
1109      * @param methodName the name of the method in {@code this.getClass()} to be parsed
1110      * @param allowAssumptions specifies if {@link Assumption}s can be made compiling the graph
1111      */
1112     protected final StructuredGraph parseEager(String methodName, AllowAssumptions allowAssumptions) {
1113         return parseEager(getResolvedJavaMethod(methodName), allowAssumptions, getInitialOptions());
1114     }
1115 
1116     /**
1117      * Parses a Java method with {@linkplain GraphBuilderConfiguration#withEagerResolving(boolean)}
1118      * set to true to produce a graph.
1119      *
1120      * @param methodName the name of the method in {@code this.getClass()} to be parsed
1121      * @param allowAssumptions specifies if {@link Assumption}s can be made compiling the graph
1122      * @param options the option values to be used when compiling the graph
1123      */
1124     protected final StructuredGraph parseEager(String methodName, AllowAssumptions allowAssumptions, OptionValues options) {
1125         return parseEager(getResolvedJavaMethod(methodName), allowAssumptions, options);
1126     }
1127 
1128     /**
1129      * Parses a Java method with {@linkplain GraphBuilderConfiguration#withEagerResolving(boolean)}
1130      * set to true to produce a graph.
1131      *
1132      * @param method the method to be parsed
1133      * @param allowAssumptions specifies if {@link Assumption}s can be made compiling the graph
1134      */
1135     protected final StructuredGraph parseEager(ResolvedJavaMethod method, AllowAssumptions allowAssumptions) {
1136         return parseEager(method, allowAssumptions, getCompilationId(method), getInitialOptions());
1137     }
1138 
1139     /**
1140      * Parses a Java method with {@linkplain GraphBuilderConfiguration#withEagerResolving(boolean)}
1141      * set to true to produce a graph.
1142      *
1143      * @param method the method to be parsed
1144      * @param allowAssumptions specifies if {@link Assumption}s can be made compiling the graph
1145      * @param options the option values to be used when compiling the graph
1146      */
1147     protected final StructuredGraph parseEager(ResolvedJavaMethod method, AllowAssumptions allowAssumptions, OptionValues options) {
1148         return parseEager(method, allowAssumptions, getCompilationId(method), options);
1149     }
1150 
1151     /**
1152      * Parses a Java method with {@linkplain GraphBuilderConfiguration#withEagerResolving(boolean)}
1153      * set to true to produce a graph.
1154      *
1155      * @param method the method to be parsed
1156      * @param allowAssumptions specifies if {@link Assumption}s can be made compiling the graph
1157      * @param compilationId the compilation identifier to be associated with the graph
1158      * @param options the option values to be used when compiling the graph
1159      */
1160     protected StructuredGraph parseEager(ResolvedJavaMethod method, AllowAssumptions allowAssumptions, CompilationIdentifier compilationId, OptionValues options) {
1161         return parse1(method, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getDefault(getDefaultGraphBuilderPlugins()).withEagerResolving(true)), allowAssumptions, compilationId, options);
1162     }
1163 
1164     /**
1165      * Parses a Java method using {@linkplain GraphBuilderConfiguration#withFullInfopoints(boolean)
1166      * full debug} set to true to produce a graph.
1167      *
1168      * @param method the method to be parsed
1169      * @param allowAssumptions specifies if {@link Assumption}s can be made compiling the graph
1170      */
1171     protected StructuredGraph parseDebug(ResolvedJavaMethod method, AllowAssumptions allowAssumptions) {
1172         return parse1(method, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getDefault(getDefaultGraphBuilderPlugins()).withFullInfopoints(true)), allowAssumptions, getCompilationId(method),
1173                         getInitialOptions());
1174     }
1175 
1176     @SuppressWarnings("try")
1177     private StructuredGraph parse1(ResolvedJavaMethod javaMethod, PhaseSuite<HighTierContext> graphBuilderSuite, AllowAssumptions allowAssumptions, CompilationIdentifier compilationId,
1178                     OptionValues options) {
1179         assert javaMethod.getAnnotation(Test.class) == null : "shouldn't parse method with @Test annotation: " + javaMethod;
1180         StructuredGraph graph = new StructuredGraph.Builder(options, allowAssumptions).method(javaMethod).speculationLog(getSpeculationLog()).useProfilingInfo(true).compilationId(
1181                         compilationId).build();
1182         try (Scope ds = Debug.scope("Parsing", javaMethod, graph)) {
1183             graphBuilderSuite.apply(graph, getDefaultHighTierContext());
1184             return graph;
1185         } catch (Throwable e) {
1186             throw Debug.handle(e);
1187         }
1188     }
1189 
1190     protected Plugins getDefaultGraphBuilderPlugins() {
1191         PhaseSuite<HighTierContext> suite = backend.getSuites().getDefaultGraphBuilderSuite();
1192         Plugins defaultPlugins = ((GraphBuilderPhase) suite.findPhase(GraphBuilderPhase.class).previous()).getGraphBuilderConfig().getPlugins();
1193         // defensive copying
1194         return new Plugins(defaultPlugins);
1195     }
1196 
1197     protected PhaseSuite<HighTierContext> getDefaultGraphBuilderSuite() {
1198         // defensive copying
1199         return backend.getSuites().getDefaultGraphBuilderSuite().copy();
1200     }
1201 


1291      * case.
1292      *
1293      * @param i the iteration count of the loop
1294      * @param cond the condition of the loop
1295      * @return cond
1296      */
1297     protected static boolean iterationCount(double i, boolean cond) {
1298         return GraalDirectives.injectIterationCount(i, cond);
1299     }
1300 
1301     /**
1302      * Test if the current test runs on the given platform. The name must match the name given in
1303      * the {@link Architecture#getName()}.
1304      *
1305      * @param name The name to test
1306      * @return true if we run on the architecture given by name
1307      */
1308     protected boolean isArchitecture(String name) {
1309         return name.equals(backend.getTarget().arch.getName());
1310     }
1311 
1312     /**
1313      * This method should be called in "timeout" tests which JUnit runs in a different thread.
1314      */
1315     public static void initializeForTimeout() {
1316         // timeout tests run in a separate thread which needs the DebugEnvironment to be
1317         // initialized
1318         DebugEnvironment.ensureInitialized(getInitialOptions());
1319     }
1320 }
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File