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 | 5 // modification, are permitted provided that the following conditions |
6 // are met: | 6 // are 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 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
688 // for a detailed comment on the layout (globals.h). | 688 // for a detailed comment on the layout (globals.h). |
689 // | 689 // |
690 // If the provided buffer is NULL, the assembler allocates and grows its own | 690 // If the provided buffer is NULL, the assembler allocates and grows its own |
691 // buffer, and buffer_size determines the initial buffer size. The buffer is | 691 // buffer, and buffer_size determines the initial buffer size. The buffer is |
692 // owned by the assembler and deallocated upon destruction of the assembler. | 692 // owned by the assembler and deallocated upon destruction of the assembler. |
693 // | 693 // |
694 // If the provided buffer is not NULL, the assembler uses the provided buffer | 694 // If the provided buffer is not NULL, the assembler uses the provided buffer |
695 // for code generation and assumes its size to be buffer_size. If the buffer | 695 // for code generation and assumes its size to be buffer_size. If the buffer |
696 // is too small, a fatal error occurs. No deallocation of the buffer is done | 696 // is too small, a fatal error occurs. No deallocation of the buffer is done |
697 // upon destruction of the assembler. | 697 // upon destruction of the assembler. |
698 Assembler(Isolate* isolate, void* buffer, int buffer_size); | 698 Assembler(Isolate* isolate, void* buffer, int buffer_size) |
| 699 : Assembler(IsolateData(isolate), buffer, buffer_size) {} |
| 700 Assembler(IsolateData isolate_data, void* buffer, int buffer_size); |
699 virtual ~Assembler(); | 701 virtual ~Assembler(); |
700 | 702 |
701 // GetCode emits any pending (non-emitted) code and fills the descriptor | 703 // GetCode emits any pending (non-emitted) code and fills the descriptor |
702 // desc. GetCode() is idempotent; it returns the same result if no other | 704 // desc. GetCode() is idempotent; it returns the same result if no other |
703 // Assembler functions are invoked in between GetCode() calls. | 705 // Assembler functions are invoked in between GetCode() calls. |
704 void GetCode(CodeDesc* desc); | 706 void GetCode(CodeDesc* desc); |
705 | 707 |
706 // Label operations & relative jumps (PPUM Appendix D) | 708 // Label operations & relative jumps (PPUM Appendix D) |
707 // | 709 // |
708 // Takes a branch opcode (cc) and a label (L) and generates | 710 // Takes a branch opcode (cc) and a label (L) and generates |
(...skipping 19 matching lines...) Expand all Loading... |
728 // Returns true if the given pc address is the start of a constant pool load | 730 // Returns true if the given pc address is the start of a constant pool load |
729 // instruction sequence. | 731 // instruction sequence. |
730 INLINE(static bool is_constant_pool_load(Address pc)); | 732 INLINE(static bool is_constant_pool_load(Address pc)); |
731 | 733 |
732 // Return the address in the constant pool of the code target address used by | 734 // Return the address in the constant pool of the code target address used by |
733 // the branch/call instruction at pc, or the object in a mov. | 735 // the branch/call instruction at pc, or the object in a mov. |
734 INLINE(static Address constant_pool_entry_address(Address pc, | 736 INLINE(static Address constant_pool_entry_address(Address pc, |
735 Address constant_pool)); | 737 Address constant_pool)); |
736 | 738 |
737 // Read/Modify the code target address in the branch/call instruction at pc. | 739 // Read/Modify the code target address in the branch/call instruction at pc. |
| 740 // The isolate argument is unused (and may be nullptr) when skipping flushing. |
738 INLINE(static Address target_address_at(Address pc, Address constant_pool)); | 741 INLINE(static Address target_address_at(Address pc, Address constant_pool)); |
739 INLINE(static void set_target_address_at( | 742 INLINE(static void set_target_address_at( |
740 Isolate* isolate, Address pc, Address constant_pool, Address target, | 743 Isolate* isolate, Address pc, Address constant_pool, Address target, |
741 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)); | 744 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)); |
742 INLINE(static Address target_address_at(Address pc, Code* code)); | 745 INLINE(static Address target_address_at(Address pc, Code* code)); |
743 INLINE(static void set_target_address_at( | 746 INLINE(static void set_target_address_at( |
744 Isolate* isolate, Address pc, Code* code, Address target, | 747 Isolate* isolate, Address pc, Code* code, Address target, |
745 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)); | 748 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)); |
746 | 749 |
747 // Return the code target address at a call site from the return address | 750 // Return the code target address at a call site from the return address |
(...skipping 944 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1692 return IsEnabled(VFP32DREGS) || | 1695 return IsEnabled(VFP32DREGS) || |
1693 (reg.reg_code < LowDwVfpRegister::kMaxNumLowRegisters); | 1696 (reg.reg_code < LowDwVfpRegister::kMaxNumLowRegisters); |
1694 } | 1697 } |
1695 | 1698 |
1696 bool VfpRegisterIsAvailable(QwNeonRegister reg) { | 1699 bool VfpRegisterIsAvailable(QwNeonRegister reg) { |
1697 DCHECK(reg.is_valid()); | 1700 DCHECK(reg.is_valid()); |
1698 return IsEnabled(VFP32DREGS) || | 1701 return IsEnabled(VFP32DREGS) || |
1699 (reg.reg_code < LowDwVfpRegister::kMaxNumLowRegisters / 2); | 1702 (reg.reg_code < LowDwVfpRegister::kMaxNumLowRegisters / 2); |
1700 } | 1703 } |
1701 | 1704 |
1702 private: | 1705 inline void emit(Instr x); |
1703 int next_buffer_check_; // pc offset of next buffer check | |
1704 | 1706 |
1705 // Code generation | 1707 // Code generation |
1706 // The relocation writer's position is at least kGap bytes below the end of | 1708 // The relocation writer's position is at least kGap bytes below the end of |
1707 // the generated instructions. This is so that multi-instruction sequences do | 1709 // the generated instructions. This is so that multi-instruction sequences do |
1708 // not have to check for overflow. The same is true for writes of large | 1710 // not have to check for overflow. The same is true for writes of large |
1709 // relocation info entries. | 1711 // relocation info entries. |
1710 static constexpr int kGap = 32; | 1712 static constexpr int kGap = 32; |
1711 | 1713 |
| 1714 // Relocation info generation |
| 1715 // Each relocation is encoded as a variable size value |
| 1716 static constexpr int kMaxRelocSize = RelocInfoWriter::kMaxSize; |
| 1717 RelocInfoWriter reloc_info_writer; |
| 1718 |
| 1719 // ConstantPoolEntry records are used during code generation as temporary |
| 1720 // containers for constants and code target addresses until they are emitted |
| 1721 // to the constant pool. These records are temporarily stored in a separate |
| 1722 // buffer until a constant pool is emitted. |
| 1723 // If every instruction in a long sequence is accessing the pool, we need one |
| 1724 // pending relocation entry per instruction. |
| 1725 |
| 1726 // The buffers of pending constant pool entries. |
| 1727 std::vector<ConstantPoolEntry> pending_32_bit_constants_; |
| 1728 std::vector<ConstantPoolEntry> pending_64_bit_constants_; |
| 1729 |
| 1730 private: |
| 1731 int next_buffer_check_; // pc offset of next buffer check |
| 1732 |
1712 // Constant pool generation | 1733 // Constant pool generation |
1713 // Pools are emitted in the instruction stream, preferably after unconditional | 1734 // Pools are emitted in the instruction stream, preferably after unconditional |
1714 // jumps or after returns from functions (in dead code locations). | 1735 // jumps or after returns from functions (in dead code locations). |
1715 // If a long code sequence does not contain unconditional jumps, it is | 1736 // If a long code sequence does not contain unconditional jumps, it is |
1716 // necessary to emit the constant pool before the pool gets too far from the | 1737 // necessary to emit the constant pool before the pool gets too far from the |
1717 // location it is accessed from. In this case, we emit a jump over the emitted | 1738 // location it is accessed from. In this case, we emit a jump over the emitted |
1718 // constant pool. | 1739 // constant pool. |
1719 // Constants in the pool may be addresses of functions that gets relocated; | 1740 // Constants in the pool may be addresses of functions that gets relocated; |
1720 // if so, a relocation info entry is associated to the constant pool entry. | 1741 // if so, a relocation info entry is associated to the constant pool entry. |
1721 | 1742 |
1722 // Repeated checking whether the constant pool should be emitted is rather | 1743 // Repeated checking whether the constant pool should be emitted is rather |
1723 // expensive. By default we only check again once a number of instructions | 1744 // expensive. By default we only check again once a number of instructions |
1724 // has been generated. That also means that the sizing of the buffers is not | 1745 // has been generated. That also means that the sizing of the buffers is not |
1725 // an exact science, and that we rely on some slop to not overrun buffers. | 1746 // an exact science, and that we rely on some slop to not overrun buffers. |
1726 static constexpr int kCheckPoolIntervalInst = 32; | 1747 static constexpr int kCheckPoolIntervalInst = 32; |
1727 static constexpr int kCheckPoolInterval = kCheckPoolIntervalInst * kInstrSize; | 1748 static constexpr int kCheckPoolInterval = kCheckPoolIntervalInst * kInstrSize; |
1728 | 1749 |
1729 | 1750 |
1730 // Emission of the constant pool may be blocked in some code sequences. | 1751 // Emission of the constant pool may be blocked in some code sequences. |
1731 int const_pool_blocked_nesting_; // Block emission if this is not zero. | 1752 int const_pool_blocked_nesting_; // Block emission if this is not zero. |
1732 int no_const_pool_before_; // Block emission before this pc offset. | 1753 int no_const_pool_before_; // Block emission before this pc offset. |
1733 | 1754 |
1734 // Keep track of the first instruction requiring a constant pool entry | 1755 // Keep track of the first instruction requiring a constant pool entry |
1735 // since the previous constant pool was emitted. | 1756 // since the previous constant pool was emitted. |
1736 int first_const_pool_32_use_; | 1757 int first_const_pool_32_use_; |
1737 int first_const_pool_64_use_; | 1758 int first_const_pool_64_use_; |
1738 | 1759 |
1739 // Relocation info generation | |
1740 // Each relocation is encoded as a variable size value | |
1741 static constexpr int kMaxRelocSize = RelocInfoWriter::kMaxSize; | |
1742 RelocInfoWriter reloc_info_writer; | |
1743 | |
1744 // ConstantPoolEntry records are used during code generation as temporary | |
1745 // containers for constants and code target addresses until they are emitted | |
1746 // to the constant pool. These records are temporarily stored in a separate | |
1747 // buffer until a constant pool is emitted. | |
1748 // If every instruction in a long sequence is accessing the pool, we need one | |
1749 // pending relocation entry per instruction. | |
1750 | |
1751 // The buffers of pending constant pool entries. | |
1752 std::vector<ConstantPoolEntry> pending_32_bit_constants_; | |
1753 std::vector<ConstantPoolEntry> pending_64_bit_constants_; | |
1754 | |
1755 ConstantPoolBuilder constant_pool_builder_; | 1760 ConstantPoolBuilder constant_pool_builder_; |
1756 | 1761 |
1757 // The bound position, before this we cannot do instruction elimination. | 1762 // The bound position, before this we cannot do instruction elimination. |
1758 int last_bound_pos_; | 1763 int last_bound_pos_; |
1759 | 1764 |
1760 // Code emission | |
1761 inline void CheckBuffer(); | 1765 inline void CheckBuffer(); |
1762 void GrowBuffer(); | 1766 void GrowBuffer(); |
1763 inline void emit(Instr x); | |
1764 | 1767 |
1765 // 32-bit immediate values | 1768 // 32-bit immediate values |
1766 void move_32_bit_immediate(Register rd, | 1769 void move_32_bit_immediate(Register rd, |
1767 const Operand& x, | 1770 const Operand& x, |
1768 Condition cond = al); | 1771 Condition cond = al); |
1769 | 1772 |
1770 // Instruction generation | 1773 // Instruction generation |
1771 void addrmod1(Instr instr, Register rn, Register rd, const Operand& x); | 1774 void addrmod1(Instr instr, Register rn, Register rd, const Operand& x); |
1772 void addrmod2(Instr instr, Register rd, const MemOperand& x); | 1775 void addrmod2(Instr instr, Register rd, const MemOperand& x); |
1773 void addrmod3(Instr instr, Register rd, const MemOperand& x); | 1776 void addrmod3(Instr instr, Register rd, const MemOperand& x); |
(...skipping 18 matching lines...) Expand all Loading... |
1792 friend class EnsureSpace; | 1795 friend class EnsureSpace; |
1793 }; | 1796 }; |
1794 | 1797 |
1795 constexpr int kNoCodeAgeSequenceLength = 3 * Assembler::kInstrSize; | 1798 constexpr int kNoCodeAgeSequenceLength = 3 * Assembler::kInstrSize; |
1796 | 1799 |
1797 class EnsureSpace BASE_EMBEDDED { | 1800 class EnsureSpace BASE_EMBEDDED { |
1798 public: | 1801 public: |
1799 INLINE(explicit EnsureSpace(Assembler* assembler)); | 1802 INLINE(explicit EnsureSpace(Assembler* assembler)); |
1800 }; | 1803 }; |
1801 | 1804 |
| 1805 class PatchingAssembler : public Assembler { |
| 1806 public: |
| 1807 PatchingAssembler(IsolateData isolate_data, byte* address, int instructions); |
| 1808 ~PatchingAssembler(); |
| 1809 |
| 1810 void Emit(Address addr); |
| 1811 void FlushICache(Isolate* isolate); |
| 1812 }; |
| 1813 |
1802 | 1814 |
1803 } // namespace internal | 1815 } // namespace internal |
1804 } // namespace v8 | 1816 } // namespace v8 |
1805 | 1817 |
1806 #endif // V8_ARM_ASSEMBLER_ARM_H_ | 1818 #endif // V8_ARM_ASSEMBLER_ARM_H_ |
OLD | NEW |