OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #include "src/x64/assembler-x64.h" | 5 #include "src/x64/assembler-x64.h" |
6 | 6 |
7 #include <cstring> | 7 #include <cstring> |
8 | 8 |
9 #if V8_TARGET_ARCH_X64 | 9 #if V8_TARGET_ARCH_X64 |
10 | 10 |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 DCHECK(IsWasmMemorySizeReference(rmode_)); | 136 DCHECK(IsWasmMemorySizeReference(rmode_)); |
137 return Memory::uint32_at(pc_); | 137 return Memory::uint32_at(pc_); |
138 } | 138 } |
139 | 139 |
140 uint32_t RelocInfo::wasm_function_table_size_reference() { | 140 uint32_t RelocInfo::wasm_function_table_size_reference() { |
141 DCHECK(IsWasmFunctionTableSizeReference(rmode_)); | 141 DCHECK(IsWasmFunctionTableSizeReference(rmode_)); |
142 return Memory::uint32_at(pc_); | 142 return Memory::uint32_at(pc_); |
143 } | 143 } |
144 | 144 |
145 void RelocInfo::unchecked_update_wasm_memory_reference( | 145 void RelocInfo::unchecked_update_wasm_memory_reference( |
146 Address address, ICacheFlushMode icache_flush_mode) { | 146 Isolate* isolate, Address address, ICacheFlushMode icache_flush_mode) { |
147 Memory::Address_at(pc_) = address; | 147 Memory::Address_at(pc_) = address; |
148 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 148 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
149 Assembler::FlushICache(isolate_, pc_, sizeof(Address)); | 149 Assembler::FlushICache(isolate, pc_, sizeof(Address)); |
150 } | 150 } |
151 } | 151 } |
152 | 152 |
153 void RelocInfo::unchecked_update_wasm_size(uint32_t size, | 153 void RelocInfo::unchecked_update_wasm_size(Isolate* isolate, uint32_t size, |
154 ICacheFlushMode icache_flush_mode) { | 154 ICacheFlushMode icache_flush_mode) { |
155 Memory::uint32_at(pc_) = size; | 155 Memory::uint32_at(pc_) = size; |
156 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 156 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
157 Assembler::FlushICache(isolate_, pc_, sizeof(uint32_t)); | 157 Assembler::FlushICache(isolate, pc_, sizeof(uint32_t)); |
158 } | 158 } |
159 } | 159 } |
160 | 160 |
161 // ----------------------------------------------------------------------------- | 161 // ----------------------------------------------------------------------------- |
162 // Implementation of Operand | 162 // Implementation of Operand |
163 | 163 |
164 Operand::Operand(Register base, int32_t disp) : rex_(0) { | 164 Operand::Operand(Register base, int32_t disp) : rex_(0) { |
165 len_ = 1; | 165 len_ = 1; |
166 if (base.is(rsp) || base.is(r12)) { | 166 if (base.is(rsp) || base.is(r12)) { |
167 // SIB byte is needed to encode (rsp + offset) or (r12 + offset). | 167 // SIB byte is needed to encode (rsp + offset) or (r12 + offset). |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 return code == base_code; | 285 return code == base_code; |
286 } else { | 286 } else { |
287 // A base register with low bits of 0x05 (rbp or r13) and mod = 0 means | 287 // A base register with low bits of 0x05 (rbp or r13) and mod = 0 means |
288 // no base register. | 288 // no base register. |
289 if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false; | 289 if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false; |
290 base_code |= ((rex_ & 0x01) << 3); | 290 base_code |= ((rex_ & 0x01) << 3); |
291 return code == base_code; | 291 return code == base_code; |
292 } | 292 } |
293 } | 293 } |
294 | 294 |
295 | |
296 // ----------------------------------------------------------------------------- | 295 // ----------------------------------------------------------------------------- |
297 // Implementation of Assembler. | 296 // Implementation of Assembler. |
298 | 297 |
299 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) | 298 Assembler::Assembler(IsolateData isolate_data, void* buffer, int buffer_size) |
300 : AssemblerBase(isolate, buffer, buffer_size), code_targets_(100) { | 299 : AssemblerBase(isolate_data, buffer, buffer_size), code_targets_(100) { |
301 // Clear the buffer in debug mode unless it was provided by the | 300 // Clear the buffer in debug mode unless it was provided by the |
302 // caller in which case we can't be sure it's okay to overwrite | 301 // caller in which case we can't be sure it's okay to overwrite |
303 // existing code in it. | 302 // existing code in it. |
304 #ifdef DEBUG | 303 #ifdef DEBUG |
305 if (own_buffer_) { | 304 if (own_buffer_) { |
306 memset(buffer_, 0xCC, buffer_size_); // int3 | 305 memset(buffer_, 0xCC, buffer_size_); // int3 |
307 } | 306 } |
308 #endif | 307 #endif |
309 | 308 |
310 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); | 309 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 if (!own_buffer_) FATAL("external code buffer is too small"); | 409 if (!own_buffer_) FATAL("external code buffer is too small"); |
411 | 410 |
412 // Compute new buffer size. | 411 // Compute new buffer size. |
413 CodeDesc desc; // the new buffer | 412 CodeDesc desc; // the new buffer |
414 desc.buffer_size = 2 * buffer_size_; | 413 desc.buffer_size = 2 * buffer_size_; |
415 | 414 |
416 // Some internal data structures overflow for very large buffers, | 415 // Some internal data structures overflow for very large buffers, |
417 // they must ensure that kMaximalBufferSize is not too large. | 416 // they must ensure that kMaximalBufferSize is not too large. |
418 if (desc.buffer_size > kMaximalBufferSize || | 417 if (desc.buffer_size > kMaximalBufferSize || |
419 static_cast<size_t>(desc.buffer_size) > | 418 static_cast<size_t>(desc.buffer_size) > |
420 isolate()->heap()->MaxOldGenerationSize()) { | 419 isolate_data().max_old_generation_size_) { |
421 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer"); | 420 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer"); |
422 } | 421 } |
423 | 422 |
424 // Set up new buffer. | 423 // Set up new buffer. |
425 desc.buffer = NewArray<byte>(desc.buffer_size); | 424 desc.buffer = NewArray<byte>(desc.buffer_size); |
426 desc.origin = this; | 425 desc.origin = this; |
427 desc.instr_size = pc_offset(); | 426 desc.instr_size = pc_offset(); |
428 desc.reloc_size = | 427 desc.reloc_size = |
429 static_cast<int>((buffer_ + buffer_size_) - (reloc_info_writer.pos())); | 428 static_cast<int>((buffer_ + buffer_size_) - (reloc_info_writer.pos())); |
430 | 429 |
(...skipping 4232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4663 void Assembler::emit_sse_operand(Register dst, XMMRegister src) { | 4662 void Assembler::emit_sse_operand(Register dst, XMMRegister src) { |
4664 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); | 4663 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); |
4665 } | 4664 } |
4666 | 4665 |
4667 void Assembler::emit_sse_operand(XMMRegister dst) { | 4666 void Assembler::emit_sse_operand(XMMRegister dst) { |
4668 emit(0xD8 | dst.low_bits()); | 4667 emit(0xD8 | dst.low_bits()); |
4669 } | 4668 } |
4670 | 4669 |
4671 void Assembler::RecordProtectedInstructionLanding(int pc_offset) { | 4670 void Assembler::RecordProtectedInstructionLanding(int pc_offset) { |
4672 EnsureSpace ensure_space(this); | 4671 EnsureSpace ensure_space(this); |
4673 RelocInfo rinfo(isolate(), pc(), | 4672 RelocInfo rinfo(pc(), RelocInfo::WASM_PROTECTED_INSTRUCTION_LANDING, |
4674 RelocInfo::WASM_PROTECTED_INSTRUCTION_LANDING, pc_offset, | 4673 pc_offset, nullptr); |
4675 nullptr); | |
4676 reloc_info_writer.Write(&rinfo); | 4674 reloc_info_writer.Write(&rinfo); |
4677 } | 4675 } |
4678 | 4676 |
4679 | 4677 |
4680 void Assembler::db(uint8_t data) { | 4678 void Assembler::db(uint8_t data) { |
4681 EnsureSpace ensure_space(this); | 4679 EnsureSpace ensure_space(this); |
4682 emit(data); | 4680 emit(data); |
4683 } | 4681 } |
4684 | 4682 |
4685 | 4683 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4721 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { | 4719 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { |
4722 DCHECK(!RelocInfo::IsNone(rmode)); | 4720 DCHECK(!RelocInfo::IsNone(rmode)); |
4723 // Don't record external references unless the heap will be serialized. | 4721 // Don't record external references unless the heap will be serialized. |
4724 if (rmode == RelocInfo::EXTERNAL_REFERENCE && | 4722 if (rmode == RelocInfo::EXTERNAL_REFERENCE && |
4725 !serializer_enabled() && !emit_debug_code()) { | 4723 !serializer_enabled() && !emit_debug_code()) { |
4726 return; | 4724 return; |
4727 } else if (rmode == RelocInfo::CODE_AGE_SEQUENCE) { | 4725 } else if (rmode == RelocInfo::CODE_AGE_SEQUENCE) { |
4728 // Don't record psuedo relocation info for code age sequence mode. | 4726 // Don't record psuedo relocation info for code age sequence mode. |
4729 return; | 4727 return; |
4730 } | 4728 } |
4731 RelocInfo rinfo(isolate(), pc_, rmode, data, NULL); | 4729 RelocInfo rinfo(pc_, rmode, data, NULL); |
4732 reloc_info_writer.Write(&rinfo); | 4730 reloc_info_writer.Write(&rinfo); |
4733 } | 4731 } |
4734 | 4732 |
4735 | 4733 |
4736 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask | | 4734 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask | |
4737 1 << RelocInfo::RUNTIME_ENTRY | | 4735 1 << RelocInfo::RUNTIME_ENTRY | |
4738 1 << RelocInfo::INTERNAL_REFERENCE | | 4736 1 << RelocInfo::INTERNAL_REFERENCE | |
4739 1 << RelocInfo::CODE_AGE_SEQUENCE; | 4737 1 << RelocInfo::CODE_AGE_SEQUENCE; |
4740 | 4738 |
4741 | 4739 |
4742 bool RelocInfo::IsCodedSpecially() { | 4740 bool RelocInfo::IsCodedSpecially() { |
4743 // The deserializer needs to know whether a pointer is specially coded. Being | 4741 // The deserializer needs to know whether a pointer is specially coded. Being |
4744 // specially coded on x64 means that it is a relative 32 bit address, as used | 4742 // specially coded on x64 means that it is a relative 32 bit address, as used |
4745 // by branch instructions. | 4743 // by branch instructions. |
4746 return (1 << rmode_) & kApplyMask; | 4744 return (1 << rmode_) & kApplyMask; |
4747 } | 4745 } |
4748 | 4746 |
4749 | 4747 |
4750 bool RelocInfo::IsInConstantPool() { | 4748 bool RelocInfo::IsInConstantPool() { |
4751 return false; | 4749 return false; |
4752 } | 4750 } |
4753 | 4751 |
4754 | 4752 |
4755 } // namespace internal | 4753 } // namespace internal |
4756 } // namespace v8 | 4754 } // namespace v8 |
4757 | 4755 |
4758 #endif // V8_TARGET_ARCH_X64 | 4756 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |