reg_type_cache.cc revision 637c65b1e431fd90195b71c141b3590bd81cc91a
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"
204f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h"
212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h"
222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h"
23776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "object_utils.h"
24776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
25776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersnamespace art {
26776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersnamespace verifier {
271bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
2851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asalbool RegTypeCache::primitive_initialized_ = false;
2951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asaluint16_t RegTypeCache::primitive_start_ = 0;
3051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asaluint16_t RegTypeCache::primitive_count_ = 0;
31776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
3251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asalstatic bool MatchingPrecisionForClass(RegType* entry, bool precise)
3351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
3451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  return (entry->IsPreciseReference() == precise) || (entry->GetClass()->IsFinal() && !precise);
35776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
36776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
3751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asalvoid RegTypeCache::FillPrimitiveTypes() {
3851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(UndefinedType::GetInstance());
3951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(ConflictType::GetInstance());
4051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(BooleanType::GetInstance());
4151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(ByteType::GetInstance());
4251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(ShortType::GetInstance());
4351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(CharType::GetInstance());
4451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(IntegerType::GetInstance());
4551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(LongLoType::GetInstance());
4651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(LongHiType::GetInstance());
4751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(FloatType::GetInstance());
4851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(DoubleLoType::GetInstance());
4951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(DoubleHiType::GetInstance());
5051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  DCHECK_EQ(entries_.size(), primitive_count_);
5151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal}
5251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal
531bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogersconst RegType& RegTypeCache::FromDescriptor(mirror::ClassLoader* loader, const char* descriptor,
541bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers                                            bool precise) {
551bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers  DCHECK(RegTypeCache::primitive_initialized_);
561bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers  if (descriptor[1] == '\0') {
57776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    switch (descriptor[0]) {
5851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      case 'Z':
5951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        return Boolean();
6051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      case 'B':
6151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        return Byte();
6251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      case 'S':
6351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        return Short();
6451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      case 'C':
6551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        return Char();
6651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      case 'I':
6751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        return Integer();
6851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      case 'J':
6951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        return LongLo();
7051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      case 'F':
7151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        return Float();
7251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      case 'D':
7351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        return DoubleLo();
7451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      case 'V':  // For void types, conflict types.
7551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      default:
7651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        return Conflict();
77776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
78776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else if (descriptor[0] == 'L' || descriptor[0] == '[') {
7951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return From(loader, descriptor, precise);
80776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
8151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return Conflict();
82776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
8351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal};
84776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
851bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogersconst RegType& RegTypeCache::RegTypeFromPrimitiveType(Primitive::Type prim_type) const {
8651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  CHECK(RegTypeCache::primitive_initialized_);
8751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  switch (prim_type) {
8851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    case Primitive::kPrimBoolean:
8951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      return *BooleanType::GetInstance();
9051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    case Primitive::kPrimByte:
9151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      return *ByteType::GetInstance();
9251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    case Primitive::kPrimShort:
9351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      return *ShortType::GetInstance();
9451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    case Primitive::kPrimChar:
9551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      return *CharType::GetInstance();
9651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    case Primitive::kPrimInt:
9751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      return *IntegerType::GetInstance();
9851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    case Primitive::kPrimLong:
9951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      return *LongLoType::GetInstance();
10051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    case Primitive::kPrimFloat:
10151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      return *FloatType::GetInstance();
10251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    case Primitive::kPrimDouble:
10351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      return *DoubleLoType::GetInstance();
10451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    case Primitive::kPrimVoid:
10551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    default:
10651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      return *ConflictType::GetInstance();
10751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
108b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers}
109b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers
1101bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogersbool RegTypeCache::MatchDescriptor(size_t idx, const char* descriptor, bool precise) {
111637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers  RegType* entry = entries_[idx];
112637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers  if (entry->descriptor_ != descriptor) {
113637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers    return false;
114637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers  }
115637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers  if (entry->HasClass() && MatchingPrecisionForClass(entry, precise)) {
11651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return true;
11751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
118637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers  return entry->IsUnresolvedReference();
11951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal}
12051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal
1211bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogersmirror::Class* RegTypeCache::ResolveClass(const char* descriptor, mirror::ClassLoader* loader) {
12251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  // Class was not found, must create new type.
12351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  // Try resolving class
12451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
12551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  mirror::Class* klass = NULL;
12651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  if (can_load_classes_) {
1271bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers    klass = class_linker->FindClass(descriptor, loader);
128776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
1291bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers    klass = class_linker->LookupClass(descriptor, loader);
13062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    if (klass != NULL && !klass->IsLoaded()) {
13162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      // We found the class but without it being loaded its not safe for use.
13262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      klass = NULL;
13362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    }
13451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
13551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  return klass;
13651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal}
1371bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
13851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asalvoid RegTypeCache::ClearException() {
13951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  if (can_load_classes_) {
14051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    DCHECK(Thread::Current()->IsExceptionPending());
14151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    Thread::Current()->ClearException();
14251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  } else {
14351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    DCHECK(!Thread::Current()->IsExceptionPending());
14451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
14551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal}
1462c6de22d6dcdc6fe1a065480582989e15a47fcb5Sameer Abu Asal
1471bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogersconst RegType& RegTypeCache::From(mirror::ClassLoader* loader, const char* descriptor,
1481bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers                                  bool precise) {
1492c6de22d6dcdc6fe1a065480582989e15a47fcb5Sameer Abu Asal  // Try looking up the class in the cache first.
1502c6de22d6dcdc6fe1a065480582989e15a47fcb5Sameer Abu Asal  for (size_t i = primitive_count_; i < entries_.size(); i++) {
1512c6de22d6dcdc6fe1a065480582989e15a47fcb5Sameer Abu Asal    if (MatchDescriptor(i, descriptor, precise)) {
1522c6de22d6dcdc6fe1a065480582989e15a47fcb5Sameer Abu Asal      return *(entries_[i]);
1532c6de22d6dcdc6fe1a065480582989e15a47fcb5Sameer Abu Asal    }
1542c6de22d6dcdc6fe1a065480582989e15a47fcb5Sameer Abu Asal  }
1552c6de22d6dcdc6fe1a065480582989e15a47fcb5Sameer Abu Asal  // Class not found in the cache, will create a new type for that.
15651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  // Try resolving class.
15751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  mirror::Class* klass = ResolveClass(descriptor, loader);
15851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  if (klass != NULL) {
15951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    // Class resolved, first look for the class in the list of entries
16051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    // Class was not found, must create new type.
1619f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal    //To pass the verification, the type should be imprecise,
1629f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal    // instantiable or an interface with the precise type set to false.
16302c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal    DCHECK(!precise || klass->IsInstantiable());
1649f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal    // Create a precise type if:
1652c6de22d6dcdc6fe1a065480582989e15a47fcb5Sameer Abu Asal    // 1- Class is final and NOT an interface. a precise interface is meaningless !!
1669f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal    // 2- Precise Flag passed as true.
16751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    RegType* entry;
1689f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal    // Create an imprecise type if we can't tell for a fact that it is precise.
1699f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal    if ((klass->IsFinal()) || precise) {
17002c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal      DCHECK(!(klass->IsAbstract()) || klass->IsArrayClass());
17102c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal      DCHECK(!klass->IsInterface());
17251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      entry = new PreciseReferenceType(klass, descriptor, entries_.size());
17380537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes    } else {
17451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      entry = new ReferenceType(klass, descriptor, entries_.size());
17580537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes    }
17651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    entries_.push_back(entry);
17751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return *entry;
17851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  } else {  // Class not resolved.
17951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    // We tried loading the class and failed, this might get an exception raised
18051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    // so we want to clear it before we go on.
18151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    ClearException();
1821bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers    if (IsValidDescriptor(descriptor)) {
18351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      RegType* entry = new UnresolvedReferenceType(descriptor, entries_.size());
184776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      entries_.push_back(entry);
185776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      return *entry;
186776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    } else {
18751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      // The descriptor is broken return the unknown type as there's nothing sensible that
18851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      // could be done at runtime
18951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      return Conflict();
190776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
191776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
192776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
1931bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
194637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogersconst RegType& RegTypeCache::FromClass(const char* descriptor, mirror::Class* klass, bool precise) {
195776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  if (klass->IsPrimitive()) {
19651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return RegTypeFromPrimitiveType(klass->GetPrimitiveType());
197776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
19851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    // Look for the reference in the list of entries to have.
19951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    for (size_t i = primitive_count_; i < entries_.size(); i++) {
200776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      RegType* cur_entry = entries_[i];
201637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers      if (cur_entry->klass_ == klass && MatchingPrecisionForClass(cur_entry, precise)) {
202776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers        return *cur_entry;
203776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      }
204776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
20551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    // No reference to the class was found, create new reference.
20651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    RegType* entry;
20751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    if (precise) {
208637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers      entry = new PreciseReferenceType(klass, descriptor, entries_.size());
20951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    } else {
210637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers      entry = new ReferenceType(klass, descriptor, entries_.size());
21151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    }
212776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    entries_.push_back(entry);
213776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return *entry;
214776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
215776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
216776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
21751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu AsalRegTypeCache::~RegTypeCache() {
21851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  CHECK_LE(primitive_count_, entries_.size());
21951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  // Delete only the non primitive types.
22062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  if (entries_.size() == kNumPrimitives) {
22151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    // All entries are primitive, nothing to delete.
22251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    return;
22351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
22451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  std::vector<RegType*>::iterator non_primitive_begin = entries_.begin();
22562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  std::advance(non_primitive_begin, kNumPrimitives);
22651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  STLDeleteContainerPointers(non_primitive_begin, entries_.end());
22751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal}
22851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal
22951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asalvoid RegTypeCache::ShutDown() {
23051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  if (RegTypeCache::primitive_initialized_) {
23151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    UndefinedType::Destroy();
23251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    ConflictType::Destroy();
23351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    BooleanType::Destroy();
23451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    ByteType::Destroy();
23551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    ShortType::Destroy();
23651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    CharType::Destroy();
23751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    IntegerType::Destroy();
23851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    LongLoType::Destroy();
23951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    LongHiType::Destroy();
24025ae7ebfd227869dd12f807047c56177d0bf645bIan Rogers    FloatType::Destroy();
24151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    DoubleLoType::Destroy();
24251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    DoubleHiType::Destroy();
24362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    RegTypeCache::primitive_initialized_ = false;
24462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    RegTypeCache::primitive_count_ = 0;
24551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
24651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal}
24751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal
24851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asalvoid RegTypeCache::CreatePrimitiveTypes() {
24933e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<UndefinedType>("");
25033e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<ConflictType>("");
25133e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<BooleanType>("Z");
25233e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<ByteType>("B");
25333e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<ShortType>("S");
25433e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<CharType>("C");
25533e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<IntegerType>("I");
25633e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<LongLoType>("J");
25733e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<LongHiType>("J");
25833e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<FloatType>("F");
25933e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<DoubleLoType>("D");
26033e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers  CreatePrimitiveTypeInstance<DoubleHiType>("D");
26151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal}
26251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal
263529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogersconst RegType& RegTypeCache::FromUnresolvedMerge(const RegType& left, const RegType& right) {
264529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  std::set<uint16_t> types;
265529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  if (left.IsUnresolvedMergedReference()) {
26651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    RegType& non_const(const_cast<RegType&>(left));
26751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    types = (down_cast<UnresolvedMergedType*>(&non_const))->GetMergedTypes();
268529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  } else {
269529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers    types.insert(left.GetId());
270529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  }
271529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  if (right.IsUnresolvedMergedReference()) {
27251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    RegType& non_const(const_cast<RegType&>(right));
27351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    std::set<uint16_t> right_types = (down_cast<UnresolvedMergedType*>(&non_const))->GetMergedTypes();
274529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers    types.insert(right_types.begin(), right_types.end());
275529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  } else {
276529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers    types.insert(right.GetId());
277529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  }
278529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  // Check if entry already exists.
27951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  for (size_t i = primitive_count_; i < entries_.size(); i++) {
280529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers    RegType* cur_entry = entries_[i];
281529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers    if (cur_entry->IsUnresolvedMergedReference()) {
28251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      std::set<uint16_t> cur_entry_types =
28351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal          (down_cast<UnresolvedMergedType*>(cur_entry))->GetMergedTypes();
284529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers      if (cur_entry_types == types) {
285529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers        return *cur_entry;
286529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers      }
287529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers    }
288529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  }
289529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  // Create entry.
29051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  RegType* entry = new UnresolvedMergedType(left.GetId(), right.GetId(), this, entries_.size());
291529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  entries_.push_back(entry);
2921bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers  if (kIsDebugBuild) {
2931bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers    UnresolvedMergedType* tmp_entry = down_cast<UnresolvedMergedType*>(entry);
2941bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers    std::set<uint16_t> check_types = tmp_entry->GetMergedTypes();
2951bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers    CHECK(check_types == types);
2961bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers  }
297529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  return *entry;
298529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers}
2991bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
300529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogersconst RegType& RegTypeCache::FromUnresolvedSuperClass(const RegType& child) {
301529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  // Check if entry already exists.
30251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  for (size_t i = primitive_count_; i < entries_.size(); i++) {
30351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    RegType* cur_entry = entries_[i];
30451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    if (cur_entry->IsUnresolvedSuperClass()) {
30551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      UnresolvedSuperClass* tmp_entry =
30651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal          down_cast<UnresolvedSuperClass*>(cur_entry);
30751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      uint16_t unresolved_super_child_id =
30851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal          tmp_entry->GetUnresolvedSuperClassChildId();
30951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      if (unresolved_super_child_id == child.GetId()) {
31051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        return *cur_entry;
31151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      }
31251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    }
31351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
31451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  RegType* entry = new UnresolvedSuperClass(child.GetId(), this, entries_.size());
31551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  entries_.push_back(entry);
31651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  return *entry;
317529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers}
3181bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
319776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersconst RegType& RegTypeCache::Uninitialized(const RegType& type, uint32_t allocation_pc) {
32051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  RegType* entry = NULL;
32151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  RegType* cur_entry = NULL;
322637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers  const std::string& descriptor(type.GetDescriptor());
323776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  if (type.IsUnresolvedTypes()) {
32451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    for (size_t i = primitive_count_; i < entries_.size(); i++) {
32551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      cur_entry = entries_[i];
326776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      if (cur_entry->IsUnresolvedAndUninitializedReference() &&
32751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal          down_cast<UnresolvedUninitializedRefType*>(cur_entry)->GetAllocationPc() == allocation_pc &&
32851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal          (cur_entry->GetDescriptor() == descriptor)) {
329776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers        return *cur_entry;
330776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      }
331776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
332637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers    entry = new UnresolvedUninitializedRefType(descriptor, allocation_pc, entries_.size());
333776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
3342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* klass = type.GetClass();
33551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    for (size_t i = primitive_count_; i < entries_.size(); i++) {
33651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      cur_entry = entries_[i];
337776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      if (cur_entry->IsUninitializedReference() &&
3381bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers          down_cast<UninitializedReferenceType*>(cur_entry)
33951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal              ->GetAllocationPc() == allocation_pc &&
340776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers          cur_entry->GetClass() == klass) {
341776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers        return *cur_entry;
342776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      }
343776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
344637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers    entry = new UninitializedReferenceType(klass, descriptor, allocation_pc, entries_.size());
345776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
346776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  entries_.push_back(entry);
347776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  return *entry;
348776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
3491bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
350776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersconst RegType& RegTypeCache::FromUninitialized(const RegType& uninit_type) {
351776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  RegType* entry;
3529f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal
353776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  if (uninit_type.IsUnresolvedTypes()) {
3541bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers    const std::string& descriptor(uninit_type.GetDescriptor());
35551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    for (size_t i = primitive_count_; i < entries_.size(); i++) {
356776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      RegType* cur_entry = entries_[i];
35751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      if (cur_entry->IsUnresolvedReference() &&
35851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal          cur_entry->GetDescriptor() == descriptor) {
359776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers        return *cur_entry;
360776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      }
361776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
3621bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers    entry = new UnresolvedReferenceType(descriptor.c_str(), entries_.size());
363776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
3642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* klass = uninit_type.GetClass();
3659f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal    if(uninit_type.IsUninitializedThisReference() && !klass->IsFinal()) {
3669f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal      // For uninitialized this reference look for reference types that are not precise.
3679f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal      for (size_t i = primitive_count_; i < entries_.size(); i++) {
3689f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal        RegType* cur_entry = entries_[i];
3699f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal        if (cur_entry->IsReference() && cur_entry->GetClass() == klass) {
3709f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal          return *cur_entry;
3719f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal        }
3729f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal      }
3731bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers      entry = new ReferenceType(klass, "", entries_.size());
3749f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal    } else {
37502c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal        if (klass->IsFinal()) {
37602c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal          if (klass->IsInstantiable()) {
37702c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal            for (size_t i = primitive_count_; i < entries_.size(); i++) {
37802c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal              RegType* cur_entry = entries_[i];
37902c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal              if (cur_entry->IsPreciseReference() && cur_entry->GetClass() == klass) {
38002c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal                return *cur_entry;
38102c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal              }
38202c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal            }
38302c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal            // Precise type was not found , create one !
3841bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers            entry = new PreciseReferenceType(klass, "", entries_.size());
38502c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal          } else {
38602c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal            return Conflict();
38702c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal          }
38802c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal      } else {
38902c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal        // Not a final class, create an imprecise reference. Look up if we have it in the cache first.
39002c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal        for (size_t i = primitive_count_; i < entries_.size(); i++) {
39102c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal          RegType* cur_entry = entries_[i];
39202c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal          if (cur_entry->IsReference() && !(cur_entry->IsPrecise()) &&
39302c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal              cur_entry->GetClass() == klass) {
39402c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal            return *cur_entry;
39502c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal          }
3969f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal        }
3971bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers        entry = new ReferenceType(klass, "", entries_.size());
398776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      }
399776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
4009f57a86148827b36906eef65857c8be40401fbf4Sameer Abu Asal }
401776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  entries_.push_back(entry);
402776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  return *entry;
403776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
4041bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
4051bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogersconst RegType& RegTypeCache::ByteConstant() {
4062dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return FromCat1Const(std::numeric_limits<jbyte>::min(), false);
4072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4081bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
4091bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogersconst RegType& RegTypeCache::ShortConstant() {
4102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return FromCat1Const(std::numeric_limits<jshort>::min(), false);
4112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4121bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
4131bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogersconst RegType& RegTypeCache::IntConstant() {
4142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return FromCat1Const(std::numeric_limits<jint>::max(), false);
4152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4161bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
417ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogersconst RegType& RegTypeCache::UninitializedThisArgument(const RegType& type) {
418ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers  RegType* entry;
419637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers  const std::string& descriptor(type.GetDescriptor());
420ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers  if (type.IsUnresolvedTypes()) {
42151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    for (size_t i = primitive_count_; i < entries_.size(); i++) {
422ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers      RegType* cur_entry = entries_[i];
423ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers      if (cur_entry->IsUnresolvedAndUninitializedThisReference() &&
424ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers          cur_entry->GetDescriptor() == descriptor) {
425ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers        return *cur_entry;
426ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers      }
427ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers    }
4281bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers    entry = new UnresolvedUninitializedThisRefType(descriptor, entries_.size());
429ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers  } else {
4302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* klass = type.GetClass();
43151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    for (size_t i = primitive_count_; i < entries_.size(); i++) {
432ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers      RegType* cur_entry = entries_[i];
43351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal      if (cur_entry->IsUninitializedThisReference() &&
43451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal          cur_entry->GetClass() == klass) {
435ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers        return *cur_entry;
436ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers      }
437776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
438637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers    entry = new UninitializedThisReferenceType(klass, descriptor, entries_.size());
439776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
440776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  entries_.push_back(entry);
441776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  return *entry;
442776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
4431bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers
4442bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogersconst RegType& RegTypeCache::FromCat1Const(int32_t value, bool precise) {
44551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  for (size_t i = primitive_count_; i < entries_.size(); i++) {
446776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    RegType* cur_entry = entries_[i];
447637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers    if (cur_entry->klass_ == NULL && cur_entry->IsConstant() &&
448637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers        cur_entry->IsPreciseConstant() == precise &&
44951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        (down_cast<ConstantType*>(cur_entry))->ConstantValue() == value) {
450776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      return *cur_entry;
451776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
452776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
45351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  RegType* entry;
45451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  if (precise) {
45551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    entry = new PreciseConstType(value, entries_.size());
45651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  } else {
45751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    entry = new ImpreciseConstType(value, entries_.size());
45851a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
4592bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  entries_.push_back(entry);
4602bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  return *entry;
4612bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers}
4622bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers
4632bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogersconst RegType& RegTypeCache::FromCat2ConstLo(int32_t value, bool precise) {
46451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  for (size_t i = primitive_count_; i < entries_.size(); i++) {
4652bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers    RegType* cur_entry = entries_[i];
46651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    if (cur_entry->IsConstantLo() && (cur_entry->IsPrecise() == precise) &&
46751a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        (down_cast<ConstantType*>(cur_entry))->ConstantValueLo() == value) {
4682bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers      return *cur_entry;
4692bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers    }
4702bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  }
47151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  RegType* entry;
47251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  if (precise) {
47351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    entry = new PreciseConstLoType(value, entries_.size());
47451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  } else {
47551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    entry = new ImpreciseConstLoType(value, entries_.size());
47651a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
4772bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  entries_.push_back(entry);
4782bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  return *entry;
4792bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers}
4802bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers
4812bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogersconst RegType& RegTypeCache::FromCat2ConstHi(int32_t value, bool precise) {
48251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  for (size_t i = primitive_count_; i < entries_.size(); i++) {
4832bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers    RegType* cur_entry = entries_[i];
48451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    if (cur_entry->IsConstantHi() && (cur_entry->IsPrecise() == precise) &&
48551a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal        (down_cast<ConstantType*>(cur_entry))->ConstantValueHi() == value) {
4862bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers      return *cur_entry;
4872bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers    }
4882bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  }
48951a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  RegType* entry;
49051a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  if (precise) {
49151a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    entry = new PreciseConstHiType(value, entries_.size());
49251a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  } else {
49351a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal    entry = new ImpreciseConstHiType(value, entries_.size());
49451a5fb78d1b03b5235c2ae45414235282182bb86Sameer Abu Asal  }
495776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  entries_.push_back(entry);
496776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  return *entry;
497776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
498776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
4992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersconst RegType& RegTypeCache::GetComponentType(const RegType& array, mirror::ClassLoader* loader) {
500776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  CHECK(array.IsArrayTypes());
501776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  if (array.IsUnresolvedTypes()) {
5021bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers    const std::string& descriptor(array.GetDescriptor());
5031bf8d4dbe5cb9891e8a1125ff1928b544efc243aIan Rogers    const std::string component(descriptor.substr(1, descriptor.size() - 1));
504b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    return FromDescriptor(loader, component.c_str(), false);
505776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
5062dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* klass = array.GetClass()->GetComponentType();
507637c65b1e431fd90195b71c141b3590bd81cc91aIan Rogers    return FromClass(ClassHelper(klass).GetDescriptor(), klass, klass->IsFinal());
508b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers  }
509b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers}
510b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers
511b49035706fceb2b13e8154668f175af624cf88f4Ian Rogersvoid RegTypeCache::Dump(std::ostream& os) {
512b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers  for (size_t i = 0; i < entries_.size(); i++) {
513b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    RegType* cur_entry = entries_[i];
514b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    if (cur_entry != NULL) {
5152bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers      os << i << ": " << cur_entry->Dump() << "\n";
516b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    }
517776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
518776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
519776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
520a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes}  // namespace verifier
521a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes}  // namespace art
522