changeset 6409:823a2978e7ba

Lowering of call targets to direct / indirect call targets
author Christian Wimmer <christian.wimmer@oracle.com>
date Fri, 14 Sep 2012 14:45:47 -0700
parents e5768e936147
children debe42b2b92f
files graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/NestedLoopTest.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/IdentifyBoxingPhase.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/InliningPhase.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/IntrinsificationPhase.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotDirectCallTargetNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotIndirectCallTargetNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractCallTargetNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DirectCallTargetNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IndirectCallTargetNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java
diffstat 21 files changed, 411 insertions(+), 129 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/NestedLoopTest.java	Fri Sep 14 14:21:33 2012 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/NestedLoopTest.java	Fri Sep 14 14:45:47 2012 -0700
@@ -135,7 +135,7 @@
 
     private static Invoke getInvoke(String name, StructuredGraph graph) {
         for (Invoke invoke : graph.getInvokes()) {
-            if (invoke.callTarget().targetMethod().name().equals(name)) {
+            if (invoke.methodCallTarget().targetMethod().name().equals(name)) {
                 return invoke;
             }
         }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Fri Sep 14 14:21:33 2012 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Fri Sep 14 14:45:47 2012 -0700
@@ -829,7 +829,7 @@
     public abstract Variable emitCMove(Value leftVal, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue);
 
     protected FrameState stateBeforeCallWithArguments(FrameState stateAfter, MethodCallTargetNode call, int bci) {
-        return stateAfter.duplicateModified(bci, stateAfter.rethrowException(), call.returnKind(), toJVMArgumentStack(call.targetMethod().signature(), call.isStatic(), call.arguments()));
+        return stateAfter.duplicateModified(bci, stateAfter.rethrowException(), call.returnStamp().kind(), toJVMArgumentStack(call.targetMethod().signature(), call.isStatic(), call.arguments()));
     }
 
     private static ValueNode[] toJVMArgumentStack(Signature signature, boolean isStatic, NodeInputList<ValueNode> arguments) {
@@ -863,7 +863,41 @@
 
     @Override
     public void emitInvoke(Invoke x) {
-        MethodCallTargetNode callTarget = x.callTarget();
+        if (GraalOptions.XIRLowerInvokes) {
+            emitInvokeXIR(x);
+            return;
+        }
+
+        AbstractCallTargetNode callTarget = (AbstractCallTargetNode) x.callTarget();
+        Kind[] signature = callTarget.signature();
+        CallingConvention cc = frameMap.registerConfig.getCallingConvention(callTarget.callType(), signature, target(), false);
+        frameMap.callsMethod(cc, callTarget.callType());
+
+        List<Value> argList = visitInvokeArguments(cc, callTarget.arguments());
+        Value[] parameters = argList.toArray(new Value[argList.size()]);
+
+        LIRFrameState callState = stateFor(x.stateDuring(), null, x instanceof InvokeWithExceptionNode ? getLIRBlock(((InvokeWithExceptionNode) x).exceptionEdge()) : null, x.leafGraphId());
+        Value result = resultOperandFor(x.node().kind());
+
+        if (callTarget instanceof DirectCallTargetNode) {
+            emitDirectCall((DirectCallTargetNode) callTarget, result, parameters, callState);
+        } else if (callTarget instanceof IndirectCallTargetNode) {
+            emitIndirectCall((IndirectCallTargetNode) callTarget, result, parameters, callState);
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        if (isLegal(result)) {
+            setResult(x.node(), emitMove(result));
+        }
+    }
+
+    protected abstract void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, LIRFrameState callState);
+
+    protected abstract void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, LIRFrameState callState);
+
+    public void emitInvokeXIR(Invoke x) {
+        MethodCallTargetNode callTarget = x.methodCallTarget();
         JavaMethod targetMethod = callTarget.targetMethod();
 
         XirSnippet snippet = null;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/IdentifyBoxingPhase.java	Fri Sep 14 14:21:33 2012 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/IdentifyBoxingPhase.java	Fri Sep 14 14:45:47 2012 -0700
@@ -46,7 +46,10 @@
     }
 
     public void tryIntrinsify(Invoke invoke) {
-        MethodCallTargetNode callTarget = invoke.callTarget();
+        if (!(invoke.callTarget() instanceof MethodCallTargetNode)) {
+            return;
+        }
+        MethodCallTargetNode callTarget = invoke.methodCallTarget();
         ResolvedJavaMethod targetMethod = callTarget.targetMethod();
         if (pool.isSpecialMethod(targetMethod)) {
             assert callTarget.arguments().size() == 1 : "boxing/unboxing method must have exactly one argument";
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/InliningPhase.java	Fri Sep 14 14:21:33 2012 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/InliningPhase.java	Fri Sep 14 14:45:47 2012 -0700
@@ -359,8 +359,8 @@
 
             double maxSize = GraalOptions.MaximumGreedyInlineSize;
             if (GraalOptions.InliningBonusPerTransferredValue != 0) {
-                Signature signature = info.invoke.callTarget().targetMethod().signature();
-                int transferredValues = signature.argumentCount(!Modifier.isStatic(info.invoke.callTarget().targetMethod().accessFlags()));
+                Signature signature = info.invoke.methodCallTarget().targetMethod().signature();
+                int transferredValues = signature.argumentCount(!Modifier.isStatic(info.invoke.methodCallTarget().targetMethod().accessFlags()));
                 if (signature.returnKind() != Kind.Void) {
                     transferredValues++;
                 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/IntrinsificationPhase.java	Fri Sep 14 14:21:33 2012 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/IntrinsificationPhase.java	Fri Sep 14 14:45:47 2012 -0700
@@ -27,6 +27,7 @@
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 
 public class IntrinsificationPhase extends Phase {
@@ -52,9 +53,8 @@
     }
 
     private static void tryIntrinsify(Invoke invoke, GraalCodeCacheProvider runtime) {
-        ResolvedJavaMethod target = invoke.callTarget().targetMethod();
-        if (target != null) {
-            tryIntrinsify(invoke, target, runtime);
+        if (invoke.callTarget() instanceof MethodCallTargetNode && invoke.methodCallTarget().targetMethod() != null) {
+            tryIntrinsify(invoke, invoke.methodCallTarget().targetMethod(), runtime);
         }
     }
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java	Fri Sep 14 14:21:33 2012 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java	Fri Sep 14 14:45:47 2012 -0700
@@ -547,6 +547,19 @@
     }
 
     @Override
+    protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, LIRFrameState callState) {
+        append(new DirectCallOp(callTarget.target(), result, parameters, callState, null));
+    }
+
+    @Override
+    protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, LIRFrameState callState) {
+        // The current register allocator cannot handle variables at call sites, need a fixed register.
+        Value targetAddress = AMD64.rax.asValue();
+        emitMove(operand(callTarget.computedAddress()), targetAddress);
+        append(new IndirectCallOp(callTarget.target(), result, parameters, targetAddress, callState, null));
+    }
+
+    @Override
     protected void emitCall(Object targetMethod, Value result, List<Value> arguments, Value targetAddress, LIRFrameState info, CallPositionListener cpl) {
         if (isConstant(targetAddress)) {
             append(new DirectCallOp(targetMethod, result, arguments.toArray(new Value[arguments.size()]), info, cpl));
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java	Fri Sep 14 14:21:33 2012 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java	Fri Sep 14 14:45:47 2012 -0700
@@ -189,7 +189,7 @@
         public void inline(StructuredGraph graph, GraalCodeCacheProvider runtime, InliningCallback callback) {
             // receiver null check must be before the type check
             InliningUtil.receiverNullCheck(invoke);
-            ValueNode receiver = invoke.callTarget().receiver();
+            ValueNode receiver = invoke.methodCallTarget().receiver();
             ReadHubNode objectClass = graph.add(new ReadHubNode(receiver));
             IsTypeNode isTypeNode = graph.unique(new IsTypeNode(objectClass, type));
             FixedGuardNode guard = graph.add(new FixedGuardNode(isTypeNode, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile, invoke.leafGraphId()));
@@ -272,7 +272,7 @@
         private void inlineMultipleMethods(StructuredGraph graph, GraalCodeCacheProvider runtime, InliningCallback callback, int numberOfMethods, boolean hasReturnValue) {
             FixedNode continuation = invoke.next();
 
-            ValueNode originalReceiver = invoke.callTarget().receiver();
+            ValueNode originalReceiver = invoke.methodCallTarget().receiver();
             // setup merge and phi nodes for results and exceptions
             MergeNode returnMerge = graph.add(new MergeNode());
             returnMerge.setProbability(invoke.probability());
@@ -333,7 +333,7 @@
             }
 
             // replace the invoke with a switch on the type of the actual receiver
-            ReadHubNode objectClassNode = graph.add(new ReadHubNode(invoke.callTarget().receiver()));
+            ReadHubNode objectClassNode = graph.add(new ReadHubNode(invoke.methodCallTarget().receiver()));
             graph.addBeforeFixed(invoke.node(), objectClassNode);
             FixedNode dispatchOnType = createDispatchOnType(graph, objectClassNode, calleeEntryNodes, unknownTypeNode);
 
@@ -351,7 +351,7 @@
                 Invoke invokeForInlining = (Invoke) node.next();
 
                 ResolvedJavaType commonType = getLeastCommonType(i);
-                ValueNode receiver = invokeForInlining.callTarget().receiver();
+                ValueNode receiver = invokeForInlining.methodCallTarget().receiver();
                 boolean exact = getTypeCount(i) == 1;
                 PiNode anchoredReceiver = createAnchoredReceiver(graph, node, commonType, receiver, exact);
                 invokeForInlining.callTarget().replaceFirstInput(receiver, anchoredReceiver);
@@ -374,7 +374,7 @@
                 FixedNode current = returnMerge;
                 int opportunities = 0;
                 do {
-                    if (current instanceof InvokeNode && ((InvokeNode) current).callTarget().receiver() == originalReceiver) {
+                    if (current instanceof InvokeNode && ((InvokeNode) current).methodCallTarget().receiver() == originalReceiver) {
                         opportunities++;
                     } else if (current.inputs().contains(originalReceiver)) {
                         opportunities++;
@@ -419,7 +419,7 @@
 
             MergeNode calleeEntryNode = graph.add(new MergeNode());
             calleeEntryNode.setProbability(invoke.probability());
-            ReadHubNode objectClassNode = graph.add(new ReadHubNode(invoke.callTarget().receiver()));
+            ReadHubNode objectClassNode = graph.add(new ReadHubNode(invoke.methodCallTarget().receiver()));
             graph.addBeforeFixed(invoke.node(), objectClassNode);
 
             FixedNode unknownTypeNode = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TypeCheckedInliningViolated, invoke.leafGraphId()));
@@ -555,11 +555,11 @@
         @Override
         public void inline(StructuredGraph graph, GraalCodeCacheProvider runtime, InliningCallback callback) {
             if (Debug.isLogEnabled()) {
-                String targetName = MetaUtil.format("%H.%n(%p):%r", invoke.callTarget().targetMethod());
+                String targetName = MetaUtil.format("%H.%n(%p):%r", invoke.methodCallTarget().targetMethod());
                 String concreteName = MetaUtil.format("%H.%n(%p):%r", concrete);
                 Debug.log("recording concrete method assumption: %s on receiver type %s -> %s", targetName, context, concreteName);
             }
-            callback.recordConcreteMethodAssumption(invoke.callTarget().targetMethod(), context, concrete);
+            callback.recordConcreteMethodAssumption(invoke.methodCallTarget().targetMethod(), context, concrete);
 
             super.inline(graph, runtime, callback);
         }
@@ -584,8 +584,12 @@
      * @return an instance of InlineInfo, or null if no inlining is possible at the given invoke
      */
     public static InlineInfo getInlineInfo(Invoke invoke, int level, GraalCodeCacheProvider runtime, Assumptions assumptions, InliningCallback callback, OptimisticOptimizations optimisticOpts) {
+        if (!(invoke.callTarget() instanceof MethodCallTargetNode)) {
+            // The invoke has already been lowered , or has been created as a low-level node. We have no method information.
+            return null;
+        }
         ResolvedJavaMethod parent = invoke.stateAfter().method();
-        MethodCallTargetNode callTarget = invoke.callTarget();
+        MethodCallTargetNode callTarget = invoke.methodCallTarget();
         ResolvedJavaMethod targetMethod = callTarget.targetMethod();
         if (targetMethod == null) {
             return null;
@@ -727,15 +731,15 @@
 
     private static boolean checkInvokeConditions(Invoke invoke) {
         if (invoke.stateAfter() == null) {
-            Debug.log("not inlining %s because the invoke has no after state", methodName(invoke.callTarget().targetMethod(), invoke));
+            Debug.log("not inlining %s because the invoke has no after state", methodName(invoke.methodCallTarget().targetMethod(), invoke));
             return false;
         }
         if (invoke.predecessor() == null) {
-            Debug.log("not inlining %s because the invoke is dead code", methodName(invoke.callTarget().targetMethod(), invoke));
+            Debug.log("not inlining %s because the invoke is dead code", methodName(invoke.methodCallTarget().targetMethod(), invoke));
             return false;
         }
         if (!invoke.useForInlining()) {
-            Debug.log("not inlining %s because invoke is marked to be not used for inlining", methodName(invoke.callTarget().targetMethod(), invoke));
+            Debug.log("not inlining %s because invoke is marked to be not used for inlining", methodName(invoke.methodCallTarget().targetMethod(), invoke));
             return false;
         }
         return true;
@@ -939,7 +943,7 @@
     }
 
     public static void receiverNullCheck(Invoke invoke) {
-        MethodCallTargetNode callTarget = invoke.callTarget();
+        MethodCallTargetNode callTarget = invoke.methodCallTarget();
         StructuredGraph graph = (StructuredGraph) invoke.graph();
         NodeInputList<ValueNode> parameters = callTarget.arguments();
         ValueNode firstParam = parameters.size() <= 0 ? null : parameters.get(0);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Sep 14 14:21:33 2012 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Sep 14 14:45:47 2012 -0700
@@ -237,15 +237,17 @@
             SafeReadNode safeReadArrayLength = safeReadArrayLength(arrayLengthNode.array(), StructuredGraph.INVALID_GRAPH_ID);
             graph.replaceFixedWithFixed(arrayLengthNode, safeReadArrayLength);
         } else if (n instanceof Invoke) {
-            if (!GraalOptions.XIRLowerInvokes) {
-                Invoke invoke = (Invoke) n;
-                MethodCallTargetNode callTarget = invoke.callTarget();
+            Invoke invoke = (Invoke) n;
+            if (!GraalOptions.XIRLowerInvokes && invoke.callTarget() instanceof MethodCallTargetNode) {
+                MethodCallTargetNode callTarget = invoke.methodCallTarget();
                 NodeInputList<ValueNode> parameters = callTarget.arguments();
                 ValueNode receiver = parameters.size() <= 0 ? null : parameters.get(0);
                 if (!callTarget.isStatic() && receiver.kind() == Kind.Object && !receiver.objectStamp().nonNull()) {
                     invoke.node().dependencies().add(tool.createNullCheckGuard(receiver, invoke.leafGraphId()));
                 }
+                Kind[] signature = MetaUtil.signatureToKinds(callTarget.targetMethod().signature(), callTarget.isStatic() ? null : callTarget.targetMethod().holder().kind());
 
+                AbstractCallTargetNode loweredCallTarget = null;
                 if (callTarget.invokeKind() == InvokeKind.Virtual &&
                     GraalOptions.InlineVTableStubs &&
                     (GraalOptions.AlwaysInlineVTableStubs || invoke.isMegamorphic())) {
@@ -261,17 +263,19 @@
                         Stamp nonNullWordStamp = StampFactory.forWord(wordKind, true);
                         ReadNode methodOop = graph.add(new ReadNode(hub, LocationNode.create(LocationNode.ANY_LOCATION, wordKind, vtableEntryOffset, graph), nonNullWordStamp));
                         ReadNode compiledEntry = graph.add(new ReadNode(methodOop, LocationNode.create(LocationNode.ANY_LOCATION, wordKind, config.methodCompiledEntryOffset, graph), nonNullWordStamp));
-                        callTarget.setComputedAddress(compiledEntry);
 
-                        // Append the methodOop to the arguments so that it can be explicitly passed in RBX as
-                        // is required for all compiled calls in HotSpot.
-                        callTarget.arguments().add(methodOop);
+                        loweredCallTarget = graph.add(new HotSpotIndirectCallTargetNode(methodOop, compiledEntry, parameters, invoke.node().stamp(), signature, callTarget.targetMethod(), CallingConvention.Type.JavaCall));
 
                         graph.addBeforeFixed(invoke.node(), hub);
                         graph.addAfterFixed(hub, methodOop);
                         graph.addAfterFixed(methodOop, compiledEntry);
                     }
                 }
+
+                if (loweredCallTarget == null) {
+                    loweredCallTarget = graph.add(new HotSpotDirectCallTargetNode(parameters, invoke.node().stamp(), signature, callTarget.targetMethod(), CallingConvention.Type.JavaCall, callTarget.invokeKind()));
+                }
+                callTarget.replaceAndDelete(loweredCallTarget);
             }
         } else if (n instanceof LoadFieldNode) {
             LoadFieldNode field = (LoadFieldNode) n;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotDirectCallTargetNode.java	Fri Sep 14 14:45:47 2012 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012, 2012, 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.hotspot.nodes;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.CallingConvention.Type;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
+import com.oracle.graal.nodes.type.*;
+
+public class HotSpotDirectCallTargetNode extends DirectCallTargetNode {
+
+    private final InvokeKind invokeKind;
+
+    public HotSpotDirectCallTargetNode(List<ValueNode> arguments, Stamp returnStamp, Kind[] signature, Object target, Type callType, InvokeKind invokeKind) {
+        super(arguments, returnStamp, signature, target, callType);
+        this.invokeKind = invokeKind;
+    }
+
+    public InvokeKind invokeKind() {
+        return invokeKind;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotIndirectCallTargetNode.java	Fri Sep 14 14:45:47 2012 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012, 2012, 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.hotspot.nodes;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.CallingConvention.Type;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
+
+public class HotSpotIndirectCallTargetNode extends IndirectCallTargetNode {
+
+    @Input private ValueNode methodOop;
+
+    public HotSpotIndirectCallTargetNode(ValueNode methodOop, ValueNode computedAddress, List<ValueNode> arguments, Stamp returnStamp, Kind[] signature, Object target, Type callType) {
+        super(computedAddress, arguments, returnStamp, signature, target, callType);
+        this.methodOop = methodOop;
+    }
+
+    public ValueNode methodOop() {
+        return methodOop;
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java	Fri Sep 14 14:21:33 2012 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java	Fri Sep 14 14:45:47 2012 -0700
@@ -24,11 +24,9 @@
 
 import static com.oracle.graal.api.code.CallingConvention.Type.*;
 import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind.*;
 import static com.oracle.max.asm.target.amd64.AMD64.*;
 
 import java.lang.reflect.*;
-import java.util.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
@@ -40,12 +38,12 @@
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.counters.*;
 import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
 import com.oracle.max.asm.*;
 import com.oracle.max.asm.target.amd64.*;
 import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
@@ -126,55 +124,17 @@
         }
 
         @Override
-        public void emitInvoke(Invoke x) {
-            if (GraalOptions.XIRLowerInvokes) {
-                super.emitInvoke(x);
-                return;
-            }
-            final MethodCallTargetNode callTarget = x.callTarget();
-            final InvokeKind invokeKind = callTarget.invokeKind();
-            Kind[] signature = MetaUtil.signatureToKinds(callTarget.targetMethod().signature(), callTarget.isStatic() ? null : callTarget.targetMethod().holder().kind());
-            CallingConvention cc = frameMap.registerConfig.getCallingConvention(JavaCall, signature, target(), false);
-            frameMap.callsMethod(cc, JavaCall);
-
-            ValueNode methodOopNode = null;
-            boolean inlineVirtualCall = false;
-            if (callTarget.computedAddress() != null) {
-                // If a virtual dispatch address was computed, then an extra argument
-                // was append for passing the methodOop in RBX
-                methodOopNode = callTarget.arguments().remove(callTarget.arguments().size() - 1);
+        protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, LIRFrameState callState) {
+            append(new AMD64DirectCallOp(callTarget.target(), result, parameters, callState, ((HotSpotDirectCallTargetNode) callTarget).invokeKind(), lir));
+        }
 
-                if (invokeKind == Virtual) {
-                    inlineVirtualCall = true;
-                } else {
-                    // An invokevirtual may have been canonicalized into an invokespecial;
-                    // the methodOop argument is ignored in this case
-                    methodOopNode = null;
-                }
-            }
-
-            List<Value> argList = visitInvokeArguments(cc, callTarget.arguments());
-            Value[] parameters = argList.toArray(new Value[argList.size()]);
-
-            LIRFrameState callState = stateFor(x.stateDuring(), null, x instanceof InvokeWithExceptionNode ? getLIRBlock(((InvokeWithExceptionNode) x).exceptionEdge()) : null, x.leafGraphId());
-            Value result = resultOperandFor(x.node().kind());
-            // HotSpot needs the methodOop to be passed around in rbx for direct (inline cache patching) or indirect calls (C2I : the interpreter needs the methodOop)
-            // for the direct call the methodOop is patched in by the code installer
-            if (!inlineVirtualCall) {
-                assert methodOopNode == null;
-                append(new AMD64DirectCallOp(callTarget.targetMethod(), result, parameters, callState, invokeKind, lir));
-            } else {
-                assert methodOopNode != null;
-                Value methodOop = AMD64.rbx.asValue();
-                emitMove(operand(methodOopNode), methodOop);
-                Value targetAddress = AMD64.rax.asValue();
-                emitMove(operand(callTarget.computedAddress()), targetAddress);
-                append(new AMD64IndirectCallOp(callTarget.targetMethod(), result, parameters, methodOop, targetAddress, callState));
-            }
-
-            if (isLegal(result)) {
-                setResult(x.node(), emitMove(result));
-            }
+        @Override
+        protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, LIRFrameState callState) {
+            Value methodOop = AMD64.rbx.asValue();
+            emitMove(operand(((HotSpotIndirectCallTargetNode) callTarget).methodOop()), methodOop);
+            Value targetAddress = AMD64.rax.asValue();
+            emitMove(operand(callTarget.computedAddress()), targetAddress);
+            append(new AMD64IndirectCallOp(callTarget.target(), result, parameters, methodOop, targetAddress, callState));
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractCallTargetNode.java	Fri Sep 14 14:45:47 2012 -0700
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2012, 2012, 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.nodes;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.type.*;
+
+public abstract class AbstractCallTargetNode extends CallTargetNode {
+
+    private final Stamp returnStamp;
+    private final Kind[] signature;
+    private final Object target;
+    private final CallingConvention.Type callType;
+
+    public AbstractCallTargetNode(List<ValueNode> arguments, Stamp returnStamp, Kind[] signature, Object target, CallingConvention.Type callType) {
+        super(arguments);
+        this.returnStamp = returnStamp;
+        this.signature = signature;
+        this.target = target;
+        this.callType = callType;
+    }
+
+    @Override
+    public Stamp returnStamp() {
+        return returnStamp;
+    }
+
+    public Kind[] signature() {
+        return signature;
+    }
+
+    public Object target() {
+        return target;
+    }
+
+    public CallingConvention.Type callType() {
+        return callType;
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java	Fri Sep 14 14:21:33 2012 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java	Fri Sep 14 14:45:47 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, 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
@@ -22,7 +22,8 @@
  */
 package com.oracle.graal.nodes;
 
-import com.oracle.graal.api.meta.*;
+import java.util.*;
+
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -31,21 +32,12 @@
 
     @Input protected final NodeInputList<ValueNode> arguments;
 
-    /**
-     * The address computation for an indirect call (e.g., invokevirtual or invokeinterface).
-     */
-    @Input protected ValueNode computedAddress;
-
-    public ValueNode computedAddress() {
-        return computedAddress;
+    public CallTargetNode(ValueNode[] arguments) {
+        super(StampFactory.extension());
+        this.arguments = new NodeInputList<>(this, arguments);
     }
 
-    public void setComputedAddress(ValueNode address) {
-        updateUsages(this.computedAddress, address);
-        this.computedAddress = address;
-    }
-
-    public CallTargetNode(ValueNode[] arguments) {
+    public CallTargetNode(List<ValueNode> arguments) {
         super(StampFactory.extension());
         this.arguments = new NodeInputList<>(this, arguments);
     }
@@ -54,9 +46,12 @@
         return arguments;
     }
 
-    public abstract JavaType returnType();
+    public abstract Stamp returnStamp();
 
-    public abstract Kind returnKind();
+    /**
+     * A human-readable representation of the target, used for debug printing only.
+     */
+    public abstract String targetName();
 
     @Override
     public void generate(LIRGeneratorTool gen) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DirectCallTargetNode.java	Fri Sep 14 14:45:47 2012 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012, 2012, 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.nodes;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.type.*;
+
+public class DirectCallTargetNode extends AbstractCallTargetNode {
+
+    public DirectCallTargetNode(List<ValueNode> arguments, Stamp returnStamp, Kind[] signature, Object target, CallingConvention.Type callType) {
+        super(arguments, returnStamp, signature, target, callType);
+    }
+
+    @Override
+    public String targetName() {
+        if (target() instanceof JavaMethod) {
+            return "Direct#" + ((JavaMethod) target()).name();
+        } else if (target() != null) {
+            return "Direct#" + target().getClass().getSimpleName();
+        } else {
+            return "Direct#null";
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IndirectCallTargetNode.java	Fri Sep 14 14:45:47 2012 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012, 2012, 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.nodes;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.type.*;
+
+public class IndirectCallTargetNode extends AbstractCallTargetNode {
+
+    @Input protected ValueNode computedAddress;
+
+    public IndirectCallTargetNode(ValueNode computedAddress, List<ValueNode> arguments, Stamp returnStamp, Kind[] signature, Object target, CallingConvention.Type callType) {
+        super(arguments, returnStamp, signature, target, callType);
+        this.computedAddress = computedAddress;
+    }
+
+    public ValueNode computedAddress() {
+        return computedAddress;
+    }
+
+    @Override
+    public String targetName() {
+        if (target() instanceof JavaMethod) {
+            return "Indirect#" + ((JavaMethod) target()).name();
+        } else if (target() != null) {
+            return "Indirect#" + target().getClass().getSimpleName();
+        } else {
+            return "Indirect#null";
+        }
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java	Fri Sep 14 14:21:33 2012 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java	Fri Sep 14 14:45:47 2012 -0700
@@ -32,7 +32,12 @@
 
     void setNext(FixedNode x);
 
-    MethodCallTargetNode callTarget();
+    CallTargetNode callTarget();
+
+    /**
+     * Utility method that returns the {@link #callTarget()} cast to a {@link MethodCallTargetNode}.
+     */
+    MethodCallTargetNode methodCallTarget();
 
     int bci();
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Fri Sep 14 14:21:33 2012 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Fri Sep 14 14:45:47 2012 -0700
@@ -37,7 +37,7 @@
 @NodeInfo(nameTemplate = "Invoke#{p#targetMethod/s}")
 public final class InvokeNode extends AbstractStateSplit implements StateSplit, Node.IterableNodeType, Invoke, LIRLowerable, MemoryCheckpoint  {
 
-    @Input private final MethodCallTargetNode callTarget;
+    @Input private final CallTargetNode callTarget;
     private final int bci;
     private boolean megamorphic;
     private boolean useForInlining;
@@ -58,11 +58,17 @@
         this.useForInlining = true;
     }
 
-    public MethodCallTargetNode callTarget() {
+    @Override
+    public CallTargetNode callTarget() {
         return callTarget;
     }
 
     @Override
+    public MethodCallTargetNode methodCallTarget() {
+        return (MethodCallTargetNode) callTarget;
+    }
+
+    @Override
     public boolean isMegamorphic() {
         return megamorphic;
     }
@@ -89,8 +95,8 @@
     @Override
     public Map<Object, Object> getDebugProperties(Map<Object, Object> map) {
         Map<Object, Object> debugProperties = super.getDebugProperties(map);
-        if (callTarget != null && callTarget.targetMethod() != null) {
-            debugProperties.put("targetMethod", callTarget.targetMethod());
+        if (callTarget instanceof MethodCallTargetNode && methodCallTarget().targetMethod() != null) {
+            debugProperties.put("targetMethod", methodCallTarget().targetMethod());
         }
         return debugProperties;
     }
@@ -110,10 +116,7 @@
         if (verbosity == Verbosity.Long) {
             return super.toString(Verbosity.Short) + "(bci=" + bci() + ")";
         } else if (verbosity == Verbosity.Name) {
-            if (callTarget == null || callTarget.targetMethod() == null) {
-                return "Invoke#??Invalid!";
-            }
-            return "Invoke#" + callTarget.targetMethod().name();
+            return "Invoke#" + callTarget().targetName();
         } else {
             return super.toString(verbosity);
         }
@@ -131,7 +134,7 @@
     @Override
     public FrameState stateDuring() {
         FrameState stateAfter = stateAfter();
-        FrameState stateDuring = stateAfter.duplicateModified(bci(), stateAfter.rethrowException(), this.callTarget.targetMethod().signature().returnKind());
+        FrameState stateDuring = stateAfter.duplicateModified(bci(), stateAfter.rethrowException(), kind());
         stateDuring.setDuringCall(true);
         return stateDuring;
     }
@@ -139,7 +142,7 @@
     @Override
     public void intrinsify(Node node) {
         assert !(node instanceof ValueNode) || ((ValueNode) node).kind().isVoid() == kind().isVoid();
-        MethodCallTargetNode call = callTarget;
+        CallTargetNode call = callTarget;
         FrameState stateAfter = stateAfter();
         if (node instanceof StateSplit) {
             StateSplit stateSplit = (StateSplit) node;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Fri Sep 14 14:21:33 2012 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Fri Sep 14 14:45:47 2012 -0700
@@ -35,7 +35,7 @@
     public static final int NORMAL_EDGE = 0;
     public static final int EXCEPTION_EDGE = 1;
 
-    @Input private final MethodCallTargetNode callTarget;
+    @Input private final CallTargetNode callTarget;
     @Input private FrameState stateAfter;
     private final int bci;
     // megamorph should only be true when the compiler is sure that the call site is megamorph, and false when in doubt
@@ -43,7 +43,7 @@
     private boolean useForInlining;
     private final long leafGraphId;
 
-    public InvokeWithExceptionNode(MethodCallTargetNode callTarget, DispatchBeginNode exceptionEdge, int bci, long leafGraphId) {
+    public InvokeWithExceptionNode(CallTargetNode callTarget, DispatchBeginNode exceptionEdge, int bci, long leafGraphId) {
         super(callTarget.returnStamp(), new BeginNode[]{null, exceptionEdge}, new double[]{1.0, 0.0});
         this.bci = bci;
         this.callTarget = callTarget;
@@ -68,10 +68,14 @@
         setBlockSuccessor(NORMAL_EDGE, x);
     }
 
-    public MethodCallTargetNode callTarget() {
+    public CallTargetNode callTarget() {
         return callTarget;
     }
 
+    public MethodCallTargetNode methodCallTarget() {
+        return (MethodCallTargetNode) callTarget;
+    }
+
     @Override
     public boolean isMegamorphic() {
         return megamorphic;
@@ -102,7 +106,7 @@
         if (verbosity == Verbosity.Long) {
             return super.toString(Verbosity.Short) + "(bci=" + bci() + ")";
         } else if (verbosity == Verbosity.Name) {
-            return "Invoke!#" + callTarget.targetMethod().name();
+            return "Invoke#" + callTarget().targetName();
         } else {
             return super.toString(verbosity);
         }
@@ -151,7 +155,7 @@
 
     public FrameState stateDuring() {
         FrameState tempStateAfter = stateAfter();
-        FrameState stateDuring = tempStateAfter.duplicateModified(bci(), tempStateAfter.rethrowException(), this.callTarget.targetMethod().signature().returnKind());
+        FrameState stateDuring = tempStateAfter.duplicateModified(bci(), tempStateAfter.rethrowException(), kind());
         stateDuring.setDuringCall(true);
         return stateDuring;
     }
@@ -159,8 +163,8 @@
     @Override
     public Map<Object, Object> getDebugProperties(Map<Object, Object> map) {
         Map<Object, Object> debugProperties = super.getDebugProperties(map);
-        if (callTarget != null && callTarget.targetMethod() != null) {
-            debugProperties.put("targetMethod", callTarget.targetMethod());
+        if (callTarget instanceof MethodCallTargetNode && methodCallTarget().targetMethod() != null) {
+            debugProperties.put("targetMethod", methodCallTarget().targetMethod());
         }
         return debugProperties;
     }
@@ -174,7 +178,7 @@
     @Override
     public void intrinsify(Node node) {
         assert !(node instanceof ValueNode) || ((ValueNode) node).kind().isVoid() == kind().isVoid();
-        MethodCallTargetNode call = callTarget;
+        CallTargetNode call = callTarget;
         FrameState state = stateAfter();
         killExceptionEdge();
         if (node instanceof StateSplit) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Fri Sep 14 14:21:33 2012 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Fri Sep 14 14:45:47 2012 -0700
@@ -50,11 +50,6 @@
         this.targetMethod = targetMethod;
     }
 
-    @Override
-    public JavaType returnType() {
-        return returnType;
-    }
-
     /**
      * Gets the target method for this invocation instruction.
      * @return the target method
@@ -92,7 +87,6 @@
         return invokeKind() == InvokeKind.Static;
     }
 
-    @Override
     public Kind returnKind() {
         return targetMethod().signature().returnKind();
     }
@@ -137,6 +131,7 @@
         return this;
     }
 
+    @Override
     public Stamp returnStamp() {
         Kind returnKind = targetMethod.signature().returnKind();
         if (returnKind == Kind.Object && returnType instanceof ResolvedJavaType) {
@@ -145,4 +140,12 @@
             return StampFactory.forKind(returnKind);
         }
     }
+
+    @Override
+    public String targetName() {
+        if (targetMethod() == null) {
+            return "??Invalid!";
+        }
+        return targetMethod().name();
+    }
 }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java	Fri Sep 14 14:21:33 2012 -0700
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java	Fri Sep 14 14:45:47 2012 -0700
@@ -169,7 +169,7 @@
                 new SnippetIntrinsificationPhase(runtime, pool, true).apply(graph);
 
                 for (Invoke invoke : graph.getInvokes()) {
-                    MethodCallTargetNode callTarget = invoke.callTarget();
+                    MethodCallTargetNode callTarget = invoke.methodCallTarget();
                     ResolvedJavaMethod callee = callTarget.targetMethod();
                     if (policy.shouldInline(callee, method)) {
                         StructuredGraph targetGraph = parseGraph(callee, policy);
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java	Fri Sep 14 14:21:33 2012 -0700
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java	Fri Sep 14 14:45:47 2012 -0700
@@ -56,7 +56,9 @@
     protected void run(StructuredGraph graph) {
         for (Invoke i : graph.getInvokes()) {
             try {
-                tryIntrinsify(i);
+                if (i.callTarget() instanceof MethodCallTargetNode) {
+                    tryIntrinsify(i);
+                }
             } catch (NonConstantParameterError t) {
                 if (!intrinsificationOrFoldingCanBeDeferred) {
                     throw t;
@@ -78,7 +80,7 @@
     }
 
     private void tryIntrinsify(Invoke invoke) {
-        ResolvedJavaMethod target = invoke.callTarget().targetMethod();
+        ResolvedJavaMethod target = invoke.methodCallTarget().targetMethod();
         NodeIntrinsic intrinsic = target.getAnnotation(Node.NodeIntrinsic.class);
         if (intrinsic != null) {
             assert target.getAnnotation(Fold.class) == null;
@@ -104,7 +106,7 @@
             // Prepare the arguments for the reflective method call
             Object[] arguments = prepareArguments(invoke, parameterTypes, target, true);
             Object receiver = null;
-            if (!invoke.callTarget().isStatic()) {
+            if (!invoke.methodCallTarget().isStatic()) {
                 receiver = arguments[0];
                 arguments = Arrays.asList(arguments).subList(1, arguments.length).toArray();
             }
@@ -137,13 +139,13 @@
         Object[] reflectionCallArguments = new Object[arguments.size()];
         for (int i = 0; i < reflectionCallArguments.length; ++i) {
             int parameterIndex = i;
-            if (!invoke.callTarget().isStatic()) {
+            if (!invoke.methodCallTarget().isStatic()) {
                 parameterIndex--;
             }
             ValueNode argument = tryBoxingElimination(parameterIndex, target, arguments.get(i));
             if (folding || MetaUtil.getParameterAnnotation(ConstantNodeParameter.class, parameterIndex, target) != null) {
                 if (!(argument instanceof ConstantNode)) {
-                    throw new NonConstantParameterError("parameter " + parameterIndex + " must be a compile time constant for calling " + invoke.callTarget().targetMethod() + " at " + sourceLocation(invoke.node()) + ": " + argument);
+                    throw new NonConstantParameterError("parameter " + parameterIndex + " must be a compile time constant for calling " + invoke.methodCallTarget().targetMethod() + " at " + sourceLocation(invoke.node()) + ": " + argument);
                 }
                 ConstantNode constantNode = (ConstantNode) argument;
                 Constant constant = constantNode.asConstant();
@@ -193,7 +195,7 @@
                         if (node.usages().size() == 2) {
                             if (node instanceof Invoke) {
                                 Invoke invokeNode = (Invoke) node;
-                                MethodCallTargetNode callTarget = invokeNode.callTarget();
+                                MethodCallTargetNode callTarget = invokeNode.methodCallTarget();
                                 if (pool.isBoxingMethod(callTarget.targetMethod())) {
                                     FrameState stateAfter = invokeNode.stateAfter();
                                     assert stateAfter.usages().size() == 1;