1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "reg_type_cache-inl.h" 18 19 #include "base/arena_bit_vector.h" 20 #include "base/bit_vector-inl.h" 21 #include "base/casts.h" 22 #include "base/scoped_arena_allocator.h" 23 #include "base/stl_util.h" 24 #include "class_linker-inl.h" 25 #include "dex_file-inl.h" 26 #include "mirror/class-inl.h" 27 #include "mirror/object-inl.h" 28 #include "reg_type-inl.h" 29 30 namespace art { 31 namespace verifier { 32 33 bool RegTypeCache::primitive_initialized_ = false; 34 uint16_t RegTypeCache::primitive_count_ = 0; 35 const PreciseConstType* RegTypeCache::small_precise_constants_[kMaxSmallConstant - 36 kMinSmallConstant + 1]; 37 38 ALWAYS_INLINE static inline bool MatchingPrecisionForClass(const RegType* entry, bool precise) 39 SHARED_REQUIRES(Locks::mutator_lock_) { 40 if (entry->IsPreciseReference() == precise) { 41 // We were or weren't looking for a precise reference and we found what we need. 42 return true; 43 } else { 44 if (!precise && entry->GetClass()->CannotBeAssignedFromOtherTypes()) { 45 // We weren't looking for a precise reference, as we're looking up based on a descriptor, but 46 // we found a matching entry based on the descriptor. Return the precise entry in that case. 47 return true; 48 } 49 return false; 50 } 51 } 52 53 void RegTypeCache::FillPrimitiveAndSmallConstantTypes() { 54 entries_.push_back(UndefinedType::GetInstance()); 55 entries_.push_back(ConflictType::GetInstance()); 56 entries_.push_back(BooleanType::GetInstance()); 57 entries_.push_back(ByteType::GetInstance()); 58 entries_.push_back(ShortType::GetInstance()); 59 entries_.push_back(CharType::GetInstance()); 60 entries_.push_back(IntegerType::GetInstance()); 61 entries_.push_back(LongLoType::GetInstance()); 62 entries_.push_back(LongHiType::GetInstance()); 63 entries_.push_back(FloatType::GetInstance()); 64 entries_.push_back(DoubleLoType::GetInstance()); 65 entries_.push_back(DoubleHiType::GetInstance()); 66 for (int32_t value = kMinSmallConstant; value <= kMaxSmallConstant; ++value) { 67 int32_t i = value - kMinSmallConstant; 68 DCHECK_EQ(entries_.size(), small_precise_constants_[i]->GetId()); 69 entries_.push_back(small_precise_constants_[i]); 70 } 71 DCHECK_EQ(entries_.size(), primitive_count_); 72 } 73 74 const RegType& RegTypeCache::FromDescriptor(mirror::ClassLoader* loader, 75 const char* descriptor, 76 bool precise) { 77 DCHECK(RegTypeCache::primitive_initialized_); 78 if (descriptor[1] == '\0') { 79 switch (descriptor[0]) { 80 case 'Z': 81 return Boolean(); 82 case 'B': 83 return Byte(); 84 case 'S': 85 return Short(); 86 case 'C': 87 return Char(); 88 case 'I': 89 return Integer(); 90 case 'J': 91 return LongLo(); 92 case 'F': 93 return Float(); 94 case 'D': 95 return DoubleLo(); 96 case 'V': // For void types, conflict types. 97 default: 98 return Conflict(); 99 } 100 } else if (descriptor[0] == 'L' || descriptor[0] == '[') { 101 return From(loader, descriptor, precise); 102 } else { 103 return Conflict(); 104 } 105 } 106 107 const RegType& RegTypeCache::RegTypeFromPrimitiveType(Primitive::Type prim_type) const { 108 DCHECK(RegTypeCache::primitive_initialized_); 109 switch (prim_type) { 110 case Primitive::kPrimBoolean: 111 return *BooleanType::GetInstance(); 112 case Primitive::kPrimByte: 113 return *ByteType::GetInstance(); 114 case Primitive::kPrimShort: 115 return *ShortType::GetInstance(); 116 case Primitive::kPrimChar: 117 return *CharType::GetInstance(); 118 case Primitive::kPrimInt: 119 return *IntegerType::GetInstance(); 120 case Primitive::kPrimLong: 121 return *LongLoType::GetInstance(); 122 case Primitive::kPrimFloat: 123 return *FloatType::GetInstance(); 124 case Primitive::kPrimDouble: 125 return *DoubleLoType::GetInstance(); 126 case Primitive::kPrimVoid: 127 default: 128 return *ConflictType::GetInstance(); 129 } 130 } 131 132 bool RegTypeCache::MatchDescriptor(size_t idx, const StringPiece& descriptor, bool precise) { 133 const RegType* entry = entries_[idx]; 134 if (descriptor != entry->descriptor_) { 135 return false; 136 } 137 if (entry->HasClass()) { 138 return MatchingPrecisionForClass(entry, precise); 139 } 140 // There is no notion of precise unresolved references, the precise information is just dropped 141 // on the floor. 142 DCHECK(entry->IsUnresolvedReference()); 143 return true; 144 } 145 146 mirror::Class* RegTypeCache::ResolveClass(const char* descriptor, mirror::ClassLoader* loader) { 147 // Class was not found, must create new type. 148 // Try resolving class 149 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 150 Thread* self = Thread::Current(); 151 StackHandleScope<1> hs(self); 152 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(loader)); 153 mirror::Class* klass = nullptr; 154 if (can_load_classes_) { 155 klass = class_linker->FindClass(self, descriptor, class_loader); 156 } else { 157 klass = class_linker->LookupClass(self, descriptor, ComputeModifiedUtf8Hash(descriptor), 158 loader); 159 if (klass != nullptr && !klass->IsResolved()) { 160 // We found the class but without it being loaded its not safe for use. 161 klass = nullptr; 162 } 163 } 164 return klass; 165 } 166 167 StringPiece RegTypeCache::AddString(const StringPiece& string_piece) { 168 char* ptr = arena_.AllocArray<char>(string_piece.length()); 169 memcpy(ptr, string_piece.data(), string_piece.length()); 170 return StringPiece(ptr, string_piece.length()); 171 } 172 173 const RegType& RegTypeCache::From(mirror::ClassLoader* loader, 174 const char* descriptor, 175 bool precise) { 176 StringPiece sp_descriptor(descriptor); 177 // Try looking up the class in the cache first. We use a StringPiece to avoid continual strlen 178 // operations on the descriptor. 179 for (size_t i = primitive_count_; i < entries_.size(); i++) { 180 if (MatchDescriptor(i, sp_descriptor, precise)) { 181 return *(entries_[i]); 182 } 183 } 184 // Class not found in the cache, will create a new type for that. 185 // Try resolving class. 186 mirror::Class* klass = ResolveClass(descriptor, loader); 187 if (klass != nullptr) { 188 // Class resolved, first look for the class in the list of entries 189 // Class was not found, must create new type. 190 // To pass the verification, the type should be imprecise, 191 // instantiable or an interface with the precise type set to false. 192 DCHECK(!precise || klass->IsInstantiable()); 193 // Create a precise type if: 194 // 1- Class is final and NOT an interface. a precise interface is meaningless !! 195 // 2- Precise Flag passed as true. 196 RegType* entry; 197 // Create an imprecise type if we can't tell for a fact that it is precise. 198 if (klass->CannotBeAssignedFromOtherTypes() || precise) { 199 DCHECK(!(klass->IsAbstract()) || klass->IsArrayClass()); 200 DCHECK(!klass->IsInterface()); 201 entry = new (&arena_) PreciseReferenceType(klass, AddString(sp_descriptor), entries_.size()); 202 } else { 203 entry = new (&arena_) ReferenceType(klass, AddString(sp_descriptor), entries_.size()); 204 } 205 return AddEntry(entry); 206 } else { // Class not resolved. 207 // We tried loading the class and failed, this might get an exception raised 208 // so we want to clear it before we go on. 209 if (can_load_classes_) { 210 DCHECK(Thread::Current()->IsExceptionPending()); 211 Thread::Current()->ClearException(); 212 } else { 213 DCHECK(!Thread::Current()->IsExceptionPending()); 214 } 215 if (IsValidDescriptor(descriptor)) { 216 return AddEntry( 217 new (&arena_) UnresolvedReferenceType(AddString(sp_descriptor), entries_.size())); 218 } else { 219 // The descriptor is broken return the unknown type as there's nothing sensible that 220 // could be done at runtime 221 return Conflict(); 222 } 223 } 224 } 225 226 const RegType* RegTypeCache::FindClass(mirror::Class* klass, bool precise) const { 227 DCHECK(klass != nullptr); 228 if (klass->IsPrimitive()) { 229 // Note: precise isn't used for primitive classes. A char is assignable to an int. All 230 // primitive classes are final. 231 return &RegTypeFromPrimitiveType(klass->GetPrimitiveType()); 232 } 233 for (auto& pair : klass_entries_) { 234 mirror::Class* const reg_klass = pair.first.Read(); 235 if (reg_klass == klass) { 236 const RegType* reg_type = pair.second; 237 if (MatchingPrecisionForClass(reg_type, precise)) { 238 return reg_type; 239 } 240 } 241 } 242 return nullptr; 243 } 244 245 const RegType* RegTypeCache::InsertClass(const StringPiece& descriptor, 246 mirror::Class* klass, 247 bool precise) { 248 // No reference to the class was found, create new reference. 249 DCHECK(FindClass(klass, precise) == nullptr); 250 RegType* const reg_type = precise 251 ? static_cast<RegType*>( 252 new (&arena_) PreciseReferenceType(klass, descriptor, entries_.size())) 253 : new (&arena_) ReferenceType(klass, descriptor, entries_.size()); 254 return &AddEntry(reg_type); 255 } 256 257 const RegType& RegTypeCache::FromClass(const char* descriptor, mirror::Class* klass, bool precise) { 258 DCHECK(klass != nullptr); 259 const RegType* reg_type = FindClass(klass, precise); 260 if (reg_type == nullptr) { 261 reg_type = InsertClass(AddString(StringPiece(descriptor)), klass, precise); 262 } 263 return *reg_type; 264 } 265 266 RegTypeCache::RegTypeCache(bool can_load_classes, ScopedArenaAllocator& arena) 267 : entries_(arena.Adapter(kArenaAllocVerifier)), 268 klass_entries_(arena.Adapter(kArenaAllocVerifier)), 269 can_load_classes_(can_load_classes), 270 arena_(arena) { 271 if (kIsDebugBuild) { 272 Thread::Current()->AssertThreadSuspensionIsAllowable(gAborting == 0); 273 } 274 // The klass_entries_ array does not have primitives or small constants. 275 static constexpr size_t kNumReserveEntries = 32; 276 klass_entries_.reserve(kNumReserveEntries); 277 // We want to have room for additional entries after inserting primitives and small 278 // constants. 279 entries_.reserve(kNumReserveEntries + kNumPrimitivesAndSmallConstants); 280 FillPrimitiveAndSmallConstantTypes(); 281 } 282 283 RegTypeCache::~RegTypeCache() { 284 DCHECK_LE(primitive_count_, entries_.size()); 285 } 286 287 void RegTypeCache::ShutDown() { 288 if (RegTypeCache::primitive_initialized_) { 289 UndefinedType::Destroy(); 290 ConflictType::Destroy(); 291 BooleanType::Destroy(); 292 ByteType::Destroy(); 293 ShortType::Destroy(); 294 CharType::Destroy(); 295 IntegerType::Destroy(); 296 LongLoType::Destroy(); 297 LongHiType::Destroy(); 298 FloatType::Destroy(); 299 DoubleLoType::Destroy(); 300 DoubleHiType::Destroy(); 301 for (int32_t value = kMinSmallConstant; value <= kMaxSmallConstant; ++value) { 302 const PreciseConstType* type = small_precise_constants_[value - kMinSmallConstant]; 303 delete type; 304 small_precise_constants_[value - kMinSmallConstant] = nullptr; 305 } 306 RegTypeCache::primitive_initialized_ = false; 307 RegTypeCache::primitive_count_ = 0; 308 } 309 } 310 311 template <class Type> 312 const Type* RegTypeCache::CreatePrimitiveTypeInstance(const std::string& descriptor) { 313 mirror::Class* klass = nullptr; 314 // Try loading the class from linker. 315 if (!descriptor.empty()) { 316 klass = art::Runtime::Current()->GetClassLinker()->FindSystemClass(Thread::Current(), 317 descriptor.c_str()); 318 DCHECK(klass != nullptr); 319 } 320 const Type* entry = Type::CreateInstance(klass, descriptor, RegTypeCache::primitive_count_); 321 RegTypeCache::primitive_count_++; 322 return entry; 323 } 324 325 void RegTypeCache::CreatePrimitiveAndSmallConstantTypes() { 326 CreatePrimitiveTypeInstance<UndefinedType>(""); 327 CreatePrimitiveTypeInstance<ConflictType>(""); 328 CreatePrimitiveTypeInstance<BooleanType>("Z"); 329 CreatePrimitiveTypeInstance<ByteType>("B"); 330 CreatePrimitiveTypeInstance<ShortType>("S"); 331 CreatePrimitiveTypeInstance<CharType>("C"); 332 CreatePrimitiveTypeInstance<IntegerType>("I"); 333 CreatePrimitiveTypeInstance<LongLoType>("J"); 334 CreatePrimitiveTypeInstance<LongHiType>("J"); 335 CreatePrimitiveTypeInstance<FloatType>("F"); 336 CreatePrimitiveTypeInstance<DoubleLoType>("D"); 337 CreatePrimitiveTypeInstance<DoubleHiType>("D"); 338 for (int32_t value = kMinSmallConstant; value <= kMaxSmallConstant; ++value) { 339 PreciseConstType* type = new PreciseConstType(value, primitive_count_); 340 small_precise_constants_[value - kMinSmallConstant] = type; 341 primitive_count_++; 342 } 343 } 344 345 const RegType& RegTypeCache::FromUnresolvedMerge(const RegType& left, const RegType& right) { 346 ArenaBitVector types(&arena_, 347 kDefaultArenaBitVectorBytes * kBitsPerByte, // Allocate at least 8 bytes. 348 true); // Is expandable. 349 const RegType* left_resolved; 350 bool left_unresolved_is_array; 351 if (left.IsUnresolvedMergedReference()) { 352 const UnresolvedMergedType& left_merge = *down_cast<const UnresolvedMergedType*>(&left); 353 354 types.Copy(&left_merge.GetUnresolvedTypes()); 355 left_resolved = &left_merge.GetResolvedPart(); 356 left_unresolved_is_array = left.IsArrayTypes(); 357 } else if (left.IsUnresolvedTypes()) { 358 types.ClearAllBits(); 359 types.SetBit(left.GetId()); 360 left_resolved = &Zero(); 361 left_unresolved_is_array = left.IsArrayTypes(); 362 } else { 363 types.ClearAllBits(); 364 left_resolved = &left; 365 left_unresolved_is_array = false; 366 } 367 368 const RegType* right_resolved; 369 bool right_unresolved_is_array; 370 if (right.IsUnresolvedMergedReference()) { 371 const UnresolvedMergedType& right_merge = *down_cast<const UnresolvedMergedType*>(&right); 372 373 types.Union(&right_merge.GetUnresolvedTypes()); 374 right_resolved = &right_merge.GetResolvedPart(); 375 right_unresolved_is_array = right.IsArrayTypes(); 376 } else if (right.IsUnresolvedTypes()) { 377 types.SetBit(right.GetId()); 378 right_resolved = &Zero(); 379 right_unresolved_is_array = right.IsArrayTypes(); 380 } else { 381 right_resolved = &right; 382 right_unresolved_is_array = false; 383 } 384 385 // Merge the resolved parts. Left and right might be equal, so use SafeMerge. 386 const RegType& resolved_parts_merged = left_resolved->SafeMerge(*right_resolved, this); 387 // If we get a conflict here, the merge result is a conflict, not an unresolved merge type. 388 if (resolved_parts_merged.IsConflict()) { 389 return Conflict(); 390 } 391 392 bool resolved_merged_is_array = resolved_parts_merged.IsArrayTypes(); 393 if (left_unresolved_is_array || right_unresolved_is_array || resolved_merged_is_array) { 394 // Arrays involved, see if we need to merge to Object. 395 396 // Is the resolved part a primitive array? 397 if (resolved_merged_is_array && !resolved_parts_merged.IsObjectArrayTypes()) { 398 return JavaLangObject(false /* precise */); 399 } 400 401 // Is any part not an array (but exists)? 402 if ((!left_unresolved_is_array && left_resolved != &left) || 403 (!right_unresolved_is_array && right_resolved != &right) || 404 !resolved_merged_is_array) { 405 return JavaLangObject(false /* precise */); 406 } 407 } 408 409 // Check if entry already exists. 410 for (size_t i = primitive_count_; i < entries_.size(); i++) { 411 const RegType* cur_entry = entries_[i]; 412 if (cur_entry->IsUnresolvedMergedReference()) { 413 const UnresolvedMergedType* cmp_type = down_cast<const UnresolvedMergedType*>(cur_entry); 414 const RegType& resolved_part = cmp_type->GetResolvedPart(); 415 const BitVector& unresolved_part = cmp_type->GetUnresolvedTypes(); 416 // Use SameBitsSet. "types" is expandable to allow merging in the components, but the 417 // BitVector in the final RegType will be made non-expandable. 418 if (&resolved_part == &resolved_parts_merged && types.SameBitsSet(&unresolved_part)) { 419 return *cur_entry; 420 } 421 } 422 } 423 return AddEntry(new (&arena_) UnresolvedMergedType(resolved_parts_merged, 424 types, 425 this, 426 entries_.size())); 427 } 428 429 const RegType& RegTypeCache::FromUnresolvedSuperClass(const RegType& child) { 430 // Check if entry already exists. 431 for (size_t i = primitive_count_; i < entries_.size(); i++) { 432 const RegType* cur_entry = entries_[i]; 433 if (cur_entry->IsUnresolvedSuperClass()) { 434 const UnresolvedSuperClass* tmp_entry = 435 down_cast<const UnresolvedSuperClass*>(cur_entry); 436 uint16_t unresolved_super_child_id = 437 tmp_entry->GetUnresolvedSuperClassChildId(); 438 if (unresolved_super_child_id == child.GetId()) { 439 return *cur_entry; 440 } 441 } 442 } 443 return AddEntry(new (&arena_) UnresolvedSuperClass(child.GetId(), this, entries_.size())); 444 } 445 446 const UninitializedType& RegTypeCache::Uninitialized(const RegType& type, uint32_t allocation_pc) { 447 UninitializedType* entry = nullptr; 448 const StringPiece& descriptor(type.GetDescriptor()); 449 if (type.IsUnresolvedTypes()) { 450 for (size_t i = primitive_count_; i < entries_.size(); i++) { 451 const RegType* cur_entry = entries_[i]; 452 if (cur_entry->IsUnresolvedAndUninitializedReference() && 453 down_cast<const UnresolvedUninitializedRefType*>(cur_entry)->GetAllocationPc() 454 == allocation_pc && 455 (cur_entry->GetDescriptor() == descriptor)) { 456 return *down_cast<const UnresolvedUninitializedRefType*>(cur_entry); 457 } 458 } 459 entry = new (&arena_) UnresolvedUninitializedRefType(descriptor, 460 allocation_pc, 461 entries_.size()); 462 } else { 463 mirror::Class* klass = type.GetClass(); 464 for (size_t i = primitive_count_; i < entries_.size(); i++) { 465 const RegType* cur_entry = entries_[i]; 466 if (cur_entry->IsUninitializedReference() && 467 down_cast<const UninitializedReferenceType*>(cur_entry) 468 ->GetAllocationPc() == allocation_pc && 469 cur_entry->GetClass() == klass) { 470 return *down_cast<const UninitializedReferenceType*>(cur_entry); 471 } 472 } 473 entry = new (&arena_) UninitializedReferenceType(klass, 474 descriptor, 475 allocation_pc, 476 entries_.size()); 477 } 478 return AddEntry(entry); 479 } 480 481 const RegType& RegTypeCache::FromUninitialized(const RegType& uninit_type) { 482 RegType* entry; 483 484 if (uninit_type.IsUnresolvedTypes()) { 485 const StringPiece& descriptor(uninit_type.GetDescriptor()); 486 for (size_t i = primitive_count_; i < entries_.size(); i++) { 487 const RegType* cur_entry = entries_[i]; 488 if (cur_entry->IsUnresolvedReference() && 489 cur_entry->GetDescriptor() == descriptor) { 490 return *cur_entry; 491 } 492 } 493 entry = new (&arena_) UnresolvedReferenceType(descriptor, entries_.size()); 494 } else { 495 mirror::Class* klass = uninit_type.GetClass(); 496 if (uninit_type.IsUninitializedThisReference() && !klass->IsFinal()) { 497 // For uninitialized "this reference" look for reference types that are not precise. 498 for (size_t i = primitive_count_; i < entries_.size(); i++) { 499 const RegType* cur_entry = entries_[i]; 500 if (cur_entry->IsReference() && cur_entry->GetClass() == klass) { 501 return *cur_entry; 502 } 503 } 504 entry = new (&arena_) ReferenceType(klass, "", entries_.size()); 505 } else if (!klass->IsPrimitive()) { 506 // We're uninitialized because of allocation, look or create a precise type as allocations 507 // may only create objects of that type. 508 // Note: we do not check whether the given klass is actually instantiable (besides being 509 // primitive), that is, we allow interfaces and abstract classes here. The reasoning is 510 // twofold: 511 // 1) The "new-instance" instruction to generate the uninitialized type will already 512 // queue an instantiation error. This is a soft error that must be thrown at runtime, 513 // and could potentially change if the class is resolved differently at runtime. 514 // 2) Checking whether the klass is instantiable and using conflict may produce a hard 515 // error when the value is used, which leads to a VerifyError, which is not the 516 // correct semantics. 517 for (size_t i = primitive_count_; i < entries_.size(); i++) { 518 const RegType* cur_entry = entries_[i]; 519 if (cur_entry->IsPreciseReference() && cur_entry->GetClass() == klass) { 520 return *cur_entry; 521 } 522 } 523 entry = new (&arena_) PreciseReferenceType(klass, 524 uninit_type.GetDescriptor(), 525 entries_.size()); 526 } else { 527 return Conflict(); 528 } 529 } 530 return AddEntry(entry); 531 } 532 533 const UninitializedType& RegTypeCache::UninitializedThisArgument(const RegType& type) { 534 UninitializedType* entry; 535 const StringPiece& descriptor(type.GetDescriptor()); 536 if (type.IsUnresolvedTypes()) { 537 for (size_t i = primitive_count_; i < entries_.size(); i++) { 538 const RegType* cur_entry = entries_[i]; 539 if (cur_entry->IsUnresolvedAndUninitializedThisReference() && 540 cur_entry->GetDescriptor() == descriptor) { 541 return *down_cast<const UninitializedType*>(cur_entry); 542 } 543 } 544 entry = new (&arena_) UnresolvedUninitializedThisRefType(descriptor, entries_.size()); 545 } else { 546 mirror::Class* klass = type.GetClass(); 547 for (size_t i = primitive_count_; i < entries_.size(); i++) { 548 const RegType* cur_entry = entries_[i]; 549 if (cur_entry->IsUninitializedThisReference() && cur_entry->GetClass() == klass) { 550 return *down_cast<const UninitializedType*>(cur_entry); 551 } 552 } 553 entry = new (&arena_) UninitializedThisReferenceType(klass, descriptor, entries_.size()); 554 } 555 return AddEntry(entry); 556 } 557 558 const ConstantType& RegTypeCache::FromCat1NonSmallConstant(int32_t value, bool precise) { 559 for (size_t i = primitive_count_; i < entries_.size(); i++) { 560 const RegType* cur_entry = entries_[i]; 561 if (cur_entry->klass_.IsNull() && cur_entry->IsConstant() && 562 cur_entry->IsPreciseConstant() == precise && 563 (down_cast<const ConstantType*>(cur_entry))->ConstantValue() == value) { 564 return *down_cast<const ConstantType*>(cur_entry); 565 } 566 } 567 ConstantType* entry; 568 if (precise) { 569 entry = new (&arena_) PreciseConstType(value, entries_.size()); 570 } else { 571 entry = new (&arena_) ImpreciseConstType(value, entries_.size()); 572 } 573 return AddEntry(entry); 574 } 575 576 const ConstantType& RegTypeCache::FromCat2ConstLo(int32_t value, bool precise) { 577 for (size_t i = primitive_count_; i < entries_.size(); i++) { 578 const RegType* cur_entry = entries_[i]; 579 if (cur_entry->IsConstantLo() && (cur_entry->IsPrecise() == precise) && 580 (down_cast<const ConstantType*>(cur_entry))->ConstantValueLo() == value) { 581 return *down_cast<const ConstantType*>(cur_entry); 582 } 583 } 584 ConstantType* entry; 585 if (precise) { 586 entry = new (&arena_) PreciseConstLoType(value, entries_.size()); 587 } else { 588 entry = new (&arena_) ImpreciseConstLoType(value, entries_.size()); 589 } 590 return AddEntry(entry); 591 } 592 593 const ConstantType& RegTypeCache::FromCat2ConstHi(int32_t value, bool precise) { 594 for (size_t i = primitive_count_; i < entries_.size(); i++) { 595 const RegType* cur_entry = entries_[i]; 596 if (cur_entry->IsConstantHi() && (cur_entry->IsPrecise() == precise) && 597 (down_cast<const ConstantType*>(cur_entry))->ConstantValueHi() == value) { 598 return *down_cast<const ConstantType*>(cur_entry); 599 } 600 } 601 ConstantType* entry; 602 if (precise) { 603 entry = new (&arena_) PreciseConstHiType(value, entries_.size()); 604 } else { 605 entry = new (&arena_) ImpreciseConstHiType(value, entries_.size()); 606 } 607 return AddEntry(entry); 608 } 609 610 const RegType& RegTypeCache::GetComponentType(const RegType& array, mirror::ClassLoader* loader) { 611 if (!array.IsArrayTypes()) { 612 return Conflict(); 613 } else if (array.IsUnresolvedTypes()) { 614 DCHECK(!array.IsUnresolvedMergedReference()); // Caller must make sure not to ask for this. 615 const std::string descriptor(array.GetDescriptor().as_string()); 616 return FromDescriptor(loader, descriptor.c_str() + 1, false); 617 } else { 618 mirror::Class* klass = array.GetClass()->GetComponentType(); 619 std::string temp; 620 const char* descriptor = klass->GetDescriptor(&temp); 621 if (klass->IsErroneous()) { 622 // Arrays may have erroneous component types, use unresolved in that case. 623 // We assume that the primitive classes are not erroneous, so we know it is a 624 // reference type. 625 return FromDescriptor(loader, descriptor, false); 626 } else { 627 return FromClass(descriptor, klass, klass->CannotBeAssignedFromOtherTypes()); 628 } 629 } 630 } 631 632 void RegTypeCache::Dump(std::ostream& os) { 633 for (size_t i = 0; i < entries_.size(); i++) { 634 const RegType* cur_entry = entries_[i]; 635 if (cur_entry != nullptr) { 636 os << i << ": " << cur_entry->Dump() << "\n"; 637 } 638 } 639 } 640 641 void RegTypeCache::VisitStaticRoots(RootVisitor* visitor) { 642 // Visit the primitive types, this is required since if there are no active verifiers they wont 643 // be in the entries array, and therefore not visited as roots. 644 if (primitive_initialized_) { 645 RootInfo ri(kRootUnknown); 646 UndefinedType::GetInstance()->VisitRoots(visitor, ri); 647 ConflictType::GetInstance()->VisitRoots(visitor, ri); 648 BooleanType::GetInstance()->VisitRoots(visitor, ri); 649 ByteType::GetInstance()->VisitRoots(visitor, ri); 650 ShortType::GetInstance()->VisitRoots(visitor, ri); 651 CharType::GetInstance()->VisitRoots(visitor, ri); 652 IntegerType::GetInstance()->VisitRoots(visitor, ri); 653 LongLoType::GetInstance()->VisitRoots(visitor, ri); 654 LongHiType::GetInstance()->VisitRoots(visitor, ri); 655 FloatType::GetInstance()->VisitRoots(visitor, ri); 656 DoubleLoType::GetInstance()->VisitRoots(visitor, ri); 657 DoubleHiType::GetInstance()->VisitRoots(visitor, ri); 658 for (int32_t value = kMinSmallConstant; value <= kMaxSmallConstant; ++value) { 659 small_precise_constants_[value - kMinSmallConstant]->VisitRoots(visitor, ri); 660 } 661 } 662 } 663 664 void RegTypeCache::VisitRoots(RootVisitor* visitor, const RootInfo& root_info) { 665 // Exclude the static roots that are visited by VisitStaticRoots(). 666 for (size_t i = primitive_count_; i < entries_.size(); ++i) { 667 entries_[i]->VisitRoots(visitor, root_info); 668 } 669 for (auto& pair : klass_entries_) { 670 GcRoot<mirror::Class>& root = pair.first; 671 root.VisitRoot(visitor, root_info); 672 } 673 } 674 675 } // namespace verifier 676 } // namespace art 677