001/*
002 * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.jtt;
024
025import static java.lang.reflect.Modifier.*;
026
027import java.util.*;
028
029import jdk.internal.jvmci.code.*;
030import jdk.internal.jvmci.meta.*;
031
032import org.junit.*;
033
034import com.oracle.graal.compiler.test.*;
035import com.oracle.graal.nodes.*;
036import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
037
038/**
039 * Base class for the JTT tests.
040 * <p>
041 * These tests are executed twice: once with arguments passed to the execution and once with the
042 * arguments bound to the test's parameters during compilation. The latter is a good test of
043 * canonicalization.
044 */
045public class JTTTest extends GraalCompilerTest {
046
047    public static final class DummyTestClass {
048    }
049
050    protected static final Set<DeoptimizationReason> EMPTY = Collections.<DeoptimizationReason> emptySet();
051    /**
052     * The arguments which, if non-null, will replace the Locals in the test method's graph.
053     */
054    Object[] argsToBind;
055
056    public JTTTest() {
057        Assert.assertNotNull(getCodeCache());
058    }
059
060    @Override
061    protected StructuredGraph parseEager(ResolvedJavaMethod m, AllowAssumptions allowAssumptions) {
062        StructuredGraph graph = super.parseEager(m, allowAssumptions);
063        if (argsToBind != null) {
064            Object receiver = isStatic(m.getModifiers()) ? null : this;
065            Object[] args = argsWithReceiver(receiver, argsToBind);
066            JavaType[] parameterTypes = m.toParameterTypes();
067            assert parameterTypes.length == args.length;
068            for (int i = 0; i < args.length; i++) {
069                ParameterNode param = graph.getParameter(i);
070                if (param != null) {
071                    JavaConstant c = getSnippetReflection().forBoxed(parameterTypes[i].getKind(), args[i]);
072                    ConstantNode replacement = ConstantNode.forConstant(c, getMetaAccess(), graph);
073                    param.replaceAtUsages(replacement);
074                } else {
075                    // Parameter is not used and has been dead-code eliminated
076                }
077            }
078        }
079        return graph;
080    }
081
082    @Override
083    protected InstalledCode getCode(ResolvedJavaMethod method, StructuredGraph graph) {
084        return super.getCode(method, graph, argsToBind != null);
085    }
086
087    Double delta;
088
089    @Override
090    protected void assertDeepEquals(Object expected, Object actual) {
091        if (delta != null) {
092            Assert.assertEquals(((Number) expected).doubleValue(), ((Number) actual).doubleValue(), delta);
093        } else {
094            super.assertDeepEquals(expected, actual);
095        }
096    }
097
098    @SuppressWarnings("hiding")
099    protected void runTestWithDelta(double delta, String name, Object... args) {
100        this.delta = Double.valueOf(delta);
101        runTest(name, args);
102    }
103
104    protected void runTest(String name, Object... args) {
105        runTest(EMPTY, name, args);
106    }
107
108    protected void runTest(Set<DeoptimizationReason> shouldNotDeopt, String name, Object... args) {
109        runTest(shouldNotDeopt, true, false, name, args);
110    }
111
112    protected void runTest(Set<DeoptimizationReason> shouldNotDeopt, boolean bind, boolean noProfile, String name, Object... args) {
113        ResolvedJavaMethod method = getResolvedJavaMethod(name);
114        Object receiver = method.isStatic() ? null : this;
115
116        Result expect = executeExpected(method, receiver, args);
117
118        if (noProfile) {
119            method.reprofile();
120        }
121
122        testAgainstExpected(method, expect, shouldNotDeopt, receiver, args);
123        if (args.length > 0 && bind) {
124            if (noProfile) {
125                method.reprofile();
126            }
127
128            this.argsToBind = args;
129            testAgainstExpected(method, expect, shouldNotDeopt, receiver, args);
130            this.argsToBind = null;
131        }
132    }
133}