changeset 5338:17a84768b1cd

fix canonicalization of InstanceOfNode
author Lukas Stadler <lukas.stadler@jku.at>
date Wed, 02 May 2012 14:53:20 +0200
parents a49538b9073f
children e8f80481326d
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java
diffstat 2 files changed, 34 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Wed May 02 14:47:04 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Wed May 02 14:53:20 2012 +0200
@@ -65,17 +65,44 @@
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         assert object() != null : this;
+
         RiResolvedType exact = object().exactType();
         if (exact != null) {
-            boolean result = exact.isSubtypeOf(targetClass());
-            if (result != negated) {
-                // The instanceof check reduces to a null check.
-                return graph().unique(new NullCheckNode(object(), false));
+            boolean subType = exact.isSubtypeOf(targetClass());
+
+            if (subType) {
+                if (object().stamp().nonNull()) {
+                    // the instanceOf matches, so return true (or false, for the negated case)
+                    return ConstantNode.forBoolean(!negated, graph());
+                } else {
+                    // the instanceof matches if the object is non-null, so return true (or false, for the negated case) depending on the null-ness.
+                    return graph().unique(new NullCheckNode(object(), negated));
+                }
             } else {
-                // The instanceof check can never succeed.
-                return ConstantNode.forBoolean(false, graph());
+                // since this type check failed for an exact type we know that it can never succeed at run time.
+                // we also don't care about null values, since they will also make the check fail.
+                // so return false (or true, for the negated case)
+                return ConstantNode.forBoolean(negated, graph());
+            }
+        } else {
+            RiResolvedType declared = object().declaredType();
+            if (declared != null) {
+                boolean subType = declared.isSubtypeOf(targetClass());
+
+                if (subType) {
+                    if (object().stamp().nonNull()) {
+                        // the instanceOf matches, so return true (or false, for the negated case)
+                        return ConstantNode.forBoolean(!negated, graph());
+                    } else {
+                        // the instanceof matches if the object is non-null, so return true (or false, for the negated case) depending on the null-ness.
+                        return graph().unique(new NullCheckNode(object(), negated));
+                    }
+                } else {
+                    // since the subtype comparison was only performed on a declared type we don't really know if it might be true at run time...
+                }
             }
         }
+
         CiConstant constant = object().asConstant();
         if (constant != null) {
             assert constant.kind == CiKind.Object;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Wed May 02 14:47:04 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Wed May 02 14:53:20 2012 +0200
@@ -232,7 +232,7 @@
     public static Stamp declared(final RiResolvedType type) {
         assert type != null;
         assert type.kind(false) == CiKind.Object;
-        return new BasicValueStamp(CiKind.Object, false, type, null);
+        return new BasicValueStamp(CiKind.Object, false, type, type.exactType());
     }
 
     public static Stamp declaredNonNull(final RiResolvedType type) {