# HG changeset patch # User Christian Wimmer # Date 1347659147 25200 # Node ID 823a2978e7badaebf89ad7001b515696ed68ce62 # Parent e5768e9361478592890341b3ba488a348d8d84e2 Lowering of call targets to direct / indirect call targets diff -r e5768e936147 -r 823a2978e7ba graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/NestedLoopTest.java --- 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; } } diff -r e5768e936147 -r 823a2978e7ba graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- 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 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 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; diff -r e5768e936147 -r 823a2978e7ba graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/IdentifyBoxingPhase.java --- 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"; diff -r e5768e936147 -r 823a2978e7ba graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/InliningPhase.java --- 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++; } diff -r e5768e936147 -r 823a2978e7ba graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/IntrinsificationPhase.java --- 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); } } diff -r e5768e936147 -r 823a2978e7ba graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java --- 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 arguments, Value targetAddress, LIRFrameState info, CallPositionListener cpl) { if (isConstant(targetAddress)) { append(new DirectCallOp(targetMethod, result, arguments.toArray(new Value[arguments.size()]), info, cpl)); diff -r e5768e936147 -r 823a2978e7ba graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java --- 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 parameters = callTarget.arguments(); ValueNode firstParam = parameters.size() <= 0 ? null : parameters.get(0); diff -r e5768e936147 -r 823a2978e7ba graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- 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 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; diff -r e5768e936147 -r 823a2978e7ba graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotDirectCallTargetNode.java --- /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 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; + } +} diff -r e5768e936147 -r 823a2978e7ba graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotIndirectCallTargetNode.java --- /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 arguments, Stamp returnStamp, Kind[] signature, Object target, Type callType) { + super(computedAddress, arguments, returnStamp, signature, target, callType); + this.methodOop = methodOop; + } + + public ValueNode methodOop() { + return methodOop; + } +} diff -r e5768e936147 -r 823a2978e7ba graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java --- 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 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)); } } diff -r e5768e936147 -r 823a2978e7ba graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractCallTargetNode.java --- /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 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; + } +} diff -r e5768e936147 -r 823a2978e7ba graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java --- 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 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 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) { diff -r e5768e936147 -r 823a2978e7ba graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DirectCallTargetNode.java --- /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 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"; + } + } +} diff -r e5768e936147 -r 823a2978e7ba graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IndirectCallTargetNode.java --- /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 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"; + } + } +} diff -r e5768e936147 -r 823a2978e7ba graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java --- 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(); diff -r e5768e936147 -r 823a2978e7ba graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java --- 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 getDebugProperties(Map map) { Map 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; diff -r e5768e936147 -r 823a2978e7ba graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java --- 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 getDebugProperties(Map map) { Map 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) { diff -r e5768e936147 -r 823a2978e7ba graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java --- 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(); + } } diff -r e5768e936147 -r 823a2978e7ba graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java --- 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); diff -r e5768e936147 -r 823a2978e7ba graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java --- 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;