< prev index next >

src/share/vm/opto/type.cpp

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

*** 148,157 **** --- 148,184 ---- return T_VOID; } return bt; } + // For two instance arrays of same dimension, return the base element types. + // Otherwise or if the arrays have different dimensions, return NULL. + void Type::get_arrays_base_elements(const Type *a1, const Type *a2, + const TypePtr **e1, const TypePtr **e2) { + + if (e1) *e1 = NULL; + if (e2) *e2 = NULL; + const TypeAryPtr* a1tap = (a1 == NULL) ? NULL : a1->isa_aryptr(); + const TypeAryPtr* a2tap = (a2 == NULL) ? NULL : a2->isa_aryptr(); + + if (a1tap != NULL && a2tap != NULL) { + // Handle multidimensional arrays + const TypePtr* a1tp = a1tap->elem()->make_ptr(); + const TypePtr* a2tp = a2tap->elem()->make_ptr(); + while (a1tp && a1tp->isa_aryptr() && a2tp && a2tp->isa_aryptr()) { + a1tap = a1tp->is_aryptr(); + a2tap = a2tp->is_aryptr(); + a1tp = a1tap->elem()->make_ptr(); + a2tp = a2tap->elem()->make_ptr(); + } + if (a1tp && a2tp) { + if (e1) *e1 = a1tp; + if (e2) *e2 = a2tp; + } + } + } + //---------------------------get_typeflow_type--------------------------------- // Import a type produced by ciTypeFlow. const Type* Type::get_typeflow_type(ciType* type) { switch (type->basic_type()) {
*** 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 --- 2054,2068 ---- //----------------------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 we have narrow_oops ! 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, --- 3163,3187 ---- // 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 + } + // Also check for evil cases of 'this' being a class array + // and 'kills' expecting an array of interfaces. + const TypePtr* ktp; + Type::get_arrays_base_elements(ft, kills, NULL, &ktp); + if (ktp != NULL) { + ktip = ktp->isa_instptr(); + 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,
< prev index next >