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