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