| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_ARM64_ASSEMBLER_ARM64_H_ | 5 #ifndef V8_ARM64_ASSEMBLER_ARM64_H_ |
| 6 #define V8_ARM64_ASSEMBLER_ARM64_H_ | 6 #define V8_ARM64_ASSEMBLER_ARM64_H_ |
| 7 | 7 |
| 8 #include <deque> | 8 #include <deque> |
| 9 #include <list> | 9 #include <list> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 // for a detailed comment on the layout (globals.h). | 710 // for a detailed comment on the layout (globals.h). |
| 711 // | 711 // |
| 712 // If the provided buffer is NULL, the assembler allocates and grows its own | 712 // If the provided buffer is NULL, the assembler allocates and grows its own |
| 713 // buffer, and buffer_size determines the initial buffer size. The buffer is | 713 // buffer, and buffer_size determines the initial buffer size. The buffer is |
| 714 // owned by the assembler and deallocated upon destruction of the assembler. | 714 // owned by the assembler and deallocated upon destruction of the assembler. |
| 715 // | 715 // |
| 716 // If the provided buffer is not NULL, the assembler uses the provided buffer | 716 // If the provided buffer is not NULL, the assembler uses the provided buffer |
| 717 // for code generation and assumes its size to be buffer_size. If the buffer | 717 // for code generation and assumes its size to be buffer_size. If the buffer |
| 718 // is too small, a fatal error occurs. No deallocation of the buffer is done | 718 // is too small, a fatal error occurs. No deallocation of the buffer is done |
| 719 // upon destruction of the assembler. | 719 // upon destruction of the assembler. |
| 720 Assembler(Isolate* arg_isolate, void* buffer, int buffer_size); | 720 Assembler(Isolate* isolate, void* buffer, int buffer_size) |
| 721 : Assembler(IsolateData(isolate), buffer, buffer_size) {} |
| 722 Assembler(IsolateData isolate_data, void* buffer, int buffer_size); |
| 721 | 723 |
| 722 virtual ~Assembler(); | 724 virtual ~Assembler(); |
| 723 | 725 |
| 724 virtual void AbortedCodeGeneration() { | 726 virtual void AbortedCodeGeneration() { |
| 725 constpool_.Clear(); | 727 constpool_.Clear(); |
| 726 } | 728 } |
| 727 | 729 |
| 728 // System functions --------------------------------------------------------- | 730 // System functions --------------------------------------------------------- |
| 729 // Start generating code from the beginning of the buffer, discarding any code | 731 // Start generating code from the beginning of the buffer, discarding any code |
| 730 // and data that has already been emitted into the buffer. | 732 // and data that has already been emitted into the buffer. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 761 // RelocInfo and pools ------------------------------------------------------ | 763 // RelocInfo and pools ------------------------------------------------------ |
| 762 | 764 |
| 763 // Record relocation information for current pc_. | 765 // Record relocation information for current pc_. |
| 764 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); | 766 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); |
| 765 | 767 |
| 766 // Return the address in the constant pool of the code target address used by | 768 // Return the address in the constant pool of the code target address used by |
| 767 // the branch/call instruction at pc. | 769 // the branch/call instruction at pc. |
| 768 inline static Address target_pointer_address_at(Address pc); | 770 inline static Address target_pointer_address_at(Address pc); |
| 769 | 771 |
| 770 // Read/Modify the code target address in the branch/call instruction at pc. | 772 // Read/Modify the code target address in the branch/call instruction at pc. |
| 773 // The isolate argument is unused (and may be nullptr) when skipping flushing. |
| 771 inline static Address target_address_at(Address pc, Address constant_pool); | 774 inline static Address target_address_at(Address pc, Address constant_pool); |
| 772 inline static void set_target_address_at( | 775 inline static void set_target_address_at( |
| 773 Isolate* isolate, Address pc, Address constant_pool, Address target, | 776 Isolate* isolate, Address pc, Address constant_pool, Address target, |
| 774 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED); | 777 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED); |
| 775 static inline Address target_address_at(Address pc, Code* code); | 778 static inline Address target_address_at(Address pc, Code* code); |
| 776 static inline void set_target_address_at( | 779 static inline void set_target_address_at( |
| 777 Isolate* isolate, Address pc, Code* code, Address target, | 780 Isolate* isolate, Address pc, Code* code, Address target, |
| 778 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED); | 781 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED); |
| 779 | 782 |
| 780 // Return the code target address at a call site from the return address of | 783 // Return the code target address at a call site from the return address of |
| (...skipping 1257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2038 int const_pool_blocked_nesting_; // Block emission if this is not zero. | 2041 int const_pool_blocked_nesting_; // Block emission if this is not zero. |
| 2039 int no_const_pool_before_; // Block emission before this pc offset. | 2042 int no_const_pool_before_; // Block emission before this pc offset. |
| 2040 | 2043 |
| 2041 // Emission of the veneer pools may be blocked in some code sequences. | 2044 // Emission of the veneer pools may be blocked in some code sequences. |
| 2042 int veneer_pool_blocked_nesting_; // Block emission if this is not zero. | 2045 int veneer_pool_blocked_nesting_; // Block emission if this is not zero. |
| 2043 | 2046 |
| 2044 // Relocation info generation | 2047 // Relocation info generation |
| 2045 // Each relocation is encoded as a variable size value | 2048 // Each relocation is encoded as a variable size value |
| 2046 static constexpr int kMaxRelocSize = RelocInfoWriter::kMaxSize; | 2049 static constexpr int kMaxRelocSize = RelocInfoWriter::kMaxSize; |
| 2047 RelocInfoWriter reloc_info_writer; | 2050 RelocInfoWriter reloc_info_writer; |
| 2051 |
| 2048 // Internal reference positions, required for (potential) patching in | 2052 // Internal reference positions, required for (potential) patching in |
| 2049 // GrowBuffer(); contains only those internal references whose labels | 2053 // GrowBuffer(); contains only those internal references whose labels |
| 2050 // are already bound. | 2054 // are already bound. |
| 2051 std::deque<int> internal_reference_positions_; | 2055 std::deque<int> internal_reference_positions_; |
| 2052 | 2056 |
| 2053 // Relocation info records are also used during code generation as temporary | 2057 // Relocation info records are also used during code generation as temporary |
| 2054 // containers for constants and code target addresses until they are emitted | 2058 // containers for constants and code target addresses until they are emitted |
| 2055 // to the constant pool. These pending relocation info records are temporarily | 2059 // to the constant pool. These pending relocation info records are temporarily |
| 2056 // stored in a separate buffer until a constant pool is emitted. | 2060 // stored in a separate buffer until a constant pool is emitted. |
| 2057 // If every instruction in a long sequence is accessing the pool, we need one | 2061 // If every instruction in a long sequence is accessing the pool, we need one |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2149 class PatchingAssembler : public Assembler { | 2153 class PatchingAssembler : public Assembler { |
| 2150 public: | 2154 public: |
| 2151 // Create an Assembler with a buffer starting at 'start'. | 2155 // Create an Assembler with a buffer starting at 'start'. |
| 2152 // The buffer size is | 2156 // The buffer size is |
| 2153 // size of instructions to patch + kGap | 2157 // size of instructions to patch + kGap |
| 2154 // Where kGap is the distance from which the Assembler tries to grow the | 2158 // Where kGap is the distance from which the Assembler tries to grow the |
| 2155 // buffer. | 2159 // buffer. |
| 2156 // If more or fewer instructions than expected are generated or if some | 2160 // If more or fewer instructions than expected are generated or if some |
| 2157 // relocation information takes space in the buffer, the PatchingAssembler | 2161 // relocation information takes space in the buffer, the PatchingAssembler |
| 2158 // will crash trying to grow the buffer. | 2162 // will crash trying to grow the buffer. |
| 2159 PatchingAssembler(Isolate* isolate, Instruction* start, unsigned count) | 2163 |
| 2160 : Assembler(isolate, reinterpret_cast<byte*>(start), | 2164 // This version will flush at destruction. |
| 2161 count * kInstructionSize + kGap) { | 2165 PatchingAssembler(Isolate* isolate, byte* start, unsigned count) |
| 2162 StartBlockPools(); | 2166 : PatchingAssembler(IsolateData(isolate), start, count) { |
| 2167 CHECK_NOT_NULL(isolate); |
| 2168 isolate_ = isolate; |
| 2163 } | 2169 } |
| 2164 | 2170 |
| 2165 PatchingAssembler(Isolate* isolate, byte* start, unsigned count) | 2171 // This version will not flush. |
| 2166 : Assembler(isolate, start, count * kInstructionSize + kGap) { | 2172 PatchingAssembler(IsolateData isolate_data, byte* start, unsigned count) |
| 2173 : Assembler(isolate_data, start, count * kInstructionSize + kGap), |
| 2174 isolate_(nullptr) { |
| 2167 // Block constant pool emission. | 2175 // Block constant pool emission. |
| 2168 StartBlockPools(); | 2176 StartBlockPools(); |
| 2169 } | 2177 } |
| 2170 | 2178 |
| 2171 ~PatchingAssembler() { | 2179 ~PatchingAssembler() { |
| 2172 // Const pool should still be blocked. | 2180 // Const pool should still be blocked. |
| 2173 DCHECK(is_const_pool_blocked()); | 2181 DCHECK(is_const_pool_blocked()); |
| 2174 EndBlockPools(); | 2182 EndBlockPools(); |
| 2175 // Verify we have generated the number of instruction we expected. | 2183 // Verify we have generated the number of instruction we expected. |
| 2176 DCHECK((pc_offset() + kGap) == buffer_size_); | 2184 DCHECK((pc_offset() + kGap) == buffer_size_); |
| 2177 // Verify no relocation information has been emitted. | 2185 // Verify no relocation information has been emitted. |
| 2178 DCHECK(IsConstPoolEmpty()); | 2186 DCHECK(IsConstPoolEmpty()); |
| 2179 // Flush the Instruction cache. | 2187 // Flush the Instruction cache. |
| 2180 size_t length = buffer_size_ - kGap; | 2188 size_t length = buffer_size_ - kGap; |
| 2181 Assembler::FlushICache(isolate(), buffer_, length); | 2189 if (isolate_ != nullptr) Assembler::FlushICache(isolate_, buffer_, length); |
| 2182 } | 2190 } |
| 2183 | 2191 |
| 2184 // See definition of PatchAdrFar() for details. | 2192 // See definition of PatchAdrFar() for details. |
| 2185 static constexpr int kAdrFarPatchableNNops = 2; | 2193 static constexpr int kAdrFarPatchableNNops = 2; |
| 2186 static constexpr int kAdrFarPatchableNInstrs = kAdrFarPatchableNNops + 2; | 2194 static constexpr int kAdrFarPatchableNInstrs = kAdrFarPatchableNNops + 2; |
| 2187 void PatchAdrFar(int64_t target_offset); | 2195 void PatchAdrFar(int64_t target_offset); |
| 2196 |
| 2197 private: |
| 2198 Isolate* isolate_; |
| 2188 }; | 2199 }; |
| 2189 | 2200 |
| 2190 | 2201 |
| 2191 class EnsureSpace BASE_EMBEDDED { | 2202 class EnsureSpace BASE_EMBEDDED { |
| 2192 public: | 2203 public: |
| 2193 explicit EnsureSpace(Assembler* assembler) { | 2204 explicit EnsureSpace(Assembler* assembler) { |
| 2194 assembler->CheckBufferSpace(); | 2205 assembler->CheckBufferSpace(); |
| 2195 } | 2206 } |
| 2196 }; | 2207 }; |
| 2197 | 2208 |
| 2198 } // namespace internal | 2209 } // namespace internal |
| 2199 } // namespace v8 | 2210 } // namespace v8 |
| 2200 | 2211 |
| 2201 #endif // V8_ARM64_ASSEMBLER_ARM64_H_ | 2212 #endif // V8_ARM64_ASSEMBLER_ARM64_H_ |
| OLD | NEW |