Chromium Code Reviews| Index: src/x64/macro-assembler-x64.cc |
| =================================================================== |
| --- src/x64/macro-assembler-x64.cc (revision 5816) |
| +++ 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,24 @@ |
| } |
| -void MacroAssembler::PrepareCallApiFunction(int stack_space) { |
| - EnterApiExitFrame(stack_space, 0); |
| +void MacroAssembler::PrepareCallApiFunction(int stack_space, int argc) { |
| +#ifdef _WIN64 |
| + // We need to prepare a slot for result handle on stack and put |
| + // a pointer to it into 1st arg register. |
| + int register_based_args = argc > 3 ? 3 : argc; |
| + EnterApiExitFrame(stack_space, argc - register_based_args + 1); |
| + |
| + int return_value_slot = (argc > 3 ? argc - 3 + 1 : 4); |
| + // rcx must be used to pass the pointer to the return value slot. |
| + lea(rcx, Operand(rsp, return_value_slot * kPointerSize)); |
| +#else |
| + EnterApiExitFrame(stack_space, argc); |
| +#endif |
| } |
| -void MacroAssembler::CallApiFunctionAndReturn(ApiFunction* function) { |
| +MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn( |
| + ApiFunction* function) { |
| Label empty_result; |
| Label prologue; |
| Label promote_scheduled_exception; |
| @@ -539,7 +578,11 @@ |
| ret(0); |
| 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 +597,8 @@ |
| call(rax); |
| movq(rax, prev_limit_reg); |
| jmp(&leave_exit_frame); |
| + |
| + return result; |
| } |
| @@ -566,6 +611,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()); |
| @@ -1742,6 +1796,10 @@ |
| int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; |
| lea(r12, Operand(rbp, (stack_space * kPointerSize) + offset)); |
| +#ifndef _WIN64 |
| + ASSERT(argc <= 6); // EnterApiExitFrame supports only register based args. |
|
antonm
2010/11/15 16:22:06
Sorry, I still don't understand what. What will h
SeRya
2010/11/15 16:37:50
Currently it's used only for getters for x64 (yet)
|
| +#endif |
| + |
| EnterExitFrameEpilogue(result_size, argc); |
| } |