changeset 9784:747b2517feae

use invoker's stamp if target's return stamp is of different type
author twisti
date Tue, 21 May 2013 17:56:37 -0700
parents 5402504894fe
children ecd5cd2806e8
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java
diffstat 2 files changed, 27 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- 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;
     }
--- 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;