Chromium Code Reviews| Index: src/x64/macro-assembler-x64.cc |
| =================================================================== |
| --- src/x64/macro-assembler-x64.cc (revision 5803) |
| +++ 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,25 @@ |
| } |
| -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 |
| + ASSERT(argc <= 6); // EnterApiExitFrame supports only register based args. |
|
antonm
2010/11/13 11:34:46
you don't have checks that revert to slow path if
SeRya
2010/11/15 12:09:11
Actually I see the following issue. EnterExitFrame
|
| + 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 +579,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 +598,8 @@ |
| call(rax); |
| movq(rax, prev_limit_reg); |
| jmp(&leave_exit_frame); |
| + |
| + return result; |
| } |
| @@ -566,6 +612,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()); |