InvokeGraal.java revision 13522:0c2d710aa6df
1/*
2 * Copyright (c) 2015, 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 */
23package org.graalvm.compiler.core.test.tutorial;
24
25import static org.graalvm.compiler.core.common.CompilationRequestIdentifier.asCompilationRequest;
26import static org.graalvm.compiler.core.test.GraalCompilerTest.getInitialOptions;
27
28import java.lang.reflect.Method;
29
30import org.graalvm.compiler.api.test.Graal;
31import org.graalvm.compiler.code.CompilationResult;
32import org.graalvm.compiler.core.GraalCompiler;
33import org.graalvm.compiler.core.common.CompilationIdentifier;
34import org.graalvm.compiler.core.target.Backend;
35import org.graalvm.compiler.debug.DebugHandlersFactory;
36import org.graalvm.compiler.debug.DebugContext;
37import org.graalvm.compiler.debug.DebugDumpScope;
38import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory;
39import org.graalvm.compiler.lir.phases.LIRSuites;
40import org.graalvm.compiler.nodes.StructuredGraph;
41import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
42import org.graalvm.compiler.options.OptionValues;
43import org.graalvm.compiler.phases.OptimisticOptimizations;
44import org.graalvm.compiler.phases.PhaseSuite;
45import org.graalvm.compiler.phases.tiers.HighTierContext;
46import org.graalvm.compiler.phases.tiers.Suites;
47import org.graalvm.compiler.phases.util.Providers;
48import org.graalvm.compiler.runtime.RuntimeProvider;
49
50import jdk.vm.ci.code.CodeCacheProvider;
51import jdk.vm.ci.code.InstalledCode;
52import jdk.vm.ci.meta.MetaAccessProvider;
53import jdk.vm.ci.meta.ProfilingInfo;
54import jdk.vm.ci.meta.ResolvedJavaMethod;
55
56/**
57 * Sample code that shows how to invoke Graal from an application.
58 */
59public class InvokeGraal {
60
61    protected final Backend backend;
62    protected final Providers providers;
63    protected final MetaAccessProvider metaAccess;
64    protected final CodeCacheProvider codeCache;
65
66    public InvokeGraal() {
67        /* Ask the hosting Java VM for the entry point object to the Graal API. */
68        RuntimeProvider runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class);
69
70        /*
71         * The default backend (architecture, VM configuration) that the hosting VM is running on.
72         */
73        backend = runtimeProvider.getHostBackend();
74        /* Access to all of the Graal API providers, as implemented by the hosting VM. */
75        providers = backend.getProviders();
76        /* Some frequently used providers and configuration objects. */
77        metaAccess = providers.getMetaAccess();
78        codeCache = providers.getCodeCache();
79    }
80
81    /**
82     * The simplest way to compile a method, using the default behavior for everything.
83     */
84    @SuppressWarnings("try")
85    protected InstalledCode compileAndInstallMethod(ResolvedJavaMethod method) {
86        /* Create a unique compilation identifier, visible in IGV. */
87        CompilationIdentifier compilationId = backend.getCompilationIdentifier(method);
88        OptionValues options = getInitialOptions();
89        DebugContext debug = DebugContext.create(options, DebugHandlersFactory.LOADER);
90        try (DebugContext.Scope s = debug.scope("compileAndInstallMethod", new DebugDumpScope(String.valueOf(compilationId), true))) {
91
92            /*
93             * The graph that is compiled. We leave it empty (no nodes added yet). This means that
94             * it will be filled according to the graphBuilderSuite defined below. We also specify
95             * that we want the compilation to make optimistic assumptions about runtime state such
96             * as the loaded class hierarchy.
97             */
98            StructuredGraph graph = new StructuredGraph.Builder(options, debug, AllowAssumptions.YES).method(method).compilationId(compilationId).build();
99
100            /*
101             * The phases used to build the graph. Usually this is just the GraphBuilderPhase. If
102             * the graph already contains nodes, it is ignored.
103             */
104            PhaseSuite<HighTierContext> graphBuilderSuite = backend.getSuites().getDefaultGraphBuilderSuite();
105
106            /*
107             * The optimization phases that are applied to the graph. This is the main configuration
108             * point for Graal. Add or remove phases to customize your compilation.
109             */
110            Suites suites = backend.getSuites().getDefaultSuites(options);
111
112            /*
113             * The low-level phases that are applied to the low-level representation.
114             */
115            LIRSuites lirSuites = backend.getSuites().getDefaultLIRSuites(options);
116
117            /*
118             * We want Graal to perform all speculative optimistic optimizations, using the
119             * profiling information that comes with the method (collected by the interpreter) for
120             * speculation.
121             */
122            OptimisticOptimizations optimisticOpts = OptimisticOptimizations.ALL;
123            ProfilingInfo profilingInfo = graph.getProfilingInfo(method);
124
125            /* The default class and configuration for compilation results. */
126            CompilationResult compilationResult = new CompilationResult(graph.compilationId());
127            CompilationResultBuilderFactory factory = CompilationResultBuilderFactory.Default;
128
129            /* Invoke the whole Graal compilation pipeline. */
130            GraalCompiler.compileGraph(graph, method, providers, backend, graphBuilderSuite, optimisticOpts, profilingInfo, suites, lirSuites, compilationResult, factory);
131
132            /*
133             * Install the compilation result into the VM, i.e., copy the byte[] array that contains
134             * the machine code into an actual executable memory location.
135             */
136            return backend.addInstalledCode(debug, method, asCompilationRequest(compilationId), compilationResult);
137        } catch (Throwable ex) {
138            throw debug.handle(ex);
139        }
140    }
141
142    /**
143     * Look up a method using Java reflection and convert it to the Graal API method object.
144     */
145    protected ResolvedJavaMethod findMethod(Class<?> declaringClass, String name) {
146        Method reflectionMethod = null;
147        for (Method m : declaringClass.getDeclaredMethods()) {
148            if (m.getName().equals(name)) {
149                assert reflectionMethod == null : "More than one method with name " + name + " in class " + declaringClass.getName();
150                reflectionMethod = m;
151            }
152        }
153        assert reflectionMethod != null : "No method with name " + name + " in class " + declaringClass.getName();
154        return metaAccess.lookupJavaMethod(reflectionMethod);
155    }
156}
157