| 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 |