# HG changeset patch # User twisti # Date 1369184197 25200 # Node ID 747b2517feaefb04375408dab678eeb6bb53579b # Parent 5402504894fe7487fd082993aae25f4d9f7f8267 use invoker's stamp if target's return stamp is of different type diff -r 5402504894fe -r 747b2517feae graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java Tue May 21 19:51:00 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java Tue May 21 17:56:37 2013 -0700 @@ -273,9 +273,20 @@ ValueNode[] args = replacementArguments.toArray(new ValueNode[replacementArguments.size()]); callTarget = new SelfReplacingMethodCallTargetNode(invokeKind, targetMethod, targetArguments, returnType, replacementTargetMethod, args, replacementReturnType); } + graph().add(callTarget); - graph().add(callTarget); - InvokeNode invoke = graph().add(new InvokeNode(callTarget, getBci())); + // The call target can have a different return type than the invoker, + // e.g. the target returns an Object but the invoker void. In this case + // we need to use the stamp of the invoker. Note: always using the + // invoker's stamp would be wrong because it's a less concrete type + // (usually java.lang.Object). + InvokeNode invoke; + if (callTarget.returnStamp().kind() != stamp().kind()) { + invoke = new InvokeNode(callTarget, getBci(), stamp()); + } else { + invoke = new InvokeNode(callTarget, getBci()); + } + graph().add(invoke); invoke.setStateAfter(stateAfter()); return invoke; } diff -r 5402504894fe -r 747b2517feae 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 Tue May 21 19:51:00 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Tue May 21 17:56:37 2013 -0700 @@ -29,6 +29,7 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.Stamp; import com.oracle.graal.nodes.util.*; /** @@ -47,11 +48,22 @@ /** * Constructs a new Invoke instruction. * + * @param callTarget the target method being called * @param bci the bytecode index of the original invoke (used for debug infos) - * @param callTarget the target method being called */ public InvokeNode(CallTargetNode callTarget, int bci) { - super(callTarget.returnStamp()); + this(callTarget, bci, callTarget.returnStamp()); + } + + /** + * Constructs a new Invoke instruction. + * + * @param callTarget the target method being called + * @param bci the bytecode index of the original invoke (used for debug infos) + * @param stamp the stamp to be used for this value + */ + public InvokeNode(CallTargetNode callTarget, int bci, Stamp stamp) { + super(stamp); this.callTarget = callTarget; this.bci = bci; this.polymorphic = false;