diff options
Diffstat (limited to 'deps/v8/src/ia32/assembler-ia32.cc')
-rw-r--r-- | deps/v8/src/ia32/assembler-ia32.cc | 176 |
1 files changed, 45 insertions, 131 deletions
diff --git a/deps/v8/src/ia32/assembler-ia32.cc b/deps/v8/src/ia32/assembler-ia32.cc index ff589c820b..b0c359034a 100644 --- a/deps/v8/src/ia32/assembler-ia32.cc +++ b/deps/v8/src/ia32/assembler-ia32.cc @@ -50,7 +50,6 @@ #include "src/assembler-inl.h" #include "src/base/bits.h" #include "src/base/cpu.h" -#include "src/code-stubs.h" #include "src/conversions-inl.h" #include "src/deoptimizer.h" #include "src/disassembler.h" @@ -70,13 +69,6 @@ Immediate Immediate::EmbeddedNumber(double value) { return result; } -Immediate Immediate::EmbeddedCode(CodeStub* stub) { - Immediate result(0, RelocInfo::CODE_TARGET); - result.is_heap_object_request_ = true; - result.value_.heap_object_request = HeapObjectRequest(stub); - return result; -} - Immediate Immediate::EmbeddedStringConstant(const StringConstantBase* str) { Immediate result(0, RelocInfo::EMBEDDED_OBJECT); result.is_heap_object_request_ = true; @@ -198,7 +190,6 @@ void Displacement::init(Label* L, Type type) { const int RelocInfo::kApplyMask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) | - RelocInfo::ModeMask(RelocInfo::JS_TO_WASM_CALL) | RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET) | RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY); @@ -210,28 +201,10 @@ bool RelocInfo::IsCodedSpecially() { return RelocInfo::ModeMask(rmode_) & kApplyMask; } - bool RelocInfo::IsInConstantPool() { return false; } -int RelocInfo::GetDeoptimizationId(Isolate* isolate, DeoptimizeKind kind) { - DCHECK(IsRuntimeEntry(rmode_)); - return Deoptimizer::GetDeoptimizationId(isolate, target_address(), kind); -} - -void RelocInfo::set_js_to_wasm_address(Address address, - ICacheFlushMode icache_flush_mode) { - DCHECK_EQ(rmode_, JS_TO_WASM_CALL); - Assembler::set_target_address_at(pc_, constant_pool_, address, - icache_flush_mode); -} - -Address RelocInfo::js_to_wasm_address() const { - DCHECK_EQ(rmode_, JS_TO_WASM_CALL); - return Assembler::target_address_at(pc_, constant_pool_); -} - uint32_t RelocInfo::wasm_call_tag() const { DCHECK(rmode_ == WASM_CALL || rmode_ == WASM_STUB_CALL); return Memory<uint32_t>(pc_); @@ -316,10 +289,6 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { object = isolate->factory()->NewHeapNumber(request.heap_number(), TENURED); break; - case HeapObjectRequest::kCodeStub: - request.code_stub()->set_isolate(isolate); - object = request.code_stub()->GetCode(); - break; case HeapObjectRequest::kStringConstant: { const StringConstantBase* str = request.string(); CHECK_NOT_NULL(str); @@ -327,7 +296,7 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { break; } } - Address pc = reinterpret_cast<Address>(buffer_) + request.offset(); + Address pc = reinterpret_cast<Address>(buffer_start_) + request.offset(); Memory<Handle<Object>>(pc) = object; } } @@ -339,20 +308,14 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { #define EMIT(x) \ *pc_++ = (x) -Assembler::Assembler(const AssemblerOptions& options, void* buffer, - int buffer_size) - : AssemblerBase(options, buffer, buffer_size) { -// Clear the buffer in debug mode unless it was provided by the -// caller in which case we can't be sure it's okay to overwrite -// existing code in it. -#ifdef DEBUG - if (own_buffer_) ZapCode(reinterpret_cast<Address>(buffer_), buffer_size_); -#endif - - reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); +Assembler::Assembler(const AssemblerOptions& options, + std::unique_ptr<AssemblerBuffer> buffer) + : AssemblerBase(options, std::move(buffer)) { + reloc_info_writer.Reposition(buffer_start_ + buffer_->size(), pc_); } void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) { + int code_comments_size = WriteCodeComments(); // Finalize code (at this point overflow() may be true, but the gap ensures // that we are still not overlapping instructions and relocation info). DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap. @@ -360,15 +323,19 @@ void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) { AllocateAndInstallRequestedHeapObjects(isolate); // Set up code descriptor. - desc->buffer = buffer_; - desc->buffer_size = buffer_size_; + desc->buffer = buffer_start_; + desc->buffer_size = buffer_->size(); desc->instr_size = pc_offset(); - desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); + desc->reloc_size = + (buffer_start_ + desc->buffer_size) - reloc_info_writer.pos(); desc->origin = this; desc->constant_pool_size = 0; desc->unwinding_info_size = 0; desc->unwinding_info = nullptr; + desc->code_comments_size = code_comments_size; +} +void Assembler::FinalizeJumpOptimizationInfo() { // Collection stage auto jump_opt = jump_optimization_info(); if (jump_opt && jump_opt->is_collecting()) { @@ -393,7 +360,6 @@ void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) { } } - void Assembler::Align(int m) { DCHECK(base::bits::IsPowerOfTwo(m)); int mask = m - 1; @@ -413,7 +379,6 @@ bool Assembler::IsNop(Address addr) { void Assembler::Nop(int bytes) { EnsureSpace ensure_space(this); - // Multi byte nops from http://support.amd.com/us/Processor_TechDocs/40546.pdf while (bytes > 0) { switch (bytes) { @@ -501,7 +466,6 @@ void Assembler::pushad() { void Assembler::popad() { EnsureSpace ensure_space(this); - AssertIsAddressable(ebx); EMIT(0x61); } @@ -538,7 +502,6 @@ void Assembler::push_imm32(int32_t imm32) { void Assembler::push(Register src) { - AssertIsAddressable(src); EnsureSpace ensure_space(this); EMIT(0x50 | src.code()); } @@ -551,7 +514,6 @@ void Assembler::push(Operand src) { void Assembler::pop(Register dst) { - AssertIsAddressable(dst); DCHECK_NOT_NULL(reloc_info_writer.last_pc()); EnsureSpace ensure_space(this); EMIT(0x58 | dst.code()); @@ -623,7 +585,6 @@ void Assembler::mov_w(Operand dst, const Immediate& src) { void Assembler::mov(Register dst, int32_t imm32) { - AssertIsAddressable(dst); EnsureSpace ensure_space(this); EMIT(0xB8 | dst.code()); emit(imm32); @@ -631,14 +592,12 @@ void Assembler::mov(Register dst, int32_t imm32) { void Assembler::mov(Register dst, const Immediate& x) { - AssertIsAddressable(dst); EnsureSpace ensure_space(this); EMIT(0xB8 | dst.code()); emit(x); } void Assembler::mov(Register dst, Handle<HeapObject> handle) { - AssertIsAddressable(dst); EnsureSpace ensure_space(this); EMIT(0xB8 | dst.code()); emit(handle); @@ -652,8 +611,6 @@ void Assembler::mov(Register dst, Operand src) { void Assembler::mov(Register dst, Register src) { - AssertIsAddressable(src); - AssertIsAddressable(dst); EnsureSpace ensure_space(this); EMIT(0x89); EMIT(0xC0 | src.code() << 3 | dst.code()); @@ -687,6 +644,7 @@ void Assembler::mov(Operand dst, Register src) { } void Assembler::movsx_b(Register dst, Operand src) { + DCHECK_IMPLIES(src.is_reg_only(), src.reg().is_byte_register()); EnsureSpace ensure_space(this); EMIT(0x0F); EMIT(0xBE); @@ -701,6 +659,7 @@ void Assembler::movsx_w(Register dst, Operand src) { } void Assembler::movzx_b(Register dst, Operand src) { + DCHECK_IMPLIES(src.is_reg_only(), src.reg().is_byte_register()); EnsureSpace ensure_space(this); EMIT(0x0F); EMIT(0xB6); @@ -758,8 +717,6 @@ void Assembler::stos() { void Assembler::xchg(Register dst, Register src) { - AssertIsAddressable(src); - AssertIsAddressable(dst); EnsureSpace ensure_space(this); if (src == eax || dst == eax) { // Single-byte encoding. EMIT(0x90 | (src == eax ? dst.code() : src.code())); @@ -990,7 +947,6 @@ void Assembler::cmpw_ax(Operand op) { void Assembler::dec_b(Register dst) { - AssertIsAddressable(dst); CHECK(dst.is_byte_register()); EnsureSpace ensure_space(this); EMIT(0xFE); @@ -1005,7 +961,6 @@ void Assembler::dec_b(Operand dst) { void Assembler::dec(Register dst) { - AssertIsAddressable(dst); EnsureSpace ensure_space(this); EMIT(0x48 | dst.code()); } @@ -1036,7 +991,6 @@ void Assembler::div(Operand src) { void Assembler::imul(Register reg) { - AssertIsAddressable(reg); EnsureSpace ensure_space(this); EMIT(0xF7); EMIT(0xE8 | reg.code()); @@ -1069,7 +1023,6 @@ void Assembler::imul(Register dst, Operand src, int32_t imm32) { void Assembler::inc(Register dst) { - AssertIsAddressable(dst); EnsureSpace ensure_space(this); EMIT(0x40 | dst.code()); } @@ -1088,7 +1041,6 @@ void Assembler::lea(Register dst, Operand src) { void Assembler::mul(Register src) { - AssertIsAddressable(src); EnsureSpace ensure_space(this); EMIT(0xF7); EMIT(0xE0 | src.code()); @@ -1096,14 +1048,12 @@ void Assembler::mul(Register src) { void Assembler::neg(Register dst) { - AssertIsAddressable(dst); EnsureSpace ensure_space(this); EMIT(0xF7); EMIT(0xD8 | dst.code()); } void Assembler::neg(Operand dst) { - AllowExplicitEbxAccessScope register_used_for_regcode(this); EnsureSpace ensure_space(this); EMIT(0xF7); emit_operand(ebx, dst); @@ -1111,7 +1061,6 @@ void Assembler::neg(Operand dst) { void Assembler::not_(Register dst) { - AssertIsAddressable(dst); EnsureSpace ensure_space(this); EMIT(0xF7); EMIT(0xD0 | dst.code()); @@ -1148,7 +1097,6 @@ void Assembler::or_(Operand dst, Register src) { void Assembler::rcl(Register dst, uint8_t imm8) { - AssertIsAddressable(dst); EnsureSpace ensure_space(this); DCHECK(is_uint5(imm8)); // illegal shift count if (imm8 == 1) { @@ -1163,7 +1111,6 @@ void Assembler::rcl(Register dst, uint8_t imm8) { void Assembler::rcr(Register dst, uint8_t imm8) { - AssertIsAddressable(dst); EnsureSpace ensure_space(this); DCHECK(is_uint5(imm8)); // illegal shift count if (imm8 == 1) { @@ -1321,7 +1268,6 @@ void Assembler::test(Register reg, const Immediate& imm) { return; } - AssertIsAddressable(reg); EnsureSpace ensure_space(this); // This is not using emit_arith because test doesn't support // sign-extension of 8-bit operands. @@ -1362,7 +1308,6 @@ void Assembler::test(Operand op, const Immediate& imm) { } void Assembler::test_b(Register reg, Immediate imm8) { - AssertIsAddressable(reg); DCHECK(imm8.is_uint8()); EnsureSpace ensure_space(this); // Only use test against byte for registers that have a byte @@ -1392,7 +1337,6 @@ void Assembler::test_b(Operand op, Immediate imm8) { } void Assembler::test_w(Register reg, Immediate imm16) { - AssertIsAddressable(reg); DCHECK(imm16.is_int16() || imm16.is_uint16()); EnsureSpace ensure_space(this); if (reg == eax) { @@ -1449,7 +1393,6 @@ void Assembler::xor_(Operand dst, const Immediate& x) { } void Assembler::bswap(Register dst) { - AssertIsAddressable(dst); EnsureSpace ensure_space(this); EMIT(0x0F); EMIT(0xC8 + dst.code()); @@ -1561,10 +1504,10 @@ void Assembler::bind_to(Label* L, int pos) { Displacement disp = disp_at(L); int fixup_pos = L->pos(); if (disp.type() == Displacement::CODE_ABSOLUTE) { - long_at_put(fixup_pos, reinterpret_cast<int>(buffer_ + pos)); + long_at_put(fixup_pos, reinterpret_cast<int>(buffer_start_ + pos)); internal_reference_positions_.push_back(fixup_pos); } else if (disp.type() == Displacement::CODE_RELATIVE) { - // Relative to Code* heap object pointer. + // Relative to Code heap object pointer. long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag); } else { if (disp.type() == Displacement::UNCONDITIONAL_JUMP) { @@ -1678,12 +1621,6 @@ void Assembler::call(Handle<Code> code, RelocInfo::Mode rmode) { emit(code, rmode); } -void Assembler::call(CodeStub* stub) { - EnsureSpace ensure_space(this); - EMIT(0xE8); - emit(Immediate::EmbeddedCode(stub)); -} - void Assembler::jmp_rel(int offset) { EnsureSpace ensure_space(this); const int short_size = 2; @@ -1878,7 +1815,6 @@ void Assembler::fld_d(Operand adr) { } void Assembler::fstp_s(Operand adr) { - AllowExplicitEbxAccessScope register_used_for_regcode(this); EnsureSpace ensure_space(this); EMIT(0xD9); emit_operand(ebx, adr); @@ -1891,7 +1827,6 @@ void Assembler::fst_s(Operand adr) { } void Assembler::fstp_d(Operand adr) { - AllowExplicitEbxAccessScope register_used_for_regcode(this); EnsureSpace ensure_space(this); EMIT(0xDD); emit_operand(ebx, adr); @@ -1916,7 +1851,6 @@ void Assembler::fild_d(Operand adr) { } void Assembler::fistp_s(Operand adr) { - AllowExplicitEbxAccessScope register_used_for_regcode(this); EnsureSpace ensure_space(this); EMIT(0xDB); emit_operand(ebx, adr); @@ -2204,7 +2138,6 @@ void Assembler::sahf() { void Assembler::setcc(Condition cc, Register reg) { - AssertIsAddressable(reg); DCHECK(reg.is_byte_register()); EnsureSpace ensure_space(this); EMIT(0x0F); @@ -2214,6 +2147,8 @@ void Assembler::setcc(Condition cc, Register reg) { void Assembler::cvttss2si(Register dst, Operand src) { EnsureSpace ensure_space(this); + // The [src] might contain ebx's register code, but in + // this case, it refers to xmm3, so it is OK to emit. EMIT(0xF3); EMIT(0x0F); EMIT(0x2C); @@ -2222,6 +2157,8 @@ void Assembler::cvttss2si(Register dst, Operand src) { void Assembler::cvttsd2si(Register dst, Operand src) { EnsureSpace ensure_space(this); + // The [src] might contain ebx's register code, but in + // this case, it refers to xmm3, so it is OK to emit. EMIT(0xF2); EMIT(0x0F); EMIT(0x2C); @@ -3185,7 +3122,6 @@ void Assembler::vinstr(byte op, XMMRegister dst, XMMRegister src1, Operand src2, } void Assembler::emit_sse_operand(XMMRegister reg, Operand adr) { - AllowExplicitEbxAccessScope accessing_xmm_register(this); Register ireg = Register::from_code(reg.code()); emit_operand(ireg, adr); } @@ -3197,13 +3133,11 @@ void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) { void Assembler::emit_sse_operand(Register dst, XMMRegister src) { - AssertIsAddressable(dst); EMIT(0xC0 | dst.code() << 3 | src.code()); } void Assembler::emit_sse_operand(XMMRegister dst, Register src) { - AssertIsAddressable(src); EMIT(0xC0 | (dst.code() << 3) | src.code()); } @@ -3231,56 +3165,51 @@ void Assembler::emit_vex_prefix(Register vreg, VectorLength l, SIMDPrefix pp, void Assembler::GrowBuffer() { DCHECK(buffer_overflow()); - if (!own_buffer_) FATAL("external code buffer is too small"); + DCHECK_EQ(buffer_start_, buffer_->start()); // Compute new buffer size. - CodeDesc desc; // the new buffer - desc.buffer_size = 2 * buffer_size_; + int old_size = buffer_->size(); + int new_size = 2 * old_size; // Some internal data structures overflow for very large buffers, // they must ensure that kMaximalBufferSize is not too large. - if (desc.buffer_size > kMaximalBufferSize) { + if (new_size > kMaximalBufferSize) { V8::FatalProcessOutOfMemory(nullptr, "Assembler::GrowBuffer"); } // Set up new buffer. - desc.buffer = NewArray<byte>(desc.buffer_size); - desc.origin = this; - desc.instr_size = pc_offset(); - desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos()); - - // Clear the buffer in debug mode. Use 'int3' instructions to make - // sure to get into problems if we ever run uninitialized code. -#ifdef DEBUG - ZapCode(reinterpret_cast<Address>(desc.buffer), desc.buffer_size); -#endif + std::unique_ptr<AssemblerBuffer> new_buffer = buffer_->Grow(new_size); + DCHECK_EQ(new_size, new_buffer->size()); + byte* new_start = new_buffer->start(); // Copy the data. - int pc_delta = desc.buffer - buffer_; - int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_); - MemMove(desc.buffer, buffer_, desc.instr_size); + intptr_t pc_delta = new_start - buffer_start_; + intptr_t rc_delta = (new_start + new_size) - (buffer_start_ + old_size); + size_t reloc_size = (buffer_start_ + old_size) - reloc_info_writer.pos(); + MemMove(new_start, buffer_start_, pc_offset()); MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(), - desc.reloc_size); + reloc_size); // Switch buffers. - DeleteArray(buffer_); - buffer_ = desc.buffer; - buffer_size_ = desc.buffer_size; + buffer_ = std::move(new_buffer); + buffer_start_ = new_start; pc_ += pc_delta; reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, reloc_info_writer.last_pc() + pc_delta); // Relocate internal references. for (auto pos : internal_reference_positions_) { - int32_t* p = reinterpret_cast<int32_t*>(buffer_ + pos); + int32_t* p = reinterpret_cast<int32_t*>(buffer_start_ + pos); *p += pc_delta; } // Relocate pc-relative references. - int mode_mask = RelocInfo::ModeMask(RelocInfo::JS_TO_WASM_CALL) | - RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET); + int mode_mask = RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET); DCHECK_EQ(mode_mask, RelocInfo::kApplyMask & mode_mask); - for (RelocIterator it(desc, mode_mask); !it.done(); it.next()) { + Vector<byte> instructions{buffer_start_, static_cast<size_t>(pc_offset())}; + Vector<const byte> reloc_info{reloc_info_writer.pos(), reloc_size}; + for (RelocIterator it(instructions, reloc_info, 0, mode_mask); !it.done(); + it.next()) { it.rinfo()->apply(pc_delta); } @@ -3289,7 +3218,6 @@ void Assembler::GrowBuffer() { void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) { - AssertIsAddressable(dst); DCHECK(is_uint8(op1) && is_uint8(op2)); // wrong opcode DCHECK(is_uint8(imm8)); DCHECK_EQ(op1 & 0x01, 0); // should be 8bit operation @@ -3300,7 +3228,6 @@ void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) { void Assembler::emit_arith(int sel, Operand dst, const Immediate& x) { - AssertIsAddressable(dst); DCHECK((0 <= sel) && (sel <= 7)); Register ireg = Register::from_code(sel); if (x.is_int8()) { @@ -3327,16 +3254,13 @@ void Assembler::emit_operand(XMMRegister reg, Operand adr) { } void Assembler::emit_operand(int code, Operand adr) { - AssertIsAddressable(adr); - AssertIsAddressable(Register::from_code(code)); // Isolate-independent code may not embed relocatable addresses. DCHECK(!options().isolate_independent_code || adr.rmode_ != RelocInfo::CODE_TARGET); DCHECK(!options().isolate_independent_code || adr.rmode_ != RelocInfo::EMBEDDED_OBJECT); - // TODO(jgruber,v8:6666): Enable once kRootRegister exists. - // DCHECK(!options().isolate_independent_code || - // adr.rmode_ != RelocInfo::EXTERNAL_REFERENCE); + DCHECK(!options().isolate_independent_code || + adr.rmode_ != RelocInfo::EXTERNAL_REFERENCE); const unsigned length = adr.len_; DCHECK_GT(length, 0); @@ -3364,7 +3288,7 @@ void Assembler::emit_operand(int code, Operand adr) { void Assembler::emit_label(Label* label) { if (label->is_bound()) { internal_reference_positions_.push_back(pc_offset()); - emit(reinterpret_cast<uint32_t>(buffer_ + label->pos())); + emit(reinterpret_cast<uint32_t>(buffer_start_ + label->pos())); } else { emit_disp(label, Displacement::CODE_ABSOLUTE); } @@ -3406,20 +3330,10 @@ void Assembler::dd(Label* label) { void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { if (!ShouldRecordRelocInfo(rmode)) return; - RelocInfo rinfo(reinterpret_cast<Address>(pc_), rmode, data, nullptr); + RelocInfo rinfo(reinterpret_cast<Address>(pc_), rmode, data, Code()); reloc_info_writer.Write(&rinfo); } -#ifdef DEBUG -void Assembler::AssertIsAddressable(const Operand& operand) { - DCHECK(is_ebx_addressable_ || !operand.UsesEbx()); -} - -void Assembler::AssertIsAddressable(const Register& reg) { - DCHECK(is_ebx_addressable_ || reg != ebx); -} -#endif // DEBUG - } // namespace internal } // namespace v8 |