# HG changeset patch # User Thomas Wuerthinger # Date 1373310720 -7200 # Node ID d71c56c679213541c4cad00003f71af025996050 # Parent ab689f0086bb8aa7409ee7d122de179fbb70718e Improve performance of calling Truffle call targets. diff -r ab689f0086bb -r d71c56c67921 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Mon Jul 08 21:08:14 2013 +0200 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Mon Jul 08 21:12:00 2013 +0200 @@ -241,6 +241,13 @@ } @Override + protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { + AllocatableValue targetAddress = AMD64.rax.asValue(); + emitMove(targetAddress, operand(callTarget.computedAddress())); + append(new AMD64Call.IndirectCallOp(callTarget.target(), result, parameters, temps, targetAddress, callState)); + } + + @Override public void emitOverflowCheckBranch(LabelRef destination, boolean negated) { append(new BranchOp(negated ? ConditionFlag.NoOverflow : ConditionFlag.Overflow, destination)); } diff -r ab689f0086bb -r d71c56c67921 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Mon Jul 08 21:08:14 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Mon Jul 08 21:12:00 2013 +0200 @@ -38,6 +38,7 @@ import com.oracle.graal.compiler.gen.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.stubs.*; @@ -341,11 +342,15 @@ @Override protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { - AllocatableValue metaspaceMethod = AMD64.rbx.asValue(); - emitMove(metaspaceMethod, operand(((HotSpotIndirectCallTargetNode) callTarget).metaspaceMethod())); - AllocatableValue targetAddress = AMD64.rax.asValue(); - emitMove(targetAddress, operand(callTarget.computedAddress())); - append(new AMD64IndirectCallOp(callTarget.target(), result, parameters, temps, metaspaceMethod, targetAddress, callState)); + if (callTarget instanceof HotSpotIndirectCallTargetNode) { + AllocatableValue metaspaceMethod = AMD64.rbx.asValue(); + emitMove(metaspaceMethod, operand(((HotSpotIndirectCallTargetNode) callTarget).metaspaceMethod())); + AllocatableValue targetAddress = AMD64.rax.asValue(); + emitMove(targetAddress, operand(callTarget.computedAddress())); + append(new AMD64IndirectCallOp(callTarget.target(), result, parameters, temps, metaspaceMethod, targetAddress, callState)); + } else { + super.emitIndirectCall(callTarget, result, parameters, temps, callState); + } } @Override diff -r ab689f0086bb -r d71c56c67921 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Mon Jul 08 21:08:14 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Mon Jul 08 21:12:00 2013 +0200 @@ -187,5 +187,5 @@ * stub that does the necessary argument shuffling and a tail call via an indirect jump to the * verified entry point of the given native method. */ - private static native Object executeCompiledMethodIntrinsic(Object arg1, Object arg2, Object arg3, HotSpotInstalledCode hotspotInstalledCode); + public static native Object executeCompiledMethodIntrinsic(Object arg1, Object arg2, Object arg3, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException; } diff -r ab689f0086bb -r d71c56c67921 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java Mon Jul 08 21:08:14 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java Mon Jul 08 21:12:00 2013 +0200 @@ -29,6 +29,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.bridge.*; /** * Implementation of {@link InstalledCode} for code installed as an nmethod. The nmethod stores a @@ -100,7 +101,11 @@ assert method.getSignature().getParameterKind(0) == Kind.Object; assert method.getSignature().getParameterKind(1) == Kind.Object; assert !Modifier.isStatic(method.getModifiers()) || method.getSignature().getParameterKind(2) == Kind.Object; - return graalRuntime().getCompilerToVM().executeCompiledMethod(arg1, arg2, arg3, this); + return executeHelper(arg1, arg2, arg3, this); + } + + private static Object executeHelper(Object arg1, Object arg2, Object arg3, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException { + return CompilerToVMImpl.executeCompiledMethodIntrinsic(arg1, arg2, arg3, hotspotInstalledCode); } private boolean checkArgs(Object... args) { diff -r ab689f0086bb -r d71c56c67921 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotNmethodExecuteNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotNmethodExecuteNode.java Mon Jul 08 21:08:14 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotNmethodExecuteNode.java Mon Jul 08 21:12:00 2013 +0200 @@ -22,95 +22,45 @@ */ package com.oracle.graal.hotspot.nodes; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; - -import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; -import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.hotspot.replacements.*; +import com.oracle.graal.hotspot.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -import com.oracle.graal.phases.common.*; - -public class HotSpotNmethodExecuteNode extends AbstractCallNode implements Lowerable, MemoryCheckpoint.Single { - - @Input private ValueNode code; - private final Class[] signature; +import com.oracle.graal.replacements.nodes.*; - public HotSpotNmethodExecuteNode(Kind kind, Class[] signature, ValueNode code, ValueNode arg1, ValueNode arg2, ValueNode arg3) { - super(StampFactory.forKind(kind), new ValueNode[]{arg1, arg2, arg3}); - this.code = code; - this.signature = signature; - } +public class HotSpotNmethodExecuteNode extends MacroNode implements Lowerable { - @Override - public LocationIdentity getLocationIdentity() { - return LocationIdentity.ANY_LOCATION; + public HotSpotNmethodExecuteNode(Invoke invoke) { + super(invoke); } @Override public void lower(LoweringTool tool, LoweringType loweringType) { - if (code.isConstant() && code.asConstant().asObject() instanceof HotSpotNmethod) { - HotSpotNmethod nmethod = (HotSpotNmethod) code.asConstant().asObject(); - InvokeNode invoke = replaceWithInvoke(tool.getRuntime()); - StructuredGraph graph = (StructuredGraph) nmethod.getGraph(); - if (graph != null) { - InliningUtil.inline(invoke, graph, false); + if (loweringType == LoweringType.AFTER_GUARDS) { + + ValueNode hotspotNmethod = arguments.get(3); + + ReadNode readNode = graph().add(new ReadNode(hotspotNmethod, 16, LocationIdentity.ANY_LOCATION, Kind.Long)); + graph().addBeforeFixed(this, readNode); + readNode.setNullCheck(true); + + int verifiedEntryOffset = HotSpotGraalRuntime.graalRuntime().getConfig().nmethodEntryOffset; + ReadNode readAddressNode = graph().add(new ReadNode(readNode, verifiedEntryOffset, LocationIdentity.ANY_LOCATION, Kind.Long)); + graph().addBeforeFixed(this, readAddressNode); + readAddressNode.setNullCheck(true); + + JavaType[] signatureTypes = new JavaType[getTargetMethod().getSignature().getParameterCount(false)]; + for (int i = 0; i < signatureTypes.length; ++i) { + signatureTypes[i] = getTargetMethod().getSignature().getParameterType(i, getTargetMethod().getDeclaringClass()); } - } else { - replaceWithInvoke(tool.getRuntime()); + + IndirectCallTargetNode callTarget = graph().add(new IndirectCallTargetNode(readAddressNode, arguments, StampFactory.object(), signatureTypes, super.getTargetMethod(), Type.JavaCall)); + InvokeNode invoke = graph().add(new InvokeNode(callTarget, super.getBci())); + invoke.setStateAfter(stateAfter()); + graph().replaceFixedWithFixed(this, invoke); } } - - protected InvokeNode replaceWithInvoke(MetaAccessProvider tool) { - ResolvedJavaMethod method = null; - ResolvedJavaField methodField = null; - ResolvedJavaField metaspaceMethodField = null; - ResolvedJavaField codeBlobField = null; - try { - method = tool.lookupJavaMethod(HotSpotNmethodExecuteNode.class.getMethod("placeholder", Object.class, Object.class, Object.class)); - methodField = tool.lookupJavaField(HotSpotNmethod.class.getDeclaredField("method")); - codeBlobField = tool.lookupJavaField(HotSpotInstalledCode.class.getDeclaredField("codeBlob")); - metaspaceMethodField = tool.lookupJavaField(HotSpotResolvedJavaMethod.class.getDeclaredField("metaspaceMethod")); - } catch (NoSuchMethodException | SecurityException | NoSuchFieldException e) { - throw new IllegalStateException(e); - } - ResolvedJavaType[] signatureTypes = new ResolvedJavaType[signature.length]; - for (int i = 0; i < signature.length; i++) { - signatureTypes[i] = tool.lookupJavaType(signature[i]); - } - final int verifiedEntryPointOffset = HotSpotReplacementsUtil.verifiedEntryPointOffset(); - - LoadFieldNode loadCodeBlob = graph().add(new LoadFieldNode(code, codeBlobField)); - UnsafeLoadNode load = graph().add(new UnsafeLoadNode(loadCodeBlob, verifiedEntryPointOffset, ConstantNode.forLong(0, graph()), graalRuntime().getTarget().wordKind)); - - LoadFieldNode loadMethod = graph().add(new LoadFieldNode(code, methodField)); - LoadFieldNode loadmetaspaceMethod = graph().add(new LoadFieldNode(loadMethod, metaspaceMethodField)); - - HotSpotIndirectCallTargetNode callTarget = graph().add( - new HotSpotIndirectCallTargetNode(loadmetaspaceMethod, load, arguments(), stamp(), signatureTypes, method, CallingConvention.Type.JavaCall)); - - InvokeNode invoke = graph().add(new InvokeNode(callTarget, 0)); - - invoke.setStateAfter(stateAfter()); - graph().replaceFixedWithFixed(this, invoke); - - graph().addBeforeFixed(invoke, loadmetaspaceMethod); - graph().addBeforeFixed(loadmetaspaceMethod, loadMethod); - graph().addBeforeFixed(invoke, load); - graph().addBeforeFixed(load, loadCodeBlob); - - return invoke; - } - - public static Object placeholder(@SuppressWarnings("unused") Object a1, @SuppressWarnings("unused") Object a2, @SuppressWarnings("unused") Object a3) { - return 1; - } - - @NodeIntrinsic - public static native T call(@ConstantNodeParameter Kind kind, @ConstantNodeParameter Class[] signature, Object code, Object arg1, Object arg2, Object arg3); - } diff -r ab689f0086bb -r d71c56c67921 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNmethodSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNmethodSubstitutions.java Mon Jul 08 21:08:14 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNmethodSubstitutions.java Mon Jul 08 21:12:00 2013 +0200 @@ -22,19 +22,17 @@ */ package com.oracle.graal.hotspot.replacements; -import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; +import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.Snippet.Fold; @ClassSubstitution(HotSpotNmethod.class) public class HotSpotNmethodSubstitutions { - @MethodSubstitution(isStatic = false) - public static Object execute(HotSpotInstalledCode code, final Object arg1, final Object arg2, final Object arg3) { - return HotSpotNmethodExecuteNode.call(Kind.Object, getSignature(), code, arg1, arg2, arg3); - } + @MacroSubstitution(macro = HotSpotNmethodExecuteNode.class, isStatic = true) + public static native Object executeHelper(final Object arg1, final Object arg2, final Object arg3, HotSpotInstalledCode code); @Fold private static Class[] getSignature() { diff -r ab689f0086bb -r d71c56c67921 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Mon Jul 08 21:08:14 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Mon Jul 08 21:12:00 2013 +0200 @@ -42,7 +42,7 @@ super(object, location, stamp, guard, barrierType, compress); } - private ReadNode(ValueNode object, int displacement, LocationIdentity locationIdentity, Kind kind) { + public ReadNode(ValueNode object, int displacement, LocationIdentity locationIdentity, Kind kind) { super(object, ConstantLocationNode.create(locationIdentity, kind, displacement, object.graph()), StampFactory.forKind(kind)); } diff -r ab689f0086bb -r d71c56c67921 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Mon Jul 08 21:08:14 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Mon Jul 08 21:12:00 2013 +0200 @@ -71,37 +71,39 @@ @Override public Object call(PackedFrame caller, Arguments args) { - for (;;) { - if (compiledMethod != null) { - try { - return compiledMethod.execute(this, caller, args); - } catch (InvalidInstalledCodeException ex) { - compiledMethod = null; - invokeCounter = invalidationReprofileCount; - if (TruffleFunctionInlining.getValue()) { - originalInvokeCounter += invalidationReprofileCount; - } - if (TraceTruffleCompilation.getValue()) { - OUT.printf("[truffle] invalidated %-48s |Alive %5.0fms\n", rootNode, (System.nanoTime() - timeCompilationFinished) / 1e6); - } + if (compiledMethod != null) { + try { + return compiledMethod.execute(this, caller, args); + } catch (InvalidInstalledCodeException ex) { + compiledMethod = null; + invokeCounter = invalidationReprofileCount; + if (TruffleFunctionInlining.getValue()) { + originalInvokeCounter += invalidationReprofileCount; + } + if (TraceTruffleCompilation.getValue()) { + OUT.printf("[truffle] invalidated %-48s |Alive %5.0fms\n", rootNode, (System.nanoTime() - timeCompilationFinished) / 1e6); } + return call(caller, args); + } + } else { + return interpreterCall(caller, args); + } + } + + private Object interpreterCall(PackedFrame caller, Arguments args) { + invokeCounter--; + loopAndInvokeCounter--; + if (disableCompilation || loopAndInvokeCounter > 0 || invokeCounter > 0) { + return executeHelper(caller, args); + } else { + if (TruffleFunctionInlining.getValue() && inline()) { + invokeCounter = 2; + loopAndInvokeCounter = inliningReprofileCount; + originalInvokeCounter = inliningReprofileCount; } else { - invokeCounter--; - loopAndInvokeCounter--; - if (disableCompilation || loopAndInvokeCounter > 0 || invokeCounter > 0) { - return executeHelper(caller, args); - } else { - if (TruffleFunctionInlining.getValue()) { - if (inline()) { - invokeCounter = 2; - loopAndInvokeCounter = inliningReprofileCount; - originalInvokeCounter = inliningReprofileCount; - continue; - } - } - compile(); - } + compile(); } + return call(caller, args); } } diff -r ab689f0086bb -r d71c56c67921 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java Mon Jul 08 21:08:14 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java Mon Jul 08 21:12:00 2013 +0200 @@ -33,7 +33,7 @@ public class OptimizedCallTargetSubstitutions { @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false) - public static native Object call(OptimizedCallTarget target, PackedFrame caller, Arguments args); + public static native Object interpreterCall(OptimizedCallTarget target, PackedFrame caller, Arguments args); @MethodSubstitution private static FrameWithoutBoxing createFrame(FrameDescriptor descriptor, PackedFrame caller, Arguments args) { diff -r ab689f0086bb -r d71c56c67921 src/cpu/x86/vm/graalCodeInstaller_x86.hpp --- a/src/cpu/x86/vm/graalCodeInstaller_x86.hpp Mon Jul 08 21:08:14 2013 +0200 +++ b/src/cpu/x86/vm/graalCodeInstaller_x86.hpp Mon Jul 08 21:12:00 2013 +0200 @@ -179,7 +179,6 @@ break; } default: - fatal("invalid _next_call_type value"); break; } }