changeset 16183:b1be2a46cc5c

canonicalize LoadMethodNodes
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Tue, 24 Jun 2014 11:28:00 -0700
parents 0a7e9347f8d0
children 8fde32ece68e
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java
diffstat 2 files changed, 54 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Tue Jun 24 13:23:58 2014 -0400
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Tue Jun 24 11:28:00 2014 -0700
@@ -229,6 +229,12 @@
                 return runtime.getHostProviders().getMetaAccess().lookupJavaType((Class<?>) obj);
             }
         }
+        if (constant instanceof HotSpotMetaspaceConstant) {
+            Object obj = HotSpotMetaspaceConstant.getMetaspaceObject(constant);
+            if (obj instanceof HotSpotResolvedObjectType) {
+                return (ResolvedJavaType) obj;
+            }
+        }
         return null;
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java	Tue Jun 24 13:23:58 2014 -0400
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java	Tue Jun 24 11:28:00 2014 -0700
@@ -24,13 +24,16 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 
 /**
  * Loads a method from the virtual method table of a given hub.
  */
-public final class LoadMethodNode extends FixedWithNextNode implements Lowerable {
+public final class LoadMethodNode extends FixedWithNextNode implements Lowerable, Canonicalizable {
 
     @Input private ValueNode hub;
     private final ResolvedJavaMethod method;
@@ -55,6 +58,50 @@
         tool.getLowerer().lower(this, tool);
     }
 
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
+        if (hub instanceof LoadHubNode) {
+            ValueNode object = ((LoadHubNode) hub).object();
+            ResolvedJavaType type = StampTool.typeOrNull(object);
+            if (StampTool.isExactType(object)) {
+                return resolveExactMethod(tool, type);
+            }
+            if (type != null && tool.assumptions().useOptimisticAssumptions()) {
+                ResolvedJavaMethod resolvedMethod = type.findUniqueConcreteMethod(method);
+                if (resolvedMethod != null && !type.isInterface() && method.getDeclaringClass().isAssignableFrom(type)) {
+                    tool.assumptions().recordConcreteMethod(method, type, resolvedMethod);
+                    return ConstantNode.forConstant(resolvedMethod.getEncoding(), tool.getMetaAccess(), graph());
+                }
+            }
+        }
+        if (hub.isConstant()) {
+            return resolveExactMethod(tool, tool.getConstantReflection().asJavaType(hub.asConstant()));
+        }
+
+        return this;
+    }
+
+    /**
+     * Find the method which would be loaded.
+     *
+     * @param tool
+     * @param type the exact type of object being loaded from
+     * @return the method which would be invoked for {@code type} or null if it doesn't implement
+     *         the method
+     */
+    private Node resolveExactMethod(CanonicalizerTool tool, ResolvedJavaType type) {
+        ResolvedJavaMethod newMethod = type.resolveMethod(method, type);
+        if (newMethod == null) {
+            /*
+             * This really represent a misuse of LoadMethod since we're loading from a class which
+             * isn't known to implement the original method but for now at least fold it away.
+             */
+            return ConstantNode.forConstant(Constant.NULL_OBJECT, null, graph());
+        } else {
+            return ConstantNode.forConstant(newMethod.getEncoding(), tool.getMetaAccess(), graph());
+        }
+    }
+
     public ResolvedJavaMethod getMethod() {
         return method;
     }