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