summaryrefslogtreecommitdiff
path: root/deps/v8/src/ia32/assembler-ia32.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/ia32/assembler-ia32.cc')
-rw-r--r--deps/v8/src/ia32/assembler-ia32.cc176
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