| Index: src/x64/macro-assembler-x64.cc
|
| ===================================================================
|
| --- src/x64/macro-assembler-x64.cc (revision 5846)
|
| +++ src/x64/macro-assembler-x64.cc (working copy)
|
| @@ -327,7 +327,7 @@
|
|
|
|
|
| void MacroAssembler::TailCallStub(CodeStub* stub) {
|
| - ASSERT(allow_stub_calls()); // calls are not allowed in some stubs
|
| + ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs.
|
| Jump(stub->GetCode(), RelocInfo::CODE_TARGET);
|
| }
|
|
|
| @@ -456,6 +456,24 @@
|
| }
|
|
|
|
|
| +MaybeObject* MacroAssembler::TryTailCallExternalReference(
|
| + const ExternalReference& ext, int num_arguments, int result_size) {
|
| + // ----------- S t a t e -------------
|
| + // -- rsp[0] : return address
|
| + // -- rsp[8] : argument num_arguments - 1
|
| + // ...
|
| + // -- rsp[8 * num_arguments] : argument 0 (receiver)
|
| + // -----------------------------------
|
| +
|
| + // TODO(1236192): Most runtime routines don't need the number of
|
| + // arguments passed in because it is constant. At some point we
|
| + // should remove this need and make the runtime routine entry code
|
| + // smarter.
|
| + Set(rax, num_arguments);
|
| + return TryJumpToExternalReference(ext, result_size);
|
| +}
|
| +
|
| +
|
| void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid,
|
| int num_arguments,
|
| int result_size) {
|
| @@ -463,6 +481,15 @@
|
| }
|
|
|
|
|
| +MaybeObject* MacroAssembler::TryTailCallRuntime(Runtime::FunctionId fid,
|
| + int num_arguments,
|
| + int result_size) {
|
| + return TryTailCallExternalReference(ExternalReference(fid),
|
| + num_arguments,
|
| + result_size);
|
| +}
|
| +
|
| +
|
| static int Offset(ExternalReference ref0, ExternalReference ref1) {
|
| int64_t offset = (ref0.address() - ref1.address());
|
| // Check that fits into int.
|
| @@ -471,12 +498,22 @@
|
| }
|
|
|
|
|
| -void MacroAssembler::PrepareCallApiFunction(int stack_space) {
|
| - EnterApiExitFrame(stack_space, 0);
|
| +void MacroAssembler::PrepareCallApiFunction(int arg_stack_space) {
|
| +#ifdef _WIN64
|
| + // We need to prepare a slot for result handle on stack and put
|
| + // a pointer to it into 1st arg register.
|
| + EnterApiExitFrame(arg_stack_space + 1);
|
| +
|
| + // rcx must be used to pass the pointer to the return value slot.
|
| + lea(rcx, StackSpaceOperand(arg_stack_space));
|
| +#else
|
| + EnterApiExitFrame(arg_stack_space);
|
| +#endif
|
| }
|
|
|
|
|
| -void MacroAssembler::CallApiFunctionAndReturn(ApiFunction* function) {
|
| +MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn(
|
| + ApiFunction* function, int stack_space) {
|
| Label empty_result;
|
| Label prologue;
|
| Label promote_scheduled_exception;
|
| @@ -499,7 +536,7 @@
|
| // Allocate HandleScope in callee-save registers.
|
| Register prev_next_address_reg = r14;
|
| Register prev_limit_reg = rbx;
|
| - Register base_reg = kSmiConstantRegister;
|
| + Register base_reg = r12;
|
| movq(base_reg, next_address);
|
| movq(prev_next_address_reg, Operand(base_reg, kNextOffset));
|
| movq(prev_limit_reg, Operand(base_reg, kLimitOffset));
|
| @@ -528,18 +565,21 @@
|
| cmpq(prev_limit_reg, Operand(base_reg, kLimitOffset));
|
| j(not_equal, &delete_allocated_handles);
|
| bind(&leave_exit_frame);
|
| - InitializeSmiConstantRegister();
|
|
|
| // Check if the function scheduled an exception.
|
| movq(rsi, scheduled_exception_address);
|
| Cmp(Operand(rsi, 0), Factory::the_hole_value());
|
| j(not_equal, &promote_scheduled_exception);
|
|
|
| - LeaveExitFrame();
|
| - ret(0);
|
| + LeaveApiExitFrame();
|
| + ret(stack_space * kPointerSize);
|
|
|
| bind(&promote_scheduled_exception);
|
| - TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
|
| + MaybeObject* result = TryTailCallRuntime(Runtime::kPromoteScheduledException,
|
| + 0, 1);
|
| + if (result->IsFailure()) {
|
| + return result;
|
| + }
|
|
|
| bind(&empty_result);
|
| // It was zero; the result is undefined.
|
| @@ -554,6 +594,8 @@
|
| call(rax);
|
| movq(rax, prev_limit_reg);
|
| jmp(&leave_exit_frame);
|
| +
|
| + return result;
|
| }
|
|
|
|
|
| @@ -566,6 +608,15 @@
|
| }
|
|
|
|
|
| +MaybeObject* MacroAssembler::TryJumpToExternalReference(
|
| + const ExternalReference& ext, int result_size) {
|
| + // Set the entry point and jump to the C entry runtime stub.
|
| + movq(rbx, ext);
|
| + CEntryStub ces(result_size);
|
| + return TryTailCallStub(&ces);
|
| +}
|
| +
|
| +
|
| void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) {
|
| // Calls are not allowed in some stubs.
|
| ASSERT(flag == JUMP_FUNCTION || allow_stub_calls());
|
| @@ -1690,22 +1741,15 @@
|
| store_rax(context_address);
|
| }
|
|
|
| -void MacroAssembler::EnterExitFrameEpilogue(int result_size,
|
| - int argc) {
|
| +
|
| +void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space) {
|
| #ifdef _WIN64
|
| - // Reserve space on stack for result and argument structures, if necessary.
|
| - int result_stack_space = (result_size < 2) ? 0 : result_size * kPointerSize;
|
| - // Reserve space for the Arguments object. The Windows 64-bit ABI
|
| - // requires us to pass this structure as a pointer to its location on
|
| - // the stack. The structure contains 2 values.
|
| - int argument_stack_space = argc * kPointerSize;
|
| - // We also need backing space for 4 parameters, even though
|
| - // we only pass one or two parameter, and it is in a register.
|
| - int argument_mirror_space = 4 * kPointerSize;
|
| - int total_stack_space =
|
| - argument_mirror_space + argument_stack_space + result_stack_space;
|
| - subq(rsp, Immediate(total_stack_space));
|
| + const int kShaddowSpace = 4;
|
| + arg_stack_space += kShaddowSpace;
|
| #endif
|
| + if (arg_stack_space > 0) {
|
| + subq(rsp, Immediate(arg_stack_space * kPointerSize));
|
| + }
|
|
|
| // Get the required frame alignment for the OS.
|
| static const int kFrameAlignment = OS::ActivationFrameAlignment();
|
| @@ -1720,7 +1764,7 @@
|
| }
|
|
|
|
|
| -void MacroAssembler::EnterExitFrame(int result_size) {
|
| +void MacroAssembler::EnterExitFrame(int arg_stack_space) {
|
| EnterExitFramePrologue(true);
|
|
|
| // Setup argv in callee-saved register r12. It is reused in LeaveExitFrame,
|
| @@ -1728,25 +1772,17 @@
|
| int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
|
| lea(r12, Operand(rbp, r14, times_pointer_size, offset));
|
|
|
| - EnterExitFrameEpilogue(result_size, 2);
|
| + EnterExitFrameEpilogue(arg_stack_space);
|
| }
|
|
|
|
|
| -void MacroAssembler::EnterApiExitFrame(int stack_space,
|
| - int argc,
|
| - int result_size) {
|
| +void MacroAssembler::EnterApiExitFrame(int arg_stack_space) {
|
| EnterExitFramePrologue(false);
|
| -
|
| - // Setup argv in callee-saved register r12. It is reused in LeaveExitFrame,
|
| - // so it must be retained across the C-call.
|
| - int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
|
| - lea(r12, Operand(rbp, (stack_space * kPointerSize) + offset));
|
| -
|
| - EnterExitFrameEpilogue(result_size, argc);
|
| + EnterExitFrameEpilogue(arg_stack_space);
|
| }
|
|
|
|
|
| -void MacroAssembler::LeaveExitFrame(int result_size) {
|
| +void MacroAssembler::LeaveExitFrame() {
|
| // Registers:
|
| // r12 : argv
|
|
|
| @@ -1758,6 +1794,22 @@
|
| // from the caller stack.
|
| lea(rsp, Operand(r12, 1 * kPointerSize));
|
|
|
| + // Push the return address to get ready to return.
|
| + push(rcx);
|
| +
|
| + LeaveExitFrameEpilogue();
|
| +}
|
| +
|
| +
|
| +void MacroAssembler::LeaveApiExitFrame() {
|
| + movq(rsp, rbp);
|
| + pop(rbp);
|
| +
|
| + LeaveExitFrameEpilogue();
|
| +}
|
| +
|
| +
|
| +void MacroAssembler::LeaveExitFrameEpilogue() {
|
| // Restore current context from top and clear it in debug mode.
|
| ExternalReference context_address(Top::k_context_address);
|
| movq(kScratchRegister, context_address);
|
| @@ -1766,9 +1818,6 @@
|
| movq(Operand(kScratchRegister, 0), Immediate(0));
|
| #endif
|
|
|
| - // Push the return address to get ready to return.
|
| - push(rcx);
|
| -
|
| // Clear the top frame.
|
| ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address);
|
| movq(kScratchRegister, c_entry_fp_address);
|
|
|