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-inl.h" 18 19 #include "android-base/stringprintf.h" 20 21 #include "base/arena_bit_vector.h" 22 #include "base/bit_vector-inl.h" 23 #include "base/casts.h" 24 #include "class_linker-inl.h" 25 #include "dex/descriptors_names.h" 26 #include "dex/dex_file-inl.h" 27 #include "method_verifier.h" 28 #include "mirror/class-inl.h" 29 #include "mirror/class.h" 30 #include "mirror/object-inl.h" 31 #include "mirror/object_array-inl.h" 32 #include "reg_type_cache-inl.h" 33 #include "scoped_thread_state_change-inl.h" 34 35 #include <limits> 36 #include <sstream> 37 38 namespace art { 39 namespace verifier { 40 41 using android::base::StringPrintf; 42 43 const UndefinedType* UndefinedType::instance_ = nullptr; 44 const ConflictType* ConflictType::instance_ = nullptr; 45 const BooleanType* BooleanType::instance_ = nullptr; 46 const ByteType* ByteType::instance_ = nullptr; 47 const ShortType* ShortType::instance_ = nullptr; 48 const CharType* CharType::instance_ = nullptr; 49 const FloatType* FloatType::instance_ = nullptr; 50 const LongLoType* LongLoType::instance_ = nullptr; 51 const LongHiType* LongHiType::instance_ = nullptr; 52 const DoubleLoType* DoubleLoType::instance_ = nullptr; 53 const DoubleHiType* DoubleHiType::instance_ = nullptr; 54 const IntegerType* IntegerType::instance_ = nullptr; 55 const NullType* NullType::instance_ = nullptr; 56 57 PrimitiveType::PrimitiveType(ObjPtr<mirror::Class> klass, 58 const std::string_view& descriptor, 59 uint16_t cache_id) 60 : RegType(klass, descriptor, cache_id) { 61 CHECK(klass != nullptr); 62 CHECK(!descriptor.empty()); 63 } 64 65 Cat1Type::Cat1Type(ObjPtr<mirror::Class> klass, 66 const std::string_view& descriptor, 67 uint16_t cache_id) 68 : PrimitiveType(klass, descriptor, cache_id) { 69 } 70 71 Cat2Type::Cat2Type(ObjPtr<mirror::Class> klass, 72 const std::string_view& descriptor, 73 uint16_t cache_id) 74 : PrimitiveType(klass, descriptor, cache_id) { 75 } 76 77 std::string PreciseConstType::Dump() const { 78 std::stringstream result; 79 uint32_t val = ConstantValue(); 80 if (val == 0) { 81 CHECK(IsPreciseConstant()); 82 result << "Zero/null"; 83 } else { 84 result << "Precise "; 85 if (IsConstantShort()) { 86 result << StringPrintf("Constant: %d", val); 87 } else { 88 result << StringPrintf("Constant: 0x%x", val); 89 } 90 } 91 return result.str(); 92 } 93 94 std::string BooleanType::Dump() const { 95 return "Boolean"; 96 } 97 98 std::string ConflictType::Dump() const { 99 return "Conflict"; 100 } 101 102 std::string ByteType::Dump() const { 103 return "Byte"; 104 } 105 106 std::string ShortType::Dump() const { 107 return "Short"; 108 } 109 110 std::string CharType::Dump() const { 111 return "Char"; 112 } 113 114 std::string FloatType::Dump() const { 115 return "Float"; 116 } 117 118 std::string LongLoType::Dump() const { 119 return "Long (Low Half)"; 120 } 121 122 std::string LongHiType::Dump() const { 123 return "Long (High Half)"; 124 } 125 126 std::string DoubleLoType::Dump() const { 127 return "Double (Low Half)"; 128 } 129 130 std::string DoubleHiType::Dump() const { 131 return "Double (High Half)"; 132 } 133 134 std::string IntegerType::Dump() const { 135 return "Integer"; 136 } 137 138 const DoubleHiType* DoubleHiType::CreateInstance(ObjPtr<mirror::Class> klass, 139 const std::string_view& descriptor, 140 uint16_t cache_id) { 141 CHECK(instance_ == nullptr); 142 instance_ = new DoubleHiType(klass, descriptor, cache_id); 143 return instance_; 144 } 145 146 void DoubleHiType::Destroy() { 147 if (instance_ != nullptr) { 148 delete instance_; 149 instance_ = nullptr; 150 } 151 } 152 153 const DoubleLoType* DoubleLoType::CreateInstance(ObjPtr<mirror::Class> klass, 154 const std::string_view& descriptor, 155 uint16_t cache_id) { 156 CHECK(instance_ == nullptr); 157 instance_ = new DoubleLoType(klass, descriptor, cache_id); 158 return instance_; 159 } 160 161 void DoubleLoType::Destroy() { 162 if (instance_ != nullptr) { 163 delete instance_; 164 instance_ = nullptr; 165 } 166 } 167 168 const LongLoType* LongLoType::CreateInstance(ObjPtr<mirror::Class> klass, 169 const std::string_view& descriptor, 170 uint16_t cache_id) { 171 CHECK(instance_ == nullptr); 172 instance_ = new LongLoType(klass, descriptor, cache_id); 173 return instance_; 174 } 175 176 const LongHiType* LongHiType::CreateInstance(ObjPtr<mirror::Class> klass, 177 const std::string_view& descriptor, 178 uint16_t cache_id) { 179 CHECK(instance_ == nullptr); 180 instance_ = new LongHiType(klass, descriptor, cache_id); 181 return instance_; 182 } 183 184 void LongHiType::Destroy() { 185 if (instance_ != nullptr) { 186 delete instance_; 187 instance_ = nullptr; 188 } 189 } 190 191 void LongLoType::Destroy() { 192 if (instance_ != nullptr) { 193 delete instance_; 194 instance_ = nullptr; 195 } 196 } 197 198 const FloatType* FloatType::CreateInstance(ObjPtr<mirror::Class> klass, 199 const std::string_view& descriptor, 200 uint16_t cache_id) { 201 CHECK(instance_ == nullptr); 202 instance_ = new FloatType(klass, descriptor, cache_id); 203 return instance_; 204 } 205 206 void FloatType::Destroy() { 207 if (instance_ != nullptr) { 208 delete instance_; 209 instance_ = nullptr; 210 } 211 } 212 213 const CharType* CharType::CreateInstance(ObjPtr<mirror::Class> klass, 214 const std::string_view& descriptor, 215 uint16_t cache_id) { 216 CHECK(instance_ == nullptr); 217 instance_ = new CharType(klass, descriptor, cache_id); 218 return instance_; 219 } 220 221 void CharType::Destroy() { 222 if (instance_ != nullptr) { 223 delete instance_; 224 instance_ = nullptr; 225 } 226 } 227 228 const ShortType* ShortType::CreateInstance(ObjPtr<mirror::Class> klass, 229 const std::string_view& descriptor, 230 uint16_t cache_id) { 231 CHECK(instance_ == nullptr); 232 instance_ = new ShortType(klass, descriptor, cache_id); 233 return instance_; 234 } 235 236 void ShortType::Destroy() { 237 if (instance_ != nullptr) { 238 delete instance_; 239 instance_ = nullptr; 240 } 241 } 242 243 const ByteType* ByteType::CreateInstance(ObjPtr<mirror::Class> klass, 244 const std::string_view& descriptor, 245 uint16_t cache_id) { 246 CHECK(instance_ == nullptr); 247 instance_ = new ByteType(klass, descriptor, cache_id); 248 return instance_; 249 } 250 251 void ByteType::Destroy() { 252 if (instance_ != nullptr) { 253 delete instance_; 254 instance_ = nullptr; 255 } 256 } 257 258 const IntegerType* IntegerType::CreateInstance(ObjPtr<mirror::Class> klass, 259 const std::string_view& descriptor, 260 uint16_t cache_id) { 261 CHECK(instance_ == nullptr); 262 instance_ = new IntegerType(klass, descriptor, cache_id); 263 return instance_; 264 } 265 266 void IntegerType::Destroy() { 267 if (instance_ != nullptr) { 268 delete instance_; 269 instance_ = nullptr; 270 } 271 } 272 273 const ConflictType* ConflictType::CreateInstance(ObjPtr<mirror::Class> klass, 274 const std::string_view& descriptor, 275 uint16_t cache_id) { 276 CHECK(instance_ == nullptr); 277 instance_ = new ConflictType(klass, descriptor, cache_id); 278 return instance_; 279 } 280 281 void ConflictType::Destroy() { 282 if (instance_ != nullptr) { 283 delete instance_; 284 instance_ = nullptr; 285 } 286 } 287 288 const BooleanType* BooleanType::CreateInstance(ObjPtr<mirror::Class> klass, 289 const std::string_view& descriptor, 290 uint16_t cache_id) { 291 CHECK(BooleanType::instance_ == nullptr); 292 instance_ = new BooleanType(klass, descriptor, cache_id); 293 return BooleanType::instance_; 294 } 295 296 void BooleanType::Destroy() { 297 if (BooleanType::instance_ != nullptr) { 298 delete instance_; 299 instance_ = nullptr; 300 } 301 } 302 303 std::string UndefinedType::Dump() const REQUIRES_SHARED(Locks::mutator_lock_) { 304 return "Undefined"; 305 } 306 307 const UndefinedType* UndefinedType::CreateInstance(ObjPtr<mirror::Class> klass, 308 const std::string_view& descriptor, 309 uint16_t cache_id) { 310 CHECK(instance_ == nullptr); 311 instance_ = new UndefinedType(klass, descriptor, cache_id); 312 return instance_; 313 } 314 315 void UndefinedType::Destroy() { 316 if (instance_ != nullptr) { 317 delete instance_; 318 instance_ = nullptr; 319 } 320 } 321 322 PreciseReferenceType::PreciseReferenceType(ObjPtr<mirror::Class> klass, 323 const std::string_view& descriptor, 324 uint16_t cache_id) 325 : RegType(klass, descriptor, cache_id) { 326 // Note: no check for IsInstantiable() here. We may produce this in case an InstantiationError 327 // would be thrown at runtime, but we need to continue verification and *not* create a 328 // hard failure or abort. 329 CheckConstructorInvariants(this); 330 } 331 332 std::string UnresolvedMergedType::Dump() const { 333 std::stringstream result; 334 result << "UnresolvedMergedReferences(" << GetResolvedPart().Dump() << " | "; 335 const BitVector& types = GetUnresolvedTypes(); 336 337 bool first = true; 338 for (uint32_t idx : types.Indexes()) { 339 if (!first) { 340 result << ", "; 341 } else { 342 first = false; 343 } 344 result << reg_type_cache_->GetFromId(idx).Dump(); 345 } 346 result << ")"; 347 return result.str(); 348 } 349 350 std::string UnresolvedSuperClass::Dump() const { 351 std::stringstream result; 352 uint16_t super_type_id = GetUnresolvedSuperClassChildId(); 353 result << "UnresolvedSuperClass(" << reg_type_cache_->GetFromId(super_type_id).Dump() << ")"; 354 return result.str(); 355 } 356 357 std::string UnresolvedReferenceType::Dump() const { 358 std::stringstream result; 359 result << "Unresolved Reference: " << PrettyDescriptor(std::string(GetDescriptor()).c_str()); 360 return result.str(); 361 } 362 363 std::string UnresolvedUninitializedRefType::Dump() const { 364 std::stringstream result; 365 result << "Unresolved And Uninitialized Reference: " 366 << PrettyDescriptor(std::string(GetDescriptor()).c_str()) 367 << " Allocation PC: " << GetAllocationPc(); 368 return result.str(); 369 } 370 371 std::string UnresolvedUninitializedThisRefType::Dump() const { 372 std::stringstream result; 373 result << "Unresolved And Uninitialized This Reference: " 374 << PrettyDescriptor(std::string(GetDescriptor()).c_str()); 375 return result.str(); 376 } 377 378 std::string ReferenceType::Dump() const { 379 std::stringstream result; 380 result << "Reference: " << mirror::Class::PrettyDescriptor(GetClass()); 381 return result.str(); 382 } 383 384 std::string PreciseReferenceType::Dump() const { 385 std::stringstream result; 386 result << "Precise Reference: " << mirror::Class::PrettyDescriptor(GetClass()); 387 return result.str(); 388 } 389 390 std::string UninitializedReferenceType::Dump() const { 391 std::stringstream result; 392 result << "Uninitialized Reference: " << mirror::Class::PrettyDescriptor(GetClass()); 393 result << " Allocation PC: " << GetAllocationPc(); 394 return result.str(); 395 } 396 397 std::string UninitializedThisReferenceType::Dump() const { 398 std::stringstream result; 399 result << "Uninitialized This Reference: " << mirror::Class::PrettyDescriptor(GetClass()); 400 result << "Allocation PC: " << GetAllocationPc(); 401 return result.str(); 402 } 403 404 std::string ImpreciseConstType::Dump() const { 405 std::stringstream result; 406 uint32_t val = ConstantValue(); 407 if (val == 0) { 408 result << "Zero/null"; 409 } else { 410 result << "Imprecise "; 411 if (IsConstantShort()) { 412 result << StringPrintf("Constant: %d", val); 413 } else { 414 result << StringPrintf("Constant: 0x%x", val); 415 } 416 } 417 return result.str(); 418 } 419 std::string PreciseConstLoType::Dump() const { 420 std::stringstream result; 421 422 int32_t val = ConstantValueLo(); 423 result << "Precise "; 424 if (val >= std::numeric_limits<jshort>::min() && 425 val <= std::numeric_limits<jshort>::max()) { 426 result << StringPrintf("Low-half Constant: %d", val); 427 } else { 428 result << StringPrintf("Low-half Constant: 0x%x", val); 429 } 430 return result.str(); 431 } 432 433 std::string ImpreciseConstLoType::Dump() const { 434 std::stringstream result; 435 436 int32_t val = ConstantValueLo(); 437 result << "Imprecise "; 438 if (val >= std::numeric_limits<jshort>::min() && 439 val <= std::numeric_limits<jshort>::max()) { 440 result << StringPrintf("Low-half Constant: %d", val); 441 } else { 442 result << StringPrintf("Low-half Constant: 0x%x", val); 443 } 444 return result.str(); 445 } 446 447 std::string PreciseConstHiType::Dump() const { 448 std::stringstream result; 449 int32_t val = ConstantValueHi(); 450 result << "Precise "; 451 if (val >= std::numeric_limits<jshort>::min() && 452 val <= std::numeric_limits<jshort>::max()) { 453 result << StringPrintf("High-half Constant: %d", val); 454 } else { 455 result << StringPrintf("High-half Constant: 0x%x", val); 456 } 457 return result.str(); 458 } 459 460 std::string ImpreciseConstHiType::Dump() const { 461 std::stringstream result; 462 int32_t val = ConstantValueHi(); 463 result << "Imprecise "; 464 if (val >= std::numeric_limits<jshort>::min() && 465 val <= std::numeric_limits<jshort>::max()) { 466 result << StringPrintf("High-half Constant: %d", val); 467 } else { 468 result << StringPrintf("High-half Constant: 0x%x", val); 469 } 470 return result.str(); 471 } 472 473 const RegType& RegType::HighHalf(RegTypeCache* cache) const { 474 DCHECK(IsLowHalf()); 475 if (IsLongLo()) { 476 return cache->LongHi(); 477 } else if (IsDoubleLo()) { 478 return cache->DoubleHi(); 479 } else { 480 DCHECK(IsImpreciseConstantLo()); 481 const ConstantType* const_val = down_cast<const ConstantType*>(this); 482 return cache->FromCat2ConstHi(const_val->ConstantValue(), false); 483 } 484 } 485 486 Primitive::Type RegType::GetPrimitiveType() const { 487 if (IsNonZeroReferenceTypes()) { 488 return Primitive::kPrimNot; 489 } else if (IsBooleanTypes()) { 490 return Primitive::kPrimBoolean; 491 } else if (IsByteTypes()) { 492 return Primitive::kPrimByte; 493 } else if (IsShortTypes()) { 494 return Primitive::kPrimShort; 495 } else if (IsCharTypes()) { 496 return Primitive::kPrimChar; 497 } else if (IsFloat()) { 498 return Primitive::kPrimFloat; 499 } else if (IsIntegralTypes()) { 500 return Primitive::kPrimInt; 501 } else if (IsDoubleLo()) { 502 return Primitive::kPrimDouble; 503 } else { 504 DCHECK(IsLongTypes()); 505 return Primitive::kPrimLong; 506 } 507 } 508 509 bool UninitializedType::IsUninitializedTypes() const { 510 return true; 511 } 512 513 bool UninitializedType::IsNonZeroReferenceTypes() const { 514 return true; 515 } 516 517 bool UnresolvedType::IsNonZeroReferenceTypes() const { 518 return true; 519 } 520 521 const RegType& RegType::GetSuperClass(RegTypeCache* cache) const { 522 if (!IsUnresolvedTypes()) { 523 ObjPtr<mirror::Class> super_klass = GetClass()->GetSuperClass(); 524 if (super_klass != nullptr) { 525 // A super class of a precise type isn't precise as a precise type indicates the register 526 // holds exactly that type. 527 std::string temp; 528 return cache->FromClass(super_klass->GetDescriptor(&temp), super_klass, false); 529 } else { 530 return cache->Zero(); 531 } 532 } else { 533 if (!IsUnresolvedMergedReference() && !IsUnresolvedSuperClass() && 534 GetDescriptor()[0] == '[') { 535 // Super class of all arrays is Object. 536 return cache->JavaLangObject(true); 537 } else { 538 return cache->FromUnresolvedSuperClass(*this); 539 } 540 } 541 } 542 543 bool RegType::IsJavaLangObject() const REQUIRES_SHARED(Locks::mutator_lock_) { 544 return IsReference() && GetClass()->IsObjectClass(); 545 } 546 547 bool RegType::IsObjectArrayTypes() const REQUIRES_SHARED(Locks::mutator_lock_) { 548 if (IsUnresolvedTypes()) { 549 DCHECK(!IsUnresolvedMergedReference()); 550 551 if (IsUnresolvedSuperClass()) { 552 // Cannot be an array, as the superclass of arrays is java.lang.Object (which cannot be 553 // unresolved). 554 return false; 555 } 556 557 // Primitive arrays will always resolve. 558 DCHECK(descriptor_[1] == 'L' || descriptor_[1] == '['); 559 return descriptor_[0] == '['; 560 } else if (HasClass()) { 561 ObjPtr<mirror::Class> type = GetClass(); 562 return type->IsArrayClass() && !type->GetComponentType()->IsPrimitive(); 563 } else { 564 return false; 565 } 566 } 567 568 bool RegType::IsArrayTypes() const REQUIRES_SHARED(Locks::mutator_lock_) { 569 if (IsUnresolvedTypes()) { 570 DCHECK(!IsUnresolvedMergedReference()); 571 572 if (IsUnresolvedSuperClass()) { 573 // Cannot be an array, as the superclass of arrays is java.lang.Object (which cannot be 574 // unresolved). 575 return false; 576 } 577 return descriptor_[0] == '['; 578 } else if (HasClass()) { 579 return GetClass()->IsArrayClass(); 580 } else { 581 return false; 582 } 583 } 584 585 bool RegType::IsJavaLangObjectArray() const { 586 if (HasClass()) { 587 ObjPtr<mirror::Class> type = GetClass(); 588 return type->IsArrayClass() && type->GetComponentType()->IsObjectClass(); 589 } 590 return false; 591 } 592 593 bool RegType::IsInstantiableTypes() const { 594 return IsUnresolvedTypes() || (IsNonZeroReferenceTypes() && GetClass()->IsInstantiable()); 595 } 596 597 static const RegType& SelectNonConstant(const RegType& a, const RegType& b) { 598 return a.IsConstantTypes() ? b : a; 599 } 600 601 static const RegType& SelectNonConstant2(const RegType& a, const RegType& b) { 602 return a.IsConstantTypes() ? (b.IsZero() ? a : b) : a; 603 } 604 605 const RegType& RegType::Merge(const RegType& incoming_type, 606 RegTypeCache* reg_types, 607 MethodVerifier* verifier) const { 608 DCHECK(!Equals(incoming_type)); // Trivial equality handled by caller 609 // Perform pointer equality tests for undefined and conflict to avoid virtual method dispatch. 610 const UndefinedType& undefined = reg_types->Undefined(); 611 const ConflictType& conflict = reg_types->Conflict(); 612 DCHECK_EQ(this == &undefined, IsUndefined()); 613 DCHECK_EQ(&incoming_type == &undefined, incoming_type.IsUndefined()); 614 DCHECK_EQ(this == &conflict, IsConflict()); 615 DCHECK_EQ(&incoming_type == &conflict, incoming_type.IsConflict()); 616 if (this == &undefined || &incoming_type == &undefined) { 617 // There is a difference between undefined and conflict. Conflicts may be copied around, but 618 // not used. Undefined registers must not be copied. So any merge with undefined should return 619 // undefined. 620 return undefined; 621 } else if (this == &conflict || &incoming_type == &conflict) { 622 return conflict; // (Conflict MERGE *) or (* MERGE Conflict) => Conflict 623 } else if (IsConstant() && incoming_type.IsConstant()) { 624 const ConstantType& type1 = *down_cast<const ConstantType*>(this); 625 const ConstantType& type2 = *down_cast<const ConstantType*>(&incoming_type); 626 int32_t val1 = type1.ConstantValue(); 627 int32_t val2 = type2.ConstantValue(); 628 if (val1 >= 0 && val2 >= 0) { 629 // +ve1 MERGE +ve2 => MAX(+ve1, +ve2) 630 if (val1 >= val2) { 631 if (!type1.IsPreciseConstant()) { 632 return *this; 633 } else { 634 return reg_types->FromCat1Const(val1, false); 635 } 636 } else { 637 if (!type2.IsPreciseConstant()) { 638 return type2; 639 } else { 640 return reg_types->FromCat1Const(val2, false); 641 } 642 } 643 } else if (val1 < 0 && val2 < 0) { 644 // -ve1 MERGE -ve2 => MIN(-ve1, -ve2) 645 if (val1 <= val2) { 646 if (!type1.IsPreciseConstant()) { 647 return *this; 648 } else { 649 return reg_types->FromCat1Const(val1, false); 650 } 651 } else { 652 if (!type2.IsPreciseConstant()) { 653 return type2; 654 } else { 655 return reg_types->FromCat1Const(val2, false); 656 } 657 } 658 } else { 659 // Values are +ve and -ve, choose smallest signed type in which they both fit 660 if (type1.IsConstantByte()) { 661 if (type2.IsConstantByte()) { 662 return reg_types->ByteConstant(); 663 } else if (type2.IsConstantShort()) { 664 return reg_types->ShortConstant(); 665 } else { 666 return reg_types->IntConstant(); 667 } 668 } else if (type1.IsConstantShort()) { 669 if (type2.IsConstantShort()) { 670 return reg_types->ShortConstant(); 671 } else { 672 return reg_types->IntConstant(); 673 } 674 } else { 675 return reg_types->IntConstant(); 676 } 677 } 678 } else if (IsConstantLo() && incoming_type.IsConstantLo()) { 679 const ConstantType& type1 = *down_cast<const ConstantType*>(this); 680 const ConstantType& type2 = *down_cast<const ConstantType*>(&incoming_type); 681 int32_t val1 = type1.ConstantValueLo(); 682 int32_t val2 = type2.ConstantValueLo(); 683 return reg_types->FromCat2ConstLo(val1 | val2, false); 684 } else if (IsConstantHi() && incoming_type.IsConstantHi()) { 685 const ConstantType& type1 = *down_cast<const ConstantType*>(this); 686 const ConstantType& type2 = *down_cast<const ConstantType*>(&incoming_type); 687 int32_t val1 = type1.ConstantValueHi(); 688 int32_t val2 = type2.ConstantValueHi(); 689 return reg_types->FromCat2ConstHi(val1 | val2, false); 690 } else if (IsIntegralTypes() && incoming_type.IsIntegralTypes()) { 691 if (IsBooleanTypes() && incoming_type.IsBooleanTypes()) { 692 return reg_types->Boolean(); // boolean MERGE boolean => boolean 693 } 694 if (IsByteTypes() && incoming_type.IsByteTypes()) { 695 return reg_types->Byte(); // byte MERGE byte => byte 696 } 697 if (IsShortTypes() && incoming_type.IsShortTypes()) { 698 return reg_types->Short(); // short MERGE short => short 699 } 700 if (IsCharTypes() && incoming_type.IsCharTypes()) { 701 return reg_types->Char(); // char MERGE char => char 702 } 703 return reg_types->Integer(); // int MERGE * => int 704 } else if ((IsFloatTypes() && incoming_type.IsFloatTypes()) || 705 (IsLongTypes() && incoming_type.IsLongTypes()) || 706 (IsLongHighTypes() && incoming_type.IsLongHighTypes()) || 707 (IsDoubleTypes() && incoming_type.IsDoubleTypes()) || 708 (IsDoubleHighTypes() && incoming_type.IsDoubleHighTypes())) { 709 // check constant case was handled prior to entry 710 DCHECK(!IsConstant() || !incoming_type.IsConstant()); 711 // float/long/double MERGE float/long/double_constant => float/long/double 712 return SelectNonConstant(*this, incoming_type); 713 } else if (IsReferenceTypes() && incoming_type.IsReferenceTypes()) { 714 if (IsUninitializedTypes() || incoming_type.IsUninitializedTypes()) { 715 // Something that is uninitialized hasn't had its constructor called. Unitialized types are 716 // special. They may only ever be merged with themselves (must be taken care of by the 717 // caller of Merge(), see the DCHECK on entry). So mark any other merge as conflicting here. 718 return conflict; 719 } else if (IsZeroOrNull() || incoming_type.IsZeroOrNull()) { 720 return SelectNonConstant2(*this, incoming_type); // 0 MERGE ref => ref 721 } else if (IsJavaLangObject() || incoming_type.IsJavaLangObject()) { 722 return reg_types->JavaLangObject(false); // Object MERGE ref => Object 723 } else if (IsUnresolvedTypes() || incoming_type.IsUnresolvedTypes()) { 724 // We know how to merge an unresolved type with itself, 0 or Object. In this case we 725 // have two sub-classes and don't know how to merge. Create a new string-based unresolved 726 // type that reflects our lack of knowledge and that allows the rest of the unresolved 727 // mechanics to continue. 728 return reg_types->FromUnresolvedMerge(*this, incoming_type, verifier); 729 } else { // Two reference types, compute Join 730 // Do not cache the classes as ClassJoin() can suspend and invalidate ObjPtr<>s. 731 DCHECK(GetClass() != nullptr && !GetClass()->IsPrimitive()); 732 DCHECK(incoming_type.GetClass() != nullptr && !incoming_type.GetClass()->IsPrimitive()); 733 ObjPtr<mirror::Class> join_class = ClassJoin(GetClass(), incoming_type.GetClass()); 734 if (UNLIKELY(join_class == nullptr)) { 735 // Internal error joining the classes (e.g., OOME). Report an unresolved reference type. 736 // We cannot report an unresolved merge type, as that will attempt to merge the resolved 737 // components, leaving us in an infinite loop. 738 // We do not want to report the originating exception, as that would require a fast path 739 // out all the way to VerifyClass. Instead attempt to continue on without a detailed type. 740 Thread* self = Thread::Current(); 741 self->AssertPendingException(); 742 self->ClearException(); 743 744 // When compiling on the host, we rather want to abort to ensure determinism for preopting. 745 // (In that case, it is likely a misconfiguration of dex2oat.) 746 if (!kIsTargetBuild && Runtime::Current()->IsAotCompiler()) { 747 LOG(FATAL) << "Could not create class join of " 748 << GetClass()->PrettyClass() 749 << " & " 750 << incoming_type.GetClass()->PrettyClass(); 751 UNREACHABLE(); 752 } 753 754 return reg_types->MakeUnresolvedReference(); 755 } 756 757 // Record the dependency that both `GetClass()` and `incoming_type.GetClass()` 758 // are assignable to `join_class`. The `verifier` is null during unit tests. 759 if (verifier != nullptr) { 760 VerifierDeps::MaybeRecordAssignability(verifier->GetDexFile(), 761 join_class, 762 GetClass(), 763 /* is_strict= */ true, 764 /* is_assignable= */ true); 765 VerifierDeps::MaybeRecordAssignability(verifier->GetDexFile(), 766 join_class, 767 incoming_type.GetClass(), 768 /* is_strict= */ true, 769 /* is_assignable= */ true); 770 } 771 if (GetClass() == join_class && !IsPreciseReference()) { 772 return *this; 773 } else if (incoming_type.GetClass() == join_class && !incoming_type.IsPreciseReference()) { 774 return incoming_type; 775 } else { 776 std::string temp; 777 const char* descriptor = join_class->GetDescriptor(&temp); 778 return reg_types->FromClass(descriptor, join_class, /* precise= */ false); 779 } 780 } 781 } else { 782 return conflict; // Unexpected types => Conflict 783 } 784 } 785 786 // See comment in reg_type.h 787 ObjPtr<mirror::Class> RegType::ClassJoin(ObjPtr<mirror::Class> s, ObjPtr<mirror::Class> t) { 788 DCHECK(!s->IsPrimitive()) << s->PrettyClass(); 789 DCHECK(!t->IsPrimitive()) << t->PrettyClass(); 790 if (s == t) { 791 return s; 792 } else if (s->IsAssignableFrom(t)) { 793 return s; 794 } else if (t->IsAssignableFrom(s)) { 795 return t; 796 } else if (s->IsArrayClass() && t->IsArrayClass()) { 797 ObjPtr<mirror::Class> s_ct = s->GetComponentType(); 798 ObjPtr<mirror::Class> t_ct = t->GetComponentType(); 799 if (s_ct->IsPrimitive() || t_ct->IsPrimitive()) { 800 // Given the types aren't the same, if either array is of primitive types then the only 801 // common parent is java.lang.Object 802 ObjPtr<mirror::Class> result = s->GetSuperClass(); // short-cut to java.lang.Object 803 DCHECK(result->IsObjectClass()); 804 return result; 805 } 806 Thread* self = Thread::Current(); 807 ObjPtr<mirror::Class> common_elem = ClassJoin(s_ct, t_ct); 808 if (UNLIKELY(common_elem == nullptr)) { 809 self->AssertPendingException(); 810 return nullptr; 811 } 812 // Note: The following lookup invalidates existing ObjPtr<>s. 813 ObjPtr<mirror::Class> array_class = 814 Runtime::Current()->GetClassLinker()->FindArrayClass(self, common_elem); 815 if (UNLIKELY(array_class == nullptr)) { 816 self->AssertPendingException(); 817 return nullptr; 818 } 819 return array_class; 820 } else { 821 size_t s_depth = s->Depth(); 822 size_t t_depth = t->Depth(); 823 // Get s and t to the same depth in the hierarchy 824 if (s_depth > t_depth) { 825 while (s_depth > t_depth) { 826 s = s->GetSuperClass(); 827 s_depth--; 828 } 829 } else { 830 while (t_depth > s_depth) { 831 t = t->GetSuperClass(); 832 t_depth--; 833 } 834 } 835 // Go up the hierarchy until we get to the common parent 836 while (s != t) { 837 s = s->GetSuperClass(); 838 t = t->GetSuperClass(); 839 } 840 return s; 841 } 842 } 843 844 void RegType::CheckInvariants() const { 845 if (IsConstant() || IsConstantLo() || IsConstantHi()) { 846 CHECK(descriptor_.empty()) << *this; 847 CHECK(klass_.IsNull()) << *this; 848 } 849 if (!klass_.IsNull()) { 850 CHECK(!descriptor_.empty()) << *this; 851 std::string temp; 852 CHECK_EQ(descriptor_, klass_.Read()->GetDescriptor(&temp)) << *this; 853 } 854 } 855 856 void RegType::VisitRoots(RootVisitor* visitor, const RootInfo& root_info) const { 857 klass_.VisitRootIfNonNull(visitor, root_info); 858 } 859 860 void UninitializedThisReferenceType::CheckInvariants() const { 861 CHECK_EQ(GetAllocationPc(), 0U) << *this; 862 } 863 864 void UnresolvedUninitializedThisRefType::CheckInvariants() const { 865 CHECK_EQ(GetAllocationPc(), 0U) << *this; 866 CHECK(!descriptor_.empty()) << *this; 867 CHECK(klass_.IsNull()) << *this; 868 } 869 870 void UnresolvedUninitializedRefType::CheckInvariants() const { 871 CHECK(!descriptor_.empty()) << *this; 872 CHECK(klass_.IsNull()) << *this; 873 } 874 875 UnresolvedMergedType::UnresolvedMergedType(const RegType& resolved, 876 const BitVector& unresolved, 877 const RegTypeCache* reg_type_cache, 878 uint16_t cache_id) 879 : UnresolvedType("", cache_id), 880 reg_type_cache_(reg_type_cache), 881 resolved_part_(resolved), 882 unresolved_types_(unresolved, false, unresolved.GetAllocator()) { 883 CheckConstructorInvariants(this); 884 } 885 void UnresolvedMergedType::CheckInvariants() const { 886 CHECK(reg_type_cache_ != nullptr); 887 888 // Unresolved merged types: merged types should be defined. 889 CHECK(descriptor_.empty()) << *this; 890 CHECK(klass_.IsNull()) << *this; 891 892 CHECK(!resolved_part_.IsConflict()); 893 CHECK(resolved_part_.IsReferenceTypes()); 894 CHECK(!resolved_part_.IsUnresolvedTypes()); 895 896 CHECK(resolved_part_.IsZero() || 897 !(resolved_part_.IsArrayTypes() && !resolved_part_.IsObjectArrayTypes())); 898 899 CHECK_GT(unresolved_types_.NumSetBits(), 0U); 900 bool unresolved_is_array = 901 reg_type_cache_->GetFromId(unresolved_types_.GetHighestBitSet()).IsArrayTypes(); 902 for (uint32_t idx : unresolved_types_.Indexes()) { 903 const RegType& t = reg_type_cache_->GetFromId(idx); 904 CHECK_EQ(unresolved_is_array, t.IsArrayTypes()); 905 } 906 907 if (!resolved_part_.IsZero()) { 908 CHECK_EQ(resolved_part_.IsArrayTypes(), unresolved_is_array); 909 } 910 } 911 912 bool UnresolvedMergedType::IsArrayTypes() const { 913 // For a merge to be an array, both the resolved and the unresolved part need to be object 914 // arrays. 915 // (Note: we encode a missing resolved part [which doesn't need to be an array] as zero.) 916 917 if (!resolved_part_.IsZero() && !resolved_part_.IsArrayTypes()) { 918 return false; 919 } 920 921 // It is enough to check just one of the merged types. Otherwise the merge should have been 922 // collapsed (checked in CheckInvariants on construction). 923 uint32_t idx = unresolved_types_.GetHighestBitSet(); 924 const RegType& unresolved = reg_type_cache_->GetFromId(idx); 925 return unresolved.IsArrayTypes(); 926 } 927 bool UnresolvedMergedType::IsObjectArrayTypes() const { 928 // Same as IsArrayTypes, as primitive arrays are always resolved. 929 return IsArrayTypes(); 930 } 931 932 void UnresolvedReferenceType::CheckInvariants() const { 933 CHECK(!descriptor_.empty()) << *this; 934 CHECK(klass_.IsNull()) << *this; 935 } 936 937 void UnresolvedSuperClass::CheckInvariants() const { 938 // Unresolved merged types: merged types should be defined. 939 CHECK(descriptor_.empty()) << *this; 940 CHECK(klass_.IsNull()) << *this; 941 CHECK_NE(unresolved_child_id_, 0U) << *this; 942 } 943 944 std::ostream& operator<<(std::ostream& os, const RegType& rhs) { 945 os << rhs.Dump(); 946 return os; 947 } 948 949 bool RegType::CanAssignArray(const RegType& src, 950 RegTypeCache& reg_types, 951 Handle<mirror::ClassLoader> class_loader, 952 MethodVerifier* verifier, 953 bool* soft_error) const { 954 if (!IsArrayTypes() || !src.IsArrayTypes()) { 955 *soft_error = false; 956 return false; 957 } 958 959 if (IsUnresolvedMergedReference() || src.IsUnresolvedMergedReference()) { 960 // An unresolved array type means that it's an array of some reference type. Reference arrays 961 // can never be assigned to primitive-type arrays, and vice versa. So it is a soft error if 962 // both arrays are reference arrays, otherwise a hard error. 963 *soft_error = IsObjectArrayTypes() && src.IsObjectArrayTypes(); 964 return false; 965 } 966 967 const RegType& cmp1 = reg_types.GetComponentType(*this, class_loader.Get()); 968 const RegType& cmp2 = reg_types.GetComponentType(src, class_loader.Get()); 969 970 if (cmp1.IsAssignableFrom(cmp2, verifier)) { 971 return true; 972 } 973 if (cmp1.IsUnresolvedTypes()) { 974 if (cmp2.IsIntegralTypes() || cmp2.IsFloatTypes() || cmp2.IsArrayTypes()) { 975 *soft_error = false; 976 return false; 977 } 978 *soft_error = true; 979 return false; 980 } 981 if (cmp2.IsUnresolvedTypes()) { 982 if (cmp1.IsIntegralTypes() || cmp1.IsFloatTypes() || cmp1.IsArrayTypes()) { 983 *soft_error = false; 984 return false; 985 } 986 *soft_error = true; 987 return false; 988 } 989 if (!cmp1.IsArrayTypes() || !cmp2.IsArrayTypes()) { 990 *soft_error = false; 991 return false; 992 } 993 return cmp1.CanAssignArray(cmp2, reg_types, class_loader, verifier, soft_error); 994 } 995 996 const NullType* NullType::CreateInstance(ObjPtr<mirror::Class> klass, 997 const std::string_view& descriptor, 998 uint16_t cache_id) { 999 CHECK(instance_ == nullptr); 1000 instance_ = new NullType(klass, descriptor, cache_id); 1001 return instance_; 1002 } 1003 1004 void NullType::Destroy() { 1005 if (NullType::instance_ != nullptr) { 1006 delete instance_; 1007 instance_ = nullptr; 1008 } 1009 } 1010 1011 1012 } // namespace verifier 1013 } // namespace art 1014