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 /** 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 } | 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 /** 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 } |