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 |