diff options
Diffstat (limited to 'deps/v8/src/ia32/assembler-ia32.h')
-rw-r--r-- | deps/v8/src/ia32/assembler-ia32.h | 217 |
1 files changed, 25 insertions, 192 deletions
diff --git a/deps/v8/src/ia32/assembler-ia32.h b/deps/v8/src/ia32/assembler-ia32.h index b721542f13..96bf2c7eeb 100644 --- a/deps/v8/src/ia32/assembler-ia32.h +++ b/deps/v8/src/ia32/assembler-ia32.h @@ -41,122 +41,16 @@ #include "src/assembler.h" #include "src/ia32/constants-ia32.h" +#include "src/ia32/register-ia32.h" #include "src/ia32/sse-instr.h" #include "src/isolate.h" +#include "src/label.h" +#include "src/objects/smi.h" #include "src/utils.h" namespace v8 { namespace internal { -#define GENERAL_REGISTERS(V) \ - V(eax) \ - V(ecx) \ - V(edx) \ - V(ebx) \ - V(esp) \ - V(ebp) \ - V(esi) \ - V(edi) - -#define ALLOCATABLE_GENERAL_REGISTERS(V) \ - V(eax) \ - V(ecx) \ - V(edx) \ - V(ebx) \ - V(esi) \ - V(edi) - -#define DOUBLE_REGISTERS(V) \ - V(xmm0) \ - V(xmm1) \ - V(xmm2) \ - V(xmm3) \ - V(xmm4) \ - V(xmm5) \ - V(xmm6) \ - V(xmm7) - -#define FLOAT_REGISTERS DOUBLE_REGISTERS -#define SIMD128_REGISTERS DOUBLE_REGISTERS - -#define ALLOCATABLE_DOUBLE_REGISTERS(V) \ - V(xmm1) \ - V(xmm2) \ - V(xmm3) \ - V(xmm4) \ - V(xmm5) \ - V(xmm6) \ - V(xmm7) - -enum RegisterCode { -#define REGISTER_CODE(R) kRegCode_##R, - GENERAL_REGISTERS(REGISTER_CODE) -#undef REGISTER_CODE - kRegAfterLast -}; - -class Register : public RegisterBase<Register, kRegAfterLast> { - public: - bool is_byte_register() const { return reg_code_ <= 3; } - - private: - friend class RegisterBase<Register, kRegAfterLast>; - explicit constexpr Register(int code) : RegisterBase(code) {} -}; - -ASSERT_TRIVIALLY_COPYABLE(Register); -static_assert(sizeof(Register) == sizeof(int), - "Register can efficiently be passed by value"); - -#define DEFINE_REGISTER(R) \ - constexpr Register R = Register::from_code<kRegCode_##R>(); -GENERAL_REGISTERS(DEFINE_REGISTER) -#undef DEFINE_REGISTER -constexpr Register no_reg = Register::no_reg(); - -constexpr bool kPadArguments = false; -constexpr bool kSimpleFPAliasing = true; -constexpr bool kSimdMaskRegisters = false; - -enum DoubleCode { -#define REGISTER_CODE(R) kDoubleCode_##R, - DOUBLE_REGISTERS(REGISTER_CODE) -#undef REGISTER_CODE - kDoubleAfterLast -}; - -class XMMRegister : public RegisterBase<XMMRegister, kDoubleAfterLast> { - friend class RegisterBase<XMMRegister, kDoubleAfterLast>; - explicit constexpr XMMRegister(int code) : RegisterBase(code) {} -}; - -typedef XMMRegister FloatRegister; - -typedef XMMRegister DoubleRegister; - -typedef XMMRegister Simd128Register; - -#define DEFINE_REGISTER(R) \ - constexpr DoubleRegister R = DoubleRegister::from_code<kDoubleCode_##R>(); -DOUBLE_REGISTERS(DEFINE_REGISTER) -#undef DEFINE_REGISTER -constexpr DoubleRegister no_dreg = DoubleRegister::no_reg(); - -// Note that the bit values must match those used in actual instruction encoding -constexpr int kNumRegs = 8; - -// Caller-saved registers -constexpr RegList kJSCallerSaved = - Register::ListOf<eax, ecx, edx, - ebx, // used as a caller-saved register in JavaScript code - edi // callee function - >(); - -constexpr int kNumJSCallerSaved = 5; - -// Number of registers for which space is reserved in safepoints. -constexpr int kNumSafepointRegisters = 8; - enum Condition { // any value < 0 is considered no_condition no_condition = -1, @@ -218,11 +112,10 @@ class Immediate { : Immediate(ext.address(), RelocInfo::EXTERNAL_REFERENCE) {} inline explicit Immediate(Handle<HeapObject> handle) : Immediate(handle.address(), RelocInfo::EMBEDDED_OBJECT) {} - inline explicit Immediate(Smi* value) - : Immediate(reinterpret_cast<intptr_t>(value)) {} + inline explicit Immediate(Smi value) + : Immediate(static_cast<intptr_t>(value.ptr())) {} static Immediate EmbeddedNumber(double number); // Smi or HeapNumber. - static Immediate EmbeddedCode(CodeStub* code); static Immediate EmbeddedStringConstant(const StringConstantBase* str); static Immediate CodeRelativeOffset(Label* label) { @@ -246,6 +139,14 @@ class Immediate { return value_.immediate; } + bool is_embedded_object() const { + return !is_heap_object_request() && rmode() == RelocInfo::EMBEDDED_OBJECT; + } + + Handle<HeapObject> embedded_object() const { + return Handle<HeapObject>(reinterpret_cast<Address*>(immediate())); + } + bool is_external_reference() const { return rmode() == RelocInfo::EXTERNAL_REFERENCE; } @@ -361,17 +262,10 @@ class V8_EXPORT_PRIVATE Operand { // register. Register reg() const; -#ifdef DEBUG - bool UsesEbx() const { return uses_ebx_; } -#endif // DEBUG - private: // Set the ModRM byte without an encoded 'reg' register. The // register is encoded later as part of the emit_operand operation. inline void set_modrm(int mod, Register rm) { -#ifdef DEBUG - AddUsedRegister(rm); -#endif DCHECK_EQ(mod & -4, 0); buf_[0] = mod << 6 | rm.code(); len_ = 1; @@ -398,23 +292,12 @@ class V8_EXPORT_PRIVATE Operand { // Only valid if len_ > 4. RelocInfo::Mode rmode_ = RelocInfo::NONE; -#ifdef DEBUG - // TODO(v8:6666): Remove once kRootRegister support is complete. - bool uses_ebx_ = false; - void AddUsedRegister(Register reg) { - if (reg == ebx) uses_ebx_ = true; - } -#endif // DEBUG - // TODO(clemensh): Get rid of this friendship, or make Operand immutable. friend class Assembler; }; ASSERT_TRIVIALLY_COPYABLE(Operand); -// TODO(v8:6666): Re-enable globally once kRootRegister support is complete. -#ifndef DEBUG static_assert(sizeof(Operand) <= 2 * kPointerSize, "Operand must be small enough to pass it by value"); -#endif // ----------------------------------------------------------------------------- // A Displacement describes the 32bit immediate field of an instruction which @@ -485,15 +368,9 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { // for a detailed comment on the layout (globals.h). // // If the provided buffer is nullptr, the assembler allocates and grows its - // own buffer, and buffer_size determines the initial buffer size. The buffer - // is owned by the assembler and deallocated upon destruction of the - // assembler. - // - // If the provided buffer is not nullptr, the assembler uses the provided - // buffer for code generation and assumes its size to be buffer_size. If the - // buffer is too small, a fatal error occurs. No deallocation of the buffer is - // done upon destruction of the assembler. - Assembler(const AssemblerOptions& options, void* buffer, int buffer_size); + // own buffer. Otherwise it takes ownership of the provided buffer. + explicit Assembler(const AssemblerOptions&, + std::unique_ptr<AssemblerBuffer> = {}); virtual ~Assembler() {} // GetCode emits any pending (non-emitted) code and fills the descriptor @@ -501,6 +378,8 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { // Assembler functions are invoked in between GetCode() calls. void GetCode(Isolate* isolate, CodeDesc* desc); + void FinalizeJumpOptimizationInfo(); + // Read/Modify the code target in the branch/call instruction at pc. // The isolate argument is unused (and may be nullptr) when skipping flushing. inline static Address target_address_at(Address pc, Address constant_pool); @@ -515,7 +394,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { // This sets the branch destination (which is in the instruction on x86). // This is for calls and branches within generated code. inline static void deserialization_set_special_target_at( - Address instruction_payload, Code* code, Address target); + Address instruction_payload, Code code, Address target); // Get the size of the special target encoded at 'instruction_payload'. inline static int deserialization_special_target_size( @@ -532,8 +411,6 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { // and the return address static constexpr int kCallTargetAddressOffset = kPointerSize; - static constexpr int kCallInstructionLength = 5; - // One byte opcode for test al, 0xXX. static constexpr byte kTestAlByte = 0xA8; // One byte opcode for nop. @@ -851,7 +728,6 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { void call(Register reg) { call(Operand(reg)); } void call(Operand adr); void call(Handle<Code> code, RelocInfo::Mode rmode); - void call(CodeStub* stub); void wasm_call(Address address, RelocInfo::Mode rmode); // Jumps @@ -1733,9 +1609,6 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { return pc_offset() - label->pos(); } - // Use --code-comments to enable. - void RecordComment(const char* msg); - // Record a deoptimization reason that can be used by a log or cpu profiler. // Use --trace-deopt to enable. void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position, @@ -1762,45 +1635,14 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { static bool IsNop(Address addr); int relocation_writer_size() { - return (buffer_ + buffer_size_) - reloc_info_writer.pos(); + return (buffer_start_ + buffer_->size()) - reloc_info_writer.pos(); } // Avoid overflows for displacements etc. static constexpr int kMaximalBufferSize = 512 * MB; - byte byte_at(int pos) { return buffer_[pos]; } - void set_byte_at(int pos, byte value) { buffer_[pos] = value; } - - void PatchConstantPoolAccessInstruction(int pc_offset, int offset, - ConstantPoolEntry::Access access, - ConstantPoolEntry::Type type) { - // No embedded constant pool support. - UNREACHABLE(); - } - - // Temporary helper data structures while adding kRootRegister support to ia32 - // builtins. The SupportsRootRegisterScope is intended to mark each builtin - // and helper that fully supports the root register, i.e. that does not - // clobber ebx. The AllowExplicitEbxAccessScope marks regions that are allowed - // to clobber ebx, e.g. when ebx is spilled and restored. - // TODO(v8:6666): Remove once kRootRegister is fully supported. - template <bool new_value> - class SetRootRegisterSupportScope final { - public: - explicit SetRootRegisterSupportScope(Assembler* assembler) - : assembler_(assembler), old_value_(assembler->is_ebx_addressable_) { - assembler_->is_ebx_addressable_ = new_value; - } - ~SetRootRegisterSupportScope() { - assembler_->is_ebx_addressable_ = old_value_; - } - - private: - Assembler* assembler_; - const bool old_value_; - }; - typedef SetRootRegisterSupportScope<false> SupportsRootRegisterScope; - typedef SetRootRegisterSupportScope<true> AllowExplicitEbxAccessScope; + byte byte_at(int pos) { return buffer_start_[pos]; } + void set_byte_at(int pos, byte value) { buffer_start_[pos] = value; } protected: void emit_sse_operand(XMMRegister reg, Operand adr); @@ -1808,18 +1650,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { void emit_sse_operand(Register dst, XMMRegister src); void emit_sse_operand(XMMRegister dst, Register src); - byte* addr_at(int pos) { return buffer_ + pos; } - -#ifdef DEBUG - // TODO(v8:6666): Remove once kRootRegister is fully supported. - void AssertIsAddressable(const Register& reg); - void AssertIsAddressable(const Operand& operand); -#else - // An empty inline definition to avoid slowing down release builds. - void AssertIsAddressable(const Register&) {} - void AssertIsAddressable(const Operand&) {} -#endif // DEBUG - bool is_ebx_addressable_ = true; + byte* addr_at(int pos) { return buffer_start_ + pos; } private: uint32_t long_at(int pos) { @@ -1902,6 +1733,8 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { void AllocateAndInstallRequestedHeapObjects(Isolate* isolate); + int WriteCodeComments(); + friend class EnsureSpace; // Internal reference positions, required for (potential) patching in |