changeset 18713:cbb097347545

Convert compare against Class to compare against Klass
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Wed, 17 Dec 2014 19:57:58 -0800
parents 37a5c6b8b930
children b56e88144e0a
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HubGetClassNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java
diffstat 5 files changed, 92 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java	Wed Dec 17 13:39:48 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java	Wed Dec 17 19:57:58 2014 -0800
@@ -25,6 +25,7 @@
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.calc.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.hotspot.*;
@@ -34,6 +35,7 @@
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.HeapAccess.BarrierType;
+import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 
@@ -44,7 +46,7 @@
  * {@link ReadNode#canonicalizeRead(ValueNode, LocationNode, ValueNode, CanonicalizerTool)}.
  */
 @NodeInfo
-public class ClassGetHubNode extends FloatingGuardedNode implements Lowerable, Canonicalizable {
+public class ClassGetHubNode extends FloatingGuardedNode implements Lowerable, Canonicalizable, ConvertNode {
     @Input protected ValueNode clazz;
     protected final HotSpotGraalRuntimeProvider runtime;
 
@@ -110,4 +112,36 @@
     @NodeIntrinsic
     public static native KlassPointer readClass(Class<?> clazz, GuardingNode guard);
 
+    public ValueNode getValue() {
+        return clazz;
+    }
+
+    public Constant convert(Constant c) {
+        ResolvedJavaType exactType = runtime.getHostProviders().getConstantReflection().asJavaType(c);
+        if (exactType instanceof HotSpotResolvedObjectType) {
+            HotSpotResolvedObjectType objectType = (HotSpotResolvedObjectType) exactType;
+            return objectType.getObjectHub();
+        } else {
+            assert exactType instanceof HotSpotResolvedPrimitiveType;
+            return JavaConstant.NULL_POINTER;
+        }
+    }
+
+    public Constant reverse(Constant c) {
+        assert !c.equals(JavaConstant.NULL_POINTER);
+        ResolvedJavaType objectType = runtime.getHostProviders().getConstantReflection().asJavaType(c);
+        return objectType.getJavaClass();
+    }
+
+    public boolean isLossless() {
+        return false;
+    }
+
+    @Override
+    public boolean preservesOrder(Condition op, Constant value) {
+        assert op == Condition.EQ || op == Condition.NE;
+        ResolvedJavaType exactType = runtime.getHostProviders().getConstantReflection().asJavaType(value);
+        return exactType instanceof HotSpotResolvedObjectType;
+    }
+
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HubGetClassNode.java	Wed Dec 17 13:39:48 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HubGetClassNode.java	Wed Dec 17 19:57:58 2014 -0800
@@ -29,10 +29,12 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.word.*;
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.HeapAccess.BarrierType;
+import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 
@@ -41,18 +43,18 @@
  * also used by {@link ClassGetHubNode} to eliminate chains of {@code klass._java_mirror._klass}.
  */
 @NodeInfo
-public class HubGetClassNode extends FloatingGuardedNode implements Lowerable, Canonicalizable {
+public class HubGetClassNode extends FloatingGuardedNode implements Lowerable, Canonicalizable, ConvertNode {
     @Input protected ValueNode hub;
-    protected final HotSpotVMConfig config;
+    protected final HotSpotGraalRuntimeProvider runtime;
 
-    public static HubGetClassNode create(@InjectedNodeParameter MetaAccessProvider metaAccess, @InjectedNodeParameter HotSpotVMConfig config, ValueNode hub) {
-        return new HubGetClassNode(hub, metaAccess, config);
+    public static HubGetClassNode create(@InjectedNodeParameter MetaAccessProvider metaAccess, @InjectedNodeParameter HotSpotGraalRuntimeProvider runtime, ValueNode hub) {
+        return new HubGetClassNode(hub, metaAccess, runtime);
     }
 
-    protected HubGetClassNode(ValueNode hub, MetaAccessProvider metaAccess, HotSpotVMConfig config) {
+    protected HubGetClassNode(ValueNode hub, MetaAccessProvider metaAccess, HotSpotGraalRuntimeProvider runtime) {
         super(StampFactory.declaredNonNull(metaAccess.lookupJavaType(Class.class)), null);
         this.hub = hub;
-        this.config = config;
+        this.runtime = runtime;
     }
 
     public ValueNode getHub() {
@@ -81,7 +83,7 @@
             return;
         }
 
-        LocationNode location = ConstantLocationNode.create(CLASS_MIRROR_LOCATION, config.classMirrorOffset, graph());
+        LocationNode location = ConstantLocationNode.create(CLASS_MIRROR_LOCATION, runtime.getConfig().classMirrorOffset, graph());
         assert !hub.isConstant();
         FloatingReadNode read = graph().unique(FloatingReadNode.create(hub, location, null, stamp(), getGuard(), BarrierType.NONE));
         graph().replaceFloating(this, read);
@@ -90,4 +92,32 @@
     @NodeIntrinsic
     public static native Class<?> readClass(KlassPointer hub);
 
+    @Override
+    public ValueNode getValue() {
+        return hub;
+    }
+
+    @Override
+    public Constant convert(Constant c) {
+        return runtime.getHostProviders().getConstantReflection().asJavaType(c).getJavaClass();
+    }
+
+    @Override
+    public Constant reverse(Constant c) {
+        ResolvedJavaType type = runtime.getHostProviders().getConstantReflection().asJavaType(c);
+        if (type instanceof HotSpotResolvedObjectType) {
+            return ((HotSpotResolvedObjectType) type).getObjectHub();
+        } else {
+            assert type instanceof HotSpotResolvedPrimitiveType;
+            return JavaConstant.NULL_POINTER;
+        }
+    }
+
+    @Override
+    public boolean isLossless() {
+        /*
+         * Any concrete Klass* has a corresponding java.lang.Class
+         */
+        return true;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Wed Dec 17 13:39:48 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Wed Dec 17 19:57:58 2014 -0800
@@ -137,7 +137,7 @@
     }
 
     private ConstantNode canonicalConvertConstant(CanonicalizerTool tool, ConvertNode convert, Constant constant) {
-        if (convert.preservesOrder(condition())) {
+        if (convert.preservesOrder(condition(), constant)) {
             Constant reverseConverted = convert.reverse(constant);
             if (convert.convert(reverseConverted).equals(constant)) {
                 return ConstantNode.forConstant(convert.getValue().stamp(), reverseConverted, tool.getMetaAccess());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java	Wed Dec 17 13:39:48 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java	Wed Dec 17 19:57:58 2014 -0800
@@ -56,5 +56,16 @@
         return isLossless();
     }
 
+    /**
+     * Check whether a conversion preserves comparison order against a particular constant value.
+     *
+     * @param op a comparison operator
+     * @param value
+     * @return true iff (c1 op value) == (convert(c1) op convert(value)) for value and all c1
+     */
+    default boolean preservesOrder(Condition op, Constant value) {
+        return preservesOrder(op);
+    }
+
     ValueNode asNode();
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java	Wed Dec 17 13:39:48 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java	Wed Dec 17 19:57:58 2014 -0800
@@ -23,6 +23,7 @@
 package com.oracle.graal.nodes.calc;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
@@ -84,7 +85,7 @@
                 /*
                  * One of the two objects has identity, the other doesn't. In code, this looks like
                  * "Integer.valueOf(a) == new Integer(b)", which is always false.
-                 * 
+                 *
                  * In other words: an object created via valueOf can never be equal to one created
                  * by new in the same compilation unit.
                  */
@@ -111,6 +112,11 @@
 
     @Override
     protected CompareNode duplicateModified(ValueNode newX, ValueNode newY) {
-        return ObjectEqualsNode.create(newX, newY);
+        if (newX.stamp() instanceof ObjectStamp && newY.stamp() instanceof ObjectStamp) {
+            return ObjectEqualsNode.create(newX, newY);
+        } else if (newX.stamp() instanceof AbstractPointerStamp && newY.stamp() instanceof AbstractPointerStamp) {
+            return PointerEqualsNode.create(newX, newY);
+        }
+        throw GraalInternalError.shouldNotReachHere();
     }
 }