diff options
Diffstat (limited to 'compiler/optimizing')
| -rw-r--r-- | compiler/optimizing/reference_type_propagation.cc | 27 | 
1 files changed, 20 insertions, 7 deletions
diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc index 3b78264727..0d05c49fc5 100644 --- a/compiler/optimizing/reference_type_propagation.cc +++ b/compiler/optimizing/reference_type_propagation.cc @@ -614,23 +614,36 @@ ReferenceTypeInfo ReferenceTypePropagation::MergeTypes(const ReferenceTypeInfo&    }    bool is_exact = a.IsExact() && b.IsExact(); -  Handle<mirror::Class> type_handle; +  ReferenceTypeInfo::TypeHandle result_type_handle; +  ReferenceTypeInfo::TypeHandle a_type_handle = a.GetTypeHandle(); +  ReferenceTypeInfo::TypeHandle b_type_handle = b.GetTypeHandle(); +  bool a_is_interface = a_type_handle->IsInterface(); +  bool b_is_interface = b_type_handle->IsInterface();    if (a.GetTypeHandle().Get() == b.GetTypeHandle().Get()) { -    type_handle = a.GetTypeHandle(); +    result_type_handle = a_type_handle;    } else if (a.IsSupertypeOf(b)) { -    type_handle = a.GetTypeHandle(); +    result_type_handle = a_type_handle;      is_exact = false;    } else if (b.IsSupertypeOf(a)) { -    type_handle = b.GetTypeHandle(); +    result_type_handle = b_type_handle; +    is_exact = false; +  } else if (!a_is_interface && !b_is_interface) { +    result_type_handle = handles_->NewHandle(a_type_handle->GetCommonSuperClass(b_type_handle));      is_exact = false;    } else { -    // TODO: Find the first common super class. -    type_handle = object_class_handle_; +    // This can happen if: +    //    - both types are interfaces. TODO(calin): implement +    //    - one is an interface, the other a class, and the type does not implement the interface +    //      e.g: +    //        void foo(Interface i, boolean cond) { +    //          Object o = cond ? i : new Object(); +    //        } +    result_type_handle = object_class_handle_;      is_exact = false;    } -  return ReferenceTypeInfo::Create(type_handle, is_exact); +  return ReferenceTypeInfo::Create(result_type_handle, is_exact);  }  static void UpdateArrayGet(HArrayGet* instr,  |