reg_type_cache.cc revision 2dd0e2cea360bc9206eb88ecc40d259e796c239d
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 17776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "reg_type_cache.h" 18776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h" 202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h" 21776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "object_utils.h" 22776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 23776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersnamespace art { 24776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersnamespace verifier { 25776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 26776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersstatic RegType::Type RegTypeFromPrimitiveType(Primitive::Type prim_type) { 27776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers switch (prim_type) { 28776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers case Primitive::kPrimBoolean: return RegType::kRegTypeBoolean; 29776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers case Primitive::kPrimByte: return RegType::kRegTypeByte; 30776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers case Primitive::kPrimShort: return RegType::kRegTypeShort; 31776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers case Primitive::kPrimChar: return RegType::kRegTypeChar; 32776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers case Primitive::kPrimInt: return RegType::kRegTypeInteger; 33776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers case Primitive::kPrimLong: return RegType::kRegTypeLongLo; 34776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers case Primitive::kPrimFloat: return RegType::kRegTypeFloat; 35776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers case Primitive::kPrimDouble: return RegType::kRegTypeDoubleLo; 36776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers case Primitive::kPrimVoid: 37ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers default: return RegType::kRegTypeConflict; 38776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 39776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers} 40776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 41776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersstatic RegType::Type RegTypeFromDescriptor(const std::string& descriptor) { 42776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers if (descriptor.length() == 1) { 43776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers switch (descriptor[0]) { 44776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers case 'Z': return RegType::kRegTypeBoolean; 45776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers case 'B': return RegType::kRegTypeByte; 46776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers case 'S': return RegType::kRegTypeShort; 47776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers case 'C': return RegType::kRegTypeChar; 48776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers case 'I': return RegType::kRegTypeInteger; 49776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers case 'J': return RegType::kRegTypeLongLo; 50776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers case 'F': return RegType::kRegTypeFloat; 51776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers case 'D': return RegType::kRegTypeDoubleLo; 52776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers case 'V': 53ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers default: return RegType::kRegTypeConflict; 54776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 55776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } else if (descriptor[0] == 'L' || descriptor[0] == '[') { 56776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return RegType::kRegTypeReference; 57776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } else { 58ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers return RegType::kRegTypeConflict; 59776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 60776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers} 61776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersconst RegType& RegTypeCache::FromDescriptor(mirror::ClassLoader* loader, const char* descriptor, 63b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers bool precise) { 64b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers return From(RegTypeFromDescriptor(descriptor), loader, descriptor, precise); 65776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers} 66776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 67b49035706fceb2b13e8154668f175af624cf88f4Ian Rogersstatic bool MatchingPrecisionForClass(RegType* entry, bool precise) 68b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 69b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers return (entry->IsPreciseReference() == precise) || (entry->GetClass()->IsFinal() && !precise); 70b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers} 71b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers 722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersconst RegType& RegTypeCache::From(RegType::Type type, mirror::ClassLoader* loader, 732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers const char* descriptor, bool precise) { 74776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers if (type <= RegType::kRegTypeLastFixedLocation) { 75776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // entries should be sized greater than primitive types 76776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers DCHECK_GT(entries_.size(), static_cast<size_t>(type)); 77776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers RegType* entry = entries_[type]; 78776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers if (entry == NULL) { 792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* c = NULL; 80776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers if (strlen(descriptor) != 0) { 8180537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes c = Runtime::Current()->GetClassLinker()->FindSystemClass(descriptor); 82776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 8380537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes entry = new RegType(type, c, 0, type); 84776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers entries_[type] = entry; 85776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 86776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return *entry; 87776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } else { 88b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers DCHECK(type == RegType::kRegTypeReference || type == RegType::kRegTypePreciseReference); 89776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers ClassHelper kh; 90776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) { 91776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers RegType* cur_entry = entries_[i]; 92776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // check resolved and unresolved references, ignore uninitialized references 93b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers if (cur_entry->HasClass()) { 94776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers kh.ChangeClass(cur_entry->GetClass()); 95b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers if (MatchingPrecisionForClass(cur_entry, precise) && 96b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers (strcmp(descriptor, kh.GetDescriptor()) == 0)) { 97776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return *cur_entry; 98776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 99776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } else if (cur_entry->IsUnresolvedReference() && 10080537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes cur_entry->GetDescriptor() == descriptor) { 101776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return *cur_entry; 102776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 103776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 10480537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1052dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* c; 10680537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes if (can_load_classes_) { 10780537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes c = class_linker->FindClass(descriptor, loader); 10880537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes } else { 10980537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes c = class_linker->LookupClass(descriptor, loader); 11080537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes } 11180537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes if (c != NULL) { 112b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers // Able to resolve so create resolved register type that is precise if we 113b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers // know the type is final. 11480537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes RegType* entry = new RegType(c->IsFinal() ? RegType::kRegTypePreciseReference 11580537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes : RegType::kRegTypeReference, 11680537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes c, 0, entries_.size()); 117776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers entries_.push_back(entry); 118776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return *entry; 119776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } else { 120776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // TODO: we assume unresolved, but we may be able to do better by validating whether the 121776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // descriptor string is valid 122776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // Unable to resolve so create unresolved register type 12380537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes if (can_load_classes_) { 12480537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes DCHECK(Thread::Current()->IsExceptionPending()); 12580537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes Thread::Current()->ClearException(); 12680537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes } else { 12780537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes DCHECK(!Thread::Current()->IsExceptionPending()); 12880537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes } 129776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers if (IsValidDescriptor(descriptor)) { 1302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers RegType* entry = 1312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers new RegType(RegType::kRegTypeUnresolvedReference, descriptor, 0, entries_.size()); 132776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers entries_.push_back(entry); 133776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return *entry; 134776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } else { 135776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // The descriptor is broken return the unknown type as there's nothing sensible that 136776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // could be done at runtime 137ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers return Conflict(); 138776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 139776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 140776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 141776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers} 142776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 1432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersconst RegType& RegTypeCache::FromClass(mirror::Class* klass, bool precise) { 144776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers if (klass->IsPrimitive()) { 145776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers RegType::Type type = RegTypeFromPrimitiveType(klass->GetPrimitiveType()); 146776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers // entries should be sized greater than primitive types 147776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers DCHECK_GT(entries_.size(), static_cast<size_t>(type)); 148776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers RegType* entry = entries_[type]; 149776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers if (entry == NULL) { 150776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers entry = new RegType(type, klass, 0, type); 151776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers entries_[type] = entry; 152776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 153776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return *entry; 154776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } else { 155776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) { 156776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers RegType* cur_entry = entries_[i]; 157b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers if ((cur_entry->HasClass()) && 158b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers MatchingPrecisionForClass(cur_entry, precise) && cur_entry->GetClass() == klass) { 159776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return *cur_entry; 160776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 161776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 162b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers RegType* entry = new RegType(precise ? RegType::kRegTypePreciseReference 163b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers : RegType::kRegTypeReference, 164b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers klass, 0, entries_.size()); 165776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers entries_.push_back(entry); 166776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return *entry; 167776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 168776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers} 169776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 170529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogersconst RegType& RegTypeCache::FromUnresolvedMerge(const RegType& left, const RegType& right) { 171529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers std::set<uint16_t> types; 172529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers if (left.IsUnresolvedMergedReference()) { 173529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers types = left.GetMergedTypes(this); 174529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers } else { 175529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers types.insert(left.GetId()); 176529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers } 177529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers if (right.IsUnresolvedMergedReference()) { 178529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers std::set<uint16_t> right_types = right.GetMergedTypes(this); 179529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers types.insert(right_types.begin(), right_types.end()); 180529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers } else { 181529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers types.insert(right.GetId()); 182529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers } 183529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers // Check if entry already exists. 184529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) { 185529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers RegType* cur_entry = entries_[i]; 186529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers if (cur_entry->IsUnresolvedMergedReference()) { 187529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers std::set<uint16_t> cur_entry_types = cur_entry->GetMergedTypes(this); 188529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers if (cur_entry_types == types) { 189529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers return *cur_entry; 190529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers } 191529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers } 192529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers } 193529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers // Create entry. 194529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers uint32_t merged_ids = static_cast<uint32_t>(left.GetId()) << 16 | 195529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers static_cast<uint32_t>(right.GetId()); 196529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers RegType* entry = new RegType(RegType::kRegTypeUnresolvedMergedReference, NULL, merged_ids, 197529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers entries_.size()); 198529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers entries_.push_back(entry); 199529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers#ifndef DEBUG 200529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers std::set<uint16_t> check_types = entry->GetMergedTypes(this); 201529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers CHECK(check_types == types); 202529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers#endif 203529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers return *entry; 204529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers} 205529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers 206529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogersconst RegType& RegTypeCache::FromUnresolvedSuperClass(const RegType& child) { 207529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers // Check if entry already exists. 208529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) { 209529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers RegType* cur_entry = entries_[i]; 210529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers if (cur_entry->IsUnresolvedSuperClass()) { 211529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers uint16_t unresolved_super_child_id = cur_entry->GetUnresolvedSuperClassChildId(); 212529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers if (unresolved_super_child_id == child.GetId()) { 213529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers return *cur_entry; 214529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers } 215529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers } 216529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers } 217529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers // Create entry. 218529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers RegType* entry = new RegType(RegType::kRegTypeUnresolvedSuperClass, NULL, child.GetId(), 219529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers entries_.size()); 220529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers entries_.push_back(entry); 221529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers return *entry; 222529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers} 223529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers 224776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersconst RegType& RegTypeCache::Uninitialized(const RegType& type, uint32_t allocation_pc) { 225776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers RegType* entry; 226776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers if (type.IsUnresolvedTypes()) { 22780537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes std::string descriptor(type.GetDescriptor()); 228776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) { 229776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers RegType* cur_entry = entries_[i]; 230776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers if (cur_entry->IsUnresolvedAndUninitializedReference() && 231776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers cur_entry->GetAllocationPc() == allocation_pc && 232776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers cur_entry->GetDescriptor() == descriptor) { 233776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return *cur_entry; 234776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 235776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 236776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers entry = new RegType(RegType::kRegTypeUnresolvedAndUninitializedReference, 237776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers descriptor, allocation_pc, entries_.size()); 238776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } else { 2392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* klass = type.GetClass(); 240776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) { 241776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers RegType* cur_entry = entries_[i]; 242776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers if (cur_entry->IsUninitializedReference() && 243776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers cur_entry->GetAllocationPc() == allocation_pc && 244776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers cur_entry->GetClass() == klass) { 245776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return *cur_entry; 246776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 247776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 248776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers entry = new RegType(RegType::kRegTypeUninitializedReference, 249776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers klass, allocation_pc, entries_.size()); 250776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 251776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers entries_.push_back(entry); 252776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return *entry; 253776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers} 254776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 255776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersconst RegType& RegTypeCache::FromUninitialized(const RegType& uninit_type) { 256776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers RegType* entry; 257776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers if (uninit_type.IsUnresolvedTypes()) { 25880537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes std::string descriptor(uninit_type.GetDescriptor()); 259776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) { 260776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers RegType* cur_entry = entries_[i]; 261776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers if (cur_entry->IsUnresolvedReference() && cur_entry->GetDescriptor() == descriptor) { 262776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return *cur_entry; 263776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 264776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 265776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers entry = new RegType(RegType::kRegTypeUnresolvedReference, descriptor, 0, entries_.size()); 266776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } else { 2672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* klass = uninit_type.GetClass(); 268776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) { 269776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers RegType* cur_entry = entries_[i]; 270b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers if (cur_entry->IsPreciseReference() && cur_entry->GetClass() == klass) { 271776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return *cur_entry; 272776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 273776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 274b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers entry = new RegType(RegType::kRegTypePreciseReference, klass, 0, entries_.size()); 275776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 276776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers entries_.push_back(entry); 277776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return *entry; 278776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers} 279776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 2802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersconst RegType& RegTypeCache::ByteConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return FromCat1Const(std::numeric_limits<jbyte>::min(), false); 2822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersconst RegType& RegTypeCache::ShortConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return FromCat1Const(std::numeric_limits<jshort>::min(), false); 2862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersconst RegType& RegTypeCache::IntConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return FromCat1Const(std::numeric_limits<jint>::max(), false); 2902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 292ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogersconst RegType& RegTypeCache::UninitializedThisArgument(const RegType& type) { 293ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers // TODO: implement descriptor version. 294ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers RegType* entry; 295ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers if (type.IsUnresolvedTypes()) { 29680537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes std::string descriptor(type.GetDescriptor()); 297ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) { 298ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers RegType* cur_entry = entries_[i]; 299ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers if (cur_entry->IsUnresolvedAndUninitializedThisReference() && 300ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers cur_entry->GetDescriptor() == descriptor) { 301ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers return *cur_entry; 302ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers } 303ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers } 304ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers entry = new RegType(RegType::kRegTypeUnresolvedAndUninitializedThisReference, descriptor, 0, 305ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers entries_.size()); 306ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers } else { 3072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* klass = type.GetClass(); 308ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) { 309ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers RegType* cur_entry = entries_[i]; 310ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers if (cur_entry->IsUninitializedThisReference() && cur_entry->GetClass() == klass) { 311ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers return *cur_entry; 312ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers } 313776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 314ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers entry = new RegType(RegType::kRegTypeUninitializedThisReference, klass, 0, entries_.size()); 315776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 316776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers entries_.push_back(entry); 317776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return *entry; 318776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers} 319776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 320776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersconst RegType& RegTypeCache::FromType(RegType::Type type) { 321776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers CHECK(type < RegType::kRegTypeReference); 322776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers switch (type) { 323b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers case RegType::kRegTypeBoolean: return From(type, NULL, "Z", true); 324b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers case RegType::kRegTypeByte: return From(type, NULL, "B", true); 325b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers case RegType::kRegTypeShort: return From(type, NULL, "S", true); 326b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers case RegType::kRegTypeChar: return From(type, NULL, "C", true); 327b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers case RegType::kRegTypeInteger: return From(type, NULL, "I", true); 328b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers case RegType::kRegTypeFloat: return From(type, NULL, "F", true); 329776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers case RegType::kRegTypeLongLo: 330b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers case RegType::kRegTypeLongHi: return From(type, NULL, "J", true); 331776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers case RegType::kRegTypeDoubleLo: 332b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers case RegType::kRegTypeDoubleHi: return From(type, NULL, "D", true); 333b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers default: return From(type, NULL, "", true); 334776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 335776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers} 336776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 3372bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogersconst RegType& RegTypeCache::FromCat1Const(int32_t value, bool precise) { 3382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers RegType::Type wanted_type = 3392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers precise ? RegType::kRegTypePreciseConst : RegType::kRegTypeImpreciseConst; 340776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) { 341776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers RegType* cur_entry = entries_[i]; 3422bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers if (cur_entry->GetType() == wanted_type && cur_entry->ConstantValue() == value) { 343776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return *cur_entry; 344776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 345776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 3462bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers RegType* entry = new RegType(wanted_type, NULL, value, entries_.size()); 3472bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers entries_.push_back(entry); 3482bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers return *entry; 3492bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers} 3502bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers 3512bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogersconst RegType& RegTypeCache::FromCat2ConstLo(int32_t value, bool precise) { 3522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers RegType::Type wanted_type = 3532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers precise ? RegType::kRegTypePreciseConstLo : RegType::kRegTypeImpreciseConstLo; 3542bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) { 3552bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers RegType* cur_entry = entries_[i]; 3562bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers if (cur_entry->GetType() == wanted_type && cur_entry->ConstantValueLo() == value) { 3572bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers return *cur_entry; 3582bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers } 3592bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers } 3602bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers RegType* entry = new RegType(wanted_type, NULL, value, entries_.size()); 3612bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers entries_.push_back(entry); 3622bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers return *entry; 3632bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers} 3642bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers 3652bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogersconst RegType& RegTypeCache::FromCat2ConstHi(int32_t value, bool precise) { 3662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers RegType::Type wanted_type = 3672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers precise ? RegType::kRegTypePreciseConstHi : RegType::kRegTypeImpreciseConstHi; 3682bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) { 3692bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers RegType* cur_entry = entries_[i]; 3702bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers if (cur_entry->GetType() == wanted_type && cur_entry->ConstantValueHi() == value) { 3712bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers return *cur_entry; 3722bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers } 3732bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers } 3742bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers RegType* entry = new RegType(wanted_type, NULL, value, entries_.size()); 375776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers entries_.push_back(entry); 376776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers return *entry; 377776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers} 378776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 3792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersconst RegType& RegTypeCache::GetComponentType(const RegType& array, mirror::ClassLoader* loader) { 380776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers CHECK(array.IsArrayTypes()); 381776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers if (array.IsUnresolvedTypes()) { 38280537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes std::string descriptor(array.GetDescriptor()); 383776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers std::string component(descriptor.substr(1, descriptor.size() - 1)); 384b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers return FromDescriptor(loader, component.c_str(), false); 385776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } else { 3862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* klass = array.GetClass()->GetComponentType(); 387b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers return FromClass(klass, klass->IsFinal()); 388b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers } 389b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers} 390b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers 391b49035706fceb2b13e8154668f175af624cf88f4Ian Rogersvoid RegTypeCache::Dump(std::ostream& os) { 392b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers for (size_t i = 0; i < entries_.size(); i++) { 393b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers RegType* cur_entry = entries_[i]; 394b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers if (cur_entry != NULL) { 3952bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers os << i << ": " << cur_entry->Dump() << "\n"; 396b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers } 397776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers } 398776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers} 399776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers 400a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes} // namespace verifier 401a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes} // namespace art 402