Mercurial > hg > truffle
changeset 12536:16e507054ebb
Merge
author | Matthias Grimmer <grimmer@ssw.jku.at> |
---|---|
date | Wed, 23 Oct 2013 13:41:10 +0200 |
parents | cee7f686c470 (diff) 2583afcd26ee (current diff) |
children | c95e11c431b0 |
files | graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java |
diffstat | 13 files changed, 204 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java Wed Oct 23 10:29:53 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java Wed Oct 23 13:41:10 2013 +0200 @@ -42,6 +42,16 @@ InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult); /** + * Sets the given compilation result as the default implementation of the given method. + * + * @param method a method to which the executable code is begin added + * @param compResult the compilation result to be added + * @return a reference to the compiled and ready-to-run code or null if the code installation + * failed + */ + InstalledCode setDefaultMethod(ResolvedJavaMethod method, CompilationResult compResult); + + /** * Returns a disassembly of some compiled code. * * @param compResult some compiled code
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Wed Oct 23 10:29:53 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Wed Oct 23 13:41:10 2013 +0200 @@ -210,7 +210,7 @@ } } - private static void decodePointer(AMD64MacroAssembler masm, Register resRegister, Register heapBaseRegister, long base, int shift, int alignment) { + public static void decodePointer(AMD64MacroAssembler masm, Register resRegister, Register heapBaseRegister, long base, int shift, int alignment) { // If the base is zero, the compressed address has to be shifted left // in order to be uncompressed. if (base == 0) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Wed Oct 23 10:29:53 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Wed Oct 23 13:41:10 2013 +0200 @@ -218,6 +218,8 @@ long readUnsafeKlassPointer(Object o); + void doNotInlineOrCompile(long metaspaceMethod); + /** * Invalidates the profiling information and restarts profiling upon the next invocation. *
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Wed Oct 23 10:29:53 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Wed Oct 23 13:41:10 2013 +0200 @@ -178,6 +178,9 @@ public native long readUnsafeKlassPointer(Object o); @Override + public native void doNotInlineOrCompile(long metaspaceMethod); + + @Override public Object executeCompiledMethod(Object arg1, Object arg2, Object arg3, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException { return executeCompiledMethodIntrinsic(arg1, arg2, arg3, hotspotInstalledCode); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Wed Oct 23 10:29:53 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Wed Oct 23 13:41:10 2013 +0200 @@ -36,6 +36,7 @@ import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.bridge.CompilerToVM.CodeInstallResult; import com.oracle.graal.java.*; +import com.oracle.graal.nodes.*; import com.oracle.graal.printer.*; /** @@ -173,6 +174,11 @@ return code; } + public InstalledCode setDefaultMethod(ResolvedJavaMethod method, CompilationResult compResult) { + HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method; + return installMethod(hotspotMethod, StructuredGraph.INVOCATION_ENTRY_BCI, compResult); + } + public InstalledCode addExternalMethod(ResolvedJavaMethod method, CompilationResult compResult) { HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) method;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Wed Oct 23 10:29:53 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Wed Oct 23 13:41:10 2013 +0200 @@ -190,6 +190,14 @@ } /** + * Manually adds a DontInline annotation to this method. + */ + public void setDontInline() { + dontInline = true; + runtime().getCompilerToVM().doNotInlineOrCompile(metaspaceMethod); + } + + /** * Returns true if this method is one of the special methods that is ignored by security stack * walks. *
--- a/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64HotSpotTruffleBackend.java Wed Oct 23 10:29:53 2013 +0200 +++ b/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64HotSpotTruffleBackend.java Wed Oct 23 13:41:10 2013 +0200 @@ -22,16 +22,20 @@ */ package com.oracle.graal.truffle.hotspot.amd64; +import com.oracle.graal.amd64.*; +import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.amd64.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.truffle.*; +import com.oracle.graal.truffle.hotspot.amd64.util.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; @@ -42,7 +46,7 @@ */ class AMD64HotSpotTruffleBackend extends AMD64HotSpotBackend { - private ResolvedJavaMethod optimizedCallTargetCall; + private HotSpotResolvedJavaMethod optimizedCallTargetCall; public AMD64HotSpotTruffleBackend(HotSpotGraalRuntime runtime, HotSpotProviders providers) { super(runtime, providers); @@ -51,7 +55,9 @@ private ResolvedJavaMethod getInstrumentedMethod() throws GraalInternalError { if (optimizedCallTargetCall == null) { try { - optimizedCallTargetCall = getProviders().getMetaAccess().lookupJavaMethod(OptimizedCallTarget.class.getDeclaredMethod("call", PackedFrame.class, Arguments.class)); + optimizedCallTargetCall = (HotSpotResolvedJavaMethod) getProviders().getMetaAccess().lookupJavaMethod( + OptimizedCallTarget.class.getDeclaredMethod("call", PackedFrame.class, Arguments.class)); + optimizedCallTargetCall.setDontInline(); } catch (NoSuchMethodException | SecurityException e) { throw new GraalInternalError(e); } @@ -63,7 +69,31 @@ protected void emitCodePrefix(ResolvedJavaMethod installedCodeOwner, TargetMethodAssembler tasm, AMD64MacroAssembler asm, RegisterConfig regConfig, HotSpotVMConfig config, Label verifiedStub) { super.emitCodePrefix(installedCodeOwner, tasm, asm, regConfig, config, verifiedStub); if (getInstrumentedMethod().equals(installedCodeOwner)) { - // TODO emit tailcall code + HotSpotProviders providers = getRuntime().getHostProviders(); + Register thisRegister = providers.getCodeCache().getRegisterConfig().getCallingConventionRegisters(Type.JavaCall, Kind.Object)[0]; + Register spillRegister = AMD64.r10; // TODO(mg): fix me + AMD64Address nMethodAddress = new AMD64Address(thisRegister, OptimizedCallTargetFieldInfo.getCompiledMethodFieldOffset()); + if (config.useCompressedOops) { + asm.movl(spillRegister, nMethodAddress); + AMD64HotSpotMove.decodePointer(asm, spillRegister, providers.getRegisters().getHeapBaseRegister(), config.narrowOopBase, config.narrowOopShift, config.logMinObjAlignment); + } else { + asm.movq(spillRegister, nMethodAddress); + } + Label doProlog = new Label(); + + asm.cmpq(spillRegister, 0); + asm.jcc(ConditionFlag.Equal, doProlog); + + AMD64Address codeBlobAddress = new AMD64Address(spillRegister, OptimizedCallTargetFieldInfo.getCodeBlobFieldOffset()); + asm.movq(spillRegister, codeBlobAddress); + asm.cmpq(spillRegister, 0); + asm.jcc(ConditionFlag.Equal, doProlog); + + AMD64Address verifiedEntryPointAddress = new AMD64Address(spillRegister, config.nmethodEntryOffset); + asm.movq(spillRegister, verifiedEntryPointAddress); + asm.jmp(spillRegister); + + asm.bind(doProlog); } } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/util/OptimizedCallTargetFieldInfo.java Wed Oct 23 13:41:10 2013 +0200 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.hotspot.amd64.util; + +import java.lang.reflect.*; + +import sun.misc.*; + +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.truffle.*; + +public class OptimizedCallTargetFieldInfo { + + private static final Unsafe unsafe = UnsafeAccess.unsafe; + private static int compiledMethodFieldOffset = -1; + private static int codeBlobFieldOffset = -1; + + public static int getCodeBlobFieldOffset() { + if (codeBlobFieldOffset == -1) { + codeBlobFieldOffset = getFieldOffset("codeBlob", HotSpotInstalledCode.class); + } + return codeBlobFieldOffset; + } + + public static int getCompiledMethodFieldOffset() { + if (compiledMethodFieldOffset == -1) { + compiledMethodFieldOffset = getFieldOffset("compiledMethod", OptimizedCallTarget.class); + } + return compiledMethodFieldOffset; + + } + + private static int getFieldOffset(String name, Class container) { + try { + container.getDeclaredField(name).setAccessible(true); + Field field = container.getDeclaredField(name); + return (int) unsafe.objectFieldOffset(field); + } catch (NoSuchFieldException | SecurityException e) { + throw GraalInternalError.shouldNotReachHere(); + } + } +}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Wed Oct 23 10:29:53 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Wed Oct 23 13:41:10 2013 +0200 @@ -22,11 +22,28 @@ */ package com.oracle.graal.truffle; +import static com.oracle.graal.api.code.CodeUtil.*; import static com.oracle.graal.truffle.TruffleCompilerOptions.*; +import java.lang.reflect.*; import java.util.*; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CallingConvention.Type; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.runtime.*; +import com.oracle.graal.compiler.*; +import com.oracle.graal.compiler.target.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.java.*; +import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.PhasePlan.PhasePosition; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.phases.util.*; +import com.oracle.graal.runtime.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.impl.*; @@ -47,6 +64,7 @@ private ArrayList<String> excludes; private GraalTruffleRuntime() { + installOptimizedCallTargetCallMethod(); } public String getName() { @@ -138,4 +156,43 @@ } } } + + public static void installOptimizedCallTargetCallMethod() { + Providers providers = getGraalProviders(); + MetaAccessProvider metaAccess = providers.getMetaAccess(); + ResolvedJavaMethod resolvedCallMethod = metaAccess.lookupJavaMethod(getCallMethod()); + providers.getCodeCache().setDefaultMethod(resolvedCallMethod, compileMethod(resolvedCallMethod)); + } + + private static Method getCallMethod() { + Method method; + try { + method = OptimizedCallTarget.class.getDeclaredMethod("call", new Class[]{PackedFrame.class, Arguments.class}); + } catch (NoSuchMethodException | SecurityException e) { + throw GraalInternalError.shouldNotReachHere(); + } + return method; + } + + private static CompilationResult compileMethod(ResolvedJavaMethod javaMethod) { + Providers providers = getGraalProviders(); + MetaAccessProvider metaAccess = providers.getMetaAccess(); + Suites suites = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getSuites().createSuites(); + suites.getHighTier().findPhase(InliningPhase.class).remove(); + StructuredGraph graph = new StructuredGraph(javaMethod); + ForeignCallsProvider foreignCalls = providers.getForeignCalls(); + new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); + PhasePlan phasePlan = new PhasePlan(); + GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); + phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); + CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false); + Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend(); + return GraalCompiler.compileGraph(graph, cc, javaMethod, providers, backend, providers.getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, new SpeculationLog(), suites, + new CompilationResult()); + } + + private static Providers getGraalProviders() { + RuntimeProvider runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class); + return runtimeProvider.getHostBackend().getProviders(); + } }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Wed Oct 23 10:29:53 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Wed Oct 23 13:41:10 2013 +0200 @@ -75,6 +75,14 @@ } private Object callHelper(PackedFrame caller, Arguments args) { + if (compiledMethod != null && compiledMethod.isValid()) { + TruffleRuntime runtime = Truffle.getRuntime(); + if (runtime instanceof GraalTruffleRuntime) { + OUT.printf("[truffle] reinstall OptimizedCallTarget.call code with frame prolog shortcut."); + OUT.println(); + GraalTruffleRuntime.installOptimizedCallTargetCallMethod(); + } + } if (TruffleCallTargetProfiling.getValue()) { callCount++; }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java Wed Oct 23 10:29:53 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java Wed Oct 23 13:41:10 2013 +0200 @@ -34,6 +34,9 @@ public class OptimizedCallTargetSubstitutions { @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false) + public static native Object call(OptimizedCallTarget target, PackedFrame caller, Arguments args); + + @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false) public static native Object callHelper(OptimizedCallTarget target, PackedFrame caller, Arguments args); @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false)
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BlockNode.java Wed Oct 23 10:29:53 2013 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BlockNode.java Wed Oct 23 13:41:10 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.truffle.sl.nodes; import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; public class BlockNode extends StatementNode { @@ -33,6 +34,7 @@ } @Override + @ExplodeLoop public void executeVoid(VirtualFrame frame) { for (StatementNode statement : statements) { statement.executeVoid(frame);
--- a/src/share/vm/graal/graalCompilerToVM.cpp Wed Oct 23 10:29:53 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Wed Oct 23 13:41:10 2013 +0200 @@ -642,6 +642,13 @@ return id; } +C2V_VMENTRY(void, doNotInlineOrCompile,(JNIEnv *, jobject, jlong metaspace_method)) + methodHandle method = asMethod(metaspace_method); + method->set_not_c1_compilable(); + method->set_not_c2_compilable(); + method->set_dont_inline(true); +C2V_END + C2V_ENTRY(void, initializeConfiguration, (JNIEnv *env, jobject, jobject config)) #define set_boolean(name, value) do { env->SetBooleanField(config, getFieldID(env, config, name, "Z"), value); } while (0) @@ -1196,6 +1203,7 @@ {CC"getUniqueImplementor", CC"("HS_RESOLVED_TYPE")"RESOLVED_TYPE, FN_PTR(getUniqueImplementor)}, {CC"getStackTraceElement", CC"("METASPACE_METHOD"I)"STACK_TRACE_ELEMENT, FN_PTR(getStackTraceElement)}, {CC"initializeMethod", CC"("METASPACE_METHOD HS_RESOLVED_METHOD")V", FN_PTR(initializeMethod)}, + {CC"doNotInlineOrCompile", CC"("METASPACE_METHOD")V", FN_PTR(doNotInlineOrCompile)}, {CC"initializeMethodData", CC"("METASPACE_METHOD_DATA METHOD_DATA")V", FN_PTR(initializeMethodData)}, {CC"isMethodCompilable", CC"("METASPACE_METHOD")Z", FN_PTR(isMethodCompilable)}, {CC"getCompiledCodeSize", CC"("METASPACE_METHOD")I", FN_PTR(getCompiledCodeSize)},