--- 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.