6730716: nulls from two unrelated classes compare not equal
authorrasbold
Tue, 19 Aug 2008 07:25:02 -0700
changeset 1058 52be2dbbdc79
parent 1057 44220ef9a775
child 1059 3ab6bb629000
6730716: nulls from two unrelated classes compare not equal Summary: check for not-nullness after proving that types are unrelated Reviewed-by: kvn, never
hotspot/src/share/vm/opto/subnode.cpp
--- a/hotspot/src/share/vm/opto/subnode.cpp	Mon Aug 18 23:17:51 2008 -0700
+++ b/hotspot/src/share/vm/opto/subnode.cpp	Tue Aug 19 07:25:02 2008 -0700
@@ -633,20 +633,31 @@
         kps != 1 &&             // both or neither are klass pointers
         !klass0->is_interface() && // do not trust interfaces
         !klass1->is_interface()) {
+      bool unrelated_classes = false;
       // See if neither subclasses the other, or if the class on top
-      // is precise.  In either of these cases, the compare must fail.
+      // is precise.  In either of these cases, the compare is known
+      // to fail if at least one of the pointers is provably not null.
       if (klass0->equals(klass1)   ||   // if types are unequal but klasses are
           !klass0->is_java_klass() ||   // types not part of Java language?
           !klass1->is_java_klass()) {   // types not part of Java language?
         // Do nothing; we know nothing for imprecise types
       } else if (klass0->is_subtype_of(klass1)) {
-        // If klass1's type is PRECISE, then we can fail.
-        if (xklass1)  return TypeInt::CC_GT;
+        // If klass1's type is PRECISE, then classes are unrelated.
+        unrelated_classes = xklass1;
       } else if (klass1->is_subtype_of(klass0)) {
-        // If klass0's type is PRECISE, then we can fail.
-        if (xklass0)  return TypeInt::CC_GT;
+        // If klass0's type is PRECISE, then classes are unrelated.
+        unrelated_classes = xklass0;
       } else {                  // Neither subtypes the other
-        return TypeInt::CC_GT;  // ...so always fail
+        unrelated_classes = true;
+      }
+      if (unrelated_classes) {
+        // The oops classes are known to be unrelated. If the joined PTRs of
+        // two oops is not Null and not Bottom, then we are sure that one
+        // of the two oops is non-null, and the comparison will always fail.
+        TypePtr::PTR jp = r0->join_ptr(r1->_ptr);
+        if (jp != TypePtr::Null && jp != TypePtr::BotPTR) {
+          return TypeInt::CC_GT;
+        }
       }
     }
   }
@@ -777,20 +788,31 @@
         kps != 1 &&             // both or neither are klass pointers
         !klass0->is_interface() && // do not trust interfaces
         !klass1->is_interface()) {
+      bool unrelated_classes = false;
       // See if neither subclasses the other, or if the class on top
-      // is precise.  In either of these cases, the compare must fail.
+      // is precise.  In either of these cases, the compare is known
+      // to fail if at least one of the pointers is provably not null.
       if (klass0->equals(klass1)   ||   // if types are unequal but klasses are
           !klass0->is_java_klass() ||   // types not part of Java language?
           !klass1->is_java_klass()) {   // types not part of Java language?
         // Do nothing; we know nothing for imprecise types
       } else if (klass0->is_subtype_of(klass1)) {
-        // If klass1's type is PRECISE, then we can fail.
-        if (xklass1)  return TypeInt::CC_GT;
+        // If klass1's type is PRECISE, then classes are unrelated.
+        unrelated_classes = xklass1;
       } else if (klass1->is_subtype_of(klass0)) {
-        // If klass0's type is PRECISE, then we can fail.
-        if (xklass0)  return TypeInt::CC_GT;
+        // If klass0's type is PRECISE, then classes are unrelated.
+        unrelated_classes = xklass0;
       } else {                  // Neither subtypes the other
-        return TypeInt::CC_GT;  // ...so always fail
+        unrelated_classes = true;
+      }
+      if (unrelated_classes) {
+        // The oops classes are known to be unrelated. If the joined PTRs of
+        // two oops is not Null and not Bottom, then we are sure that one
+        // of the two oops is non-null, and the comparison will always fail.
+        TypePtr::PTR jp = r0->join_ptr(r1->_ptr);
+        if (jp != TypePtr::Null && jp != TypePtr::BotPTR) {
+          return TypeInt::CC_GT;
+        }
       }
     }
   }