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 |