/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "reg_type-inl.h"

#include "android-base/stringprintf.h"

#include "base/arena_bit_vector.h"
#include "base/bit_vector-inl.h"
#include "base/casts.h"
#include "class_linker-inl.h"
#include "dex/descriptors_names.h"
#include "dex/dex_file-inl.h"
#include "method_verifier.h"
#include "mirror/class-inl.h"
#include "mirror/class.h"
#include "mirror/object-inl.h"
#include "mirror/object_array-inl.h"
#include "reg_type_cache-inl.h"
#include "scoped_thread_state_change-inl.h"

#include <limits>
#include <sstream>

namespace art {
namespace verifier {

using android::base::StringPrintf;

const UndefinedType* UndefinedType::instance_ = nullptr;
const ConflictType* ConflictType::instance_ = nullptr;
const BooleanType* BooleanType::instance_ = nullptr;
const ByteType* ByteType::instance_ = nullptr;
const ShortType* ShortType::instance_ = nullptr;
const CharType* CharType::instance_ = nullptr;
const FloatType* FloatType::instance_ = nullptr;
const LongLoType* LongLoType::instance_ = nullptr;
const LongHiType* LongHiType::instance_ = nullptr;
const DoubleLoType* DoubleLoType::instance_ = nullptr;
const DoubleHiType* DoubleHiType::instance_ = nullptr;
const IntegerType* IntegerType::instance_ = nullptr;
const NullType* NullType::instance_ = nullptr;

PrimitiveType::PrimitiveType(ObjPtr<mirror::Class> klass,
                             const StringPiece& descriptor,
                             uint16_t cache_id)
    : RegType(klass, descriptor, cache_id) {
  CHECK(klass != nullptr);
  CHECK(!descriptor.empty());
}

Cat1Type::Cat1Type(ObjPtr<mirror::Class> klass, const StringPiece& descriptor, uint16_t cache_id)
    : PrimitiveType(klass, descriptor, cache_id) {
}

Cat2Type::Cat2Type(ObjPtr<mirror::Class> klass, const StringPiece& descriptor, uint16_t cache_id)
    : PrimitiveType(klass, descriptor, cache_id) {
}

std::string PreciseConstType::Dump() const {
  std::stringstream result;
  uint32_t val = ConstantValue();
  if (val == 0) {
    CHECK(IsPreciseConstant());
    result << "Zero/null";
  } else {
    result << "Precise ";
    if (IsConstantShort()) {
      result << StringPrintf("Constant: %d", val);
    } else {
      result << StringPrintf("Constant: 0x%x", val);
    }
  }
  return result.str();
}

std::string BooleanType::Dump() const {
  return "Boolean";
}

std::string ConflictType::Dump() const {
    return "Conflict";
}

std::string ByteType::Dump() const {
  return "Byte";
}

std::string ShortType::Dump() const {
  return "Short";
}

std::string CharType::Dump() const {
  return "Char";
}

std::string FloatType::Dump() const {
  return "Float";
}

std::string LongLoType::Dump() const {
  return "Long (Low Half)";
}

std::string LongHiType::Dump() const {
  return "Long (High Half)";
}

std::string DoubleLoType::Dump() const {
  return "Double (Low Half)";
}

std::string DoubleHiType::Dump() const {
  return "Double (High Half)";
}

std::string IntegerType::Dump() const {
  return "Integer";
}

const DoubleHiType* DoubleHiType::CreateInstance(ObjPtr<mirror::Class> klass,
                                                 const StringPiece& descriptor,
                                                 uint16_t cache_id) {
  CHECK(instance_ == nullptr);
  instance_ = new DoubleHiType(klass, descriptor, cache_id);
  return instance_;
}

void DoubleHiType::Destroy() {
  if (instance_ != nullptr) {
    delete instance_;
    instance_ = nullptr;
  }
}

const DoubleLoType* DoubleLoType::CreateInstance(ObjPtr<mirror::Class> klass,
                                                 const StringPiece& descriptor,
                                                 uint16_t cache_id) {
  CHECK(instance_ == nullptr);
  instance_ = new DoubleLoType(klass, descriptor, cache_id);
  return instance_;
}

void DoubleLoType::Destroy() {
  if (instance_ != nullptr) {
    delete instance_;
    instance_ = nullptr;
  }
}

const LongLoType* LongLoType::CreateInstance(ObjPtr<mirror::Class> klass,
                                             const StringPiece& descriptor,
                                             uint16_t cache_id) {
  CHECK(instance_ == nullptr);
  instance_ = new LongLoType(klass, descriptor, cache_id);
  return instance_;
}

const LongHiType* LongHiType::CreateInstance(ObjPtr<mirror::Class> klass,
                                             const StringPiece& descriptor,
                                             uint16_t cache_id) {
  CHECK(instance_ == nullptr);
  instance_ = new LongHiType(klass, descriptor, cache_id);
  return instance_;
}

void LongHiType::Destroy() {
  if (instance_ != nullptr) {
    delete instance_;
    instance_ = nullptr;
  }
}

void LongLoType::Destroy() {
  if (instance_ != nullptr) {
    delete instance_;
    instance_ = nullptr;
  }
}

const FloatType* FloatType::CreateInstance(ObjPtr<mirror::Class> klass,
                                           const StringPiece& descriptor,
                                           uint16_t cache_id) {
  CHECK(instance_ == nullptr);
  instance_ = new FloatType(klass, descriptor, cache_id);
  return instance_;
}

void FloatType::Destroy() {
  if (instance_ != nullptr) {
    delete instance_;
    instance_ = nullptr;
  }
}

const CharType* CharType::CreateInstance(ObjPtr<mirror::Class> klass,
                                         const StringPiece& descriptor,
                                         uint16_t cache_id) {
  CHECK(instance_ == nullptr);
  instance_ = new CharType(klass, descriptor, cache_id);
  return instance_;
}

void CharType::Destroy() {
  if (instance_ != nullptr) {
    delete instance_;
    instance_ = nullptr;
  }
}

const ShortType* ShortType::CreateInstance(ObjPtr<mirror::Class> klass,
                                           const StringPiece& descriptor,
                                           uint16_t cache_id) {
  CHECK(instance_ == nullptr);
  instance_ = new ShortType(klass, descriptor, cache_id);
  return instance_;
}

void ShortType::Destroy() {
  if (instance_ != nullptr) {
    delete instance_;
    instance_ = nullptr;
  }
}

const ByteType* ByteType::CreateInstance(ObjPtr<mirror::Class> klass,
                                         const StringPiece& descriptor,
                                         uint16_t cache_id) {
  CHECK(instance_ == nullptr);
  instance_ = new ByteType(klass, descriptor, cache_id);
  return instance_;
}

void ByteType::Destroy() {
  if (instance_ != nullptr) {
    delete instance_;
    instance_ = nullptr;
  }
}

const IntegerType* IntegerType::CreateInstance(ObjPtr<mirror::Class> klass,
                                               const StringPiece& descriptor,
                                               uint16_t cache_id) {
  CHECK(instance_ == nullptr);
  instance_ = new IntegerType(klass, descriptor, cache_id);
  return instance_;
}

void IntegerType::Destroy() {
  if (instance_ != nullptr) {
    delete instance_;
    instance_ = nullptr;
  }
}

const ConflictType* ConflictType::CreateInstance(ObjPtr<mirror::Class> klass,
                                                 const StringPiece& descriptor,
                                                 uint16_t cache_id) {
  CHECK(instance_ == nullptr);
  instance_ = new ConflictType(klass, descriptor, cache_id);
  return instance_;
}

void ConflictType::Destroy() {
  if (instance_ != nullptr) {
    delete instance_;
    instance_ = nullptr;
  }
}

const BooleanType* BooleanType::CreateInstance(ObjPtr<mirror::Class> klass,
                                               const StringPiece& descriptor,
                                               uint16_t cache_id) {
  CHECK(BooleanType::instance_ == nullptr);
  instance_ = new BooleanType(klass, descriptor, cache_id);
  return BooleanType::instance_;
}

void BooleanType::Destroy() {
  if (BooleanType::instance_ != nullptr) {
    delete instance_;
    instance_ = nullptr;
  }
}

std::string UndefinedType::Dump() const REQUIRES_SHARED(Locks::mutator_lock_) {
  return "Undefined";
}

const UndefinedType* UndefinedType::CreateInstance(ObjPtr<mirror::Class> klass,
                                                   const StringPiece& descriptor,
                                                   uint16_t cache_id) {
  CHECK(instance_ == nullptr);
  instance_ = new UndefinedType(klass, descriptor, cache_id);
  return instance_;
}

void UndefinedType::Destroy() {
  if (instance_ != nullptr) {
    delete instance_;
    instance_ = nullptr;
  }
}

PreciseReferenceType::PreciseReferenceType(ObjPtr<mirror::Class> klass,
                                           const StringPiece& descriptor,
                                           uint16_t cache_id)
    : RegType(klass, descriptor, cache_id) {
  // Note: no check for IsInstantiable() here. We may produce this in case an InstantiationError
  //       would be thrown at runtime, but we need to continue verification and *not* create a
  //       hard failure or abort.
  CheckConstructorInvariants(this);
}

std::string UnresolvedMergedType::Dump() const {
  std::stringstream result;
  result << "UnresolvedMergedReferences(" << GetResolvedPart().Dump() << " | ";
  const BitVector& types = GetUnresolvedTypes();

  bool first = true;
  for (uint32_t idx : types.Indexes()) {
    if (!first) {
      result << ", ";
    } else {
      first = false;
    }
    result << reg_type_cache_->GetFromId(idx).Dump();
  }
  result << ")";
  return result.str();
}

std::string UnresolvedSuperClass::Dump() const {
  std::stringstream result;
  uint16_t super_type_id = GetUnresolvedSuperClassChildId();
  result << "UnresolvedSuperClass(" << reg_type_cache_->GetFromId(super_type_id).Dump() << ")";
  return result.str();
}

std::string UnresolvedReferenceType::Dump() const {
  std::stringstream result;
  result << "Unresolved Reference" << ": " << PrettyDescriptor(GetDescriptor().as_string().c_str());
  return result.str();
}

std::string UnresolvedUninitializedRefType::Dump() const {
  std::stringstream result;
  result << "Unresolved And Uninitialized Reference" << ": "
      << PrettyDescriptor(GetDescriptor().as_string().c_str())
      << " Allocation PC: " << GetAllocationPc();
  return result.str();
}

std::string UnresolvedUninitializedThisRefType::Dump() const {
  std::stringstream result;
  result << "Unresolved And Uninitialized This Reference"
      << PrettyDescriptor(GetDescriptor().as_string().c_str());
  return result.str();
}

std::string ReferenceType::Dump() const {
  std::stringstream result;
  result << "Reference" << ": " << mirror::Class::PrettyDescriptor(GetClass());
  return result.str();
}

std::string PreciseReferenceType::Dump() const {
  std::stringstream result;
  result << "Precise Reference" << ": "<< mirror::Class::PrettyDescriptor(GetClass());
  return result.str();
}

std::string UninitializedReferenceType::Dump() const {
  std::stringstream result;
  result << "Uninitialized Reference" << ": " << mirror::Class::PrettyDescriptor(GetClass());
  result << " Allocation PC: " << GetAllocationPc();
  return result.str();
}

std::string UninitializedThisReferenceType::Dump() const {
  std::stringstream result;
  result << "Uninitialized This Reference" << ": " << mirror::Class::PrettyDescriptor(GetClass());
  result << "Allocation PC: " << GetAllocationPc();
  return result.str();
}

std::string ImpreciseConstType::Dump() const {
  std::stringstream result;
  uint32_t val = ConstantValue();
  if (val == 0) {
    result << "Zero/null";
  } else {
    result << "Imprecise ";
    if (IsConstantShort()) {
      result << StringPrintf("Constant: %d", val);
    } else {
      result << StringPrintf("Constant: 0x%x", val);
    }
  }
  return result.str();
}
std::string PreciseConstLoType::Dump() const {
  std::stringstream result;

  int32_t val = ConstantValueLo();
  result << "Precise ";
  if (val >= std::numeric_limits<jshort>::min() &&
      val <= std::numeric_limits<jshort>::max()) {
    result << StringPrintf("Low-half Constant: %d", val);
  } else {
    result << StringPrintf("Low-half Constant: 0x%x", val);
  }
  return result.str();
}

std::string ImpreciseConstLoType::Dump() const {
  std::stringstream result;

  int32_t val = ConstantValueLo();
  result << "Imprecise ";
  if (val >= std::numeric_limits<jshort>::min() &&
      val <= std::numeric_limits<jshort>::max()) {
    result << StringPrintf("Low-half Constant: %d", val);
  } else {
    result << StringPrintf("Low-half Constant: 0x%x", val);
  }
  return result.str();
}

std::string PreciseConstHiType::Dump() const {
  std::stringstream result;
  int32_t val = ConstantValueHi();
  result << "Precise ";
  if (val >= std::numeric_limits<jshort>::min() &&
      val <= std::numeric_limits<jshort>::max()) {
    result << StringPrintf("High-half Constant: %d", val);
  } else {
    result << StringPrintf("High-half Constant: 0x%x", val);
  }
  return result.str();
}

std::string ImpreciseConstHiType::Dump() const {
  std::stringstream result;
  int32_t val = ConstantValueHi();
  result << "Imprecise ";
  if (val >= std::numeric_limits<jshort>::min() &&
      val <= std::numeric_limits<jshort>::max()) {
    result << StringPrintf("High-half Constant: %d", val);
  } else {
    result << StringPrintf("High-half Constant: 0x%x", val);
  }
  return result.str();
}

const RegType& RegType::HighHalf(RegTypeCache* cache) const {
  DCHECK(IsLowHalf());
  if (IsLongLo()) {
    return cache->LongHi();
  } else if (IsDoubleLo()) {
    return cache->DoubleHi();
  } else {
    DCHECK(IsImpreciseConstantLo());
    const ConstantType* const_val = down_cast<const ConstantType*>(this);
    return cache->FromCat2ConstHi(const_val->ConstantValue(), false);
  }
}

Primitive::Type RegType::GetPrimitiveType() const {
  if (IsNonZeroReferenceTypes()) {
    return Primitive::kPrimNot;
  } else if (IsBooleanTypes()) {
    return Primitive::kPrimBoolean;
  } else if (IsByteTypes()) {
    return Primitive::kPrimByte;
  } else if (IsShortTypes()) {
    return Primitive::kPrimShort;
  } else if (IsCharTypes()) {
    return Primitive::kPrimChar;
  } else if (IsFloat()) {
    return Primitive::kPrimFloat;
  } else if (IsIntegralTypes()) {
    return Primitive::kPrimInt;
  } else if (IsDoubleLo()) {
    return Primitive::kPrimDouble;
  } else {
    DCHECK(IsLongTypes());
    return Primitive::kPrimLong;
  }
}

bool UninitializedType::IsUninitializedTypes() const {
  return true;
}

bool UninitializedType::IsNonZeroReferenceTypes() const {
  return true;
}

bool UnresolvedType::IsNonZeroReferenceTypes() const {
  return true;
}

const RegType& RegType::GetSuperClass(RegTypeCache* cache) const {
  if (!IsUnresolvedTypes()) {
    ObjPtr<mirror::Class> super_klass = GetClass()->GetSuperClass();
    if (super_klass != nullptr) {
      // A super class of a precise type isn't precise as a precise type indicates the register
      // holds exactly that type.
      std::string temp;
      return cache->FromClass(super_klass->GetDescriptor(&temp), super_klass, false);
    } else {
      return cache->Zero();
    }
  } else {
    if (!IsUnresolvedMergedReference() && !IsUnresolvedSuperClass() &&
        GetDescriptor()[0] == '[') {
      // Super class of all arrays is Object.
      return cache->JavaLangObject(true);
    } else {
      return cache->FromUnresolvedSuperClass(*this);
    }
  }
}

bool RegType::IsJavaLangObject() const REQUIRES_SHARED(Locks::mutator_lock_) {
  return IsReference() && GetClass()->IsObjectClass();
}

bool RegType::IsObjectArrayTypes() const REQUIRES_SHARED(Locks::mutator_lock_) {
  if (IsUnresolvedTypes()) {
    DCHECK(!IsUnresolvedMergedReference());

    if (IsUnresolvedSuperClass()) {
      // Cannot be an array, as the superclass of arrays is java.lang.Object (which cannot be
      // unresolved).
      return false;
    }

    // Primitive arrays will always resolve.
    DCHECK(descriptor_[1] == 'L' || descriptor_[1] == '[');
    return descriptor_[0] == '[';
  } else if (HasClass()) {
    ObjPtr<mirror::Class> type = GetClass();
    return type->IsArrayClass() && !type->GetComponentType()->IsPrimitive();
  } else {
    return false;
  }
}

bool RegType::IsArrayTypes() const REQUIRES_SHARED(Locks::mutator_lock_) {
  if (IsUnresolvedTypes()) {
    DCHECK(!IsUnresolvedMergedReference());

    if (IsUnresolvedSuperClass()) {
      // Cannot be an array, as the superclass of arrays is java.lang.Object (which cannot be
      // unresolved).
      return false;
    }
    return descriptor_[0] == '[';
  } else if (HasClass()) {
    return GetClass()->IsArrayClass();
  } else {
    return false;
  }
}

bool RegType::IsJavaLangObjectArray() const {
  if (HasClass()) {
    ObjPtr<mirror::Class> type = GetClass();
    return type->IsArrayClass() && type->GetComponentType()->IsObjectClass();
  }
  return false;
}

bool RegType::IsInstantiableTypes() const {
  return IsUnresolvedTypes() || (IsNonZeroReferenceTypes() && GetClass()->IsInstantiable());
}

static const RegType& SelectNonConstant(const RegType& a, const RegType& b) {
  return a.IsConstantTypes() ? b : a;
}

static const RegType& SelectNonConstant2(const RegType& a, const RegType& b) {
  return a.IsConstantTypes() ? (b.IsZero() ? a : b) : a;
}

const RegType& RegType::Merge(const RegType& incoming_type,
                              RegTypeCache* reg_types,
                              MethodVerifier* verifier) const {
  DCHECK(!Equals(incoming_type));  // Trivial equality handled by caller
  // Perform pointer equality tests for undefined and conflict to avoid virtual method dispatch.
  const UndefinedType& undefined = reg_types->Undefined();
  const ConflictType& conflict = reg_types->Conflict();
  DCHECK_EQ(this == &undefined, IsUndefined());
  DCHECK_EQ(&incoming_type == &undefined, incoming_type.IsUndefined());
  DCHECK_EQ(this == &conflict, IsConflict());
  DCHECK_EQ(&incoming_type == &conflict, incoming_type.IsConflict());
  if (this == &undefined || &incoming_type == &undefined) {
    // There is a difference between undefined and conflict. Conflicts may be copied around, but
    // not used. Undefined registers must not be copied. So any merge with undefined should return
    // undefined.
    return undefined;
  } else if (this == &conflict || &incoming_type == &conflict) {
    return conflict;  // (Conflict MERGE *) or (* MERGE Conflict) => Conflict
  } else if (IsConstant() && incoming_type.IsConstant()) {
    const ConstantType& type1 = *down_cast<const ConstantType*>(this);
    const ConstantType& type2 = *down_cast<const ConstantType*>(&incoming_type);
    int32_t val1 = type1.ConstantValue();
    int32_t val2 = type2.ConstantValue();
    if (val1 >= 0 && val2 >= 0) {
      // +ve1 MERGE +ve2 => MAX(+ve1, +ve2)
      if (val1 >= val2) {
        if (!type1.IsPreciseConstant()) {
          return *this;
        } else {
          return reg_types->FromCat1Const(val1, false);
        }
      } else {
        if (!type2.IsPreciseConstant()) {
          return type2;
        } else {
          return reg_types->FromCat1Const(val2, false);
        }
      }
    } else if (val1 < 0 && val2 < 0) {
      // -ve1 MERGE -ve2 => MIN(-ve1, -ve2)
      if (val1 <= val2) {
        if (!type1.IsPreciseConstant()) {
          return *this;
        } else {
          return reg_types->FromCat1Const(val1, false);
        }
      } else {
        if (!type2.IsPreciseConstant()) {
          return type2;
        } else {
          return reg_types->FromCat1Const(val2, false);
        }
      }
    } else {
      // Values are +ve and -ve, choose smallest signed type in which they both fit
      if (type1.IsConstantByte()) {
        if (type2.IsConstantByte()) {
          return reg_types->ByteConstant();
        } else if (type2.IsConstantShort()) {
          return reg_types->ShortConstant();
        } else {
          return reg_types->IntConstant();
        }
      } else if (type1.IsConstantShort()) {
        if (type2.IsConstantShort()) {
          return reg_types->ShortConstant();
        } else {
          return reg_types->IntConstant();
        }
      } else {
        return reg_types->IntConstant();
      }
    }
  } else if (IsConstantLo() && incoming_type.IsConstantLo()) {
    const ConstantType& type1 = *down_cast<const ConstantType*>(this);
    const ConstantType& type2 = *down_cast<const ConstantType*>(&incoming_type);
    int32_t val1 = type1.ConstantValueLo();
    int32_t val2 = type2.ConstantValueLo();
    return reg_types->FromCat2ConstLo(val1 | val2, false);
  } else if (IsConstantHi() && incoming_type.IsConstantHi()) {
    const ConstantType& type1 = *down_cast<const ConstantType*>(this);
    const ConstantType& type2 = *down_cast<const ConstantType*>(&incoming_type);
    int32_t val1 = type1.ConstantValueHi();
    int32_t val2 = type2.ConstantValueHi();
    return reg_types->FromCat2ConstHi(val1 | val2, false);
  } else if (IsIntegralTypes() && incoming_type.IsIntegralTypes()) {
    if (IsBooleanTypes() && incoming_type.IsBooleanTypes()) {
      return reg_types->Boolean();  // boolean MERGE boolean => boolean
    }
    if (IsByteTypes() && incoming_type.IsByteTypes()) {
      return reg_types->Byte();  // byte MERGE byte => byte
    }
    if (IsShortTypes() && incoming_type.IsShortTypes()) {
      return reg_types->Short();  // short MERGE short => short
    }
    if (IsCharTypes() && incoming_type.IsCharTypes()) {
      return reg_types->Char();  // char MERGE char => char
    }
    return reg_types->Integer();  // int MERGE * => int
  } else if ((IsFloatTypes() && incoming_type.IsFloatTypes()) ||
             (IsLongTypes() && incoming_type.IsLongTypes()) ||
             (IsLongHighTypes() && incoming_type.IsLongHighTypes()) ||
             (IsDoubleTypes() && incoming_type.IsDoubleTypes()) ||
             (IsDoubleHighTypes() && incoming_type.IsDoubleHighTypes())) {
    // check constant case was handled prior to entry
    DCHECK(!IsConstant() || !incoming_type.IsConstant());
    // float/long/double MERGE float/long/double_constant => float/long/double
    return SelectNonConstant(*this, incoming_type);
  } else if (IsReferenceTypes() && incoming_type.IsReferenceTypes()) {
    if (IsUninitializedTypes() || incoming_type.IsUninitializedTypes()) {
      // Something that is uninitialized hasn't had its constructor called. Unitialized types are
      // special. They may only ever be merged with themselves (must be taken care of by the
      // caller of Merge(), see the DCHECK on entry). So mark any other merge as conflicting here.
      return conflict;
    } else if (IsZeroOrNull() || incoming_type.IsZeroOrNull()) {
      return SelectNonConstant2(*this, incoming_type);  // 0 MERGE ref => ref
    } else if (IsJavaLangObject() || incoming_type.IsJavaLangObject()) {
      return reg_types->JavaLangObject(false);  // Object MERGE ref => Object
    } else if (IsUnresolvedTypes() || incoming_type.IsUnresolvedTypes()) {
      // We know how to merge an unresolved type with itself, 0 or Object. In this case we
      // have two sub-classes and don't know how to merge. Create a new string-based unresolved
      // type that reflects our lack of knowledge and that allows the rest of the unresolved
      // mechanics to continue.
      return reg_types->FromUnresolvedMerge(*this, incoming_type, verifier);
    } else {  // Two reference types, compute Join
      // Do not cache the classes as ClassJoin() can suspend and invalidate ObjPtr<>s.
      DCHECK(GetClass() != nullptr && !GetClass()->IsPrimitive());
      DCHECK(incoming_type.GetClass() != nullptr && !incoming_type.GetClass()->IsPrimitive());
      ObjPtr<mirror::Class> join_class = ClassJoin(GetClass(), incoming_type.GetClass());
      if (UNLIKELY(join_class == nullptr)) {
        // Internal error joining the classes (e.g., OOME). Report an unresolved reference type.
        // We cannot report an unresolved merge type, as that will attempt to merge the resolved
        // components, leaving us in an infinite loop.
        // We do not want to report the originating exception, as that would require a fast path
        // out all the way to VerifyClass. Instead attempt to continue on without a detailed type.
        Thread* self = Thread::Current();
        self->AssertPendingException();
        self->ClearException();

        // When compiling on the host, we rather want to abort to ensure determinism for preopting.
        // (In that case, it is likely a misconfiguration of dex2oat.)
        if (!kIsTargetBuild && Runtime::Current()->IsAotCompiler()) {
          LOG(FATAL) << "Could not create class join of "
                     << GetClass()->PrettyClass()
                     << " & "
                     << incoming_type.GetClass()->PrettyClass();
          UNREACHABLE();
        }

        return reg_types->MakeUnresolvedReference();
      }

      // Record the dependency that both `GetClass()` and `incoming_type.GetClass()`
      // are assignable to `join_class`. The `verifier` is null during unit tests.
      if (verifier != nullptr) {
        VerifierDeps::MaybeRecordAssignability(verifier->GetDexFile(),
                                               join_class,
                                               GetClass(),
                                               /* strict */ true,
                                               /* is_assignable */ true);
        VerifierDeps::MaybeRecordAssignability(verifier->GetDexFile(),
                                               join_class,
                                               incoming_type.GetClass(),
                                               /* strict */ true,
                                               /* is_assignable */ true);
      }
      if (GetClass() == join_class && !IsPreciseReference()) {
        return *this;
      } else if (incoming_type.GetClass() == join_class && !incoming_type.IsPreciseReference()) {
        return incoming_type;
      } else {
        std::string temp;
        const char* descriptor = join_class->GetDescriptor(&temp);
        return reg_types->FromClass(descriptor, join_class, /* precise */ false);
      }
    }
  } else {
    return conflict;  // Unexpected types => Conflict
  }
}

// See comment in reg_type.h
ObjPtr<mirror::Class> RegType::ClassJoin(ObjPtr<mirror::Class> s, ObjPtr<mirror::Class> t) {
  DCHECK(!s->IsPrimitive()) << s->PrettyClass();
  DCHECK(!t->IsPrimitive()) << t->PrettyClass();
  if (s == t) {
    return s;
  } else if (s->IsAssignableFrom(t)) {
    return s;
  } else if (t->IsAssignableFrom(s)) {
    return t;
  } else if (s->IsArrayClass() && t->IsArrayClass()) {
    ObjPtr<mirror::Class> s_ct = s->GetComponentType();
    ObjPtr<mirror::Class> t_ct = t->GetComponentType();
    if (s_ct->IsPrimitive() || t_ct->IsPrimitive()) {
      // Given the types aren't the same, if either array is of primitive types then the only
      // common parent is java.lang.Object
      ObjPtr<mirror::Class> result = s->GetSuperClass();  // short-cut to java.lang.Object
      DCHECK(result->IsObjectClass());
      return result;
    }
    Thread* self = Thread::Current();
    ObjPtr<mirror::Class> common_elem = ClassJoin(s_ct, t_ct);
    if (UNLIKELY(common_elem == nullptr)) {
      self->AssertPendingException();
      return nullptr;
    }
    // Note: The following lookup invalidates existing ObjPtr<>s.
    ObjPtr<mirror::Class> array_class =
        Runtime::Current()->GetClassLinker()->FindArrayClass(self, &common_elem);
    if (UNLIKELY(array_class == nullptr)) {
      self->AssertPendingException();
      return nullptr;
    }
    return array_class;
  } else {
    size_t s_depth = s->Depth();
    size_t t_depth = t->Depth();
    // Get s and t to the same depth in the hierarchy
    if (s_depth > t_depth) {
      while (s_depth > t_depth) {
        s = s->GetSuperClass();
        s_depth--;
      }
    } else {
      while (t_depth > s_depth) {
        t = t->GetSuperClass();
        t_depth--;
      }
    }
    // Go up the hierarchy until we get to the common parent
    while (s != t) {
      s = s->GetSuperClass();
      t = t->GetSuperClass();
    }
    return s;
  }
}

void RegType::CheckInvariants() const {
  if (IsConstant() || IsConstantLo() || IsConstantHi()) {
    CHECK(descriptor_.empty()) << *this;
    CHECK(klass_.IsNull()) << *this;
  }
  if (!klass_.IsNull()) {
    CHECK(!descriptor_.empty()) << *this;
    std::string temp;
    CHECK_EQ(descriptor_, klass_.Read()->GetDescriptor(&temp)) << *this;
  }
}

void RegType::VisitRoots(RootVisitor* visitor, const RootInfo& root_info) const {
  klass_.VisitRootIfNonNull(visitor, root_info);
}

void UninitializedThisReferenceType::CheckInvariants() const {
  CHECK_EQ(GetAllocationPc(), 0U) << *this;
}

void UnresolvedUninitializedThisRefType::CheckInvariants() const {
  CHECK_EQ(GetAllocationPc(), 0U) << *this;
  CHECK(!descriptor_.empty()) << *this;
  CHECK(klass_.IsNull()) << *this;
}

void UnresolvedUninitializedRefType::CheckInvariants() const {
  CHECK(!descriptor_.empty()) << *this;
  CHECK(klass_.IsNull()) << *this;
}

UnresolvedMergedType::UnresolvedMergedType(const RegType& resolved,
                                           const BitVector& unresolved,
                                           const RegTypeCache* reg_type_cache,
                                           uint16_t cache_id)
    : UnresolvedType("", cache_id),
      reg_type_cache_(reg_type_cache),
      resolved_part_(resolved),
      unresolved_types_(unresolved, false, unresolved.GetAllocator()) {
  CheckConstructorInvariants(this);
}
void UnresolvedMergedType::CheckInvariants() const {
  CHECK(reg_type_cache_ != nullptr);

  // Unresolved merged types: merged types should be defined.
  CHECK(descriptor_.empty()) << *this;
  CHECK(klass_.IsNull()) << *this;

  CHECK(!resolved_part_.IsConflict());
  CHECK(resolved_part_.IsReferenceTypes());
  CHECK(!resolved_part_.IsUnresolvedTypes());

  CHECK(resolved_part_.IsZero() ||
        !(resolved_part_.IsArrayTypes() && !resolved_part_.IsObjectArrayTypes()));

  CHECK_GT(unresolved_types_.NumSetBits(), 0U);
  bool unresolved_is_array =
      reg_type_cache_->GetFromId(unresolved_types_.GetHighestBitSet()).IsArrayTypes();
  for (uint32_t idx : unresolved_types_.Indexes()) {
    const RegType& t = reg_type_cache_->GetFromId(idx);
    CHECK_EQ(unresolved_is_array, t.IsArrayTypes());
  }

  if (!resolved_part_.IsZero()) {
    CHECK_EQ(resolved_part_.IsArrayTypes(), unresolved_is_array);
  }
}

bool UnresolvedMergedType::IsArrayTypes() const {
  // For a merge to be an array, both the resolved and the unresolved part need to be object
  // arrays.
  // (Note: we encode a missing resolved part [which doesn't need to be an array] as zero.)

  if (!resolved_part_.IsZero() && !resolved_part_.IsArrayTypes()) {
    return false;
  }

  // It is enough to check just one of the merged types. Otherwise the merge should have been
  // collapsed (checked in CheckInvariants on construction).
  uint32_t idx = unresolved_types_.GetHighestBitSet();
  const RegType& unresolved = reg_type_cache_->GetFromId(idx);
  return unresolved.IsArrayTypes();
}
bool UnresolvedMergedType::IsObjectArrayTypes() const {
  // Same as IsArrayTypes, as primitive arrays are always resolved.
  return IsArrayTypes();
}

void UnresolvedReferenceType::CheckInvariants() const {
  CHECK(!descriptor_.empty()) << *this;
  CHECK(klass_.IsNull()) << *this;
}

void UnresolvedSuperClass::CheckInvariants() const {
  // Unresolved merged types: merged types should be defined.
  CHECK(descriptor_.empty()) << *this;
  CHECK(klass_.IsNull()) << *this;
  CHECK_NE(unresolved_child_id_, 0U) << *this;
}

std::ostream& operator<<(std::ostream& os, const RegType& rhs) {
  os << rhs.Dump();
  return os;
}

bool RegType::CanAssignArray(const RegType& src,
                             RegTypeCache& reg_types,
                             Handle<mirror::ClassLoader> class_loader,
                             MethodVerifier* verifier,
                             bool* soft_error) const {
  if (!IsArrayTypes() || !src.IsArrayTypes()) {
    *soft_error = false;
    return false;
  }

  if (IsUnresolvedMergedReference() || src.IsUnresolvedMergedReference()) {
    // An unresolved array type means that it's an array of some reference type. Reference arrays
    // can never be assigned to primitive-type arrays, and vice versa. So it is a soft error if
    // both arrays are reference arrays, otherwise a hard error.
    *soft_error = IsObjectArrayTypes() && src.IsObjectArrayTypes();
    return false;
  }

  const RegType& cmp1 = reg_types.GetComponentType(*this, class_loader.Get());
  const RegType& cmp2 = reg_types.GetComponentType(src, class_loader.Get());

  if (cmp1.IsAssignableFrom(cmp2, verifier)) {
    return true;
  }
  if (cmp1.IsUnresolvedTypes()) {
    if (cmp2.IsIntegralTypes() || cmp2.IsFloatTypes() || cmp2.IsArrayTypes()) {
      *soft_error = false;
      return false;
    }
    *soft_error = true;
    return false;
  }
  if (cmp2.IsUnresolvedTypes()) {
    if (cmp1.IsIntegralTypes() || cmp1.IsFloatTypes() || cmp1.IsArrayTypes()) {
      *soft_error = false;
      return false;
    }
    *soft_error = true;
    return false;
  }
  if (!cmp1.IsArrayTypes() || !cmp2.IsArrayTypes()) {
    *soft_error = false;
    return false;
  }
  return cmp1.CanAssignArray(cmp2, reg_types, class_loader, verifier, soft_error);
}

const NullType* NullType::CreateInstance(ObjPtr<mirror::Class> klass,
                                         const StringPiece& descriptor,
                                         uint16_t cache_id) {
  CHECK(instance_ == nullptr);
  instance_ = new NullType(klass, descriptor, cache_id);
  return instance_;
}

void NullType::Destroy() {
  if (NullType::instance_ != nullptr) {
    delete instance_;
    instance_ = nullptr;
  }
}


}  // namespace verifier
}  // namespace art
