1 /*
   2  * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.graalvm.compiler.jtt;
  24 
  25 import static java.lang.reflect.Modifier.isStatic;
  26 
  27 import java.util.Collections;
  28 import java.util.Set;
  29 
  30 import org.graalvm.compiler.core.test.GraalCompilerTest;
  31 import org.graalvm.compiler.nodes.ConstantNode;
  32 import org.graalvm.compiler.nodes.ParameterNode;
  33 import org.graalvm.compiler.nodes.StructuredGraph;
  34 import org.graalvm.compiler.nodes.StructuredGraph.Builder;
  35 import org.graalvm.compiler.options.OptionValues;
  36 import org.graalvm.compiler.phases.PhaseSuite;
  37 import org.graalvm.compiler.phases.tiers.HighTierContext;
  38 import org.junit.Assert;
  39 
  40 import jdk.vm.ci.code.InstalledCode;
  41 import jdk.vm.ci.meta.DeoptimizationReason;
  42 import jdk.vm.ci.meta.JavaConstant;
  43 import jdk.vm.ci.meta.JavaType;
  44 import jdk.vm.ci.meta.ResolvedJavaMethod;
  45 
  46 /**
  47  * Base class for the JTT tests.
  48  * <p>
  49  * These tests are executed twice: once with arguments passed to the execution and once with the
  50  * arguments bound to the test's parameters during compilation. The latter is a good test of
  51  * canonicalization.
  52  */
  53 public class JTTTest extends GraalCompilerTest {
  54 
  55     public static final class DummyTestClass {
  56     }
  57 
  58     protected static final Set<DeoptimizationReason> EMPTY = Collections.<DeoptimizationReason> emptySet();
  59     /**
  60      * The arguments which, if non-null, will replace the Locals in the test method's graph.
  61      */
  62     Object[] argsToBind;
  63 
  64     public JTTTest() {
  65         Assert.assertNotNull(getCodeCache());
  66     }
  67 
  68     @Override
  69     protected StructuredGraph parse(Builder builder, PhaseSuite<HighTierContext> graphBuilderSuite) {
  70         StructuredGraph graph = super.parse(builder, graphBuilderSuite);
  71         if (argsToBind != null) {
  72             ResolvedJavaMethod m = graph.method();
  73             Object receiver = isStatic(m.getModifiers()) ? null : this;
  74             Object[] args = argsWithReceiver(receiver, argsToBind);
  75             JavaType[] parameterTypes = m.toParameterTypes();
  76             assert parameterTypes.length == args.length;
  77             for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
  78                 JavaConstant c = getSnippetReflection().forBoxed(parameterTypes[param.index()].getJavaKind(), args[param.index()]);
  79                 ConstantNode replacement = ConstantNode.forConstant(c, getMetaAccess(), graph);
  80                 param.replaceAtUsages(replacement);
  81             }
  82         }
  83         return graph;
  84     }
  85 
  86     @Override
  87     protected InstalledCode getCode(ResolvedJavaMethod method, StructuredGraph graph, boolean forceCompile, boolean installAsDefault, OptionValues options) {
  88         return super.getCode(method, graph, argsToBind != null, installAsDefault, options);
  89     }
  90 
  91     Double delta;
  92 
  93     @Override
  94     protected void assertDeepEquals(Object expected, Object actual) {
  95         if (delta != null) {
  96             Assert.assertEquals(((Number) expected).doubleValue(), ((Number) actual).doubleValue(), delta);
  97         } else {
  98             super.assertDeepEquals(expected, actual);
  99         }
 100     }
 101 
 102     @SuppressWarnings("hiding")
 103     protected void runTestWithDelta(double delta, String name, Object... args) {
 104         this.delta = Double.valueOf(delta);
 105         runTest(name, args);
 106     }
 107 
 108     protected void runTest(String name, Object... args) {
 109         runTest(getInitialOptions(), name, args);
 110     }
 111 
 112     protected void runTest(OptionValues options, String name, Object... args) {
 113         runTest(options, EMPTY, true, false, name, args);
 114     }
 115 
 116     protected void runTest(Set<DeoptimizationReason> shouldNotDeopt, String name, Object... args) {
 117         runTest(getInitialOptions(), shouldNotDeopt, true, false, name, args);
 118     }
 119 
 120     protected void runTest(OptionValues options, Set<DeoptimizationReason> shouldNotDeopt, boolean bind, boolean noProfile, String name, Object... args) {
 121         ResolvedJavaMethod method = getResolvedJavaMethod(name);
 122         Object receiver = method.isStatic() ? null : this;
 123 
 124         Result expect = executeExpected(method, receiver, args);
 125 
 126         if (noProfile) {
 127             method.reprofile();
 128         }
 129 
 130         testAgainstExpected(options, method, expect, shouldNotDeopt, receiver, args);
 131         if (args.length > 0 && bind) {
 132             if (noProfile) {
 133                 method.reprofile();
 134             }
 135 
 136             this.argsToBind = args;
 137             testAgainstExpected(options, method, expect, shouldNotDeopt, receiver, args);
 138             this.argsToBind = null;
 139         }
 140     }
 141 }