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/casts.h" 20 #include "dex_file-inl.h" 21 #include "mirror/class-inl.h" 22 #include "mirror/object-inl.h" 23 #include "object_utils.h" 24 25 namespace art { 26 namespace verifier { 27 28 bool RegTypeCache::primitive_initialized_ = false; 29 uint16_t RegTypeCache::primitive_start_ = 0; 30 uint16_t RegTypeCache::primitive_count_ = 0; 31 32 static bool MatchingPrecisionForClass(RegType* entry, bool precise) 33 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 34 if (entry->IsPreciseReference() == precise) { 35 // We were or weren't looking for a precise reference and we found what we need. 36 return true; 37 } else { 38 if (!precise && entry->GetClass()->CannotBeAssignedFromOtherTypes()) { 39 // We weren't looking for a precise reference, as we're looking up based on a descriptor, but 40 // we found a matching entry based on the descriptor. Return the precise entry in that case. 41 return true; 42 } 43 return false; 44 } 45 } 46 47 void RegTypeCache::FillPrimitiveTypes() { 48 entries_.push_back(UndefinedType::GetInstance()); 49 entries_.push_back(ConflictType::GetInstance()); 50 entries_.push_back(BooleanType::GetInstance()); 51 entries_.push_back(ByteType::GetInstance()); 52 entries_.push_back(ShortType::GetInstance()); 53 entries_.push_back(CharType::GetInstance()); 54 entries_.push_back(IntegerType::GetInstance()); 55 entries_.push_back(LongLoType::GetInstance()); 56 entries_.push_back(LongHiType::GetInstance()); 57 entries_.push_back(FloatType::GetInstance()); 58 entries_.push_back(DoubleLoType::GetInstance()); 59 entries_.push_back(DoubleHiType::GetInstance()); 60 DCHECK_EQ(entries_.size(), primitive_count_); 61 } 62 63 const RegType& RegTypeCache::FromDescriptor(mirror::ClassLoader* loader, const char* descriptor, 64 bool precise) { 65 DCHECK(RegTypeCache::primitive_initialized_); 66 if (descriptor[1] == '\0') { 67 switch (descriptor[0]) { 68 case 'Z': 69 return Boolean(); 70 case 'B': 71 return Byte(); 72 case 'S': 73 return Short(); 74 case 'C': 75 return Char(); 76 case 'I': 77 return Integer(); 78 case 'J': 79 return LongLo(); 80 case 'F': 81 return Float(); 82 case 'D': 83 return DoubleLo(); 84 case 'V': // For void types, conflict types. 85 default: 86 return Conflict(); 87 } 88 } else if (descriptor[0] == 'L' || descriptor[0] == '[') { 89 return From(loader, descriptor, precise); 90 } else { 91 return Conflict(); 92 } 93 }; 94 95 const RegType& RegTypeCache::RegTypeFromPrimitiveType(Primitive::Type prim_type) const { 96 CHECK(RegTypeCache::primitive_initialized_); 97 switch (prim_type) { 98 case Primitive::kPrimBoolean: 99 return *BooleanType::GetInstance(); 100 case Primitive::kPrimByte: 101 return *ByteType::GetInstance(); 102 case Primitive::kPrimShort: 103 return *ShortType::GetInstance(); 104 case Primitive::kPrimChar: 105 return *CharType::GetInstance(); 106 case Primitive::kPrimInt: 107 return *IntegerType::GetInstance(); 108 case Primitive::kPrimLong: 109 return *LongLoType::GetInstance(); 110 case Primitive::kPrimFloat: 111 return *FloatType::GetInstance(); 112 case Primitive::kPrimDouble: 113 return *DoubleLoType::GetInstance(); 114 case Primitive::kPrimVoid: 115 default: 116 return *ConflictType::GetInstance(); 117 } 118 } 119 120 bool RegTypeCache::MatchDescriptor(size_t idx, const char* descriptor, bool precise) { 121 RegType* entry = entries_[idx]; 122 if (entry->descriptor_ != descriptor) { 123 return false; 124 } 125 if (entry->HasClass()) { 126 return MatchingPrecisionForClass(entry, precise); 127 } 128 // There is no notion of precise unresolved references, the precise information is just dropped 129 // on the floor. 130 DCHECK(entry->IsUnresolvedReference()); 131 return true; 132 } 133 134 mirror::Class* RegTypeCache::ResolveClass(const char* descriptor, mirror::ClassLoader* loader) { 135 // Class was not found, must create new type. 136 // Try resolving class 137 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 138 mirror::Class* klass = NULL; 139 if (can_load_classes_) { 140 klass = class_linker->FindClass(descriptor, loader); 141 } else { 142 klass = class_linker->LookupClass(descriptor, loader); 143 if (klass != NULL && !klass->IsLoaded()) { 144 // We found the class but without it being loaded its not safe for use. 145 klass = NULL; 146 } 147 } 148 return klass; 149 } 150 151 void RegTypeCache::ClearException() { 152 if (can_load_classes_) { 153 DCHECK(Thread::Current()->IsExceptionPending()); 154 Thread::Current()->ClearException(); 155 } else { 156 DCHECK(!Thread::Current()->IsExceptionPending()); 157 } 158 } 159 160 const RegType& RegTypeCache::From(mirror::ClassLoader* loader, const char* descriptor, 161 bool precise) { 162 // Try looking up the class in the cache first. 163 for (size_t i = primitive_count_; i < entries_.size(); i++) { 164 if (MatchDescriptor(i, descriptor, precise)) { 165 return *(entries_[i]); 166 } 167 } 168 // Class not found in the cache, will create a new type for that. 169 // Try resolving class. 170 mirror::Class* klass = ResolveClass(descriptor, loader); 171 if (klass != NULL) { 172 // Class resolved, first look for the class in the list of entries 173 // Class was not found, must create new type. 174 // To pass the verification, the type should be imprecise, 175 // instantiable or an interface with the precise type set to false. 176 DCHECK(!precise || klass->IsInstantiable()); 177 // Create a precise type if: 178 // 1- Class is final and NOT an interface. a precise interface is meaningless !! 179 // 2- Precise Flag passed as true. 180 RegType* entry; 181 // Create an imprecise type if we can't tell for a fact that it is precise. 182 if (klass->CannotBeAssignedFromOtherTypes() || precise) { 183 DCHECK(!(klass->IsAbstract()) || klass->IsArrayClass()); 184 DCHECK(!klass->IsInterface()); 185 entry = new PreciseReferenceType(klass, descriptor, entries_.size()); 186 } else { 187 entry = new ReferenceType(klass, descriptor, entries_.size()); 188 } 189 entries_.push_back(entry); 190 return *entry; 191 } else { // Class not resolved. 192 // We tried loading the class and failed, this might get an exception raised 193 // so we want to clear it before we go on. 194 ClearException(); 195 if (IsValidDescriptor(descriptor)) { 196 RegType* entry = new UnresolvedReferenceType(descriptor, entries_.size()); 197 entries_.push_back(entry); 198 return *entry; 199 } else { 200 // The descriptor is broken return the unknown type as there's nothing sensible that 201 // could be done at runtime 202 return Conflict(); 203 } 204 } 205 } 206 207 const RegType& RegTypeCache::FromClass(const char* descriptor, mirror::Class* klass, bool precise) { 208 if (klass->IsPrimitive()) { 209 // Note: precise isn't used for primitive classes. A char is assignable to an int. All 210 // primitive classes are final. 211 return RegTypeFromPrimitiveType(klass->GetPrimitiveType()); 212 } else { 213 // Look for the reference in the list of entries to have. 214 for (size_t i = primitive_count_; i < entries_.size(); i++) { 215 RegType* cur_entry = entries_[i]; 216 if (cur_entry->klass_ == klass && MatchingPrecisionForClass(cur_entry, precise)) { 217 return *cur_entry; 218 } 219 } 220 // No reference to the class was found, create new reference. 221 RegType* entry; 222 if (precise) { 223 entry = new PreciseReferenceType(klass, descriptor, entries_.size()); 224 } else { 225 entry = new ReferenceType(klass, descriptor, entries_.size()); 226 } 227 entries_.push_back(entry); 228 return *entry; 229 } 230 } 231 232 RegTypeCache::~RegTypeCache() { 233 CHECK_LE(primitive_count_, entries_.size()); 234 // Delete only the non primitive types. 235 if (entries_.size() == kNumPrimitives) { 236 // All entries are primitive, nothing to delete. 237 return; 238 } 239 std::vector<RegType*>::iterator non_primitive_begin = entries_.begin(); 240 std::advance(non_primitive_begin, kNumPrimitives); 241 STLDeleteContainerPointers(non_primitive_begin, entries_.end()); 242 } 243 244 void RegTypeCache::ShutDown() { 245 if (RegTypeCache::primitive_initialized_) { 246 UndefinedType::Destroy(); 247 ConflictType::Destroy(); 248 BooleanType::Destroy(); 249 ByteType::Destroy(); 250 ShortType::Destroy(); 251 CharType::Destroy(); 252 IntegerType::Destroy(); 253 LongLoType::Destroy(); 254 LongHiType::Destroy(); 255 FloatType::Destroy(); 256 DoubleLoType::Destroy(); 257 DoubleHiType::Destroy(); 258 RegTypeCache::primitive_initialized_ = false; 259 RegTypeCache::primitive_count_ = 0; 260 } 261 } 262 263 void RegTypeCache::CreatePrimitiveTypes() { 264 CreatePrimitiveTypeInstance<UndefinedType>(""); 265 CreatePrimitiveTypeInstance<ConflictType>(""); 266 CreatePrimitiveTypeInstance<BooleanType>("Z"); 267 CreatePrimitiveTypeInstance<ByteType>("B"); 268 CreatePrimitiveTypeInstance<ShortType>("S"); 269 CreatePrimitiveTypeInstance<CharType>("C"); 270 CreatePrimitiveTypeInstance<IntegerType>("I"); 271 CreatePrimitiveTypeInstance<LongLoType>("J"); 272 CreatePrimitiveTypeInstance<LongHiType>("J"); 273 CreatePrimitiveTypeInstance<FloatType>("F"); 274 CreatePrimitiveTypeInstance<DoubleLoType>("D"); 275 CreatePrimitiveTypeInstance<DoubleHiType>("D"); 276 } 277 278 const RegType& RegTypeCache::FromUnresolvedMerge(const RegType& left, const RegType& right) { 279 std::set<uint16_t> types; 280 if (left.IsUnresolvedMergedReference()) { 281 RegType& non_const(const_cast<RegType&>(left)); 282 types = (down_cast<UnresolvedMergedType*>(&non_const))->GetMergedTypes(); 283 } else { 284 types.insert(left.GetId()); 285 } 286 if (right.IsUnresolvedMergedReference()) { 287 RegType& non_const(const_cast<RegType&>(right)); 288 std::set<uint16_t> right_types = (down_cast<UnresolvedMergedType*>(&non_const))->GetMergedTypes(); 289 types.insert(right_types.begin(), right_types.end()); 290 } else { 291 types.insert(right.GetId()); 292 } 293 // Check if entry already exists. 294 for (size_t i = primitive_count_; i < entries_.size(); i++) { 295 RegType* cur_entry = entries_[i]; 296 if (cur_entry->IsUnresolvedMergedReference()) { 297 std::set<uint16_t> cur_entry_types = 298 (down_cast<UnresolvedMergedType*>(cur_entry))->GetMergedTypes(); 299 if (cur_entry_types == types) { 300 return *cur_entry; 301 } 302 } 303 } 304 // Create entry. 305 RegType* entry = new UnresolvedMergedType(left.GetId(), right.GetId(), this, entries_.size()); 306 entries_.push_back(entry); 307 if (kIsDebugBuild) { 308 UnresolvedMergedType* tmp_entry = down_cast<UnresolvedMergedType*>(entry); 309 std::set<uint16_t> check_types = tmp_entry->GetMergedTypes(); 310 CHECK(check_types == types); 311 } 312 return *entry; 313 } 314 315 const RegType& RegTypeCache::FromUnresolvedSuperClass(const RegType& child) { 316 // Check if entry already exists. 317 for (size_t i = primitive_count_; i < entries_.size(); i++) { 318 RegType* cur_entry = entries_[i]; 319 if (cur_entry->IsUnresolvedSuperClass()) { 320 UnresolvedSuperClass* tmp_entry = 321 down_cast<UnresolvedSuperClass*>(cur_entry); 322 uint16_t unresolved_super_child_id = 323 tmp_entry->GetUnresolvedSuperClassChildId(); 324 if (unresolved_super_child_id == child.GetId()) { 325 return *cur_entry; 326 } 327 } 328 } 329 RegType* entry = new UnresolvedSuperClass(child.GetId(), this, entries_.size()); 330 entries_.push_back(entry); 331 return *entry; 332 } 333 334 const RegType& RegTypeCache::Uninitialized(const RegType& type, uint32_t allocation_pc) { 335 RegType* entry = NULL; 336 RegType* cur_entry = NULL; 337 const std::string& descriptor(type.GetDescriptor()); 338 if (type.IsUnresolvedTypes()) { 339 for (size_t i = primitive_count_; i < entries_.size(); i++) { 340 cur_entry = entries_[i]; 341 if (cur_entry->IsUnresolvedAndUninitializedReference() && 342 down_cast<UnresolvedUninitializedRefType*>(cur_entry)->GetAllocationPc() == allocation_pc && 343 (cur_entry->GetDescriptor() == descriptor)) { 344 return *cur_entry; 345 } 346 } 347 entry = new UnresolvedUninitializedRefType(descriptor, allocation_pc, entries_.size()); 348 } else { 349 mirror::Class* klass = type.GetClass(); 350 for (size_t i = primitive_count_; i < entries_.size(); i++) { 351 cur_entry = entries_[i]; 352 if (cur_entry->IsUninitializedReference() && 353 down_cast<UninitializedReferenceType*>(cur_entry) 354 ->GetAllocationPc() == allocation_pc && 355 cur_entry->GetClass() == klass) { 356 return *cur_entry; 357 } 358 } 359 entry = new UninitializedReferenceType(klass, descriptor, allocation_pc, entries_.size()); 360 } 361 entries_.push_back(entry); 362 return *entry; 363 } 364 365 const RegType& RegTypeCache::FromUninitialized(const RegType& uninit_type) { 366 RegType* entry; 367 368 if (uninit_type.IsUnresolvedTypes()) { 369 const std::string& descriptor(uninit_type.GetDescriptor()); 370 for (size_t i = primitive_count_; i < entries_.size(); i++) { 371 RegType* cur_entry = entries_[i]; 372 if (cur_entry->IsUnresolvedReference() && 373 cur_entry->GetDescriptor() == descriptor) { 374 return *cur_entry; 375 } 376 } 377 entry = new UnresolvedReferenceType(descriptor.c_str(), entries_.size()); 378 } else { 379 mirror::Class* klass = uninit_type.GetClass(); 380 if (uninit_type.IsUninitializedThisReference() && !klass->IsFinal()) { 381 // For uninitialized "this reference" look for reference types that are not precise. 382 for (size_t i = primitive_count_; i < entries_.size(); i++) { 383 RegType* cur_entry = entries_[i]; 384 if (cur_entry->IsReference() && cur_entry->GetClass() == klass) { 385 return *cur_entry; 386 } 387 } 388 entry = new ReferenceType(klass, "", entries_.size()); 389 } else if (klass->IsInstantiable()) { 390 // We're uninitialized because of allocation, look or create a precise type as allocations 391 // may only create objects of that type. 392 for (size_t i = primitive_count_; i < entries_.size(); i++) { 393 RegType* cur_entry = entries_[i]; 394 if (cur_entry->IsPreciseReference() && cur_entry->GetClass() == klass) { 395 return *cur_entry; 396 } 397 } 398 entry = new PreciseReferenceType(klass, uninit_type.GetDescriptor(), entries_.size()); 399 } else { 400 return Conflict(); 401 } 402 } 403 entries_.push_back(entry); 404 return *entry; 405 } 406 407 const RegType& RegTypeCache::ByteConstant() { 408 return FromCat1Const(std::numeric_limits<jbyte>::min(), false); 409 } 410 411 const RegType& RegTypeCache::ShortConstant() { 412 return FromCat1Const(std::numeric_limits<jshort>::min(), false); 413 } 414 415 const RegType& RegTypeCache::IntConstant() { 416 return FromCat1Const(std::numeric_limits<jint>::max(), false); 417 } 418 419 const RegType& RegTypeCache::UninitializedThisArgument(const RegType& type) { 420 RegType* entry; 421 const std::string& descriptor(type.GetDescriptor()); 422 if (type.IsUnresolvedTypes()) { 423 for (size_t i = primitive_count_; i < entries_.size(); i++) { 424 RegType* cur_entry = entries_[i]; 425 if (cur_entry->IsUnresolvedAndUninitializedThisReference() && 426 cur_entry->GetDescriptor() == descriptor) { 427 return *cur_entry; 428 } 429 } 430 entry = new UnresolvedUninitializedThisRefType(descriptor, entries_.size()); 431 } else { 432 mirror::Class* klass = type.GetClass(); 433 for (size_t i = primitive_count_; i < entries_.size(); i++) { 434 RegType* cur_entry = entries_[i]; 435 if (cur_entry->IsUninitializedThisReference() && cur_entry->GetClass() == klass) { 436 return *cur_entry; 437 } 438 } 439 entry = new UninitializedThisReferenceType(klass, descriptor, entries_.size()); 440 } 441 entries_.push_back(entry); 442 return *entry; 443 } 444 445 const RegType& RegTypeCache::FromCat1Const(int32_t value, bool precise) { 446 for (size_t i = primitive_count_; i < entries_.size(); i++) { 447 RegType* cur_entry = entries_[i]; 448 if (cur_entry->klass_ == NULL && cur_entry->IsConstant() && 449 cur_entry->IsPreciseConstant() == precise && 450 (down_cast<ConstantType*>(cur_entry))->ConstantValue() == value) { 451 return *cur_entry; 452 } 453 } 454 RegType* entry; 455 if (precise) { 456 entry = new PreciseConstType(value, entries_.size()); 457 } else { 458 entry = new ImpreciseConstType(value, entries_.size()); 459 } 460 entries_.push_back(entry); 461 return *entry; 462 } 463 464 const RegType& RegTypeCache::FromCat2ConstLo(int32_t value, bool precise) { 465 for (size_t i = primitive_count_; i < entries_.size(); i++) { 466 RegType* cur_entry = entries_[i]; 467 if (cur_entry->IsConstantLo() && (cur_entry->IsPrecise() == precise) && 468 (down_cast<ConstantType*>(cur_entry))->ConstantValueLo() == value) { 469 return *cur_entry; 470 } 471 } 472 RegType* entry; 473 if (precise) { 474 entry = new PreciseConstLoType(value, entries_.size()); 475 } else { 476 entry = new ImpreciseConstLoType(value, entries_.size()); 477 } 478 entries_.push_back(entry); 479 return *entry; 480 } 481 482 const RegType& RegTypeCache::FromCat2ConstHi(int32_t value, bool precise) { 483 for (size_t i = primitive_count_; i < entries_.size(); i++) { 484 RegType* cur_entry = entries_[i]; 485 if (cur_entry->IsConstantHi() && (cur_entry->IsPrecise() == precise) && 486 (down_cast<ConstantType*>(cur_entry))->ConstantValueHi() == value) { 487 return *cur_entry; 488 } 489 } 490 RegType* entry; 491 if (precise) { 492 entry = new PreciseConstHiType(value, entries_.size()); 493 } else { 494 entry = new ImpreciseConstHiType(value, entries_.size()); 495 } 496 entries_.push_back(entry); 497 return *entry; 498 } 499 500 const RegType& RegTypeCache::GetComponentType(const RegType& array, mirror::ClassLoader* loader) { 501 CHECK(array.IsArrayTypes()); 502 if (array.IsUnresolvedTypes()) { 503 const std::string& descriptor(array.GetDescriptor()); 504 const std::string component(descriptor.substr(1, descriptor.size() - 1)); 505 return FromDescriptor(loader, component.c_str(), false); 506 } else { 507 mirror::Class* klass = array.GetClass()->GetComponentType(); 508 return FromClass(ClassHelper(klass).GetDescriptor(), klass, 509 klass->CannotBeAssignedFromOtherTypes()); 510 } 511 } 512 513 void RegTypeCache::Dump(std::ostream& os) { 514 for (size_t i = 0; i < entries_.size(); i++) { 515 RegType* cur_entry = entries_[i]; 516 if (cur_entry != NULL) { 517 os << i << ": " << cur_entry->Dump() << "\n"; 518 } 519 } 520 } 521 522 } // namespace verifier 523 } // namespace art 524