001/* 002 * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.compiler.test.tutorial; 024 025import java.lang.reflect.*; 026import java.util.concurrent.atomic.*; 027 028import jdk.internal.jvmci.code.*; 029import jdk.internal.jvmci.code.CallingConvention.Type; 030import com.oracle.graal.debug.*; 031import com.oracle.graal.debug.Debug.Scope; 032import jdk.internal.jvmci.meta.*; 033 034import com.oracle.graal.api.runtime.*; 035import com.oracle.graal.compiler.*; 036import com.oracle.graal.compiler.target.*; 037import com.oracle.graal.lir.asm.*; 038import com.oracle.graal.lir.phases.*; 039import com.oracle.graal.nodes.*; 040import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; 041import com.oracle.graal.phases.*; 042import com.oracle.graal.phases.tiers.*; 043import com.oracle.graal.phases.util.*; 044import com.oracle.graal.runtime.*; 045 046/** 047 * Sample code that shows how to invoke Graal from an application. 048 */ 049public class InvokeGraal { 050 051 protected final Backend backend; 052 protected final Providers providers; 053 protected final MetaAccessProvider metaAccess; 054 protected final CodeCacheProvider codeCache; 055 protected final TargetDescription target; 056 057 public InvokeGraal() { 058 /* Ask the hosting Java VM for the entry point object to the Graal API. */ 059 RuntimeProvider runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class); 060 061 /* 062 * The default backend (architecture, VM configuration) that the hosting VM is running on. 063 */ 064 backend = runtimeProvider.getHostBackend(); 065 /* Access to all of the Graal API providers, as implemented by the hosting VM. */ 066 providers = backend.getProviders(); 067 /* Some frequently used providers and configuration objects. */ 068 metaAccess = providers.getMetaAccess(); 069 codeCache = providers.getCodeCache(); 070 target = codeCache.getTarget(); 071 } 072 073 private static AtomicInteger compilationId = new AtomicInteger(); 074 075 /** 076 * The simplest way to compile a method, using the default behavior for everything. 077 */ 078 protected InstalledCode compileAndInstallMethod(ResolvedJavaMethod method) { 079 /* Ensure every compilation gets a unique number, visible in IGV. */ 080 try (Scope s = Debug.scope("compileAndInstallMethod", new DebugDumpScope(String.valueOf(compilationId.incrementAndGet()), true))) { 081 082 /* 083 * The graph that is compiled. We leave it empty (no nodes added yet). This means that 084 * it will be filled according to the graphBuilderSuite defined below. We also specify 085 * that we want the compilation to make optimistic assumptions about runtime state such 086 * as the loaded class hierarchy. 087 */ 088 StructuredGraph graph = new StructuredGraph(method, AllowAssumptions.YES); 089 090 /* 091 * The phases used to build the graph. Usually this is just the GraphBuilderPhase. If 092 * the graph already contains nodes, it is ignored. 093 */ 094 PhaseSuite<HighTierContext> graphBuilderSuite = backend.getSuites().getDefaultGraphBuilderSuite(); 095 096 /* 097 * The optimization phases that are applied to the graph. This is the main configuration 098 * point for Graal. Add or remove phases to customize your compilation. 099 */ 100 Suites suites = backend.getSuites().createSuites(); 101 102 /* 103 * The low-level phases that are applied to the low-level representation. 104 */ 105 LIRSuites lirSuites = backend.getSuites().createLIRSuites(); 106 107 /* 108 * The calling convention for the machine code. You should have a very good reason 109 * before you switch to a different calling convention than the one that the VM provides 110 * by default. 111 */ 112 CallingConvention callingConvention = CodeUtil.getCallingConvention(codeCache, Type.JavaCallee, method, false); 113 114 /* 115 * We want Graal to perform all speculative optimisitic optimizations, using the 116 * profiling information that comes with the method (collected by the interpreter) for 117 * speculation. 118 */ 119 OptimisticOptimizations optimisticOpts = OptimisticOptimizations.ALL; 120 ProfilingInfo profilingInfo = method.getProfilingInfo(); 121 122 /* The default class and configuration for compilation results. */ 123 CompilationResult compilationResult = new CompilationResult(); 124 CompilationResultBuilderFactory factory = CompilationResultBuilderFactory.Default; 125 126 /* Invoke the whole Graal compilation pipeline. */ 127 GraalCompiler.compileGraph(graph, callingConvention, method, providers, backend, target, graphBuilderSuite, optimisticOpts, profilingInfo, suites, lirSuites, compilationResult, factory); 128 129 /* 130 * Install the compilation result into the VM, i.e., copy the byte[] array that contains 131 * the machine code into an actual executable memory location. 132 */ 133 InstalledCode installedCode = codeCache.addMethod(method, compilationResult, null, null); 134 135 return installedCode; 136 } catch (Throwable ex) { 137 throw Debug.handle(ex); 138 } 139 } 140 141 /** 142 * Look up a method using Java reflection and convert it to the Graal API method object. 143 */ 144 protected ResolvedJavaMethod findMethod(Class<?> declaringClass, String name) { 145 Method reflectionMethod = null; 146 for (Method m : declaringClass.getDeclaredMethods()) { 147 if (m.getName().equals(name)) { 148 assert reflectionMethod == null : "More than one method with name " + name + " in class " + declaringClass.getName(); 149 reflectionMethod = m; 150 } 151 } 152 assert reflectionMethod != null : "No method with name " + name + " in class " + declaringClass.getName(); 153 return metaAccess.lookupJavaMethod(reflectionMethod); 154 } 155}