< prev index next >

src/share/vm/opto/type.cpp

Print this page
rev 9165 : 8141551: C2 can not handle returns with inccompatible interface arrays

*** 706,723 **** const Type *mt = this_t->xmeet(t); if (isa_narrowoop() || t->isa_narrowoop()) return mt; if (isa_narrowklass() || t->isa_narrowklass()) return mt; #ifdef ASSERT ! assert(mt == t->xmeet(this_t), "meet not commutative"); const Type* dual_join = mt->_dual; const Type *t2t = dual_join->xmeet(t->_dual); const Type *t2this = dual_join->xmeet(this_t->_dual); // Interface meet Oop is Not Symmetric: // Interface:AnyNull meet Oop:AnyNull == Interface:AnyNull // Interface:NotNull meet Oop:NotNull == java/lang/Object:NotNull if( !interface_vs_oop(t) && (t2t != t->_dual || t2this != this_t->_dual) ) { tty->print_cr("=== Meet Not Symmetric ==="); tty->print("t = "); t->dump(); tty->cr(); tty->print("this= "); this_t->dump(); tty->cr(); --- 706,731 ---- const Type *mt = this_t->xmeet(t); if (isa_narrowoop() || t->isa_narrowoop()) return mt; if (isa_narrowklass() || t->isa_narrowklass()) return mt; #ifdef ASSERT ! if (mt != t->xmeet(this_t)) { ! // Array of Interface meet Array of Oop is Not Commutative. ! if (!(this_t->make_ptr() && this_t->make_ptr()->isa_aryptr() && ! t->make_ptr() && t->make_ptr()->isa_aryptr() && ! interface_vs_oop(t))) { ! fatal("meet not commutative"); ! } ! } const Type* dual_join = mt->_dual; const Type *t2t = dual_join->xmeet(t->_dual); const Type *t2this = dual_join->xmeet(this_t->_dual); // Interface meet Oop is Not Symmetric: // Interface:AnyNull meet Oop:AnyNull == Interface:AnyNull // Interface:NotNull meet Oop:NotNull == java/lang/Object:NotNull + // Array of Interface meet Array of Oop is also Not Symmetric. if( !interface_vs_oop(t) && (t2t != t->_dual || t2this != this_t->_dual) ) { tty->print_cr("=== Meet Not Symmetric ==="); tty->print("t = "); t->dump(); tty->cr(); tty->print("this= "); this_t->dump(); tty->cr();
*** 2027,2037 **** //----------------------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 --- 2035,2049 ---- //----------------------interface_vs_oop--------------------------------------- #ifdef ASSERT bool TypeAry::interface_vs_oop(const Type *t) const { const TypeAry* t_ary = t->is_ary(); if (t_ary) { ! const TypePtr* this_ptr = _elem->make_ptr(); // In case it is narrow_oop ! const TypePtr* t_ptr = t_ary->_elem->make_ptr(); ! if(this_ptr != NULL && t_ptr != NULL) { ! return this_ptr->interface_vs_oop(t_ptr); ! } } return false; } #endif
*** 3132,3143 **** // both implement interface I, but their meet is at 'j/l/O' which // doesn't implement I, we have no way to tell if the result should // be 'I' or 'j/l/O'. Thus we'll pick 'j/l/O'. If this then flows // into a Phi which "knows" it's an Interface type we'll have to // uplift the type. ! if (!empty() && ktip != NULL && ktip->is_loaded() && ktip->klass()->is_interface()) return kills; // Uplift to interface return Type::TOP; // Canonical empty value } // If we have an interface-typed Phi or cast and we narrow to a class type, --- 3144,3175 ---- // both implement interface I, but their meet is at 'j/l/O' which // doesn't implement I, we have no way to tell if the result should // be 'I' or 'j/l/O'. Thus we'll pick 'j/l/O'. If this then flows // into a Phi which "knows" it's an Interface type we'll have to // uplift the type. ! if (!empty()) { ! if (ktip != NULL && ktip->is_loaded() && ktip->klass()->is_interface()) { return kills; // Uplift to interface + } + const TypeAryPtr* ftap = ft->isa_aryptr(); + const TypeAryPtr* ktap = kills->isa_aryptr(); + if (ftap != NULL && ktap != NULL) { + // Handle multidimensional arrays + const TypePtr* ftp = ftap->elem()->make_ptr(); + const TypePtr* ktp = ktap->elem()->make_ptr(); + while (ftp && ftp->isa_aryptr() && ktp && ktp->isa_aryptr()) { + ftap = ftp->is_aryptr(); + ktap = ktp->is_aryptr(); + ftp = ftap->elem()->make_ptr(); + ktp = ktap->elem()->make_ptr(); + } + ktip = ktp ? ktp->isa_instptr() : NULL; + if (ktip != NULL && ktip->is_loaded() && ktip->klass()->is_interface()) { + return kills; // Uplift to array of interface + } + } + } return Type::TOP; // Canonical empty value } // If we have an interface-typed Phi or cast and we narrow to a class type,
*** 4140,4152 **** --- 4172,4199 ---- ((tap->_klass_is_exact && this->_klass_is_exact) || // 'tap' is exact and super or unrelated: (tap->_klass_is_exact && !tap->klass()->is_subtype_of(klass())) || // 'this' is exact and super or unrelated: (this->_klass_is_exact && !klass()->is_subtype_of(tap->klass())))) { + + const TypeAry* tta = tap->_ary; + const TypeAry* mta = tary; + // Handle multidimensional arrays + const TypePtr* ftp = mta->_elem->make_ptr(); + const TypePtr* ktp = tta->_elem->make_ptr(); + while (ftp && ftp->isa_aryptr() && ktp && ktp->isa_aryptr()) { + mta = ftp->is_aryptr()->_ary; + tta = ktp->is_aryptr()->_ary; + ftp = mta->_elem->make_ptr(); + ktp = tta->_elem->make_ptr(); + } + const TypeInstPtr* ktip = ktp ? ktp->isa_instptr() : NULL; + if (ktip == NULL || !ktip->is_loaded() || !ktip->klass()->is_interface()) { if (above_centerline(ptr)) { tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable); } + } return make(NotNull, NULL, tary, lazy_klass, false, off, InstanceBot, speculative, depth); } bool xk = false; switch (tap->ptr()) {
< prev index next >