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); |
} |