src/share/vm/opto/type.cpp

changeset 8422
09687c445ce1
parent 7873
2a55e4998f0d
child 8424
2094cac55c59
     1.1 --- a/src/share/vm/opto/type.cpp	Fri Apr 15 12:02:37 2016 +0530
     1.2 +++ b/src/share/vm/opto/type.cpp	Thu Apr 21 21:53:15 2016 +0530
     1.3 @@ -149,6 +149,33 @@
     1.4    return bt;
     1.5  }
     1.6  
     1.7 +// For two instance arrays of same dimension, return the base element types.
     1.8 +// Otherwise or if the arrays have different dimensions, return NULL.
     1.9 +void Type::get_arrays_base_elements(const Type *a1, const Type *a2,
    1.10 +                                    const TypeInstPtr **e1, const TypeInstPtr **e2) {
    1.11 +
    1.12 +  if (e1) *e1 = NULL;
    1.13 +  if (e2) *e2 = NULL;
    1.14 +  const TypeAryPtr* a1tap = (a1 == NULL) ? NULL : a1->isa_aryptr();
    1.15 +  const TypeAryPtr* a2tap = (a2 == NULL) ? NULL : a2->isa_aryptr();
    1.16 +
    1.17 +  if (a1tap != NULL && a2tap != NULL) {
    1.18 +    // Handle multidimensional arrays
    1.19 +    const TypePtr* a1tp = a1tap->elem()->make_ptr();
    1.20 +    const TypePtr* a2tp = a2tap->elem()->make_ptr();
    1.21 +    while (a1tp && a1tp->isa_aryptr() && a2tp && a2tp->isa_aryptr()) {
    1.22 +      a1tap = a1tp->is_aryptr();
    1.23 +      a2tap = a2tp->is_aryptr();
    1.24 +      a1tp = a1tap->elem()->make_ptr();
    1.25 +      a2tp = a2tap->elem()->make_ptr();
    1.26 +    }
    1.27 +    if (a1tp && a1tp->isa_instptr() && a2tp && a2tp->isa_instptr()) {
    1.28 +      if (e1) *e1 = a1tp->is_instptr();
    1.29 +      if (e2) *e2 = a2tp->is_instptr();
    1.30 +    }
    1.31 +  }
    1.32 +}
    1.33 +
    1.34  //---------------------------get_typeflow_type---------------------------------
    1.35  // Import a type produced by ciTypeFlow.
    1.36  const Type* Type::get_typeflow_type(ciType* type) {
    1.37 @@ -1982,7 +2009,11 @@
    1.38  bool TypeAry::interface_vs_oop(const Type *t) const {
    1.39    const TypeAry* t_ary = t->is_ary();
    1.40    if (t_ary) {
    1.41 -    return _elem->interface_vs_oop(t_ary->_elem);
    1.42 +    const TypePtr* this_ptr = _elem->make_ptr(); // In case we have narrow_oops
    1.43 +    const TypePtr*    t_ptr = t_ary->_elem->make_ptr();
    1.44 +    if(this_ptr != NULL && t_ptr != NULL) {
    1.45 +      return this_ptr->interface_vs_oop(t_ptr);
    1.46 +    }
    1.47    }
    1.48    return false;
    1.49  }
    1.50 @@ -2834,8 +2865,17 @@
    1.51      // be 'I' or 'j/l/O'.  Thus we'll pick 'j/l/O'.  If this then flows
    1.52      // into a Phi which "knows" it's an Interface type we'll have to
    1.53      // uplift the type.
    1.54 -    if (!empty() && ktip != NULL && ktip->is_loaded() && ktip->klass()->is_interface())
    1.55 -      return kills;             // Uplift to interface
    1.56 +    if (!empty()) {
    1.57 +      if (ktip != NULL && ktip->is_loaded() && ktip->klass()->is_interface()) {
    1.58 +        return kills;           // Uplift to interface
    1.59 +      }
    1.60 +      // Also check for evil cases of 'this' being a class array
    1.61 +      // and 'kills' expecting an array of interfaces.
    1.62 +      Type::get_arrays_base_elements(ft, kills, NULL, &ktip);
    1.63 +      if (ktip != NULL && ktip->is_loaded() && ktip->klass()->is_interface()) {
    1.64 +        return kills;           // Uplift to array of interface
    1.65 +      }
    1.66 +    }
    1.67  
    1.68      return Type::TOP;           // Canonical empty value
    1.69    }

mercurial