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