reg_type_cache.cc revision 5441091dc78c64a683cb336ff27e80c364bc2cd3
1776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers/*
2776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Copyright (C) 2012 The Android Open Source Project
3776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers *
4776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Licensed under the Apache License, Version 2.0 (the "License");
5776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * you may not use this file except in compliance with the License.
6776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * You may obtain a copy of the License at
7776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers *
8776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers *      http://www.apache.org/licenses/LICENSE-2.0
9776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers *
10776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Unless required by applicable law or agreed to in writing, software
11776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * distributed under the License is distributed on an "AS IS" BASIS,
12776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * See the License for the specific language governing permissions and
14776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * limitations under the License.
15776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */
16776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
1751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal#include "reg_type_cache-inl.h"
18776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
1951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal#include "base/casts.h"
209837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers#include "class_linker-inl.h"
214f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h"
222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h"
232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h"
24776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
25776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersnamespace art {
26776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersnamespace verifier {
271bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
2851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asalbool RegTypeCache::primitive_initialized_ = false;
2951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asaluint16_t RegTypeCache::primitive_count_ = 0;
3041c65c19c15ffac41089fa9f37502f94c046960dIan RogersPreciseConstType* RegTypeCache::small_precise_constants_[kMaxSmallConstant - kMinSmallConstant + 1];
31776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
3251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asalstatic bool MatchingPrecisionForClass(RegType* entry, bool precise)
3351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
3404f94f4f02093fa0fc58007fd5f4ef4c58f8270aIan Rogers  if (entry->IsPreciseReference() == precise) {
3504f94f4f02093fa0fc58007fd5f4ef4c58f8270aIan Rogers    // We were or weren't looking for a precise reference and we found what we need.
3604f94f4f02093fa0fc58007fd5f4ef4c58f8270aIan Rogers    return true;
3704f94f4f02093fa0fc58007fd5f4ef4c58f8270aIan Rogers  } else {
3804f94f4f02093fa0fc58007fd5f4ef4c58f8270aIan Rogers    if (!precise && entry->GetClass()->CannotBeAssignedFromOtherTypes()) {
3904f94f4f02093fa0fc58007fd5f4ef4c58f8270aIan Rogers      // We weren't looking for a precise reference, as we're looking up based on a descriptor, but
4004f94f4f02093fa0fc58007fd5f4ef4c58f8270aIan Rogers      // we found a matching entry based on the descriptor. Return the precise entry in that case.
4104f94f4f02093fa0fc58007fd5f4ef4c58f8270aIan Rogers      return true;
4204f94f4f02093fa0fc58007fd5f4ef4c58f8270aIan Rogers    }
4304f94f4f02093fa0fc58007fd5f4ef4c58f8270aIan Rogers    return false;
4404f94f4f02093fa0fc58007fd5f4ef4c58f8270aIan Rogers  }
45776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
46776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
4741c65c19c15ffac41089fa9f37502f94c046960dIan Rogersvoid RegTypeCache::FillPrimitiveAndSmallConstantTypes() {
4851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(UndefinedType::GetInstance());
4951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(ConflictType::GetInstance());
5051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(BooleanType::GetInstance());
5151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(ByteType::GetInstance());
5251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(ShortType::GetInstance());
5351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(CharType::GetInstance());
5451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(IntegerType::GetInstance());
5551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(LongLoType::GetInstance());
5651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(LongHiType::GetInstance());
5751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(FloatType::GetInstance());
5851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(DoubleLoType::GetInstance());
5951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(DoubleHiType::GetInstance());
6041c65c19c15ffac41089fa9f37502f94c046960dIan Rogers  for (int32_t value = kMinSmallConstant; value <= kMaxSmallConstant; ++value) {
6141c65c19c15ffac41089fa9f37502f94c046960dIan Rogers    int32_t i = value - kMinSmallConstant;
6241c65c19c15ffac41089fa9f37502f94c046960dIan Rogers    DCHECK_EQ(entries_.size(), small_precise_constants_[i]->GetId());
6341c65c19c15ffac41089fa9f37502f94c046960dIan Rogers    entries_.push_back(small_precise_constants_[i]);
6441c65c19c15ffac41089fa9f37502f94c046960dIan Rogers  }
6551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  DCHECK_EQ(entries_.size(), primitive_count_);
6651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal}
6751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal
68d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogersconst RegType& RegTypeCache::FromDescriptor(mirror::ClassLoader* loader, const char* descriptor,
69d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogers                                            bool precise) {
701bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers  DCHECK(RegTypeCache::primitive_initialized_);
711bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers  if (descriptor[1] == '\0') {
72776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    switch (descriptor[0]) {
7351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      case 'Z':
7451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        return Boolean();
7551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      case 'B':
7651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        return Byte();
7751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      case 'S':
7851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        return Short();
7951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      case 'C':
8051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        return Char();
8151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      case 'I':
8251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        return Integer();
8351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      case 'J':
8451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        return LongLo();
8551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      case 'F':
8651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        return Float();
8751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      case 'D':
8851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        return DoubleLo();
8951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      case 'V':  // For void types, conflict types.
9051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      default:
9151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        return Conflict();
92776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
93776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else if (descriptor[0] == 'L' || descriptor[0] == '[') {
9451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return From(loader, descriptor, precise);
95776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
9651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return Conflict();
97776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
9851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal};
99776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
100d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogersconst RegType& RegTypeCache::RegTypeFromPrimitiveType(Primitive::Type prim_type) const {
10151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  CHECK(RegTypeCache::primitive_initialized_);
10251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  switch (prim_type) {
10351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    case Primitive::kPrimBoolean:
10451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      return *BooleanType::GetInstance();
10551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    case Primitive::kPrimByte:
10651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      return *ByteType::GetInstance();
10751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    case Primitive::kPrimShort:
10851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      return *ShortType::GetInstance();
10951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    case Primitive::kPrimChar:
11051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      return *CharType::GetInstance();
11151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    case Primitive::kPrimInt:
11251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      return *IntegerType::GetInstance();
11351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    case Primitive::kPrimLong:
11451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      return *LongLoType::GetInstance();
11551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    case Primitive::kPrimFloat:
11651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      return *FloatType::GetInstance();
11751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    case Primitive::kPrimDouble:
11851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      return *DoubleLoType::GetInstance();
11951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    case Primitive::kPrimVoid:
12051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    default:
12151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      return *ConflictType::GetInstance();
12251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
123b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers}
124b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers
1251ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogersbool RegTypeCache::MatchDescriptor(size_t idx, const StringPiece& descriptor, bool precise) {
126637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers  RegType* entry = entries_[idx];
1271ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers  if (descriptor != entry->descriptor_) {
128637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers    return false;
129637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers  }
13004f94f4f02093fa0fc58007fd5f4ef4c58f8270aIan Rogers  if (entry->HasClass()) {
13104f94f4f02093fa0fc58007fd5f4ef4c58f8270aIan Rogers    return MatchingPrecisionForClass(entry, precise);
13251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
13304f94f4f02093fa0fc58007fd5f4ef4c58f8270aIan Rogers  // There is no notion of precise unresolved references, the precise information is just dropped
13404f94f4f02093fa0fc58007fd5f4ef4c58f8270aIan Rogers  // on the floor.
13504f94f4f02093fa0fc58007fd5f4ef4c58f8270aIan Rogers  DCHECK(entry->IsUnresolvedReference());
13604f94f4f02093fa0fc58007fd5f4ef4c58f8270aIan Rogers  return true;
13751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal}
13851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal
1391bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogersmirror::Class* RegTypeCache::ResolveClass(const char* descriptor, mirror::ClassLoader* loader) {
14051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  // Class was not found, must create new type.
14151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  // Try resolving class
14251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1439837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers  Thread* self = Thread::Current();
144eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  StackHandleScope<1> hs(self);
145eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  Handle<mirror::ClassLoader> class_loader(hs.NewHandle(loader));
14651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  mirror::Class* klass = NULL;
14751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  if (can_load_classes_) {
1489837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers    klass = class_linker->FindClass(self, descriptor, class_loader);
149776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
1501bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers    klass = class_linker->LookupClass(descriptor, loader);
151eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    if (klass != nullptr && !klass->IsLoaded()) {
15262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      // We found the class but without it being loaded its not safe for use.
153eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier      klass = nullptr;
15462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    }
15551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
15651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  return klass;
15751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal}
1581bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
159d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogersconst RegType& RegTypeCache::From(mirror::ClassLoader* loader, const char* descriptor,
160d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogers                                  bool precise) {
1611ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers  // Try looking up the class in the cache first. We use a StringPiece to avoid continual strlen
1621ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers  // operations on the descriptor.
1631ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers  StringPiece descriptor_sp(descriptor);
1642c6de22d6dcdc6fe1a065480582989e15a47fcb5Sameer Abu Asal  for (size_t i = primitive_count_; i < entries_.size(); i++) {
1651ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers    if (MatchDescriptor(i, descriptor_sp, precise)) {
1662c6de22d6dcdc6fe1a065480582989e15a47fcb5Sameer Abu Asal      return *(entries_[i]);
1672c6de22d6dcdc6fe1a065480582989e15a47fcb5Sameer Abu Asal    }
1682c6de22d6dcdc6fe1a065480582989e15a47fcb5Sameer Abu Asal  }
1692c6de22d6dcdc6fe1a065480582989e15a47fcb5Sameer Abu Asal  // Class not found in the cache, will create a new type for that.
17051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  // Try resolving class.
17151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  mirror::Class* klass = ResolveClass(descriptor, loader);
17251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  if (klass != NULL) {
17351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    // Class resolved, first look for the class in the list of entries
17451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    // Class was not found, must create new type.
1757934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom    // To pass the verification, the type should be imprecise,
1769f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal    // instantiable or an interface with the precise type set to false.
17702c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal    DCHECK(!precise || klass->IsInstantiable());
1789f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal    // Create a precise type if:
1792c6de22d6dcdc6fe1a065480582989e15a47fcb5Sameer Abu Asal    // 1- Class is final and NOT an interface. a precise interface is meaningless !!
1809f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal    // 2- Precise Flag passed as true.
18151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    RegType* entry;
1829f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal    // Create an imprecise type if we can't tell for a fact that it is precise.
18304f94f4f02093fa0fc58007fd5f4ef4c58f8270aIan Rogers    if (klass->CannotBeAssignedFromOtherTypes() || precise) {
18402c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal      DCHECK(!(klass->IsAbstract()) || klass->IsArrayClass());
18502c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal      DCHECK(!klass->IsInterface());
1861ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers      entry = new PreciseReferenceType(klass, descriptor_sp.as_string(), entries_.size());
18780537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes    } else {
1881ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers      entry = new ReferenceType(klass, descriptor_sp.as_string(), entries_.size());
18980537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes    }
190aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampe    AddEntry(entry);
19151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return *entry;
19251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  } else {  // Class not resolved.
19351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    // We tried loading the class and failed, this might get an exception raised
19451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    // so we want to clear it before we go on.
195639815628cf52a4a944a4322cb09da37cded2de9Andreas Gampe    if (can_load_classes_) {
196639815628cf52a4a944a4322cb09da37cded2de9Andreas Gampe      DCHECK(Thread::Current()->IsExceptionPending());
197639815628cf52a4a944a4322cb09da37cded2de9Andreas Gampe      Thread::Current()->ClearException();
198639815628cf52a4a944a4322cb09da37cded2de9Andreas Gampe    } else {
199639815628cf52a4a944a4322cb09da37cded2de9Andreas Gampe      DCHECK(!Thread::Current()->IsExceptionPending());
200639815628cf52a4a944a4322cb09da37cded2de9Andreas Gampe    }
2011bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers    if (IsValidDescriptor(descriptor)) {
2021ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers      RegType* entry = new UnresolvedReferenceType(descriptor_sp.as_string(), entries_.size());
203aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampe      AddEntry(entry);
204776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      return *entry;
205776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    } else {
20651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      // The descriptor is broken return the unknown type as there's nothing sensible that
20751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      // could be done at runtime
20851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      return Conflict();
209776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
210776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
211776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
2121bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
213d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogersconst RegType& RegTypeCache::FromClass(const char* descriptor, mirror::Class* klass, bool precise) {
21458a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe  DCHECK(klass != nullptr);
215776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  if (klass->IsPrimitive()) {
21604f94f4f02093fa0fc58007fd5f4ef4c58f8270aIan Rogers    // Note: precise isn't used for primitive classes. A char is assignable to an int. All
21704f94f4f02093fa0fc58007fd5f4ef4c58f8270aIan Rogers    // primitive classes are final.
21851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return RegTypeFromPrimitiveType(klass->GetPrimitiveType());
219776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
22051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    // Look for the reference in the list of entries to have.
22151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    for (size_t i = primitive_count_; i < entries_.size(); i++) {
222776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      RegType* cur_entry = entries_[i];
2235441091dc78c64a683cb336ff27e80c364bc2cd3Ian Rogers      if (cur_entry->klass_.Read() == klass && MatchingPrecisionForClass(cur_entry, precise)) {
224776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers        return *cur_entry;
225776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      }
226776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
22751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    // No reference to the class was found, create new reference.
22851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    RegType* entry;
22951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    if (precise) {
230637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers      entry = new PreciseReferenceType(klass, descriptor, entries_.size());
23151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    } else {
232637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers      entry = new ReferenceType(klass, descriptor, entries_.size());
23351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    }
234aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampe    AddEntry(entry);
235776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return *entry;
236776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
237776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
238776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
239639815628cf52a4a944a4322cb09da37cded2de9Andreas GampeRegTypeCache::RegTypeCache(bool can_load_classes) : can_load_classes_(can_load_classes) {
240639815628cf52a4a944a4322cb09da37cded2de9Andreas Gampe  if (kIsDebugBuild && can_load_classes) {
241639815628cf52a4a944a4322cb09da37cded2de9Andreas Gampe    Thread::Current()->AssertThreadSuspensionIsAllowable();
242639815628cf52a4a944a4322cb09da37cded2de9Andreas Gampe  }
243639815628cf52a4a944a4322cb09da37cded2de9Andreas Gampe  entries_.reserve(64);
244639815628cf52a4a944a4322cb09da37cded2de9Andreas Gampe  FillPrimitiveAndSmallConstantTypes();
245639815628cf52a4a944a4322cb09da37cded2de9Andreas Gampe}
246639815628cf52a4a944a4322cb09da37cded2de9Andreas Gampe
24751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu AsalRegTypeCache::~RegTypeCache() {
24851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  CHECK_LE(primitive_count_, entries_.size());
24951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  // Delete only the non primitive types.
25041c65c19c15ffac41089fa9f37502f94c046960dIan Rogers  if (entries_.size() == kNumPrimitivesAndSmallConstants) {
25141c65c19c15ffac41089fa9f37502f94c046960dIan Rogers    // All entries are from the global pool, nothing to delete.
25251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return;
25351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
25451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  std::vector<RegType*>::iterator non_primitive_begin = entries_.begin();
25541c65c19c15ffac41089fa9f37502f94c046960dIan Rogers  std::advance(non_primitive_begin, kNumPrimitivesAndSmallConstants);
25651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  STLDeleteContainerPointers(non_primitive_begin, entries_.end());
25751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal}
25851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal
25951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asalvoid RegTypeCache::ShutDown() {
26051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  if (RegTypeCache::primitive_initialized_) {
26151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    UndefinedType::Destroy();
26251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    ConflictType::Destroy();
26351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    BooleanType::Destroy();
26451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    ByteType::Destroy();
26551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    ShortType::Destroy();
26651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    CharType::Destroy();
26751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    IntegerType::Destroy();
26851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    LongLoType::Destroy();
26951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    LongHiType::Destroy();
27025ae7ebfd227869dd12f807047c56177d0bf645bIan Rogers    FloatType::Destroy();
27151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    DoubleLoType::Destroy();
27251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    DoubleHiType::Destroy();
273dfe78a6e6b526d482298100a1f6392a8c7105522Ian Rogers    for (int32_t value = kMinSmallConstant; value <= kMaxSmallConstant; ++value) {
27441c65c19c15ffac41089fa9f37502f94c046960dIan Rogers      PreciseConstType* type = small_precise_constants_[value - kMinSmallConstant];
27541c65c19c15ffac41089fa9f37502f94c046960dIan Rogers      delete type;
276dfe78a6e6b526d482298100a1f6392a8c7105522Ian Rogers      small_precise_constants_[value - kMinSmallConstant] = nullptr;
27741c65c19c15ffac41089fa9f37502f94c046960dIan Rogers    }
27862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    RegTypeCache::primitive_initialized_ = false;
27962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    RegTypeCache::primitive_count_ = 0;
28051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
28151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal}
28251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal
28341c65c19c15ffac41089fa9f37502f94c046960dIan Rogerstemplate <class Type>
28441c65c19c15ffac41089fa9f37502f94c046960dIan RogersType* RegTypeCache::CreatePrimitiveTypeInstance(const std::string& descriptor) {
28541c65c19c15ffac41089fa9f37502f94c046960dIan Rogers  mirror::Class* klass = NULL;
28641c65c19c15ffac41089fa9f37502f94c046960dIan Rogers  // Try loading the class from linker.
28741c65c19c15ffac41089fa9f37502f94c046960dIan Rogers  if (!descriptor.empty()) {
2889837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers    klass = art::Runtime::Current()->GetClassLinker()->FindSystemClass(Thread::Current(),
2899837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers                                                                       descriptor.c_str());
29041c65c19c15ffac41089fa9f37502f94c046960dIan Rogers  }
29141c65c19c15ffac41089fa9f37502f94c046960dIan Rogers  Type* entry = Type::CreateInstance(klass, descriptor, RegTypeCache::primitive_count_);
29241c65c19c15ffac41089fa9f37502f94c046960dIan Rogers  RegTypeCache::primitive_count_++;
29341c65c19c15ffac41089fa9f37502f94c046960dIan Rogers  return entry;
29441c65c19c15ffac41089fa9f37502f94c046960dIan Rogers}
29541c65c19c15ffac41089fa9f37502f94c046960dIan Rogers
29641c65c19c15ffac41089fa9f37502f94c046960dIan Rogersvoid RegTypeCache::CreatePrimitiveAndSmallConstantTypes() {
29733e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<UndefinedType>("");
29833e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<ConflictType>("");
29933e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<BooleanType>("Z");
30033e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<ByteType>("B");
30133e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<ShortType>("S");
30233e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<CharType>("C");
30333e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<IntegerType>("I");
30433e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<LongLoType>("J");
30533e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<LongHiType>("J");
30633e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<FloatType>("F");
30733e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<DoubleLoType>("D");
30833e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<DoubleHiType>("D");
30941c65c19c15ffac41089fa9f37502f94c046960dIan Rogers  for (int32_t value = kMinSmallConstant; value <= kMaxSmallConstant; ++value) {
31041c65c19c15ffac41089fa9f37502f94c046960dIan Rogers    PreciseConstType* type = new PreciseConstType(value, primitive_count_);
31141c65c19c15ffac41089fa9f37502f94c046960dIan Rogers    small_precise_constants_[value - kMinSmallConstant] = type;
31241c65c19c15ffac41089fa9f37502f94c046960dIan Rogers    primitive_count_++;
31341c65c19c15ffac41089fa9f37502f94c046960dIan Rogers  }
31451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal}
31551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal
316d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogersconst RegType& RegTypeCache::FromUnresolvedMerge(const RegType& left, const RegType& right) {
317529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  std::set<uint16_t> types;
318529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  if (left.IsUnresolvedMergedReference()) {
319d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogers    RegType& non_const(const_cast<RegType&>(left));
320d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogers    types = (down_cast<UnresolvedMergedType*>(&non_const))->GetMergedTypes();
321529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  } else {
322529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers    types.insert(left.GetId());
323529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  }
324529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  if (right.IsUnresolvedMergedReference()) {
325d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogers    RegType& non_const(const_cast<RegType&>(right));
326d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogers    std::set<uint16_t> right_types = (down_cast<UnresolvedMergedType*>(&non_const))->GetMergedTypes();
327529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers    types.insert(right_types.begin(), right_types.end());
328529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  } else {
329529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers    types.insert(right.GetId());
330529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  }
331529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  // Check if entry already exists.
33251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  for (size_t i = primitive_count_; i < entries_.size(); i++) {
333529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers    RegType* cur_entry = entries_[i];
334529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers    if (cur_entry->IsUnresolvedMergedReference()) {
33551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      std::set<uint16_t> cur_entry_types =
33651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal          (down_cast<UnresolvedMergedType*>(cur_entry))->GetMergedTypes();
337529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers      if (cur_entry_types == types) {
338529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers        return *cur_entry;
339529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers      }
340529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers    }
341529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  }
342529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  // Create entry.
34351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  RegType* entry = new UnresolvedMergedType(left.GetId(), right.GetId(), this, entries_.size());
344aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampe  AddEntry(entry);
3451bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers  if (kIsDebugBuild) {
3461bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers    UnresolvedMergedType* tmp_entry = down_cast<UnresolvedMergedType*>(entry);
3471bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers    std::set<uint16_t> check_types = tmp_entry->GetMergedTypes();
3481bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers    CHECK(check_types == types);
3491bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers  }
350529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  return *entry;
351529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers}
3521bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
353d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogersconst RegType& RegTypeCache::FromUnresolvedSuperClass(const RegType& child) {
354529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  // Check if entry already exists.
35551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  for (size_t i = primitive_count_; i < entries_.size(); i++) {
35651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    RegType* cur_entry = entries_[i];
35751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    if (cur_entry->IsUnresolvedSuperClass()) {
35851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      UnresolvedSuperClass* tmp_entry =
35951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal          down_cast<UnresolvedSuperClass*>(cur_entry);
36051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      uint16_t unresolved_super_child_id =
36151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal          tmp_entry->GetUnresolvedSuperClassChildId();
36251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      if (unresolved_super_child_id == child.GetId()) {
36351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        return *cur_entry;
36451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      }
36551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    }
36651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
36751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  RegType* entry = new UnresolvedSuperClass(child.GetId(), this, entries_.size());
368aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampe  AddEntry(entry);
36951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  return *entry;
370529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers}
3711bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
372d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogersconst UninitializedType& RegTypeCache::Uninitialized(const RegType& type, uint32_t allocation_pc) {
37341c65c19c15ffac41089fa9f37502f94c046960dIan Rogers  UninitializedType* entry = NULL;
374637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers  const std::string& descriptor(type.GetDescriptor());
375776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  if (type.IsUnresolvedTypes()) {
37651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    for (size_t i = primitive_count_; i < entries_.size(); i++) {
37741c65c19c15ffac41089fa9f37502f94c046960dIan Rogers      RegType* cur_entry = entries_[i];
378776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      if (cur_entry->IsUnresolvedAndUninitializedReference() &&
37951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal          down_cast<UnresolvedUninitializedRefType*>(cur_entry)->GetAllocationPc() == allocation_pc &&
38051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal          (cur_entry->GetDescriptor() == descriptor)) {
38141c65c19c15ffac41089fa9f37502f94c046960dIan Rogers        return *down_cast<UnresolvedUninitializedRefType*>(cur_entry);
382776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      }
383776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
384637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers    entry = new UnresolvedUninitializedRefType(descriptor, allocation_pc, entries_.size());
385776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
3862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* klass = type.GetClass();
38751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    for (size_t i = primitive_count_; i < entries_.size(); i++) {
38841c65c19c15ffac41089fa9f37502f94c046960dIan Rogers      RegType* cur_entry = entries_[i];
389776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      if (cur_entry->IsUninitializedReference() &&
3901bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers          down_cast<UninitializedReferenceType*>(cur_entry)
39151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal              ->GetAllocationPc() == allocation_pc &&
392776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers          cur_entry->GetClass() == klass) {
39341c65c19c15ffac41089fa9f37502f94c046960dIan Rogers        return *down_cast<UninitializedReferenceType*>(cur_entry);
394776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      }
395776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
396637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers    entry = new UninitializedReferenceType(klass, descriptor, allocation_pc, entries_.size());
397776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
398aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampe  AddEntry(entry);
399776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  return *entry;
400776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
4011bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
402d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogersconst RegType& RegTypeCache::FromUninitialized(const RegType& uninit_type) {
403776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  RegType* entry;
4049f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal
405776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  if (uninit_type.IsUnresolvedTypes()) {
4061bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers    const std::string& descriptor(uninit_type.GetDescriptor());
40751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    for (size_t i = primitive_count_; i < entries_.size(); i++) {
408776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      RegType* cur_entry = entries_[i];
40951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      if (cur_entry->IsUnresolvedReference() &&
41051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal          cur_entry->GetDescriptor() == descriptor) {
411776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers        return *cur_entry;
412776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      }
413776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
4141ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers    entry = new UnresolvedReferenceType(descriptor, entries_.size());
415776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
4162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* klass = uninit_type.GetClass();
417df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom    if (uninit_type.IsUninitializedThisReference() && !klass->IsFinal()) {
41804f94f4f02093fa0fc58007fd5f4ef4c58f8270aIan Rogers      // For uninitialized "this reference" look for reference types that are not precise.
4199f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal      for (size_t i = primitive_count_; i < entries_.size(); i++) {
4209f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal        RegType* cur_entry = entries_[i];
4219f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal        if (cur_entry->IsReference() && cur_entry->GetClass() == klass) {
4229f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal          return *cur_entry;
4239f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal        }
4249f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal      }
4251bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers      entry = new ReferenceType(klass, "", entries_.size());
42662342ec720069cebe55f45aea2ff8512a17e7d62Ian Rogers    } else if (klass->IsInstantiable()) {
42762342ec720069cebe55f45aea2ff8512a17e7d62Ian Rogers      // We're uninitialized because of allocation, look or create a precise type as allocations
42862342ec720069cebe55f45aea2ff8512a17e7d62Ian Rogers      // may only create objects of that type.
42962342ec720069cebe55f45aea2ff8512a17e7d62Ian Rogers      for (size_t i = primitive_count_; i < entries_.size(); i++) {
43062342ec720069cebe55f45aea2ff8512a17e7d62Ian Rogers        RegType* cur_entry = entries_[i];
43162342ec720069cebe55f45aea2ff8512a17e7d62Ian Rogers        if (cur_entry->IsPreciseReference() && cur_entry->GetClass() == klass) {
43262342ec720069cebe55f45aea2ff8512a17e7d62Ian Rogers          return *cur_entry;
4339f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal        }
434776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      }
43562342ec720069cebe55f45aea2ff8512a17e7d62Ian Rogers      entry = new PreciseReferenceType(klass, uninit_type.GetDescriptor(), entries_.size());
43662342ec720069cebe55f45aea2ff8512a17e7d62Ian Rogers    } else {
43762342ec720069cebe55f45aea2ff8512a17e7d62Ian Rogers      return Conflict();
438776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
4396f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  }
440aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampe  AddEntry(entry);
441776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  return *entry;
442776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
4431bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
444d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogersconst ImpreciseConstType& RegTypeCache::ByteConstant() {
445d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogers  const ConstantType& result = FromCat1Const(std::numeric_limits<jbyte>::min(), false);
44641c65c19c15ffac41089fa9f37502f94c046960dIan Rogers  DCHECK(result.IsImpreciseConstant());
447d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogers  return *down_cast<const ImpreciseConstType*>(&result);
4482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4491bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
450d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogersconst ImpreciseConstType& RegTypeCache::CharConstant() {
451849600bb5cfc02bf5ab4aa9a810667ebd3b53328Sebastien Hertz  int32_t jchar_max = static_cast<int32_t>(std::numeric_limits<jchar>::max());
452d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogers  const ConstantType& result =  FromCat1Const(jchar_max, false);
453849600bb5cfc02bf5ab4aa9a810667ebd3b53328Sebastien Hertz  DCHECK(result.IsImpreciseConstant());
454d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogers  return *down_cast<const ImpreciseConstType*>(&result);
455849600bb5cfc02bf5ab4aa9a810667ebd3b53328Sebastien Hertz}
456849600bb5cfc02bf5ab4aa9a810667ebd3b53328Sebastien Hertz
457d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogersconst ImpreciseConstType& RegTypeCache::ShortConstant() {
458d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogers  const ConstantType& result =  FromCat1Const(std::numeric_limits<jshort>::min(), false);
45941c65c19c15ffac41089fa9f37502f94c046960dIan Rogers  DCHECK(result.IsImpreciseConstant());
460d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogers  return *down_cast<const ImpreciseConstType*>(&result);
4612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4621bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
463d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogersconst ImpreciseConstType& RegTypeCache::IntConstant() {
464d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogers  const ConstantType& result = FromCat1Const(std::numeric_limits<jint>::max(), false);
46541c65c19c15ffac41089fa9f37502f94c046960dIan Rogers  DCHECK(result.IsImpreciseConstant());
466d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogers  return *down_cast<const ImpreciseConstType*>(&result);
4672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4681bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
469d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogersconst ImpreciseConstType& RegTypeCache::PosByteConstant() {
470d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogers  const ConstantType& result = FromCat1Const(std::numeric_limits<jbyte>::max(), false);
471849600bb5cfc02bf5ab4aa9a810667ebd3b53328Sebastien Hertz  DCHECK(result.IsImpreciseConstant());
472d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogers  return *down_cast<const ImpreciseConstType*>(&result);
473849600bb5cfc02bf5ab4aa9a810667ebd3b53328Sebastien Hertz}
474849600bb5cfc02bf5ab4aa9a810667ebd3b53328Sebastien Hertz
475d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogersconst ImpreciseConstType& RegTypeCache::PosShortConstant() {
476d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogers  const ConstantType& result =  FromCat1Const(std::numeric_limits<jshort>::max(), false);
477849600bb5cfc02bf5ab4aa9a810667ebd3b53328Sebastien Hertz  DCHECK(result.IsImpreciseConstant());
478d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogers  return *down_cast<const ImpreciseConstType*>(&result);
479849600bb5cfc02bf5ab4aa9a810667ebd3b53328Sebastien Hertz}
480849600bb5cfc02bf5ab4aa9a810667ebd3b53328Sebastien Hertz
481d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogersconst UninitializedType& RegTypeCache::UninitializedThisArgument(const RegType& type) {
48241c65c19c15ffac41089fa9f37502f94c046960dIan Rogers  UninitializedType* entry;
483637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers  const std::string& descriptor(type.GetDescriptor());
484ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers  if (type.IsUnresolvedTypes()) {
48551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    for (size_t i = primitive_count_; i < entries_.size(); i++) {
486ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers      RegType* cur_entry = entries_[i];
487ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers      if (cur_entry->IsUnresolvedAndUninitializedThisReference() &&
488ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers          cur_entry->GetDescriptor() == descriptor) {
48941c65c19c15ffac41089fa9f37502f94c046960dIan Rogers        return *down_cast<UninitializedType*>(cur_entry);
490ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers      }
491ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers    }
4921bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers    entry = new UnresolvedUninitializedThisRefType(descriptor, entries_.size());
493ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers  } else {
4942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* klass = type.GetClass();
49551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    for (size_t i = primitive_count_; i < entries_.size(); i++) {
496ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers      RegType* cur_entry = entries_[i];
49762342ec720069cebe55f45aea2ff8512a17e7d62Ian Rogers      if (cur_entry->IsUninitializedThisReference() && cur_entry->GetClass() == klass) {
49841c65c19c15ffac41089fa9f37502f94c046960dIan Rogers        return *down_cast<UninitializedType*>(cur_entry);
499ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers      }
500776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
501637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers    entry = new UninitializedThisReferenceType(klass, descriptor, entries_.size());
502776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
503aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampe  AddEntry(entry);
504776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  return *entry;
505776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
5061bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
507d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogersconst ConstantType& RegTypeCache::FromCat1NonSmallConstant(int32_t value, bool precise) {
50851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  for (size_t i = primitive_count_; i < entries_.size(); i++) {
509776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    RegType* cur_entry = entries_[i];
5105441091dc78c64a683cb336ff27e80c364bc2cd3Ian Rogers    if (cur_entry->klass_.IsNull() && cur_entry->IsConstant() &&
511637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers        cur_entry->IsPreciseConstant() == precise &&
51251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        (down_cast<ConstantType*>(cur_entry))->ConstantValue() == value) {
51341c65c19c15ffac41089fa9f37502f94c046960dIan Rogers      return *down_cast<ConstantType*>(cur_entry);
514776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
515776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
51641c65c19c15ffac41089fa9f37502f94c046960dIan Rogers  ConstantType* entry;
51751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  if (precise) {
51851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    entry = new PreciseConstType(value, entries_.size());
51951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  } else {
52051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    entry = new ImpreciseConstType(value, entries_.size());
52151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
522aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampe  AddEntry(entry);
5232bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  return *entry;
5242bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers}
5252bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers
526d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogersconst ConstantType& RegTypeCache::FromCat2ConstLo(int32_t value, bool precise) {
52751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  for (size_t i = primitive_count_; i < entries_.size(); i++) {
5282bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers    RegType* cur_entry = entries_[i];
52951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    if (cur_entry->IsConstantLo() && (cur_entry->IsPrecise() == precise) &&
53051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        (down_cast<ConstantType*>(cur_entry))->ConstantValueLo() == value) {
53141c65c19c15ffac41089fa9f37502f94c046960dIan Rogers      return *down_cast<ConstantType*>(cur_entry);
5322bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers    }
5332bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  }
53441c65c19c15ffac41089fa9f37502f94c046960dIan Rogers  ConstantType* entry;
53551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  if (precise) {
53651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    entry = new PreciseConstLoType(value, entries_.size());
53751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  } else {
53851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    entry = new ImpreciseConstLoType(value, entries_.size());
53951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
540aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampe  AddEntry(entry);
5412bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  return *entry;
5422bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers}
5432bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers
544d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogersconst ConstantType& RegTypeCache::FromCat2ConstHi(int32_t value, bool precise) {
54551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  for (size_t i = primitive_count_; i < entries_.size(); i++) {
5462bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers    RegType* cur_entry = entries_[i];
54751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    if (cur_entry->IsConstantHi() && (cur_entry->IsPrecise() == precise) &&
54851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        (down_cast<ConstantType*>(cur_entry))->ConstantValueHi() == value) {
54941c65c19c15ffac41089fa9f37502f94c046960dIan Rogers      return *down_cast<ConstantType*>(cur_entry);
5502bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers    }
5512bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  }
55241c65c19c15ffac41089fa9f37502f94c046960dIan Rogers  ConstantType* entry;
55351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  if (precise) {
55451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    entry = new PreciseConstHiType(value, entries_.size());
55551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  } else {
55651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    entry = new ImpreciseConstHiType(value, entries_.size());
55751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
558aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampe  AddEntry(entry);
559776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  return *entry;
560776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
561776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
562d8f69b086baf6717ce949d1c4de90d73b91083b0Ian Rogersconst RegType& RegTypeCache::GetComponentType(const RegType& array, mirror::ClassLoader* loader) {
563a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers  if (!array.IsArrayTypes()) {
564a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers    return Conflict();
565a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers  } else if (array.IsUnresolvedTypes()) {
5661bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers    const std::string& descriptor(array.GetDescriptor());
5671bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers    const std::string component(descriptor.substr(1, descriptor.size() - 1));
568b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    return FromDescriptor(loader, component.c_str(), false);
569776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
5702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* klass = array.GetClass()->GetComponentType();
5711ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers    std::string temp;
572aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampe    if (klass->IsErroneous()) {
573aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampe      // Arrays may have erroneous component types, use unresolved in that case.
574aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampe      // We assume that the primitive classes are not erroneous, so we know it is a
575aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampe      // reference type.
5761ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers      return FromDescriptor(loader, klass->GetDescriptor(&temp), false);
577aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampe    } else {
5781ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers      return FromClass(klass->GetDescriptor(&temp), klass,
579aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampe                       klass->CannotBeAssignedFromOtherTypes());
580aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampe    }
581b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers  }
582b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers}
583b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers
584b49035706fceb2b13e8154668f175af624cf88f4Ian Rogersvoid RegTypeCache::Dump(std::ostream& os) {
585b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers  for (size_t i = 0; i < entries_.size(); i++) {
586b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    RegType* cur_entry = entries_[i];
587b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    if (cur_entry != NULL) {
5882bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers      os << i << ": " << cur_entry->Dump() << "\n";
589b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    }
590776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
591776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
592776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
59383c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartiervoid RegTypeCache::VisitRoots(RootCallback* callback, void* arg) {
594c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier  for (RegType* entry : entries_) {
59583c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier    entry->VisitRoots(callback, arg);
596c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier  }
597c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier}
598c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier
599aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampevoid RegTypeCache::AddEntry(RegType* new_entry) {
600aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampe  entries_.push_back(new_entry);
601aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampe}
602aa910d5ef43256102809e397de305c23f1c315e6Andreas Gampe
603a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes}  // namespace verifier
604a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes}  // namespace art
605