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 |