| Index: src/x64/macro-assembler-x64.h
|
| ===================================================================
|
| --- src/x64/macro-assembler-x64.h (revision 6800)
|
| +++ src/x64/macro-assembler-x64.h (working copy)
|
| @@ -74,7 +74,7 @@
|
|
|
| void LoadRoot(Register destination, Heap::RootListIndex index);
|
| void CompareRoot(Register with, Heap::RootListIndex index);
|
| - void CompareRoot(Operand with, Heap::RootListIndex index);
|
| + void CompareRoot(const Operand& with, Heap::RootListIndex index);
|
| void PushRoot(Heap::RootListIndex index);
|
| void StoreRoot(Register source, Heap::RootListIndex index);
|
|
|
| @@ -156,7 +156,7 @@
|
| //
|
| // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack
|
| // accessible via StackSpaceOperand.
|
| - void EnterExitFrame(int arg_stack_space = 0);
|
| + void EnterExitFrame(int arg_stack_space = 0, bool save_doubles = false);
|
|
|
| // Enter specific kind of exit frame. Allocates arg_stack_space * kPointerSize
|
| // memory (not GCed) on the stack accessible via StackSpaceOperand.
|
| @@ -165,20 +165,21 @@
|
| // Leave the current exit frame. Expects/provides the return value in
|
| // register rax:rdx (untouched) and the pointer to the first
|
| // argument in register rsi.
|
| - void LeaveExitFrame();
|
| + void LeaveExitFrame(bool save_doubles = false);
|
|
|
| // Leave the current exit frame. Expects/provides the return value in
|
| // register rax (untouched).
|
| void LeaveApiExitFrame();
|
|
|
| // Push and pop the registers that can hold pointers.
|
| - void PushSafepointRegisters() { UNIMPLEMENTED(); }
|
| - void PopSafepointRegisters() { UNIMPLEMENTED(); }
|
| + void PushSafepointRegisters() { Pushad(); }
|
| + void PopSafepointRegisters() { Popad(); }
|
| static int SafepointRegisterStackIndex(int reg_code) {
|
| - UNIMPLEMENTED();
|
| - return 0;
|
| + return kNumSafepointRegisters - 1 -
|
| + kSafepointPushRegisterIndices[reg_code];
|
| }
|
|
|
| +
|
| // ---------------------------------------------------------------------------
|
| // JavaScript invokes
|
|
|
| @@ -276,6 +277,7 @@
|
|
|
| // Is the value a tagged smi.
|
| Condition CheckSmi(Register src);
|
| + Condition CheckSmi(const Operand& src);
|
|
|
| // Is the value a non-negative tagged smi.
|
| Condition CheckNonNegativeSmi(Register src);
|
| @@ -304,6 +306,11 @@
|
| // conversion to a smi.
|
| Condition CheckUInteger32ValidSmiValue(Register src);
|
|
|
| + // Check whether src is a Smi, and set dst to zero if it is a smi,
|
| + // and to one if it isn't.
|
| + void CheckSmiToIndicator(Register dst, Register src);
|
| + void CheckSmiToIndicator(Register dst, const Operand& src);
|
| +
|
| // Test-and-jump functions. Typically combines a check function
|
| // above with a conditional jump.
|
|
|
| @@ -538,7 +545,15 @@
|
|
|
| // ---------------------------------------------------------------------------
|
| // String macros.
|
| +
|
| + // If object is a string, its map is loaded into object_map.
|
| template <typename LabelType>
|
| + void JumpIfNotString(Register object,
|
| + Register object_map,
|
| + LabelType* not_string);
|
| +
|
| +
|
| + template <typename LabelType>
|
| void JumpIfNotBothSequentialAsciiStrings(Register first_object,
|
| Register second_object,
|
| Register scratch1,
|
| @@ -594,6 +609,22 @@
|
| void Call(ExternalReference ext);
|
| void Call(Handle<Code> code_object, RelocInfo::Mode rmode);
|
|
|
| + // Emit call to the code we are currently generating.
|
| + void CallSelf() {
|
| + Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location()));
|
| + Call(self, RelocInfo::CODE_TARGET);
|
| + }
|
| +
|
| + // Non-x64 instructions.
|
| + // Push/pop all general purpose registers.
|
| + // Does not push rsp/rbp nor any of the assembler's special purpose registers
|
| + // (kScratchRegister, kSmiConstantRegister, kRootRegister).
|
| + void Pushad();
|
| + void Popad();
|
| + // Sets the stack as after performing Popad, without actually loading the
|
| + // registers.
|
| + void Dropad();
|
| +
|
| // Compare object type for heap object.
|
| // Always use unsigned comparisons: above and below, not less and greater.
|
| // Incoming register is heap_object and outgoing register is map.
|
| @@ -635,6 +666,9 @@
|
| // Abort execution if argument is not a smi. Used in debug code.
|
| void AbortIfNotSmi(Register object);
|
|
|
| + // Abort execution if argument is a string. Used in debug code.
|
| + void AbortIfNotString(Register object);
|
| +
|
| // Abort execution if argument is not the root value with the given index.
|
| void AbortIfNotRootValue(Register src,
|
| Heap::RootListIndex root_value_index,
|
| @@ -650,6 +684,13 @@
|
| // Unlink the stack handler on top of the stack from the try handler chain.
|
| void PopTryHandler();
|
|
|
| + // Activate the top handler in the try hander chain and pass the
|
| + // thrown value.
|
| + void Throw(Register value);
|
| +
|
| + // Propagate an uncatchable exception out of the current JS stack.
|
| + void ThrowUncatchable(UncatchableExceptionType type, Register value);
|
| +
|
| // ---------------------------------------------------------------------------
|
| // Inline caching support
|
|
|
| @@ -808,6 +849,9 @@
|
| // Call a runtime routine.
|
| void CallRuntime(Runtime::Function* f, int num_arguments);
|
|
|
| + // Call a runtime function and save the value of XMM registers.
|
| + void CallRuntimeSaveDoubles(Runtime::FunctionId id);
|
| +
|
| // Call a runtime function, returning the CodeStub object called.
|
| // Try to generate the stub code if necessary. Do not perform a GC
|
| // but instead return a retry after GC failure.
|
| @@ -891,6 +935,10 @@
|
|
|
| void Ret();
|
|
|
| + // Return and drop arguments from stack, where the number of arguments
|
| + // may be bigger than 2^16 - 1. Requires a scratch register.
|
| + void Ret(int bytes_dropped, Register scratch);
|
| +
|
| Handle<Object> CodeObject() { return code_object_; }
|
|
|
|
|
| @@ -927,6 +975,11 @@
|
| bool allow_stub_calls() { return allow_stub_calls_; }
|
|
|
| private:
|
| + // Order general registers are pushed by Pushad.
|
| + // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r12, r14.
|
| + static int kSafepointPushRegisterIndices[Register::kNumRegisters];
|
| + static const int kNumSafepointSavedRegisters = 11;
|
| +
|
| bool generating_stub_;
|
| bool allow_stub_calls_;
|
|
|
| @@ -957,7 +1010,7 @@
|
|
|
| // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack
|
| // accessible via StackSpaceOperand.
|
| - void EnterExitFrameEpilogue(int arg_stack_space);
|
| + void EnterExitFrameEpilogue(int arg_stack_space, bool save_doubles);
|
|
|
| void LeaveExitFrameEpilogue();
|
|
|
| @@ -1440,6 +1493,8 @@
|
| ASSERT(!src1.is(kScratchRegister));
|
| ASSERT(!src2.is(kScratchRegister));
|
| ASSERT(!dst.is(rcx));
|
| + // dst and src1 can be the same, because the one case that bails out
|
| + // is a shift by 0, which leaves dst, and therefore src1, unchanged.
|
| NearLabel result_ok;
|
| if (src1.is(rcx) || src2.is(rcx)) {
|
| movq(kScratchRegister, rcx);
|
| @@ -1574,6 +1629,17 @@
|
|
|
|
|
| template <typename LabelType>
|
| +void MacroAssembler::JumpIfNotString(Register object,
|
| + Register object_map,
|
| + LabelType* not_string) {
|
| + Condition is_smi = CheckSmi(object);
|
| + j(is_smi, not_string);
|
| + CmpObjectType(object, FIRST_NONSTRING_TYPE, object_map);
|
| + j(above_equal, not_string);
|
| +}
|
| +
|
| +
|
| +template <typename LabelType>
|
| void MacroAssembler::JumpIfNotBothSequentialAsciiStrings(Register first_object,
|
| Register second_object,
|
| Register scratch1,
|
|
|