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 28 import java.lang.reflect.Method; 29 30 import org.graalvm.compiler.api.test.Graal; 31 import org.graalvm.compiler.code.CompilationResult; 32 import org.graalvm.compiler.core.GraalCompiler; 33 import org.graalvm.compiler.core.common.CompilationIdentifier; 34 import org.graalvm.compiler.core.target.Backend; 35 import org.graalvm.compiler.debug.DebugHandlersFactory; 36 import org.graalvm.compiler.debug.DebugContext; 37 import org.graalvm.compiler.debug.DebugDumpScope; 38 import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory; 39 import org.graalvm.compiler.lir.phases.LIRSuites; 40 import org.graalvm.compiler.nodes.StructuredGraph; 41 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions; 42 import org.graalvm.compiler.options.OptionValues; 43 import org.graalvm.compiler.phases.OptimisticOptimizations; 44 import org.graalvm.compiler.phases.PhaseSuite; 45 import org.graalvm.compiler.phases.tiers.HighTierContext; 46 import org.graalvm.compiler.phases.tiers.Suites; 47 import org.graalvm.compiler.phases.util.Providers; 48 import org.graalvm.compiler.runtime.RuntimeProvider; 49 50 import jdk.vm.ci.code.CodeCacheProvider; 51 import jdk.vm.ci.code.InstalledCode; 52 import jdk.vm.ci.meta.MetaAccessProvider; 53 import jdk.vm.ci.meta.ProfilingInfo; 54 import jdk.vm.ci.meta.ResolvedJavaMethod; 55 56 /** 57 * Sample code that shows how to invoke Graal from an application. 58 */ 59 public 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(); 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 }