GraalOSRTestBase.java revision 12968:4d8a004e5c6d
1/*
2 * Copyright (c) 2016, 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
24package org.graalvm.compiler.hotspot.test;
25
26import java.util.Arrays;
27
28import org.graalvm.compiler.bytecode.Bytecode;
29import org.graalvm.compiler.bytecode.BytecodeDisassembler;
30import org.graalvm.compiler.bytecode.BytecodeStream;
31import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode;
32import org.graalvm.compiler.core.target.Backend;
33import org.graalvm.compiler.core.test.GraalCompilerTest;
34import org.graalvm.compiler.debug.GraalError;
35import org.graalvm.compiler.debug.TTY;
36import org.graalvm.compiler.hotspot.CompilationTask;
37import org.graalvm.compiler.hotspot.HotSpotGraalCompiler;
38import org.graalvm.compiler.java.BciBlockMapping;
39import org.graalvm.compiler.java.BciBlockMapping.BciBlock;
40import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
41import org.graalvm.compiler.options.OptionValues;
42import org.junit.Assert;
43
44import jdk.vm.ci.code.Architecture;
45import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
46import jdk.vm.ci.hotspot.HotSpotCompilationRequestResult;
47import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
48import jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider;
49import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
50import jdk.vm.ci.meta.ResolvedJavaMethod;
51
52public abstract class GraalOSRTestBase extends GraalCompilerTest {
53
54    protected void testOSR(OptionValues options, String methodName) {
55        testOSR(options, methodName, null);
56    }
57
58    protected void testOSR(OptionValues options, String methodName, Object receiver, Object... args) {
59        ResolvedJavaMethod method = getResolvedJavaMethod(methodName);
60        testOSR(options, method, receiver, args);
61    }
62
63    protected void testOSR(OptionValues options, ResolvedJavaMethod method, Object receiver, Object... args) {
64        // invalidate any existing compiled code
65        method.reprofile();
66        compileOSR(options, method);
67        Result result = executeExpected(method, receiver, args);
68        checkResult(result);
69    }
70
71    protected static void compile(OptionValues options, ResolvedJavaMethod method, int bci) {
72        HotSpotJVMCIRuntimeProvider runtime = HotSpotJVMCIRuntime.runtime();
73        long jvmciEnv = 0L;
74        HotSpotCompilationRequest request = new HotSpotCompilationRequest((HotSpotResolvedJavaMethod) method, bci, jvmciEnv);
75        HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) runtime.getCompiler();
76        CompilationTask task = new CompilationTask(runtime, compiler, request, true, true, options);
77        HotSpotCompilationRequestResult result = task.runCompilation();
78        if (result.getFailure() != null) {
79            throw new GraalError(result.getFailureMessage());
80        }
81    }
82
83    /**
84     * Returns the target BCI of the first bytecode backedge. This is where HotSpot triggers
85     * on-stack-replacement in case the backedge counter overflows.
86     */
87    private static int getBackedgeBCI(ResolvedJavaMethod method) {
88        Bytecode code = new ResolvedJavaMethodBytecode(method);
89        BytecodeStream stream = new BytecodeStream(code.getCode());
90        BciBlockMapping bciBlockMapping = BciBlockMapping.create(stream, code, getInitialOptions());
91
92        for (BciBlock block : bciBlockMapping.getBlocks()) {
93            if (block.startBci != -1) {
94                int bci = block.startBci;
95                for (BciBlock succ : block.getSuccessors()) {
96                    if (succ.startBci != -1) {
97                        int succBci = succ.startBci;
98                        if (succBci < bci) {
99                            // back edge
100                            return succBci;
101                        }
102                    }
103                }
104            }
105        }
106        TTY.println("Cannot find loop back edge with bytecode loops at:%s", Arrays.toString(bciBlockMapping.getLoopHeaders()));
107        TTY.println(new BytecodeDisassembler().disassemble(code));
108        return -1;
109    }
110
111    private static void checkResult(Result result) {
112        Assert.assertNull("Unexpected exception", result.exception);
113        Assert.assertNotNull(result.returnValue);
114        Assert.assertTrue(result.returnValue instanceof ReturnValue);
115        Assert.assertEquals(ReturnValue.SUCCESS, result.returnValue);
116    }
117
118    private void compileOSR(OptionValues options, ResolvedJavaMethod method) {
119        // ensure eager resolving
120        parseEager(method, AllowAssumptions.YES, options);
121        int bci = getBackedgeBCI(method);
122        assert bci != -1;
123        // ensure eager resolving
124        parseEager(method, AllowAssumptions.YES, options);
125        compile(options, method, bci);
126    }
127
128    protected enum ReturnValue {
129        SUCCESS,
130        FAILURE,
131        SIDE
132    }
133
134    public GraalOSRTestBase() {
135        super();
136    }
137
138    public GraalOSRTestBase(Class<? extends Architecture> arch) {
139        super(arch);
140    }
141
142    public GraalOSRTestBase(Backend backend) {
143        super(backend);
144    }
145
146}
147