hotspot/src/share/vm/opto/subnode.cpp
changeset 360 21d113ecbf6a
parent 206 d61cf247afd5
child 758 38c168fb8c79
child 670 ddf3e9583f2f
--- a/hotspot/src/share/vm/opto/subnode.cpp	Fri Apr 11 09:56:35 2008 -0400
+++ b/hotspot/src/share/vm/opto/subnode.cpp	Sun Apr 13 17:43:42 2008 -0400
@@ -736,6 +736,75 @@
 }
 
 //=============================================================================
+//------------------------------sub--------------------------------------------
+// Simplify an CmpN (compare 2 pointers) node, based on local information.
+// If both inputs are constants, compare them.
+const Type *CmpNNode::sub( const Type *t1, const Type *t2 ) const {
+  const TypePtr *r0 = t1->is_narrowoop()->make_oopptr(); // Handy access
+  const TypePtr *r1 = t2->is_narrowoop()->make_oopptr();
+
+  // Undefined inputs makes for an undefined result
+  if( TypePtr::above_centerline(r0->_ptr) ||
+      TypePtr::above_centerline(r1->_ptr) )
+    return Type::TOP;
+
+  if (r0 == r1 && r0->singleton()) {
+    // Equal pointer constants (klasses, nulls, etc.)
+    return TypeInt::CC_EQ;
+  }
+
+  // See if it is 2 unrelated classes.
+  const TypeOopPtr* p0 = r0->isa_oopptr();
+  const TypeOopPtr* p1 = r1->isa_oopptr();
+  if (p0 && p1) {
+    ciKlass* klass0 = p0->klass();
+    bool    xklass0 = p0->klass_is_exact();
+    ciKlass* klass1 = p1->klass();
+    bool    xklass1 = p1->klass_is_exact();
+    int kps = (p0->isa_klassptr()?1:0) + (p1->isa_klassptr()?1:0);
+    if (klass0 && klass1 &&
+        kps != 1 &&             // both or neither are klass pointers
+        !klass0->is_interface() && // do not trust interfaces
+        !klass1->is_interface()) {
+      // See if neither subclasses the other, or if the class on top
+      // is precise.  In either of these cases, the compare must fail.
+      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;
+      } else if (klass1->is_subtype_of(klass0)) {
+        // If klass0's type is PRECISE, then we can fail.
+        if (xklass0)  return TypeInt::CC_GT;
+      } else {                  // Neither subtypes the other
+        return TypeInt::CC_GT;  // ...so always fail
+      }
+    }
+  }
+
+  // Known constants can be compared exactly
+  // Null can be distinguished from any NotNull pointers
+  // Unknown inputs makes an unknown result
+  if( r0->singleton() ) {
+    intptr_t bits0 = r0->get_con();
+    if( r1->singleton() )
+      return bits0 == r1->get_con() ? TypeInt::CC_EQ : TypeInt::CC_GT;
+    return ( r1->_ptr == TypePtr::NotNull && bits0==0 ) ? TypeInt::CC_GT : TypeInt::CC;
+  } else if( r1->singleton() ) {
+    intptr_t bits1 = r1->get_con();
+    return ( r0->_ptr == TypePtr::NotNull && bits1==0 ) ? TypeInt::CC_GT : TypeInt::CC;
+  } else
+    return TypeInt::CC;
+}
+
+//------------------------------Ideal------------------------------------------
+Node *CmpNNode::Ideal( PhaseGVN *phase, bool can_reshape ) {
+  return NULL;
+}
+
+//=============================================================================
 //------------------------------Value------------------------------------------
 // Simplify an CmpF (compare 2 floats ) node, based on local information.
 // If both inputs are constants, compare them.