Home | History | Annotate | Download | only in verifier
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "reg_type-inl.h"
     18 
     19 #include "android-base/stringprintf.h"
     20 
     21 #include "base/arena_bit_vector.h"
     22 #include "base/bit_vector-inl.h"
     23 #include "base/casts.h"
     24 #include "class_linker-inl.h"
     25 #include "dex_file-inl.h"
     26 #include "method_verifier.h"
     27 #include "mirror/class.h"
     28 #include "mirror/class-inl.h"
     29 #include "mirror/object-inl.h"
     30 #include "mirror/object_array-inl.h"
     31 #include "reg_type_cache-inl.h"
     32 #include "scoped_thread_state_change-inl.h"
     33 
     34 #include <limits>
     35 #include <sstream>
     36 
     37 namespace art {
     38 namespace verifier {
     39 
     40 using android::base::StringPrintf;
     41 
     42 const UndefinedType* UndefinedType::instance_ = nullptr;
     43 const ConflictType* ConflictType::instance_ = nullptr;
     44 const BooleanType* BooleanType::instance_ = nullptr;
     45 const ByteType* ByteType::instance_ = nullptr;
     46 const ShortType* ShortType::instance_ = nullptr;
     47 const CharType* CharType::instance_ = nullptr;
     48 const FloatType* FloatType::instance_ = nullptr;
     49 const LongLoType* LongLoType::instance_ = nullptr;
     50 const LongHiType* LongHiType::instance_ = nullptr;
     51 const DoubleLoType* DoubleLoType::instance_ = nullptr;
     52 const DoubleHiType* DoubleHiType::instance_ = nullptr;
     53 const IntegerType* IntegerType::instance_ = nullptr;
     54 
     55 PrimitiveType::PrimitiveType(mirror::Class* klass, const StringPiece& descriptor, uint16_t cache_id)
     56     : RegType(klass, descriptor, cache_id) {
     57   CHECK(klass != nullptr);
     58   CHECK(!descriptor.empty());
     59 }
     60 
     61 Cat1Type::Cat1Type(mirror::Class* klass, const StringPiece& descriptor, uint16_t cache_id)
     62     : PrimitiveType(klass, descriptor, cache_id) {
     63 }
     64 
     65 Cat2Type::Cat2Type(mirror::Class* klass, const StringPiece& descriptor, uint16_t cache_id)
     66     : PrimitiveType(klass, descriptor, cache_id) {
     67 }
     68 
     69 std::string PreciseConstType::Dump() const {
     70   std::stringstream result;
     71   uint32_t val = ConstantValue();
     72   if (val == 0) {
     73     CHECK(IsPreciseConstant());
     74     result << "Zero/null";
     75   } else {
     76     result << "Precise ";
     77     if (IsConstantShort()) {
     78       result << StringPrintf("Constant: %d", val);
     79     } else {
     80       result << StringPrintf("Constant: 0x%x", val);
     81     }
     82   }
     83   return result.str();
     84 }
     85 
     86 std::string BooleanType::Dump() const {
     87   return "Boolean";
     88 }
     89 
     90 std::string ConflictType::Dump() const {
     91     return "Conflict";
     92 }
     93 
     94 std::string ByteType::Dump() const {
     95   return "Byte";
     96 }
     97 
     98 std::string ShortType::Dump() const {
     99   return "Short";
    100 }
    101 
    102 std::string CharType::Dump() const {
    103   return "Char";
    104 }
    105 
    106 std::string FloatType::Dump() const {
    107   return "Float";
    108 }
    109 
    110 std::string LongLoType::Dump() const {
    111   return "Long (Low Half)";
    112 }
    113 
    114 std::string LongHiType::Dump() const {
    115   return "Long (High Half)";
    116 }
    117 
    118 std::string DoubleLoType::Dump() const {
    119   return "Double (Low Half)";
    120 }
    121 
    122 std::string DoubleHiType::Dump() const {
    123   return "Double (High Half)";
    124 }
    125 
    126 std::string IntegerType::Dump() const {
    127   return "Integer";
    128 }
    129 
    130 const DoubleHiType* DoubleHiType::CreateInstance(mirror::Class* klass,
    131                                                  const StringPiece& descriptor,
    132                                                  uint16_t cache_id) {
    133   CHECK(instance_ == nullptr);
    134   instance_ = new DoubleHiType(klass, descriptor, cache_id);
    135   return instance_;
    136 }
    137 
    138 void DoubleHiType::Destroy() {
    139   if (instance_ != nullptr) {
    140     delete instance_;
    141     instance_ = nullptr;
    142   }
    143 }
    144 
    145 const DoubleLoType* DoubleLoType::CreateInstance(mirror::Class* klass,
    146                                                  const StringPiece& descriptor,
    147                                                  uint16_t cache_id) {
    148   CHECK(instance_ == nullptr);
    149   instance_ = new DoubleLoType(klass, descriptor, cache_id);
    150   return instance_;
    151 }
    152 
    153 void DoubleLoType::Destroy() {
    154   if (instance_ != nullptr) {
    155     delete instance_;
    156     instance_ = nullptr;
    157   }
    158 }
    159 
    160 const LongLoType* LongLoType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
    161                                              uint16_t cache_id) {
    162   CHECK(instance_ == nullptr);
    163   instance_ = new LongLoType(klass, descriptor, cache_id);
    164   return instance_;
    165 }
    166 
    167 const LongHiType* LongHiType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
    168                                              uint16_t cache_id) {
    169   CHECK(instance_ == nullptr);
    170   instance_ = new LongHiType(klass, descriptor, cache_id);
    171   return instance_;
    172 }
    173 
    174 void LongHiType::Destroy() {
    175   if (instance_ != nullptr) {
    176     delete instance_;
    177     instance_ = nullptr;
    178   }
    179 }
    180 
    181 void LongLoType::Destroy() {
    182   if (instance_ != nullptr) {
    183     delete instance_;
    184     instance_ = nullptr;
    185   }
    186 }
    187 
    188 const FloatType* FloatType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
    189                                            uint16_t cache_id) {
    190   CHECK(instance_ == nullptr);
    191   instance_ = new FloatType(klass, descriptor, cache_id);
    192   return instance_;
    193 }
    194 
    195 void FloatType::Destroy() {
    196   if (instance_ != nullptr) {
    197     delete instance_;
    198     instance_ = nullptr;
    199   }
    200 }
    201 
    202 const CharType* CharType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
    203                                          uint16_t cache_id) {
    204   CHECK(instance_ == nullptr);
    205   instance_ = new CharType(klass, descriptor, cache_id);
    206   return instance_;
    207 }
    208 
    209 void CharType::Destroy() {
    210   if (instance_ != nullptr) {
    211     delete instance_;
    212     instance_ = nullptr;
    213   }
    214 }
    215 
    216 const ShortType* ShortType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
    217                                            uint16_t cache_id) {
    218   CHECK(instance_ == nullptr);
    219   instance_ = new ShortType(klass, descriptor, cache_id);
    220   return instance_;
    221 }
    222 
    223 void ShortType::Destroy() {
    224   if (instance_ != nullptr) {
    225     delete instance_;
    226     instance_ = nullptr;
    227   }
    228 }
    229 
    230 const ByteType* ByteType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
    231                                          uint16_t cache_id) {
    232   CHECK(instance_ == nullptr);
    233   instance_ = new ByteType(klass, descriptor, cache_id);
    234   return instance_;
    235 }
    236 
    237 void ByteType::Destroy() {
    238   if (instance_ != nullptr) {
    239     delete instance_;
    240     instance_ = nullptr;
    241   }
    242 }
    243 
    244 const IntegerType* IntegerType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
    245                                                uint16_t cache_id) {
    246   CHECK(instance_ == nullptr);
    247   instance_ = new IntegerType(klass, descriptor, cache_id);
    248   return instance_;
    249 }
    250 
    251 void IntegerType::Destroy() {
    252   if (instance_ != nullptr) {
    253     delete instance_;
    254     instance_ = nullptr;
    255   }
    256 }
    257 
    258 const ConflictType* ConflictType::CreateInstance(mirror::Class* klass,
    259                                                  const StringPiece& descriptor,
    260                                                  uint16_t cache_id) {
    261   CHECK(instance_ == nullptr);
    262   instance_ = new ConflictType(klass, descriptor, cache_id);
    263   return instance_;
    264 }
    265 
    266 void ConflictType::Destroy() {
    267   if (instance_ != nullptr) {
    268     delete instance_;
    269     instance_ = nullptr;
    270   }
    271 }
    272 
    273 const BooleanType* BooleanType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
    274                                          uint16_t cache_id) {
    275   CHECK(BooleanType::instance_ == nullptr);
    276   instance_ = new BooleanType(klass, descriptor, cache_id);
    277   return BooleanType::instance_;
    278 }
    279 
    280 void BooleanType::Destroy() {
    281   if (BooleanType::instance_ != nullptr) {
    282     delete instance_;
    283     instance_ = nullptr;
    284   }
    285 }
    286 
    287 std::string UndefinedType::Dump() const REQUIRES_SHARED(Locks::mutator_lock_) {
    288   return "Undefined";
    289 }
    290 
    291 const UndefinedType* UndefinedType::CreateInstance(mirror::Class* klass,
    292                                                    const StringPiece& descriptor,
    293                                                    uint16_t cache_id) {
    294   CHECK(instance_ == nullptr);
    295   instance_ = new UndefinedType(klass, descriptor, cache_id);
    296   return instance_;
    297 }
    298 
    299 void UndefinedType::Destroy() {
    300   if (instance_ != nullptr) {
    301     delete instance_;
    302     instance_ = nullptr;
    303   }
    304 }
    305 
    306 PreciseReferenceType::PreciseReferenceType(mirror::Class* klass, const StringPiece& descriptor,
    307                                            uint16_t cache_id)
    308     : RegType(klass, descriptor, cache_id) {
    309   // Note: no check for IsInstantiable() here. We may produce this in case an InstantiationError
    310   //       would be thrown at runtime, but we need to continue verification and *not* create a
    311   //       hard failure or abort.
    312   CheckConstructorInvariants(this);
    313 }
    314 
    315 std::string UnresolvedMergedType::Dump() const {
    316   std::stringstream result;
    317   result << "UnresolvedMergedReferences(" << GetResolvedPart().Dump() << " | ";
    318   const BitVector& types = GetUnresolvedTypes();
    319 
    320   bool first = true;
    321   for (uint32_t idx : types.Indexes()) {
    322     if (!first) {
    323       result << ", ";
    324     } else {
    325       first = false;
    326     }
    327     result << reg_type_cache_->GetFromId(idx).Dump();
    328   }
    329   result << ")";
    330   return result.str();
    331 }
    332 
    333 std::string UnresolvedSuperClass::Dump() const {
    334   std::stringstream result;
    335   uint16_t super_type_id = GetUnresolvedSuperClassChildId();
    336   result << "UnresolvedSuperClass(" << reg_type_cache_->GetFromId(super_type_id).Dump() << ")";
    337   return result.str();
    338 }
    339 
    340 std::string UnresolvedReferenceType::Dump() const {
    341   std::stringstream result;
    342   result << "Unresolved Reference" << ": " << PrettyDescriptor(GetDescriptor().as_string().c_str());
    343   return result.str();
    344 }
    345 
    346 std::string UnresolvedUninitializedRefType::Dump() const {
    347   std::stringstream result;
    348   result << "Unresolved And Uninitialized Reference" << ": "
    349       << PrettyDescriptor(GetDescriptor().as_string().c_str())
    350       << " Allocation PC: " << GetAllocationPc();
    351   return result.str();
    352 }
    353 
    354 std::string UnresolvedUninitializedThisRefType::Dump() const {
    355   std::stringstream result;
    356   result << "Unresolved And Uninitialized This Reference"
    357       << PrettyDescriptor(GetDescriptor().as_string().c_str());
    358   return result.str();
    359 }
    360 
    361 std::string ReferenceType::Dump() const {
    362   std::stringstream result;
    363   result << "Reference" << ": " << mirror::Class::PrettyDescriptor(GetClass());
    364   return result.str();
    365 }
    366 
    367 std::string PreciseReferenceType::Dump() const {
    368   std::stringstream result;
    369   result << "Precise Reference" << ": "<< mirror::Class::PrettyDescriptor(GetClass());
    370   return result.str();
    371 }
    372 
    373 std::string UninitializedReferenceType::Dump() const {
    374   std::stringstream result;
    375   result << "Uninitialized Reference" << ": " << mirror::Class::PrettyDescriptor(GetClass());
    376   result << " Allocation PC: " << GetAllocationPc();
    377   return result.str();
    378 }
    379 
    380 std::string UninitializedThisReferenceType::Dump() const {
    381   std::stringstream result;
    382   result << "Uninitialized This Reference" << ": " << mirror::Class::PrettyDescriptor(GetClass());
    383   result << "Allocation PC: " << GetAllocationPc();
    384   return result.str();
    385 }
    386 
    387 std::string ImpreciseConstType::Dump() const {
    388   std::stringstream result;
    389   uint32_t val = ConstantValue();
    390   if (val == 0) {
    391     result << "Zero/null";
    392   } else {
    393     result << "Imprecise ";
    394     if (IsConstantShort()) {
    395       result << StringPrintf("Constant: %d", val);
    396     } else {
    397       result << StringPrintf("Constant: 0x%x", val);
    398     }
    399   }
    400   return result.str();
    401 }
    402 std::string PreciseConstLoType::Dump() const {
    403   std::stringstream result;
    404 
    405   int32_t val = ConstantValueLo();
    406   result << "Precise ";
    407   if (val >= std::numeric_limits<jshort>::min() &&
    408       val <= std::numeric_limits<jshort>::max()) {
    409     result << StringPrintf("Low-half Constant: %d", val);
    410   } else {
    411     result << StringPrintf("Low-half Constant: 0x%x", val);
    412   }
    413   return result.str();
    414 }
    415 
    416 std::string ImpreciseConstLoType::Dump() const {
    417   std::stringstream result;
    418 
    419   int32_t val = ConstantValueLo();
    420   result << "Imprecise ";
    421   if (val >= std::numeric_limits<jshort>::min() &&
    422       val <= std::numeric_limits<jshort>::max()) {
    423     result << StringPrintf("Low-half Constant: %d", val);
    424   } else {
    425     result << StringPrintf("Low-half Constant: 0x%x", val);
    426   }
    427   return result.str();
    428 }
    429 
    430 std::string PreciseConstHiType::Dump() const {
    431   std::stringstream result;
    432   int32_t val = ConstantValueHi();
    433   result << "Precise ";
    434   if (val >= std::numeric_limits<jshort>::min() &&
    435       val <= std::numeric_limits<jshort>::max()) {
    436     result << StringPrintf("High-half Constant: %d", val);
    437   } else {
    438     result << StringPrintf("High-half Constant: 0x%x", val);
    439   }
    440   return result.str();
    441 }
    442 
    443 std::string ImpreciseConstHiType::Dump() const {
    444   std::stringstream result;
    445   int32_t val = ConstantValueHi();
    446   result << "Imprecise ";
    447   if (val >= std::numeric_limits<jshort>::min() &&
    448       val <= std::numeric_limits<jshort>::max()) {
    449     result << StringPrintf("High-half Constant: %d", val);
    450   } else {
    451     result << StringPrintf("High-half Constant: 0x%x", val);
    452   }
    453   return result.str();
    454 }
    455 
    456 const RegType& RegType::HighHalf(RegTypeCache* cache) const {
    457   DCHECK(IsLowHalf());
    458   if (IsLongLo()) {
    459     return cache->LongHi();
    460   } else if (IsDoubleLo()) {
    461     return cache->DoubleHi();
    462   } else {
    463     DCHECK(IsImpreciseConstantLo());
    464     const ConstantType* const_val = down_cast<const ConstantType*>(this);
    465     return cache->FromCat2ConstHi(const_val->ConstantValue(), false);
    466   }
    467 }
    468 
    469 Primitive::Type RegType::GetPrimitiveType() const {
    470   if (IsNonZeroReferenceTypes()) {
    471     return Primitive::kPrimNot;
    472   } else if (IsBooleanTypes()) {
    473     return Primitive::kPrimBoolean;
    474   } else if (IsByteTypes()) {
    475     return Primitive::kPrimByte;
    476   } else if (IsShortTypes()) {
    477     return Primitive::kPrimShort;
    478   } else if (IsCharTypes()) {
    479     return Primitive::kPrimChar;
    480   } else if (IsFloat()) {
    481     return Primitive::kPrimFloat;
    482   } else if (IsIntegralTypes()) {
    483     return Primitive::kPrimInt;
    484   } else if (IsDoubleLo()) {
    485     return Primitive::kPrimDouble;
    486   } else {
    487     DCHECK(IsLongTypes());
    488     return Primitive::kPrimLong;
    489   }
    490 }
    491 
    492 bool UninitializedType::IsUninitializedTypes() const {
    493   return true;
    494 }
    495 
    496 bool UninitializedType::IsNonZeroReferenceTypes() const {
    497   return true;
    498 }
    499 
    500 bool UnresolvedType::IsNonZeroReferenceTypes() const {
    501   return true;
    502 }
    503 
    504 const RegType& RegType::GetSuperClass(RegTypeCache* cache) const {
    505   if (!IsUnresolvedTypes()) {
    506     mirror::Class* super_klass = GetClass()->GetSuperClass();
    507     if (super_klass != nullptr) {
    508       // A super class of a precise type isn't precise as a precise type indicates the register
    509       // holds exactly that type.
    510       std::string temp;
    511       return cache->FromClass(super_klass->GetDescriptor(&temp), super_klass, false);
    512     } else {
    513       return cache->Zero();
    514     }
    515   } else {
    516     if (!IsUnresolvedMergedReference() && !IsUnresolvedSuperClass() &&
    517         GetDescriptor()[0] == '[') {
    518       // Super class of all arrays is Object.
    519       return cache->JavaLangObject(true);
    520     } else {
    521       return cache->FromUnresolvedSuperClass(*this);
    522     }
    523   }
    524 }
    525 
    526 bool RegType::IsJavaLangObject() const REQUIRES_SHARED(Locks::mutator_lock_) {
    527   return IsReference() && GetClass()->IsObjectClass();
    528 }
    529 
    530 bool RegType::IsObjectArrayTypes() const REQUIRES_SHARED(Locks::mutator_lock_) {
    531   if (IsUnresolvedTypes()) {
    532     DCHECK(!IsUnresolvedMergedReference());
    533 
    534     if (IsUnresolvedSuperClass()) {
    535       // Cannot be an array, as the superclass of arrays is java.lang.Object (which cannot be
    536       // unresolved).
    537       return false;
    538     }
    539 
    540     // Primitive arrays will always resolve.
    541     DCHECK(descriptor_[1] == 'L' || descriptor_[1] == '[');
    542     return descriptor_[0] == '[';
    543   } else if (HasClass()) {
    544     mirror::Class* type = GetClass();
    545     return type->IsArrayClass() && !type->GetComponentType()->IsPrimitive();
    546   } else {
    547     return false;
    548   }
    549 }
    550 
    551 bool RegType::IsArrayTypes() const REQUIRES_SHARED(Locks::mutator_lock_) {
    552   if (IsUnresolvedTypes()) {
    553     DCHECK(!IsUnresolvedMergedReference());
    554 
    555     if (IsUnresolvedSuperClass()) {
    556       // Cannot be an array, as the superclass of arrays is java.lang.Object (which cannot be
    557       // unresolved).
    558       return false;
    559     }
    560     return descriptor_[0] == '[';
    561   } else if (HasClass()) {
    562     return GetClass()->IsArrayClass();
    563   } else {
    564     return false;
    565   }
    566 }
    567 
    568 bool RegType::IsJavaLangObjectArray() const {
    569   if (HasClass()) {
    570     mirror::Class* type = GetClass();
    571     return type->IsArrayClass() && type->GetComponentType()->IsObjectClass();
    572   }
    573   return false;
    574 }
    575 
    576 bool RegType::IsInstantiableTypes() const {
    577   return IsUnresolvedTypes() || (IsNonZeroReferenceTypes() && GetClass()->IsInstantiable());
    578 }
    579 
    580 static const RegType& SelectNonConstant(const RegType& a, const RegType& b) {
    581   return a.IsConstantTypes() ? b : a;
    582 }
    583 
    584 const RegType& RegType::Merge(const RegType& incoming_type,
    585                               RegTypeCache* reg_types,
    586                               MethodVerifier* verifier) const {
    587   DCHECK(!Equals(incoming_type));  // Trivial equality handled by caller
    588   // Perform pointer equality tests for undefined and conflict to avoid virtual method dispatch.
    589   const UndefinedType& undefined = reg_types->Undefined();
    590   const ConflictType& conflict = reg_types->Conflict();
    591   DCHECK_EQ(this == &undefined, IsUndefined());
    592   DCHECK_EQ(&incoming_type == &undefined, incoming_type.IsUndefined());
    593   DCHECK_EQ(this == &conflict, IsConflict());
    594   DCHECK_EQ(&incoming_type == &conflict, incoming_type.IsConflict());
    595   if (this == &undefined || &incoming_type == &undefined) {
    596     // There is a difference between undefined and conflict. Conflicts may be copied around, but
    597     // not used. Undefined registers must not be copied. So any merge with undefined should return
    598     // undefined.
    599     return undefined;
    600   } else if (this == &conflict || &incoming_type == &conflict) {
    601     return conflict;  // (Conflict MERGE *) or (* MERGE Conflict) => Conflict
    602   } else if (IsConstant() && incoming_type.IsConstant()) {
    603     const ConstantType& type1 = *down_cast<const ConstantType*>(this);
    604     const ConstantType& type2 = *down_cast<const ConstantType*>(&incoming_type);
    605     int32_t val1 = type1.ConstantValue();
    606     int32_t val2 = type2.ConstantValue();
    607     if (val1 >= 0 && val2 >= 0) {
    608       // +ve1 MERGE +ve2 => MAX(+ve1, +ve2)
    609       if (val1 >= val2) {
    610         if (!type1.IsPreciseConstant()) {
    611           return *this;
    612         } else {
    613           return reg_types->FromCat1Const(val1, false);
    614         }
    615       } else {
    616         if (!type2.IsPreciseConstant()) {
    617           return type2;
    618         } else {
    619           return reg_types->FromCat1Const(val2, false);
    620         }
    621       }
    622     } else if (val1 < 0 && val2 < 0) {
    623       // -ve1 MERGE -ve2 => MIN(-ve1, -ve2)
    624       if (val1 <= val2) {
    625         if (!type1.IsPreciseConstant()) {
    626           return *this;
    627         } else {
    628           return reg_types->FromCat1Const(val1, false);
    629         }
    630       } else {
    631         if (!type2.IsPreciseConstant()) {
    632           return type2;
    633         } else {
    634           return reg_types->FromCat1Const(val2, false);
    635         }
    636       }
    637     } else {
    638       // Values are +ve and -ve, choose smallest signed type in which they both fit
    639       if (type1.IsConstantByte()) {
    640         if (type2.IsConstantByte()) {
    641           return reg_types->ByteConstant();
    642         } else if (type2.IsConstantShort()) {
    643           return reg_types->ShortConstant();
    644         } else {
    645           return reg_types->IntConstant();
    646         }
    647       } else if (type1.IsConstantShort()) {
    648         if (type2.IsConstantShort()) {
    649           return reg_types->ShortConstant();
    650         } else {
    651           return reg_types->IntConstant();
    652         }
    653       } else {
    654         return reg_types->IntConstant();
    655       }
    656     }
    657   } else if (IsConstantLo() && incoming_type.IsConstantLo()) {
    658     const ConstantType& type1 = *down_cast<const ConstantType*>(this);
    659     const ConstantType& type2 = *down_cast<const ConstantType*>(&incoming_type);
    660     int32_t val1 = type1.ConstantValueLo();
    661     int32_t val2 = type2.ConstantValueLo();
    662     return reg_types->FromCat2ConstLo(val1 | val2, false);
    663   } else if (IsConstantHi() && incoming_type.IsConstantHi()) {
    664     const ConstantType& type1 = *down_cast<const ConstantType*>(this);
    665     const ConstantType& type2 = *down_cast<const ConstantType*>(&incoming_type);
    666     int32_t val1 = type1.ConstantValueHi();
    667     int32_t val2 = type2.ConstantValueHi();
    668     return reg_types->FromCat2ConstHi(val1 | val2, false);
    669   } else if (IsIntegralTypes() && incoming_type.IsIntegralTypes()) {
    670     if (IsBooleanTypes() && incoming_type.IsBooleanTypes()) {
    671       return reg_types->Boolean();  // boolean MERGE boolean => boolean
    672     }
    673     if (IsByteTypes() && incoming_type.IsByteTypes()) {
    674       return reg_types->Byte();  // byte MERGE byte => byte
    675     }
    676     if (IsShortTypes() && incoming_type.IsShortTypes()) {
    677       return reg_types->Short();  // short MERGE short => short
    678     }
    679     if (IsCharTypes() && incoming_type.IsCharTypes()) {
    680       return reg_types->Char();  // char MERGE char => char
    681     }
    682     return reg_types->Integer();  // int MERGE * => int
    683   } else if ((IsFloatTypes() && incoming_type.IsFloatTypes()) ||
    684              (IsLongTypes() && incoming_type.IsLongTypes()) ||
    685              (IsLongHighTypes() && incoming_type.IsLongHighTypes()) ||
    686              (IsDoubleTypes() && incoming_type.IsDoubleTypes()) ||
    687              (IsDoubleHighTypes() && incoming_type.IsDoubleHighTypes())) {
    688     // check constant case was handled prior to entry
    689     DCHECK(!IsConstant() || !incoming_type.IsConstant());
    690     // float/long/double MERGE float/long/double_constant => float/long/double
    691     return SelectNonConstant(*this, incoming_type);
    692   } else if (IsReferenceTypes() && incoming_type.IsReferenceTypes()) {
    693     if (IsUninitializedTypes() || incoming_type.IsUninitializedTypes()) {
    694       // Something that is uninitialized hasn't had its constructor called. Unitialized types are
    695       // special. They may only ever be merged with themselves (must be taken care of by the
    696       // caller of Merge(), see the DCHECK on entry). So mark any other merge as conflicting here.
    697       return conflict;
    698     } else if (IsZero() || incoming_type.IsZero()) {
    699       return SelectNonConstant(*this, incoming_type);  // 0 MERGE ref => ref
    700     } else if (IsJavaLangObject() || incoming_type.IsJavaLangObject()) {
    701       return reg_types->JavaLangObject(false);  // Object MERGE ref => Object
    702     } else if (IsUnresolvedTypes() || incoming_type.IsUnresolvedTypes()) {
    703       // We know how to merge an unresolved type with itself, 0 or Object. In this case we
    704       // have two sub-classes and don't know how to merge. Create a new string-based unresolved
    705       // type that reflects our lack of knowledge and that allows the rest of the unresolved
    706       // mechanics to continue.
    707       return reg_types->FromUnresolvedMerge(*this, incoming_type, verifier);
    708     } else {  // Two reference types, compute Join
    709       mirror::Class* c1 = GetClass();
    710       mirror::Class* c2 = incoming_type.GetClass();
    711       DCHECK(c1 != nullptr && !c1->IsPrimitive());
    712       DCHECK(c2 != nullptr && !c2->IsPrimitive());
    713       mirror::Class* join_class = ClassJoin(c1, c2);
    714       if (UNLIKELY(join_class == nullptr)) {
    715         // Internal error joining the classes (e.g., OOME). Report an unresolved reference type.
    716         // We cannot report an unresolved merge type, as that will attempt to merge the resolved
    717         // components, leaving us in an infinite loop.
    718         // We do not want to report the originating exception, as that would require a fast path
    719         // out all the way to VerifyClass. Instead attempt to continue on without a detailed type.
    720         Thread* self = Thread::Current();
    721         self->AssertPendingException();
    722         self->ClearException();
    723 
    724         // When compiling on the host, we rather want to abort to ensure determinism for preopting.
    725         // (In that case, it is likely a misconfiguration of dex2oat.)
    726         if (!kIsTargetBuild && Runtime::Current()->IsAotCompiler()) {
    727           LOG(FATAL) << "Could not create class join of "
    728                      << c1->PrettyClass()
    729                      << " & "
    730                      << c2->PrettyClass();
    731           UNREACHABLE();
    732         }
    733 
    734         return reg_types->MakeUnresolvedReference();
    735       }
    736 
    737       // Record the dependency that both `c1` and `c2` are assignable to `join_class`.
    738       // The `verifier` is null during unit tests.
    739       if (verifier != nullptr) {
    740         VerifierDeps::MaybeRecordAssignability(
    741             verifier->GetDexFile(), join_class, c1, true /* strict */, true /* is_assignable */);
    742         VerifierDeps::MaybeRecordAssignability(
    743             verifier->GetDexFile(), join_class, c2, true /* strict */, true /* is_assignable */);
    744       }
    745       if (c1 == join_class && !IsPreciseReference()) {
    746         return *this;
    747       } else if (c2 == join_class && !incoming_type.IsPreciseReference()) {
    748         return incoming_type;
    749       } else {
    750         std::string temp;
    751         return reg_types->FromClass(join_class->GetDescriptor(&temp), join_class, false);
    752       }
    753     }
    754   } else {
    755     return conflict;  // Unexpected types => Conflict
    756   }
    757 }
    758 
    759 // See comment in reg_type.h
    760 mirror::Class* RegType::ClassJoin(mirror::Class* s, mirror::Class* t) {
    761   DCHECK(!s->IsPrimitive()) << s->PrettyClass();
    762   DCHECK(!t->IsPrimitive()) << t->PrettyClass();
    763   if (s == t) {
    764     return s;
    765   } else if (s->IsAssignableFrom(t)) {
    766     return s;
    767   } else if (t->IsAssignableFrom(s)) {
    768     return t;
    769   } else if (s->IsArrayClass() && t->IsArrayClass()) {
    770     mirror::Class* s_ct = s->GetComponentType();
    771     mirror::Class* t_ct = t->GetComponentType();
    772     if (s_ct->IsPrimitive() || t_ct->IsPrimitive()) {
    773       // Given the types aren't the same, if either array is of primitive types then the only
    774       // common parent is java.lang.Object
    775       mirror::Class* result = s->GetSuperClass();  // short-cut to java.lang.Object
    776       DCHECK(result->IsObjectClass());
    777       return result;
    778     }
    779     Thread* self = Thread::Current();
    780     ObjPtr<mirror::Class> common_elem = ClassJoin(s_ct, t_ct);
    781     if (UNLIKELY(common_elem == nullptr)) {
    782       self->AssertPendingException();
    783       return nullptr;
    784     }
    785     ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
    786     mirror::Class* array_class = class_linker->FindArrayClass(self, &common_elem);
    787     if (UNLIKELY(array_class == nullptr)) {
    788       self->AssertPendingException();
    789       return nullptr;
    790     }
    791     return array_class;
    792   } else {
    793     size_t s_depth = s->Depth();
    794     size_t t_depth = t->Depth();
    795     // Get s and t to the same depth in the hierarchy
    796     if (s_depth > t_depth) {
    797       while (s_depth > t_depth) {
    798         s = s->GetSuperClass();
    799         s_depth--;
    800       }
    801     } else {
    802       while (t_depth > s_depth) {
    803         t = t->GetSuperClass();
    804         t_depth--;
    805       }
    806     }
    807     // Go up the hierarchy until we get to the common parent
    808     while (s != t) {
    809       s = s->GetSuperClass();
    810       t = t->GetSuperClass();
    811     }
    812     return s;
    813   }
    814 }
    815 
    816 void RegType::CheckInvariants() const {
    817   if (IsConstant() || IsConstantLo() || IsConstantHi()) {
    818     CHECK(descriptor_.empty()) << *this;
    819     CHECK(klass_.IsNull()) << *this;
    820   }
    821   if (!klass_.IsNull()) {
    822     CHECK(!descriptor_.empty()) << *this;
    823     std::string temp;
    824     CHECK_EQ(descriptor_, klass_.Read()->GetDescriptor(&temp)) << *this;
    825   }
    826 }
    827 
    828 void RegType::VisitRoots(RootVisitor* visitor, const RootInfo& root_info) const {
    829   klass_.VisitRootIfNonNull(visitor, root_info);
    830 }
    831 
    832 void UninitializedThisReferenceType::CheckInvariants() const {
    833   CHECK_EQ(GetAllocationPc(), 0U) << *this;
    834 }
    835 
    836 void UnresolvedUninitializedThisRefType::CheckInvariants() const {
    837   CHECK_EQ(GetAllocationPc(), 0U) << *this;
    838   CHECK(!descriptor_.empty()) << *this;
    839   CHECK(klass_.IsNull()) << *this;
    840 }
    841 
    842 void UnresolvedUninitializedRefType::CheckInvariants() const {
    843   CHECK(!descriptor_.empty()) << *this;
    844   CHECK(klass_.IsNull()) << *this;
    845 }
    846 
    847 UnresolvedMergedType::UnresolvedMergedType(const RegType& resolved,
    848                                            const BitVector& unresolved,
    849                                            const RegTypeCache* reg_type_cache,
    850                                            uint16_t cache_id)
    851     : UnresolvedType("", cache_id),
    852       reg_type_cache_(reg_type_cache),
    853       resolved_part_(resolved),
    854       unresolved_types_(unresolved, false, unresolved.GetAllocator()) {
    855   CheckConstructorInvariants(this);
    856 }
    857 void UnresolvedMergedType::CheckInvariants() const {
    858   CHECK(reg_type_cache_ != nullptr);
    859 
    860   // Unresolved merged types: merged types should be defined.
    861   CHECK(descriptor_.empty()) << *this;
    862   CHECK(klass_.IsNull()) << *this;
    863 
    864   CHECK(!resolved_part_.IsConflict());
    865   CHECK(resolved_part_.IsReferenceTypes());
    866   CHECK(!resolved_part_.IsUnresolvedTypes());
    867 
    868   CHECK(resolved_part_.IsZero() ||
    869         !(resolved_part_.IsArrayTypes() && !resolved_part_.IsObjectArrayTypes()));
    870 
    871   CHECK_GT(unresolved_types_.NumSetBits(), 0U);
    872   bool unresolved_is_array =
    873       reg_type_cache_->GetFromId(unresolved_types_.GetHighestBitSet()).IsArrayTypes();
    874   for (uint32_t idx : unresolved_types_.Indexes()) {
    875     const RegType& t = reg_type_cache_->GetFromId(idx);
    876     CHECK_EQ(unresolved_is_array, t.IsArrayTypes());
    877   }
    878 
    879   if (!resolved_part_.IsZero()) {
    880     CHECK_EQ(resolved_part_.IsArrayTypes(), unresolved_is_array);
    881   }
    882 }
    883 
    884 bool UnresolvedMergedType::IsArrayTypes() const {
    885   // For a merge to be an array, both the resolved and the unresolved part need to be object
    886   // arrays.
    887   // (Note: we encode a missing resolved part [which doesn't need to be an array] as zero.)
    888 
    889   if (!resolved_part_.IsZero() && !resolved_part_.IsArrayTypes()) {
    890     return false;
    891   }
    892 
    893   // It is enough to check just one of the merged types. Otherwise the merge should have been
    894   // collapsed (checked in CheckInvariants on construction).
    895   uint32_t idx = unresolved_types_.GetHighestBitSet();
    896   const RegType& unresolved = reg_type_cache_->GetFromId(idx);
    897   return unresolved.IsArrayTypes();
    898 }
    899 bool UnresolvedMergedType::IsObjectArrayTypes() const {
    900   // Same as IsArrayTypes, as primitive arrays are always resolved.
    901   return IsArrayTypes();
    902 }
    903 
    904 void UnresolvedReferenceType::CheckInvariants() const {
    905   CHECK(!descriptor_.empty()) << *this;
    906   CHECK(klass_.IsNull()) << *this;
    907 }
    908 
    909 void UnresolvedSuperClass::CheckInvariants() const {
    910   // Unresolved merged types: merged types should be defined.
    911   CHECK(descriptor_.empty()) << *this;
    912   CHECK(klass_.IsNull()) << *this;
    913   CHECK_NE(unresolved_child_id_, 0U) << *this;
    914 }
    915 
    916 std::ostream& operator<<(std::ostream& os, const RegType& rhs) {
    917   os << rhs.Dump();
    918   return os;
    919 }
    920 
    921 bool RegType::CanAssignArray(const RegType& src,
    922                              RegTypeCache& reg_types,
    923                              Handle<mirror::ClassLoader> class_loader,
    924                              MethodVerifier* verifier,
    925                              bool* soft_error) const {
    926   if (!IsArrayTypes() || !src.IsArrayTypes()) {
    927     *soft_error = false;
    928     return false;
    929   }
    930 
    931   if (IsUnresolvedMergedReference() || src.IsUnresolvedMergedReference()) {
    932     // An unresolved array type means that it's an array of some reference type. Reference arrays
    933     // can never be assigned to primitive-type arrays, and vice versa. So it is a soft error if
    934     // both arrays are reference arrays, otherwise a hard error.
    935     *soft_error = IsObjectArrayTypes() && src.IsObjectArrayTypes();
    936     return false;
    937   }
    938 
    939   const RegType& cmp1 = reg_types.GetComponentType(*this, class_loader.Get());
    940   const RegType& cmp2 = reg_types.GetComponentType(src, class_loader.Get());
    941 
    942   if (cmp1.IsAssignableFrom(cmp2, verifier)) {
    943     return true;
    944   }
    945   if (cmp1.IsUnresolvedTypes()) {
    946     if (cmp2.IsIntegralTypes() || cmp2.IsFloatTypes() || cmp2.IsArrayTypes()) {
    947       *soft_error = false;
    948       return false;
    949     }
    950     *soft_error = true;
    951     return false;
    952   }
    953   if (cmp2.IsUnresolvedTypes()) {
    954     if (cmp1.IsIntegralTypes() || cmp1.IsFloatTypes() || cmp1.IsArrayTypes()) {
    955       *soft_error = false;
    956       return false;
    957     }
    958     *soft_error = true;
    959     return false;
    960   }
    961   if (!cmp1.IsArrayTypes() || !cmp2.IsArrayTypes()) {
    962     *soft_error = false;
    963     return false;
    964   }
    965   return cmp1.CanAssignArray(cmp2, reg_types, class_loader, verifier, soft_error);
    966 }
    967 
    968 
    969 }  // namespace verifier
    970 }  // namespace art
    971