# HG changeset patch # User Lukas Stadler # Date 1335963200 -7200 # Node ID 17a84768b1cdaa5ff98d27c6c90f4d676303c8b7 # Parent a49538b9073fb233c4cd21b9ce1fb8b505082e29 fix canonicalization of InstanceOfNode diff -r a49538b9073f -r 17a84768b1cd graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java --- 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; diff -r a49538b9073f -r 17a84768b1cd graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java --- 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) {