| OLD | NEW |
| 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
| 2 // All Rights Reserved. | 2 // All Rights Reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
| 6 // met: | 6 // met: |
| 7 // | 7 // |
| 8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
| 9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
| 10 // | 10 // |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 // [6-bit data delta] [2-bit data type tag] | 249 // [6-bit data delta] [2-bit data type tag] |
| 250 // | 250 // |
| 251 // 11: long_record [2-bit high tag][4 bit middle_tag] 11 | 251 // 11: long_record [2-bit high tag][4 bit middle_tag] 11 |
| 252 // followed by variable data depending on type. | 252 // followed by variable data depending on type. |
| 253 // | 253 // |
| 254 // 2-bit data type tags, used in short_data_record and data_jump long_record: | 254 // 2-bit data type tags, used in short_data_record and data_jump long_record: |
| 255 // code_target_with_id: 00 | 255 // code_target_with_id: 00 |
| 256 // position: 01 | 256 // position: 01 |
| 257 // statement_position: 10 | 257 // statement_position: 10 |
| 258 // comment: 11 (not used in short_data_record) | 258 // comment: 11 (not used in short_data_record) |
| 259 // deopt_reason: 11 (not used in long_data_record) |
| 259 // | 260 // |
| 260 // Long record format: | 261 // Long record format: |
| 261 // 4-bit middle_tag: | 262 // 4-bit middle_tag: |
| 262 // 0000 - 1100 : Short record for RelocInfo::Mode middle_tag + 2 | 263 // 0000 - 1100 : Short record for RelocInfo::Mode middle_tag + 2 |
| 263 // (The middle_tag encodes rmode - RelocInfo::LAST_COMPACT_ENUM, | 264 // (The middle_tag encodes rmode - RelocInfo::LAST_COMPACT_ENUM, |
| 264 // and is between 0000 and 1100) | 265 // and is between 0000 and 1100) |
| 265 // The format is: | 266 // The format is: |
| 266 // 00 [4 bit middle_tag] 11 followed by | 267 // 00 [4 bit middle_tag] 11 followed by |
| 267 // 00 [6 bit pc delta] | 268 // 00 [6 bit pc delta] |
| 268 // | 269 // |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 const int kLastChunkTag = 1; | 322 const int kLastChunkTag = 1; |
| 322 | 323 |
| 323 | 324 |
| 324 const int kDataJumpExtraTag = kPCJumpExtraTag - 1; | 325 const int kDataJumpExtraTag = kPCJumpExtraTag - 1; |
| 325 | 326 |
| 326 const int kCodeWithIdTag = 0; | 327 const int kCodeWithIdTag = 0; |
| 327 const int kNonstatementPositionTag = 1; | 328 const int kNonstatementPositionTag = 1; |
| 328 const int kStatementPositionTag = 2; | 329 const int kStatementPositionTag = 2; |
| 329 const int kCommentTag = 3; | 330 const int kCommentTag = 3; |
| 330 | 331 |
| 332 // Reuse the same value for deopt reason tag in short record format. |
| 333 // It is possible because we use kCommentTag only for the long record format. |
| 334 const int kDeoptReasonTag = 3; |
| 335 |
| 331 const int kPoolExtraTag = kPCJumpExtraTag - 2; | 336 const int kPoolExtraTag = kPCJumpExtraTag - 2; |
| 332 const int kConstPoolTag = 0; | 337 const int kConstPoolTag = 0; |
| 333 const int kVeneerPoolTag = 1; | 338 const int kVeneerPoolTag = 1; |
| 334 | 339 |
| 335 | 340 |
| 336 uint32_t RelocInfoWriter::WriteVariableLengthPCJump(uint32_t pc_delta) { | 341 uint32_t RelocInfoWriter::WriteVariableLengthPCJump(uint32_t pc_delta) { |
| 337 // Return if the pc_delta can fit in kSmallPCDeltaBits bits. | 342 // Return if the pc_delta can fit in kSmallPCDeltaBits bits. |
| 338 // Otherwise write a variable length PC jump for the bits that do | 343 // Otherwise write a variable length PC jump for the bits that do |
| 339 // not fit in the kSmallPCDeltaBits bits. | 344 // not fit in the kSmallPCDeltaBits bits. |
| 340 if (is_uintn(pc_delta, kSmallPCDeltaBits)) return pc_delta; | 345 if (is_uintn(pc_delta, kSmallPCDeltaBits)) return pc_delta; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 // Check if delta is small enough to fit in a tagged byte. | 440 // Check if delta is small enough to fit in a tagged byte. |
| 436 if (is_intn(id_delta, kSmallDataBits)) { | 441 if (is_intn(id_delta, kSmallDataBits)) { |
| 437 WriteTaggedPC(pc_delta, kLocatableTag); | 442 WriteTaggedPC(pc_delta, kLocatableTag); |
| 438 WriteTaggedData(id_delta, kCodeWithIdTag); | 443 WriteTaggedData(id_delta, kCodeWithIdTag); |
| 439 } else { | 444 } else { |
| 440 // Otherwise, use costly encoding. | 445 // Otherwise, use costly encoding. |
| 441 WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag); | 446 WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag); |
| 442 WriteExtraTaggedIntData(id_delta, kCodeWithIdTag); | 447 WriteExtraTaggedIntData(id_delta, kCodeWithIdTag); |
| 443 } | 448 } |
| 444 last_id_ = static_cast<int>(rinfo->data()); | 449 last_id_ = static_cast<int>(rinfo->data()); |
| 450 } else if (rmode == RelocInfo::DEOPT_REASON) { |
| 451 DCHECK(rinfo->data() < (1 << kSmallDataBits)); |
| 452 WriteTaggedPC(pc_delta, kLocatableTag); |
| 453 WriteTaggedData(rinfo->data(), kDeoptReasonTag); |
| 445 } else if (RelocInfo::IsPosition(rmode)) { | 454 } else if (RelocInfo::IsPosition(rmode)) { |
| 446 // Use signed delta-encoding for position. | 455 // Use signed delta-encoding for position. |
| 447 DCHECK(static_cast<int>(rinfo->data()) == rinfo->data()); | 456 DCHECK(static_cast<int>(rinfo->data()) == rinfo->data()); |
| 448 int pos_delta = static_cast<int>(rinfo->data()) - last_position_; | 457 int pos_delta = static_cast<int>(rinfo->data()) - last_position_; |
| 449 int pos_type_tag = (rmode == RelocInfo::POSITION) ? kNonstatementPositionTag | 458 int pos_type_tag = (rmode == RelocInfo::POSITION) ? kNonstatementPositionTag |
| 450 : kStatementPositionTag; | 459 : kStatementPositionTag; |
| 451 // Check if delta is small enough to fit in a tagged byte. | 460 // Check if delta is small enough to fit in a tagged byte. |
| 452 if (is_intn(pos_delta, kSmallDataBits)) { | 461 if (is_intn(pos_delta, kSmallDataBits)) { |
| 453 WriteTaggedPC(pc_delta, kLocatableTag); | 462 WriteTaggedPC(pc_delta, kLocatableTag); |
| 454 WriteTaggedData(pos_delta, pos_type_tag); | 463 WriteTaggedData(pos_delta, pos_type_tag); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 466 } else if (RelocInfo::IsConstPool(rmode) || RelocInfo::IsVeneerPool(rmode)) { | 475 } else if (RelocInfo::IsConstPool(rmode) || RelocInfo::IsVeneerPool(rmode)) { |
| 467 WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag); | 476 WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag); |
| 468 WriteExtraTaggedPoolData(static_cast<int>(rinfo->data()), | 477 WriteExtraTaggedPoolData(static_cast<int>(rinfo->data()), |
| 469 RelocInfo::IsConstPool(rmode) ? kConstPoolTag | 478 RelocInfo::IsConstPool(rmode) ? kConstPoolTag |
| 470 : kVeneerPoolTag); | 479 : kVeneerPoolTag); |
| 471 } else { | 480 } else { |
| 472 DCHECK(rmode > RelocInfo::LAST_COMPACT_ENUM); | 481 DCHECK(rmode > RelocInfo::LAST_COMPACT_ENUM); |
| 473 int saved_mode = rmode - RelocInfo::LAST_COMPACT_ENUM; | 482 int saved_mode = rmode - RelocInfo::LAST_COMPACT_ENUM; |
| 474 // For all other modes we simply use the mode as the extra tag. | 483 // For all other modes we simply use the mode as the extra tag. |
| 475 // None of these modes need a data component. | 484 // None of these modes need a data component. |
| 476 DCHECK(saved_mode < kPCJumpExtraTag && saved_mode < kDataJumpExtraTag); | 485 DCHECK(saved_mode < kPoolExtraTag); |
| 477 WriteExtraTaggedPC(pc_delta, saved_mode); | 486 WriteExtraTaggedPC(pc_delta, saved_mode); |
| 478 } | 487 } |
| 479 last_pc_ = rinfo->pc(); | 488 last_pc_ = rinfo->pc(); |
| 480 #ifdef DEBUG | 489 #ifdef DEBUG |
| 481 DCHECK(begin_pos - pos_ <= kMaxSize); | 490 DCHECK(begin_pos - pos_ <= kMaxSize); |
| 482 #endif | 491 #endif |
| 483 } | 492 } |
| 484 | 493 |
| 485 | 494 |
| 486 inline int RelocIterator::AdvanceGetTag() { | 495 inline int RelocIterator::AdvanceGetTag() { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 | 585 |
| 577 | 586 |
| 578 inline void RelocIterator::ReadTaggedPosition() { | 587 inline void RelocIterator::ReadTaggedPosition() { |
| 579 int8_t signed_b = *pos_; | 588 int8_t signed_b = *pos_; |
| 580 // Signed right shift is arithmetic shift. Tested in test-utils.cc. | 589 // Signed right shift is arithmetic shift. Tested in test-utils.cc. |
| 581 last_position_ += signed_b >> kLocatableTypeTagBits; | 590 last_position_ += signed_b >> kLocatableTypeTagBits; |
| 582 rinfo_.data_ = last_position_; | 591 rinfo_.data_ = last_position_; |
| 583 } | 592 } |
| 584 | 593 |
| 585 | 594 |
| 595 inline void RelocIterator::ReadTaggedData() { |
| 596 uint8_t unsigned_b = *pos_; |
| 597 rinfo_.data_ = unsigned_b >> kTagBits; |
| 598 } |
| 599 |
| 600 |
| 586 static inline RelocInfo::Mode GetPositionModeFromTag(int tag) { | 601 static inline RelocInfo::Mode GetPositionModeFromTag(int tag) { |
| 587 DCHECK(tag == kNonstatementPositionTag || | 602 DCHECK(tag == kNonstatementPositionTag || |
| 588 tag == kStatementPositionTag); | 603 tag == kStatementPositionTag); |
| 589 return (tag == kNonstatementPositionTag) ? | 604 return (tag == kNonstatementPositionTag) ? |
| 590 RelocInfo::POSITION : | 605 RelocInfo::POSITION : |
| 591 RelocInfo::STATEMENT_POSITION; | 606 RelocInfo::STATEMENT_POSITION; |
| 592 } | 607 } |
| 593 | 608 |
| 594 | 609 |
| 595 void RelocIterator::next() { | 610 void RelocIterator::next() { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 609 if (SetMode(RelocInfo::CODE_TARGET)) return; | 624 if (SetMode(RelocInfo::CODE_TARGET)) return; |
| 610 } else if (tag == kLocatableTag) { | 625 } else if (tag == kLocatableTag) { |
| 611 ReadTaggedPC(); | 626 ReadTaggedPC(); |
| 612 Advance(); | 627 Advance(); |
| 613 int locatable_tag = GetLocatableTypeTag(); | 628 int locatable_tag = GetLocatableTypeTag(); |
| 614 if (locatable_tag == kCodeWithIdTag) { | 629 if (locatable_tag == kCodeWithIdTag) { |
| 615 if (SetMode(RelocInfo::CODE_TARGET_WITH_ID)) { | 630 if (SetMode(RelocInfo::CODE_TARGET_WITH_ID)) { |
| 616 ReadTaggedId(); | 631 ReadTaggedId(); |
| 617 return; | 632 return; |
| 618 } | 633 } |
| 634 } else if (locatable_tag == kDeoptReasonTag) { |
| 635 ReadTaggedData(); |
| 636 if (SetMode(RelocInfo::DEOPT_REASON)) return; |
| 619 } else { | 637 } else { |
| 620 // Compact encoding is never used for comments, | |
| 621 // so it must be a position. | |
| 622 DCHECK(locatable_tag == kNonstatementPositionTag || | 638 DCHECK(locatable_tag == kNonstatementPositionTag || |
| 623 locatable_tag == kStatementPositionTag); | 639 locatable_tag == kStatementPositionTag); |
| 624 if (mode_mask_ & RelocInfo::kPositionMask) { | 640 if (mode_mask_ & RelocInfo::kPositionMask) { |
| 625 ReadTaggedPosition(); | 641 ReadTaggedPosition(); |
| 626 if (SetMode(GetPositionModeFromTag(locatable_tag))) return; | 642 if (SetMode(GetPositionModeFromTag(locatable_tag))) return; |
| 627 } | 643 } |
| 628 } | 644 } |
| 629 } else { | 645 } else { |
| 630 DCHECK(tag == kDefaultTag); | 646 DCHECK(tag == kDefaultTag); |
| 631 int extra_tag = GetExtraTag(); | 647 int extra_tag = GetExtraTag(); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 776 case RelocInfo::COMMENT: | 792 case RelocInfo::COMMENT: |
| 777 return "comment"; | 793 return "comment"; |
| 778 case RelocInfo::POSITION: | 794 case RelocInfo::POSITION: |
| 779 return "position"; | 795 return "position"; |
| 780 case RelocInfo::STATEMENT_POSITION: | 796 case RelocInfo::STATEMENT_POSITION: |
| 781 return "statement position"; | 797 return "statement position"; |
| 782 case RelocInfo::EXTERNAL_REFERENCE: | 798 case RelocInfo::EXTERNAL_REFERENCE: |
| 783 return "external reference"; | 799 return "external reference"; |
| 784 case RelocInfo::INTERNAL_REFERENCE: | 800 case RelocInfo::INTERNAL_REFERENCE: |
| 785 return "internal reference"; | 801 return "internal reference"; |
| 802 case RelocInfo::DEOPT_REASON: |
| 803 return "deopt reason"; |
| 786 case RelocInfo::CONST_POOL: | 804 case RelocInfo::CONST_POOL: |
| 787 return "constant pool"; | 805 return "constant pool"; |
| 788 case RelocInfo::VENEER_POOL: | 806 case RelocInfo::VENEER_POOL: |
| 789 return "veneer pool"; | 807 return "veneer pool"; |
| 790 case RelocInfo::DEBUG_BREAK_SLOT: | 808 case RelocInfo::DEBUG_BREAK_SLOT: |
| 791 return "debug break slot"; | 809 return "debug break slot"; |
| 792 case RelocInfo::CODE_AGE_SEQUENCE: | 810 case RelocInfo::CODE_AGE_SEQUENCE: |
| 793 return "code_age_sequence"; | 811 return "code_age_sequence"; |
| 794 case RelocInfo::NUMBER_OF_MODES: | 812 case RelocInfo::NUMBER_OF_MODES: |
| 795 UNREACHABLE(); | 813 UNREACHABLE(); |
| 796 return "number_of_modes"; | 814 return "number_of_modes"; |
| 797 } | 815 } |
| 798 return "unknown relocation type"; | 816 return "unknown relocation type"; |
| 799 } | 817 } |
| 800 | 818 |
| 801 | 819 |
| 802 void RelocInfo::Print(Isolate* isolate, std::ostream& os) { // NOLINT | 820 void RelocInfo::Print(Isolate* isolate, std::ostream& os) { // NOLINT |
| 803 os << static_cast<const void*>(pc_) << " " << RelocModeName(rmode_); | 821 os << static_cast<const void*>(pc_) << " " << RelocModeName(rmode_); |
| 804 if (IsComment(rmode_)) { | 822 if (IsComment(rmode_)) { |
| 805 os << " (" << reinterpret_cast<char*>(data_) << ")"; | 823 os << " (" << reinterpret_cast<char*>(data_) << ")"; |
| 824 } else if (rmode_ == DEOPT_REASON) { |
| 825 os << " (" << Deoptimizer::GetDeoptReason( |
| 826 static_cast<Deoptimizer::DeoptReason>(data_)) << ")"; |
| 806 } else if (rmode_ == EMBEDDED_OBJECT) { | 827 } else if (rmode_ == EMBEDDED_OBJECT) { |
| 807 os << " (" << Brief(target_object()) << ")"; | 828 os << " (" << Brief(target_object()) << ")"; |
| 808 } else if (rmode_ == EXTERNAL_REFERENCE) { | 829 } else if (rmode_ == EXTERNAL_REFERENCE) { |
| 809 ExternalReferenceEncoder ref_encoder(isolate); | 830 ExternalReferenceEncoder ref_encoder(isolate); |
| 810 os << " (" << ref_encoder.NameOfAddress(target_reference()) << ") (" | 831 os << " (" << ref_encoder.NameOfAddress(target_reference()) << ") (" |
| 811 << static_cast<const void*>(target_reference()) << ")"; | 832 << static_cast<const void*>(target_reference()) << ")"; |
| 812 } else if (IsCodeTarget(rmode_)) { | 833 } else if (IsCodeTarget(rmode_)) { |
| 813 Code* code = Code::GetCodeFromTargetAddress(target_address()); | 834 Code* code = Code::GetCodeFromTargetAddress(target_address()); |
| 814 os << " (" << Code::Kind2String(code->kind()) << ") (" | 835 os << " (" << Code::Kind2String(code->kind()) << ") (" |
| 815 << static_cast<const void*>(target_address()) << ")"; | 836 << static_cast<const void*>(target_address()) << ")"; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 856 CHECK(code->address() == HeapObject::cast(found)->address()); | 877 CHECK(code->address() == HeapObject::cast(found)->address()); |
| 857 break; | 878 break; |
| 858 } | 879 } |
| 859 case RUNTIME_ENTRY: | 880 case RUNTIME_ENTRY: |
| 860 case JS_RETURN: | 881 case JS_RETURN: |
| 861 case COMMENT: | 882 case COMMENT: |
| 862 case POSITION: | 883 case POSITION: |
| 863 case STATEMENT_POSITION: | 884 case STATEMENT_POSITION: |
| 864 case EXTERNAL_REFERENCE: | 885 case EXTERNAL_REFERENCE: |
| 865 case INTERNAL_REFERENCE: | 886 case INTERNAL_REFERENCE: |
| 887 case DEOPT_REASON: |
| 866 case CONST_POOL: | 888 case CONST_POOL: |
| 867 case VENEER_POOL: | 889 case VENEER_POOL: |
| 868 case DEBUG_BREAK_SLOT: | 890 case DEBUG_BREAK_SLOT: |
| 869 case NONE32: | 891 case NONE32: |
| 870 case NONE64: | 892 case NONE64: |
| 871 break; | 893 break; |
| 872 case NUMBER_OF_MODES: | 894 case NUMBER_OF_MODES: |
| 873 UNREACHABLE(); | 895 UNREACHABLE(); |
| 874 break; | 896 break; |
| 875 case CODE_AGE_SEQUENCE: | 897 case CODE_AGE_SEQUENCE: |
| (...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1591 assembler_->RecordRelocInfo(RelocInfo::POSITION, state_.current_position); | 1613 assembler_->RecordRelocInfo(RelocInfo::POSITION, state_.current_position); |
| 1592 state_.written_position = state_.current_position; | 1614 state_.written_position = state_.current_position; |
| 1593 written = true; | 1615 written = true; |
| 1594 } | 1616 } |
| 1595 | 1617 |
| 1596 // Return whether something was written. | 1618 // Return whether something was written. |
| 1597 return written; | 1619 return written; |
| 1598 } | 1620 } |
| 1599 | 1621 |
| 1600 } } // namespace v8::internal | 1622 } } // namespace v8::internal |
| OLD | NEW |