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