diff graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java @ 14746:7544068e1a91

Perform de-virtualization of calls only in canonicalizer and not in graph builder
author Christian Wimmer <christian.wimmer@oracle.com>
date Tue, 25 Mar 2014 13:32:32 -0700
parents fd7fcd2d2072
children 8db6e76cb658
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Tue Mar 25 11:50:57 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Tue Mar 25 13:32:32 2014 -0700
@@ -126,15 +126,28 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        if (!isStatic()) {
+        if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) {
+            // attempt to devirtualize the call
+
+            // check for trivial cases (e.g. final methods, nonvirtual methods)
+            if (targetMethod.canBeStaticallyBound()) {
+                invokeKind = InvokeKind.Special;
+                return this;
+            }
+
+            // check if the exact type of the receiver can be determined
             ValueNode receiver = receiver();
-            if (receiver != null && ObjectStamp.isExactType(receiver) && ObjectStamp.typeOrNull(receiver) != null) {
-                if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) {
-                    ResolvedJavaMethod method = ObjectStamp.typeOrNull(receiver).resolveMethod(targetMethod);
-                    if (method != null) {
-                        invokeKind = InvokeKind.Special;
-                        targetMethod = method;
-                    }
+            ResolvedJavaType exact = targetMethod.getDeclaringClass().asExactType();
+            if (exact == null && ObjectStamp.isExactType(receiver)) {
+                exact = ObjectStamp.typeOrNull(receiver);
+            }
+            if (exact != null) {
+                // either the holder class is exact, or the receiver object has an exact type
+                ResolvedJavaMethod exactMethod = exact.resolveMethod(targetMethod);
+                if (exactMethod != null) {
+                    invokeKind = InvokeKind.Special;
+                    targetMethod = exactMethod;
+                    return this;
                 }
             }
         }