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