| 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 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 EMBEDDED_OBJECT, | 387 EMBEDDED_OBJECT, |
| 388 // To relocate pointers into the wasm memory embedded in wasm code | 388 // To relocate pointers into the wasm memory embedded in wasm code |
| 389 WASM_MEMORY_REFERENCE, | 389 WASM_MEMORY_REFERENCE, |
| 390 WASM_GLOBAL_REFERENCE, | 390 WASM_GLOBAL_REFERENCE, |
| 391 WASM_MEMORY_SIZE_REFERENCE, | 391 WASM_MEMORY_SIZE_REFERENCE, |
| 392 CELL, | 392 CELL, |
| 393 | 393 |
| 394 // Everything after runtime_entry (inclusive) is not GC'ed. | 394 // Everything after runtime_entry (inclusive) is not GC'ed. |
| 395 RUNTIME_ENTRY, | 395 RUNTIME_ENTRY, |
| 396 COMMENT, | 396 COMMENT, |
| 397 POSITION, // See comment for kNoPosition above. | |
| 398 STATEMENT_POSITION, // See comment for kNoPosition above. | |
| 399 | 397 |
| 400 // Additional code inserted for debug break slot. | 398 // Additional code inserted for debug break slot. |
| 401 DEBUG_BREAK_SLOT_AT_POSITION, | 399 DEBUG_BREAK_SLOT_AT_POSITION, |
| 402 DEBUG_BREAK_SLOT_AT_RETURN, | 400 DEBUG_BREAK_SLOT_AT_RETURN, |
| 403 DEBUG_BREAK_SLOT_AT_CALL, | 401 DEBUG_BREAK_SLOT_AT_CALL, |
| 404 DEBUG_BREAK_SLOT_AT_TAIL_CALL, | 402 DEBUG_BREAK_SLOT_AT_TAIL_CALL, |
| 405 | 403 |
| 406 EXTERNAL_REFERENCE, // The address of an external C++ function. | 404 EXTERNAL_REFERENCE, // The address of an external C++ function. |
| 407 INTERNAL_REFERENCE, // An address inside the same function. | 405 INTERNAL_REFERENCE, // An address inside the same function. |
| 408 | 406 |
| 409 // Encoded internal reference, used only on MIPS, MIPS64 and PPC. | 407 // Encoded internal reference, used only on MIPS, MIPS64 and PPC. |
| 410 INTERNAL_REFERENCE_ENCODED, | 408 INTERNAL_REFERENCE_ENCODED, |
| 411 | 409 |
| 412 // Continuation points for a generator yield. | 410 // Continuation points for a generator yield. |
| 413 GENERATOR_CONTINUATION, | 411 GENERATOR_CONTINUATION, |
| 414 | 412 |
| 415 // Marks constant and veneer pools. Only used on ARM and ARM64. | 413 // Marks constant and veneer pools. Only used on ARM and ARM64. |
| 416 // They use a custom noncompact encoding. | 414 // They use a custom noncompact encoding. |
| 417 CONST_POOL, | 415 CONST_POOL, |
| 418 VENEER_POOL, | 416 VENEER_POOL, |
| 419 | 417 |
| 420 DEOPT_REASON, // Deoptimization reason index. | 418 DEOPT_POSITION, // Deoptimization source position. |
| 421 DEOPT_ID, // Deoptimization inlining id. | 419 DEOPT_REASON, // Deoptimization reason index. |
| 420 DEOPT_ID, // Deoptimization inlining id. |
| 422 | 421 |
| 423 // This is not an actual reloc mode, but used to encode a long pc jump that | 422 // This is not an actual reloc mode, but used to encode a long pc jump that |
| 424 // cannot be encoded as part of another record. | 423 // cannot be encoded as part of another record. |
| 425 PC_JUMP, | 424 PC_JUMP, |
| 426 | 425 |
| 427 // Pseudo-types | 426 // Pseudo-types |
| 428 NUMBER_OF_MODES, | 427 NUMBER_OF_MODES, |
| 429 NONE32, // never recorded 32-bit value | 428 NONE32, // never recorded 32-bit value |
| 430 NONE64, // never recorded 64-bit value | 429 NONE64, // never recorded 64-bit value |
| 431 CODE_AGE_SEQUENCE, // Not stored in RelocInfo array, used explictly by | 430 CODE_AGE_SEQUENCE, // Not stored in RelocInfo array, used explictly by |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 } | 467 } |
| 469 static inline bool IsComment(Mode mode) { | 468 static inline bool IsComment(Mode mode) { |
| 470 return mode == COMMENT; | 469 return mode == COMMENT; |
| 471 } | 470 } |
| 472 static inline bool IsConstPool(Mode mode) { | 471 static inline bool IsConstPool(Mode mode) { |
| 473 return mode == CONST_POOL; | 472 return mode == CONST_POOL; |
| 474 } | 473 } |
| 475 static inline bool IsVeneerPool(Mode mode) { | 474 static inline bool IsVeneerPool(Mode mode) { |
| 476 return mode == VENEER_POOL; | 475 return mode == VENEER_POOL; |
| 477 } | 476 } |
| 477 static inline bool IsDeoptPosition(Mode mode) { |
| 478 return mode == DEOPT_POSITION; |
| 479 } |
| 478 static inline bool IsDeoptReason(Mode mode) { | 480 static inline bool IsDeoptReason(Mode mode) { |
| 479 return mode == DEOPT_REASON; | 481 return mode == DEOPT_REASON; |
| 480 } | 482 } |
| 481 static inline bool IsDeoptId(Mode mode) { | 483 static inline bool IsDeoptId(Mode mode) { |
| 482 return mode == DEOPT_ID; | 484 return mode == DEOPT_ID; |
| 483 } | 485 } |
| 484 static inline bool IsPosition(Mode mode) { | |
| 485 return mode == POSITION || mode == STATEMENT_POSITION; | |
| 486 } | |
| 487 static inline bool IsStatementPosition(Mode mode) { | |
| 488 return mode == STATEMENT_POSITION; | |
| 489 } | |
| 490 static inline bool IsExternalReference(Mode mode) { | 486 static inline bool IsExternalReference(Mode mode) { |
| 491 return mode == EXTERNAL_REFERENCE; | 487 return mode == EXTERNAL_REFERENCE; |
| 492 } | 488 } |
| 493 static inline bool IsInternalReference(Mode mode) { | 489 static inline bool IsInternalReference(Mode mode) { |
| 494 return mode == INTERNAL_REFERENCE; | 490 return mode == INTERNAL_REFERENCE; |
| 495 } | 491 } |
| 496 static inline bool IsInternalReferenceEncoded(Mode mode) { | 492 static inline bool IsInternalReferenceEncoded(Mode mode) { |
| 497 return mode == INTERNAL_REFERENCE_ENCODED; | 493 return mode == INTERNAL_REFERENCE_ENCODED; |
| 498 } | 494 } |
| 499 static inline bool IsDebugBreakSlot(Mode mode) { | 495 static inline bool IsDebugBreakSlot(Mode mode) { |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 #ifdef ENABLE_DISASSEMBLER | 656 #ifdef ENABLE_DISASSEMBLER |
| 661 // Printing | 657 // Printing |
| 662 static const char* RelocModeName(Mode rmode); | 658 static const char* RelocModeName(Mode rmode); |
| 663 void Print(Isolate* isolate, std::ostream& os); // NOLINT | 659 void Print(Isolate* isolate, std::ostream& os); // NOLINT |
| 664 #endif // ENABLE_DISASSEMBLER | 660 #endif // ENABLE_DISASSEMBLER |
| 665 #ifdef VERIFY_HEAP | 661 #ifdef VERIFY_HEAP |
| 666 void Verify(Isolate* isolate); | 662 void Verify(Isolate* isolate); |
| 667 #endif | 663 #endif |
| 668 | 664 |
| 669 static const int kCodeTargetMask = (1 << (LAST_CODE_ENUM + 1)) - 1; | 665 static const int kCodeTargetMask = (1 << (LAST_CODE_ENUM + 1)) - 1; |
| 670 static const int kPositionMask = 1 << POSITION | 1 << STATEMENT_POSITION; | 666 static const int kDataMask = (1 << CODE_TARGET_WITH_ID) | (1 << COMMENT); |
| 671 static const int kDataMask = | |
| 672 (1 << CODE_TARGET_WITH_ID) | kPositionMask | (1 << COMMENT); | |
| 673 static const int kDebugBreakSlotMask = 1 << DEBUG_BREAK_SLOT_AT_POSITION | | 667 static const int kDebugBreakSlotMask = 1 << DEBUG_BREAK_SLOT_AT_POSITION | |
| 674 1 << DEBUG_BREAK_SLOT_AT_RETURN | | 668 1 << DEBUG_BREAK_SLOT_AT_RETURN | |
| 675 1 << DEBUG_BREAK_SLOT_AT_CALL; | 669 1 << DEBUG_BREAK_SLOT_AT_CALL; |
| 676 static const int kApplyMask; // Modes affected by apply. Depends on arch. | 670 static const int kApplyMask; // Modes affected by apply. Depends on arch. |
| 677 | 671 |
| 678 private: | 672 private: |
| 679 void unchecked_update_wasm_memory_reference(Address address, | 673 void unchecked_update_wasm_memory_reference(Address address, |
| 680 ICacheFlushMode flush_mode); | 674 ICacheFlushMode flush_mode); |
| 681 void unchecked_update_wasm_memory_size(uint32_t size, | 675 void unchecked_update_wasm_memory_size(uint32_t size, |
| 682 ICacheFlushMode flush_mode); | 676 ICacheFlushMode flush_mode); |
| 683 | 677 |
| 684 Isolate* isolate_; | 678 Isolate* isolate_; |
| 685 // On ARM, note that pc_ is the address of the constant pool entry | 679 // On ARM, note that pc_ is the address of the constant pool entry |
| 686 // to be relocated and not the address of the instruction | 680 // to be relocated and not the address of the instruction |
| 687 // referencing the constant pool entry (except when rmode_ == | 681 // referencing the constant pool entry (except when rmode_ == |
| 688 // comment). | 682 // comment). |
| 689 byte* pc_; | 683 byte* pc_; |
| 690 Mode rmode_; | 684 Mode rmode_; |
| 691 intptr_t data_; | 685 intptr_t data_; |
| 692 Code* host_; | 686 Code* host_; |
| 693 friend class RelocIterator; | 687 friend class RelocIterator; |
| 694 }; | 688 }; |
| 695 | 689 |
| 696 | 690 |
| 697 // RelocInfoWriter serializes a stream of relocation info. It writes towards | 691 // RelocInfoWriter serializes a stream of relocation info. It writes towards |
| 698 // lower addresses. | 692 // lower addresses. |
| 699 class RelocInfoWriter BASE_EMBEDDED { | 693 class RelocInfoWriter BASE_EMBEDDED { |
| 700 public: | 694 public: |
| 701 RelocInfoWriter() | 695 RelocInfoWriter() : pos_(NULL), last_pc_(NULL), last_id_(0) {} |
| 702 : pos_(NULL), | 696 RelocInfoWriter(byte* pos, byte* pc) : pos_(pos), last_pc_(pc), last_id_(0) {} |
| 703 last_pc_(NULL), | |
| 704 last_id_(0), | |
| 705 last_position_(0), | |
| 706 last_mode_(RelocInfo::NUMBER_OF_MODES), | |
| 707 next_position_candidate_pos_delta_(0), | |
| 708 next_position_candidate_pc_delta_(0), | |
| 709 next_position_candidate_flushed_(true) {} | |
| 710 RelocInfoWriter(byte* pos, byte* pc) | |
| 711 : pos_(pos), | |
| 712 last_pc_(pc), | |
| 713 last_id_(0), | |
| 714 last_position_(0), | |
| 715 last_mode_(RelocInfo::NUMBER_OF_MODES), | |
| 716 next_position_candidate_pos_delta_(0), | |
| 717 next_position_candidate_pc_delta_(0), | |
| 718 next_position_candidate_flushed_(true) {} | |
| 719 | 697 |
| 720 byte* pos() const { return pos_; } | 698 byte* pos() const { return pos_; } |
| 721 byte* last_pc() const { return last_pc_; } | 699 byte* last_pc() const { return last_pc_; } |
| 722 | 700 |
| 723 void Write(const RelocInfo* rinfo); | 701 void Write(const RelocInfo* rinfo); |
| 724 | 702 |
| 725 // Update the state of the stream after reloc info buffer | 703 // Update the state of the stream after reloc info buffer |
| 726 // and/or code is moved while the stream is active. | 704 // and/or code is moved while the stream is active. |
| 727 void Reposition(byte* pos, byte* pc) { | 705 void Reposition(byte* pos, byte* pc) { |
| 728 pos_ = pos; | 706 pos_ = pos; |
| 729 last_pc_ = pc; | 707 last_pc_ = pc; |
| 730 } | 708 } |
| 731 | 709 |
| 732 void Finish() { FlushPosition(); } | |
| 733 | |
| 734 // Max size (bytes) of a written RelocInfo. Longest encoding is | 710 // Max size (bytes) of a written RelocInfo. Longest encoding is |
| 735 // ExtraTag, VariableLengthPCJump, ExtraTag, pc_delta, data_delta. | 711 // ExtraTag, VariableLengthPCJump, ExtraTag, pc_delta, data_delta. |
| 736 // On ia32 and arm this is 1 + 4 + 1 + 1 + 4 = 11. | 712 // On ia32 and arm this is 1 + 4 + 1 + 1 + 4 = 11. |
| 737 // On x64 this is 1 + 4 + 1 + 1 + 8 == 15; | 713 // On x64 this is 1 + 4 + 1 + 1 + 8 == 15; |
| 738 // Here we use the maximum of the two. | 714 // Here we use the maximum of the two. |
| 739 static const int kMaxSize = 15; | 715 static const int kMaxSize = 15; |
| 740 | 716 |
| 741 private: | 717 private: |
| 742 inline uint32_t WriteLongPCJump(uint32_t pc_delta); | 718 inline uint32_t WriteLongPCJump(uint32_t pc_delta); |
| 743 | 719 |
| 744 inline void WriteShortTaggedPC(uint32_t pc_delta, int tag); | 720 inline void WriteShortTaggedPC(uint32_t pc_delta, int tag); |
| 745 inline void WriteShortTaggedData(intptr_t data_delta, int tag); | 721 inline void WriteShortTaggedData(intptr_t data_delta, int tag); |
| 746 | 722 |
| 747 inline void WriteMode(RelocInfo::Mode rmode); | 723 inline void WriteMode(RelocInfo::Mode rmode); |
| 748 inline void WriteModeAndPC(uint32_t pc_delta, RelocInfo::Mode rmode); | 724 inline void WriteModeAndPC(uint32_t pc_delta, RelocInfo::Mode rmode); |
| 749 inline void WriteIntData(int data_delta); | 725 inline void WriteIntData(int data_delta); |
| 750 inline void WriteData(intptr_t data_delta); | 726 inline void WriteData(intptr_t data_delta); |
| 751 inline void WritePosition(int pc_delta, int pos_delta, RelocInfo::Mode rmode); | |
| 752 | |
| 753 void FlushPosition(); | |
| 754 | 727 |
| 755 byte* pos_; | 728 byte* pos_; |
| 756 byte* last_pc_; | 729 byte* last_pc_; |
| 757 int last_id_; | 730 int last_id_; |
| 758 int last_position_; | |
| 759 RelocInfo::Mode last_mode_; | 731 RelocInfo::Mode last_mode_; |
| 760 int next_position_candidate_pos_delta_; | |
| 761 uint32_t next_position_candidate_pc_delta_; | |
| 762 bool next_position_candidate_flushed_; | |
| 763 | 732 |
| 764 DISALLOW_COPY_AND_ASSIGN(RelocInfoWriter); | 733 DISALLOW_COPY_AND_ASSIGN(RelocInfoWriter); |
| 765 }; | 734 }; |
| 766 | 735 |
| 767 | 736 |
| 768 // A RelocIterator iterates over relocation information. | 737 // A RelocIterator iterates over relocation information. |
| 769 // Typical use: | 738 // Typical use: |
| 770 // | 739 // |
| 771 // for (RelocIterator it(code); !it.done(); it.next()) { | 740 // for (RelocIterator it(code); !it.done(); it.next()) { |
| 772 // // do something with it.rinfo() here | 741 // // do something with it.rinfo() here |
| (...skipping 25 matching lines...) Expand all Loading... |
| 798 // *Get* just reads and returns info on current byte. | 767 // *Get* just reads and returns info on current byte. |
| 799 void Advance(int bytes = 1) { pos_ -= bytes; } | 768 void Advance(int bytes = 1) { pos_ -= bytes; } |
| 800 int AdvanceGetTag(); | 769 int AdvanceGetTag(); |
| 801 RelocInfo::Mode GetMode(); | 770 RelocInfo::Mode GetMode(); |
| 802 | 771 |
| 803 void AdvanceReadLongPCJump(); | 772 void AdvanceReadLongPCJump(); |
| 804 | 773 |
| 805 int GetShortDataTypeTag(); | 774 int GetShortDataTypeTag(); |
| 806 void ReadShortTaggedPC(); | 775 void ReadShortTaggedPC(); |
| 807 void ReadShortTaggedId(); | 776 void ReadShortTaggedId(); |
| 808 void ReadShortTaggedPosition(); | |
| 809 void ReadShortTaggedData(); | 777 void ReadShortTaggedData(); |
| 810 | 778 |
| 811 void AdvanceReadPC(); | 779 void AdvanceReadPC(); |
| 812 void AdvanceReadId(); | 780 void AdvanceReadId(); |
| 813 void AdvanceReadInt(); | 781 void AdvanceReadInt(); |
| 814 void AdvanceReadPosition(); | |
| 815 void AdvanceReadData(); | 782 void AdvanceReadData(); |
| 816 | 783 |
| 817 // If the given mode is wanted, set it in rinfo_ and return true. | 784 // If the given mode is wanted, set it in rinfo_ and return true. |
| 818 // Else return false. Used for efficiently skipping unwanted modes. | 785 // Else return false. Used for efficiently skipping unwanted modes. |
| 819 bool SetMode(RelocInfo::Mode mode) { | 786 bool SetMode(RelocInfo::Mode mode) { |
| 820 return (mode_mask_ & (1 << mode)) ? (rinfo_.rmode_ = mode, true) : false; | 787 return (mode_mask_ & (1 << mode)) ? (rinfo_.rmode_ = mode, true) : false; |
| 821 } | 788 } |
| 822 | 789 |
| 823 byte* pos_; | 790 byte* pos_; |
| 824 byte* end_; | 791 byte* end_; |
| 825 byte* code_age_sequence_; | 792 byte* code_age_sequence_; |
| 826 RelocInfo rinfo_; | 793 RelocInfo rinfo_; |
| 827 bool done_; | 794 bool done_; |
| 828 int mode_mask_; | 795 int mode_mask_; |
| 829 int last_id_; | 796 int last_id_; |
| 830 int last_position_; | |
| 831 DISALLOW_COPY_AND_ASSIGN(RelocIterator); | 797 DISALLOW_COPY_AND_ASSIGN(RelocIterator); |
| 832 }; | 798 }; |
| 833 | 799 |
| 834 | 800 |
| 835 //------------------------------------------------------------------------------ | 801 //------------------------------------------------------------------------------ |
| 836 // External function | 802 // External function |
| 837 | 803 |
| 838 //---------------------------------------------------------------------------- | 804 //---------------------------------------------------------------------------- |
| 839 class SCTableReference; | 805 class SCTableReference; |
| 840 class Debug_Address; | 806 class Debug_Address; |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1127 void* address_; | 1093 void* address_; |
| 1128 }; | 1094 }; |
| 1129 | 1095 |
| 1130 bool operator==(ExternalReference, ExternalReference); | 1096 bool operator==(ExternalReference, ExternalReference); |
| 1131 bool operator!=(ExternalReference, ExternalReference); | 1097 bool operator!=(ExternalReference, ExternalReference); |
| 1132 | 1098 |
| 1133 size_t hash_value(ExternalReference); | 1099 size_t hash_value(ExternalReference); |
| 1134 | 1100 |
| 1135 std::ostream& operator<<(std::ostream&, ExternalReference); | 1101 std::ostream& operator<<(std::ostream&, ExternalReference); |
| 1136 | 1102 |
| 1137 | |
| 1138 // ----------------------------------------------------------------------------- | |
| 1139 // Position recording support | |
| 1140 | |
| 1141 class AssemblerPositionsRecorder : public PositionsRecorder { | |
| 1142 public: | |
| 1143 explicit AssemblerPositionsRecorder(Assembler* assembler) | |
| 1144 : assembler_(assembler), | |
| 1145 current_position_(RelocInfo::kNoPosition), | |
| 1146 written_position_(RelocInfo::kNoPosition), | |
| 1147 current_statement_position_(RelocInfo::kNoPosition), | |
| 1148 written_statement_position_(RelocInfo::kNoPosition) {} | |
| 1149 | |
| 1150 // Set current position to pos. | |
| 1151 void RecordPosition(int pos); | |
| 1152 | |
| 1153 // Set current statement position to pos. | |
| 1154 void RecordStatementPosition(int pos); | |
| 1155 | |
| 1156 private: | |
| 1157 // Write recorded positions to relocation information. | |
| 1158 void WriteRecordedPositions(); | |
| 1159 | |
| 1160 Assembler* assembler_; | |
| 1161 | |
| 1162 int current_position_; | |
| 1163 int written_position_; | |
| 1164 | |
| 1165 int current_statement_position_; | |
| 1166 int written_statement_position_; | |
| 1167 | |
| 1168 DISALLOW_COPY_AND_ASSIGN(AssemblerPositionsRecorder); | |
| 1169 }; | |
| 1170 | |
| 1171 | |
| 1172 // ----------------------------------------------------------------------------- | 1103 // ----------------------------------------------------------------------------- |
| 1173 // Utility functions | 1104 // Utility functions |
| 1174 | 1105 |
| 1175 inline int NumberOfBitsSet(uint32_t x) { | 1106 inline int NumberOfBitsSet(uint32_t x) { |
| 1176 unsigned int num_bits_set; | 1107 unsigned int num_bits_set; |
| 1177 for (num_bits_set = 0; x; x >>= 1) { | 1108 for (num_bits_set = 0; x; x >>= 1) { |
| 1178 num_bits_set += x & 1; | 1109 num_bits_set += x & 1; |
| 1179 } | 1110 } |
| 1180 return num_bits_set; | 1111 return num_bits_set; |
| 1181 } | 1112 } |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1336 std::vector<ConstantPoolEntry> shared_entries; | 1267 std::vector<ConstantPoolEntry> shared_entries; |
| 1337 }; | 1268 }; |
| 1338 | 1269 |
| 1339 Label emitted_label_; // Records pc_offset of emitted pool | 1270 Label emitted_label_; // Records pc_offset of emitted pool |
| 1340 PerTypeEntryInfo info_[ConstantPoolEntry::NUMBER_OF_TYPES]; | 1271 PerTypeEntryInfo info_[ConstantPoolEntry::NUMBER_OF_TYPES]; |
| 1341 }; | 1272 }; |
| 1342 | 1273 |
| 1343 } // namespace internal | 1274 } // namespace internal |
| 1344 } // namespace v8 | 1275 } // namespace v8 |
| 1345 #endif // V8_ASSEMBLER_H_ | 1276 #endif // V8_ASSEMBLER_H_ |
| OLD | NEW |