diff -r a49a647afe9a -r ba764ed4b6f2 src/share/vm/opto/subnode.cpp --- a/src/share/vm/opto/subnode.cpp Fri Apr 11 09:56:35 2008 -0400 +++ b/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.