diff options
Diffstat (limited to 'deps/v8/src/x64/macro-assembler-x64.h')
-rw-r--r-- | deps/v8/src/x64/macro-assembler-x64.h | 208 |
1 files changed, 101 insertions, 107 deletions
diff --git a/deps/v8/src/x64/macro-assembler-x64.h b/deps/v8/src/x64/macro-assembler-x64.h index 25c488ad35..cfd040a5c3 100644 --- a/deps/v8/src/x64/macro-assembler-x64.h +++ b/deps/v8/src/x64/macro-assembler-x64.h @@ -2,51 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef INCLUDED_FROM_MACRO_ASSEMBLER_H +#error This header must be included via macro-assembler.h +#endif + #ifndef V8_X64_MACRO_ASSEMBLER_X64_H_ #define V8_X64_MACRO_ASSEMBLER_X64_H_ #include "src/bailout-reason.h" #include "src/base/flags.h" +#include "src/contexts.h" #include "src/globals.h" -#include "src/turbo-assembler.h" #include "src/x64/assembler-x64.h" namespace v8 { namespace internal { -// Give alias names to registers for calling conventions. -constexpr Register kReturnRegister0 = rax; -constexpr Register kReturnRegister1 = rdx; -constexpr Register kReturnRegister2 = r8; -constexpr Register kJSFunctionRegister = rdi; -constexpr Register kContextRegister = rsi; -constexpr Register kAllocateSizeRegister = rdx; -constexpr Register kSpeculationPoisonRegister = r12; -constexpr Register kInterpreterAccumulatorRegister = rax; -constexpr Register kInterpreterBytecodeOffsetRegister = r9; -constexpr Register kInterpreterBytecodeArrayRegister = r14; -constexpr Register kInterpreterDispatchTableRegister = r15; - -constexpr Register kJavaScriptCallArgCountRegister = rax; -constexpr Register kJavaScriptCallCodeStartRegister = rcx; -constexpr Register kJavaScriptCallTargetRegister = kJSFunctionRegister; -constexpr Register kJavaScriptCallNewTargetRegister = rdx; -constexpr Register kJavaScriptCallExtraArg1Register = rbx; - -constexpr Register kRuntimeCallFunctionRegister = rbx; -constexpr Register kRuntimeCallArgCountRegister = rax; -constexpr Register kRuntimeCallArgvRegister = r15; -constexpr Register kWasmInstanceRegister = rsi; - -// Default scratch register used by MacroAssembler (and other code that needs -// a spare register). The register isn't callee save, and not used by the -// function calling convention. -constexpr Register kScratchRegister = r10; -constexpr XMMRegister kScratchDoubleReg = xmm15; -constexpr Register kRootRegister = r13; // callee save - -constexpr Register kOffHeapTrampolineRegister = kScratchRegister; - // Convenience for platform-independent signatures. typedef Operand MemOperand; @@ -116,14 +87,9 @@ class StackArgumentsAccessor { class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { public: - TurboAssembler(const AssemblerOptions& options, void* buffer, int buffer_size) - : TurboAssemblerBase(options, buffer, buffer_size) {} - - TurboAssembler(Isolate* isolate, const AssemblerOptions& options, - void* buffer, int buffer_size, - CodeObjectRequired create_code_object) - : TurboAssemblerBase(isolate, options, buffer, buffer_size, - create_code_object) {} + template <typename... Args> + explicit TurboAssembler(Args&&... args) + : TurboAssemblerBase(std::forward<Args>(args)...) {} template <typename Dst, typename... Args> struct AvxHelper { @@ -229,7 +195,7 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { void Push(Register src); void Push(Operand src); void Push(Immediate value); - void Push(Smi* smi); + void Push(Smi smi); void Push(Handle<HeapObject> source); // Before calling a C-function from generated code, align arguments on stack. @@ -325,9 +291,9 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { j(less, dest); } - void Move(Register dst, Smi* source); + void Move(Register dst, Smi source); - void Move(Operand dst, Smi* source) { + void Move(Operand dst, Smi source) { Register constant = GetSmiConstant(source); movp(dst, constant); } @@ -377,8 +343,8 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { // isn't changed. // If the operand is used more than once, use a scratch register // that is guaranteed not to be clobbered. - Operand ExternalOperand(ExternalReference reference, - Register scratch = kScratchRegister); + Operand ExternalReferenceAsOperand(ExternalReference reference, + Register scratch = kScratchRegister); void Call(Register reg) { call(reg); } void Call(Operand op); @@ -387,6 +353,12 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { void Call(ExternalReference ext); void Call(Label* target) { call(target); } + void CallBuiltinPointer(Register builtin_pointer) override; + + void LoadCodeObjectEntry(Register destination, Register code_object) override; + void CallCodeObject(Register code_object) override; + void JumpCodeObject(Register code_object) override; + void RetpolineCall(Register reg); void RetpolineCall(Address destination, RelocInfo::Mode rmode); @@ -398,11 +370,7 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { void RetpolineJump(Register reg); - void CallForDeoptimization(Address target, int deopt_id, - RelocInfo::Mode rmode) { - USE(deopt_id); - call(target, rmode); - } + void CallForDeoptimization(Address target, int deopt_id); // Non-SSE2 instructions. void Pextrd(Register dst, XMMRegister src, int8_t imm8); @@ -453,22 +421,13 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { Register caller_args_count_reg, Register scratch0, Register scratch1); - inline bool AllowThisStubCall(CodeStub* stub); - - // Call a code stub. This expects {stub} to be zone-allocated, as it does not - // trigger generation of the stub's code object but instead files a - // HeapObjectRequest that will be fulfilled after code assembly. - void CallStubDelayed(CodeStub* stub); - // Call a runtime routine. This expects {centry} to contain a fitting CEntry // builtin for the target runtime function and uses an indirect call. void CallRuntimeWithCEntry(Runtime::FunctionId fid, Register centry); void InitializeRootRegister() { - ExternalReference roots_array_start = - ExternalReference::roots_array_start(isolate()); - Move(kRootRegister, roots_array_start); - addp(kRootRegister, Immediate(kRootRegisterBias)); + ExternalReference isolate_root = ExternalReference::isolate_root(isolate()); + Move(kRootRegister, isolate_root); } void SaveRegisters(RegList registers); @@ -477,6 +436,9 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { void CallRecordWriteStub(Register object, Register address, RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode); + void CallRecordWriteStub(Register object, Register address, + RememberedSetAction remembered_set_action, + SaveFPRegsMode fp_mode, Address wasm_target); void MoveNumber(Register dst, double value); void MoveNonSmi(Register dst, double value); @@ -510,37 +472,78 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { void ResetSpeculationPoisonRegister(); + // --------------------------------------------------------------------------- + // Pointer compression support + + // TODO(ishell): remove |scratch_for_debug| once pointer compression works. + + // Loads a field containing a HeapObject and decompresses it if pointer + // compression is enabled. + void LoadTaggedPointerField(Register destination, Operand field_operand, + Register scratch_for_debug = no_reg); + + // Loads a field containing any tagged value and decompresses it if necessary. + // When pointer compression is enabled, uses |scratch| to decompress the + // value. + void LoadAnyTaggedField(Register destination, Operand field_operand, + Register scratch, + Register scratch_for_debug = no_reg); + + // Loads a field containing a HeapObject, decompresses it if necessary and + // pushes full pointer to the stack. When pointer compression is enabled, + // uses |scratch| to decompress the value. + void PushTaggedPointerField(Operand field_operand, Register scratch, + Register scratch_for_debug = no_reg); + + // Loads a field containing any tagged value, decompresses it if necessary and + // pushes the full pointer to the stack. When pointer compression is enabled, + // uses |scratch1| and |scratch2| to decompress the value. + void PushTaggedAnyField(Operand field_operand, Register scratch1, + Register scratch2, + Register scratch_for_debug = no_reg); + + // Loads a field containing smi value and untags it. + void SmiUntagField(Register dst, Operand src); + + // Compresses and stores tagged value to given on-heap location. + // TODO(ishell): drop once mov_tagged() can be used. + void StoreTaggedField(Operand dst_field_operand, Immediate immediate); + void StoreTaggedField(Operand dst_field_operand, Register value); + + void DecompressTaggedSigned(Register destination, Operand field_operand, + Register scratch_for_debug); + void DecompressTaggedPointer(Register destination, Operand field_operand, + Register scratch_for_debug); + void DecompressAnyTagged(Register destination, Operand field_operand, + Register scratch, Register scratch_for_debug); + protected: static const int kSmiShift = kSmiTagSize + kSmiShiftSize; int smi_count = 0; int heap_object_count = 0; - int64_t RootRegisterDelta(ExternalReference other); - // Returns a register holding the smi value. The register MUST NOT be // modified. It may be the "smi 1 constant" register. - Register GetSmiConstant(Smi* value); + Register GetSmiConstant(Smi value); + + void CallRecordWriteStub(Register object, Register address, + RememberedSetAction remembered_set_action, + SaveFPRegsMode fp_mode, Handle<Code> code_target, + Address wasm_target); }; // MacroAssembler implements a collection of frequently used macros. -class MacroAssembler : public TurboAssembler { +class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { public: - MacroAssembler(const AssemblerOptions& options, void* buffer, int size) - : TurboAssembler(options, buffer, size) {} - - MacroAssembler(Isolate* isolate, void* buffer, int size, - CodeObjectRequired create_code_object) - : MacroAssembler(isolate, AssemblerOptions::Default(isolate), buffer, - size, create_code_object) {} - - MacroAssembler(Isolate* isolate, const AssemblerOptions& options, - void* buffer, int size, CodeObjectRequired create_code_object); + template <typename... Args> + explicit MacroAssembler(Args&&... args) + : TurboAssembler(std::forward<Args>(args)...) {} // Loads and stores the value of an external reference. // Special case code for load and store to take advantage of // load_rax/store_rax if possible/necessary. // For other operations, just use: - // Operand operand = ExternalOperand(extref); + // Operand operand = ExternalReferenceAsOperand(extref); // operation(operand, ..); void Load(Register destination, ExternalReference source); void Store(ExternalReference destination, Register source); @@ -578,9 +581,8 @@ class MacroAssembler : public TurboAssembler { j(not_equal, if_not_equal, if_not_equal_distance); } - -// --------------------------------------------------------------------------- -// GC Support + // --------------------------------------------------------------------------- + // GC Support // Notify the garbage collector that we wrote a pointer into an object. // |object| is the object being stored into, |value| is the object being @@ -611,13 +613,14 @@ class MacroAssembler : public TurboAssembler { // sets up the number of arguments in register rdi and the pointer // to the first argument in register rsi. // - // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack - // accessible via StackSpaceOperand. + // Allocates arg_stack_space * kSystemPointerSize memory (not GCed) on the + // stack accessible via StackSpaceOperand. void EnterExitFrame(int arg_stack_space = 0, bool save_doubles = false, StackFrame::Type frame_type = StackFrame::EXIT); - // Enter specific kind of exit frame. Allocates arg_stack_space * kPointerSize - // memory (not GCed) on the stack accessible via StackSpaceOperand. + // Enter specific kind of exit frame. Allocates + // (arg_stack_space * kSystemPointerSize) memory (not GCed) on the stack + // accessible via StackSpaceOperand. void EnterApiExitFrame(int arg_stack_space); // Leave the current exit frame. Expects/provides the return value in @@ -664,10 +667,10 @@ class MacroAssembler : public TurboAssembler { // Simple comparison of smis. Both sides must be known smis to use these, // otherwise use Cmp. void SmiCompare(Register smi1, Register smi2); - void SmiCompare(Register dst, Smi* src); + void SmiCompare(Register dst, Smi src); void SmiCompare(Register dst, Operand src); void SmiCompare(Operand dst, Register src); - void SmiCompare(Operand dst, Smi* src); + void SmiCompare(Operand dst, Smi src); // Functions performing a check on a known or potential smi. Returns // a condition that is satisfied if the check is successful. @@ -691,15 +694,15 @@ class MacroAssembler : public TurboAssembler { // Add an integer constant to a tagged smi, giving a tagged smi as result. // No overflow testing on the result is done. - void SmiAddConstant(Operand dst, Smi* constant); + void SmiAddConstant(Operand dst, Smi constant); // Specialized operations // Converts, if necessary, a smi to a combination of number and // multiplier to be used as a scaled index. // The src register contains a *positive* smi value. The shift is the - // power of two to multiply the index value by (e.g. - // to index by smi-value * kPointerSize, pass the smi and kPointerSizeLog2). + // power of two to multiply the index value by (e.g. to index by + // smi-value * kSystemPointerSize, pass the smi and kSystemPointerSizeLog2). // The returned index register may be either src or dst, depending // on what is most efficient. If src and dst are different registers, // src is always unchanged. @@ -714,8 +717,8 @@ class MacroAssembler : public TurboAssembler { void Cmp(Register dst, Handle<Object> source); void Cmp(Operand dst, Handle<Object> source); - void Cmp(Register dst, Smi* src); - void Cmp(Operand dst, Smi* src); + void Cmp(Register dst, Smi src); + void Cmp(Operand dst, Smi src); // Emit code to discard a non-negative number of pointer-sized elements // from the stack, clobbering only the rsp register. @@ -820,14 +823,6 @@ class MacroAssembler : public TurboAssembler { // --------------------------------------------------------------------------- // Runtime calls - // Call a code stub. - // The code object is generated immediately, in contrast to - // TurboAssembler::CallStubDelayed. - void CallStub(CodeStub* stub); - - // Tail call a code stub (jump). - void TailCallStub(CodeStub* stub); - // Call a runtime routine. void CallRuntime(const Runtime::Function* f, int num_arguments, @@ -869,9 +864,6 @@ class MacroAssembler : public TurboAssembler { return SafepointRegisterStackIndex(reg.code()); } - void EnterBuiltinFrame(Register context, Register target, Register argc); - void LeaveBuiltinFrame(Register context, Register target, Register argc); - private: // Order general registers are pushed by Pushad. // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r12, r14, r15. @@ -886,8 +878,8 @@ class MacroAssembler : public TurboAssembler { void EnterExitFramePrologue(bool save_rax, StackFrame::Type frame_type); - // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack - // accessible via StackSpaceOperand. + // Allocates arg_stack_space * kSystemPointerSize memory (not GCed) on the + // stack accessible via StackSpaceOperand. void EnterExitFrameEpilogue(int arg_stack_space, bool save_doubles); void LeaveExitFrameEpilogue(); @@ -907,6 +899,8 @@ class MacroAssembler : public TurboAssembler { // Needs access to SafepointRegisterStackIndex for compiled frame // traversal. friend class StandardFrame; + + DISALLOW_IMPLICIT_CONSTRUCTORS(MacroAssembler); }; // ----------------------------------------------------------------------------- @@ -946,9 +940,9 @@ inline Operand NativeContextOperand() { inline Operand StackSpaceOperand(int index) { #ifdef _WIN64 const int kShaddowSpace = 4; - return Operand(rsp, (index + kShaddowSpace) * kPointerSize); + return Operand(rsp, (index + kShaddowSpace) * kSystemPointerSize); #else - return Operand(rsp, index * kPointerSize); + return Operand(rsp, index * kSystemPointerSize); #endif } |