changeset 10654:d71c56c67921

Improve performance of calling Truffle call targets.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Mon, 08 Jul 2013 21:12:00 +0200
parents ab689f0086bb
children 2abf1c8b062a
files graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotNmethodExecuteNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNmethodSubstitutions.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java src/cpu/x86/vm/graalCodeInstaller_x86.hpp
diffstat 10 files changed, 86 insertions(+), 120 deletions(-) [+]
line wrap: on
line diff
--- 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));
     }
--- 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
--- 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;
 }
--- 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) {
--- 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> T call(@ConstantNodeParameter Kind kind, @ConstantNodeParameter Class[] signature, Object code, Object arg1, Object arg2, Object arg3);
-
 }
--- 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() {
--- 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));
     }
 
--- 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);
         }
     }
 
--- 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) {
--- 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;
   }
 }