6837094: False positive for "meet not symmetric" failure

Have the meet not symmetric check recursively do the interface-vs-oop check on array subtypes.

Reviewed-by: jrose
This commit is contained in:
Chuck Rasbold 2009-06-23 17:52:29 -07:00 committed by Vladimir Kozlov
parent 0f4f530213
commit 2c5f52b511
3 changed files with 147 additions and 9 deletions

View file

@ -487,6 +487,23 @@ bool Type::is_nan() const {
return false;
}
//----------------------interface_vs_oop---------------------------------------
#ifdef ASSERT
bool Type::interface_vs_oop(const Type *t) const {
bool result = false;
const TypeInstPtr* this_inst = this->isa_instptr();
const TypeInstPtr* t_inst = t->isa_instptr();
if( this_inst && this_inst->is_loaded() && t_inst && t_inst->is_loaded() ) {
bool this_interface = this_inst->klass()->is_interface();
bool t_interface = t_inst->klass()->is_interface();
result = this_interface ^ t_interface;
}
return result;
}
#endif
//------------------------------meet-------------------------------------------
// Compute the MEET of two types. NOT virtual. It enforces that meet is
// commutative and the lattice is symmetric.
@ -507,16 +524,8 @@ const Type *Type::meet( const Type *t ) const {
// Interface meet Oop is Not Symmetric:
// Interface:AnyNull meet Oop:AnyNull == Interface:AnyNull
// Interface:NotNull meet Oop:NotNull == java/lang/Object:NotNull
const TypeInstPtr* this_inst = this->isa_instptr();
const TypeInstPtr* t_inst = t->isa_instptr();
bool interface_vs_oop = false;
if( this_inst && this_inst->is_loaded() && t_inst && t_inst->is_loaded() ) {
bool this_interface = this_inst->klass()->is_interface();
bool t_interface = t_inst->klass()->is_interface();
interface_vs_oop = this_interface ^ t_interface;
}
if( !interface_vs_oop && (t2t != t->_dual || t2this != _dual) ) {
if( !interface_vs_oop(t) && (t2t != t->_dual || t2this != _dual) ) {
tty->print_cr("=== Meet Not Symmetric ===");
tty->print("t = "); t->dump(); tty->cr();
tty->print("this= "); dump(); tty->cr();
@ -1800,6 +1809,17 @@ int TypeAry::hash(void) const {
return (intptr_t)_elem + (intptr_t)_size;
}
//----------------------interface_vs_oop---------------------------------------
#ifdef ASSERT
bool TypeAry::interface_vs_oop(const Type *t) const {
const TypeAry* t_ary = t->is_ary();
if (t_ary) {
return _elem->interface_vs_oop(t_ary->_elem);
}
return false;
}
#endif
//------------------------------dump2------------------------------------------
#ifndef PRODUCT
void TypeAry::dump2( Dict &d, uint depth, outputStream *st ) const {
@ -3389,6 +3409,17 @@ const Type *TypeAryPtr::xdual() const {
return new TypeAryPtr( dual_ptr(), _const_oop, _ary->dual()->is_ary(),_klass, _klass_is_exact, dual_offset(), dual_instance_id() );
}
//----------------------interface_vs_oop---------------------------------------
#ifdef ASSERT
bool TypeAryPtr::interface_vs_oop(const Type *t) const {
const TypeAryPtr* t_aryptr = t->isa_aryptr();
if (t_aryptr) {
return _ary->interface_vs_oop(t_aryptr->_ary);
}
return false;
}
#endif
//------------------------------dump2------------------------------------------
#ifndef PRODUCT
void TypeAryPtr::dump2( Dict &d, uint depth, outputStream *st ) const {

View file

@ -190,6 +190,11 @@ public:
// Currently, it also works around limitations involving interface types.
virtual const Type *filter( const Type *kills ) const;
#ifdef ASSERT
// One type is interface, the other is oop
virtual bool interface_vs_oop(const Type *t) const;
#endif
// Returns true if this pointer points at memory which contains a
// compressed oop references.
bool is_ptr_to_narrowoop() const;
@ -546,6 +551,10 @@ public:
virtual const Type *xmeet( const Type *t ) const;
virtual const Type *xdual() const; // Compute dual right now.
bool ary_must_be_exact() const; // true if arrays of such are never generic
#ifdef ASSERT
// One type is interface, the other is oop
virtual bool interface_vs_oop(const Type *t) const;
#endif
#ifndef PRODUCT
virtual void dump2( Dict &d, uint, outputStream *st ) const; // Specialized per-Type dumping
#endif
@ -867,6 +876,10 @@ public:
}
static const TypeAryPtr *_array_body_type[T_CONFLICT+1];
// sharpen the type of an int which is used as an array size
#ifdef ASSERT
// One type is interface, the other is oop
virtual bool interface_vs_oop(const Type *t) const;
#endif
#ifndef PRODUCT
virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping
#endif