Chromium Code Reviews| Index: src/x64/builtins-x64.cc |
| diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc |
| index 38d7e5abeb6fe0dea477b6be2a633a279e8db88f..18cd6d5af638f5fb433ec7c1653187984eecbf83 100644 |
| --- a/src/x64/builtins-x64.cc |
| +++ b/src/x64/builtins-x64.cc |
| @@ -771,6 +771,125 @@ void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) { |
| } |
| +// static |
| +void Builtins::Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) { |
| + // ----------- S t a t e ------------- |
| + // -- rax : the number of arguments (not including the receiver) |
| + // -- rbx : the address of the first argument to be pushed. Subsequent |
| + // arguments should be consecutive above this, in the same order as |
| + // they are to be pushed onto the stack. |
| + // -- rdi : the target to call (can be any Object). |
| + |
| + // Pop return address to allow tail-call after pushing arguments. |
| + __ Pop(rdx); |
| + |
| + // Find the address of the last argument. |
| + __ movp(rcx, rax); |
| + __ addp(rcx, Immediate(1)); // Add one for receiver. |
| + __ shlp(rcx, Immediate(kPointerSizeLog2)); |
| + __ negp(rcx); |
| + __ addp(rcx, rbx); |
| + |
| + // Push the arguments. |
| + Label loop_header, loop_check; |
| + __ j(always, &loop_check); |
| + __ bind(&loop_header); |
| + __ Push(Operand(rbx, 0)); |
| + __ subp(rbx, Immediate(kPointerSize)); |
| + __ bind(&loop_check); |
| + __ cmpp(rbx, rcx); |
| + __ j(greater, &loop_header, Label::kNear); |
| + |
| + // Call the target. |
| + __ Push(rdx); // Re-push return address. |
| + __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| +} |
| + |
| + |
| +void Builtins::Generate_InterpreterCEntry(MacroAssembler* masm) { |
| + // ----------- S t a t e ------------- |
| + // -- r14 : the number of arguments (argc). |
| + // -- r15 : the address of the first argument (argv). |
| + // -- rbx : the FunctionId of the runtime function to call. |
| + // -- rsi : current context. |
| + |
| + // TODO(rmcilroy): Things that still need to be done: |
| + // - Call ProfileEntryHookStub when isolate has a function_entry_hook. |
| + // - Deal with more than one return value. |
| + // - Deal with saving fpregs if necessary. |
| + // - Handle pending exceptions. |
| + |
| + // Get the function entry address for the FunctionID. |
| + const int kFunctionSizeLog2 = 2 + kPointerSizeLog2; |
|
Michael Starzinger
2015/09/25 11:23:26
Hmm, I am not all too excited to have lookup in th
rmcilroy
2015/09/28 16:20:47
Acknowledged. I can't think of a better way either
|
| + STATIC_ASSERT(sizeof(Runtime::Function) == 1 << kFunctionSizeLog2); |
| + __ shlp(rbx, Immediate(kFunctionSizeLog2)); |
| + __ LoadAddress(rax, ExternalReference::runtime_function_table_address()); |
| + __ addp(rbx, rax); |
| + __ movp(rbx, Operand(rbx, offsetof(Runtime::Function, entry))); |
| + |
| + // Enter the exit frame that transitions from JavaScript to C++. |
| +#ifdef _WIN64 |
| + int arg_stack_space = 2; |
| +#else // _WIN64 |
| + int arg_stack_space = 0; |
| +#endif // _WIN64 |
| + // TODO(rmcilroy): save fpregs if required. |
| + __ EnterApiExitFrame(arg_stack_space); |
| + |
| + // Check stack alignment. |
| + if (FLAG_debug_code) { |
| + __ CheckStackAlignment(); |
| + } |
| + |
| + // Call C function. |
| + // |
| + // Pass argv and argc as two parameters. The arguments object will |
| + // be created by stubs declared by DECLARE_RUNTIME_FUNCTION(). |
| +#ifdef _WIN64 |
| + // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9. |
| + __ movp(rcx, r14); // argc. |
| + __ movp(rdx, r15); // argv. |
| + __ Move(r8, ExternalReference::isolate_address(masm->isolate())); |
| +#else // _WIN64 |
| + // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9. |
| + __ movp(rdi, r14); // argc. |
| + __ movp(rsi, r15); // argv. |
| + __ Move(rdx, ExternalReference::isolate_address(masm->isolate())); |
| +#endif // _WIN64 |
| + __ call(rbx); |
| + // Result is in rax - do not destroy this register! |
| + |
| + // Check result for exception sentinel. |
| + Label exception_returned; |
| + __ CompareRoot(rax, Heap::kExceptionRootIndex); |
| + __ j(equal, &exception_returned); |
| + |
| + // Check that there is no pending exception, otherwise we |
| + // should have returned the exception sentinel. |
| + if (FLAG_debug_code) { |
| + Label okay; |
| + __ LoadRoot(r14, Heap::kTheHoleValueRootIndex); |
| + ExternalReference pending_exception_address( |
| + Isolate::kPendingExceptionAddress, masm->isolate()); |
| + Operand pending_exception_operand = |
| + masm->ExternalOperand(pending_exception_address); |
| + __ cmpp(r14, pending_exception_operand); |
| + __ j(equal, &okay, Label::kNear); |
| + __ int3(); |
| + __ bind(&okay); |
| + } |
| + |
| + // Exit the JavaScript to C++ exit frame. |
| + // TODO(rmcilroy): restore fpregs if required. |
| + __ LeaveExitFrame(false); |
| + __ ret(0); |
| + |
| + // TODO(rmcilroy): Handle exceptions. |
| + __ bind(&exception_returned); |
|
Michael Starzinger
2015/09/25 11:23:26
I am not too happy about duplicating the CEntryStu
rmcilroy
2015/09/28 16:20:47
Very good point. The missing thing in CEntryStub w
|
| + __ int3(); |
| +} |
| + |
| + |
| void Builtins::Generate_CompileLazy(MacroAssembler* masm) { |
| CallRuntimePassFunction(masm, Runtime::kCompileLazy); |
| GenerateTailCallToReturnedCode(masm); |
| @@ -1832,41 +1951,6 @@ void Builtins::Generate_Construct(MacroAssembler* masm) { |
| } |
| -// static |
| -void Builtins::Generate_PushArgsAndCall(MacroAssembler* masm) { |
| - // ----------- S t a t e ------------- |
| - // -- rax : the number of arguments (not including the receiver) |
| - // -- rbx : the address of the first argument to be pushed. Subsequent |
| - // arguments should be consecutive above this, in the same order as |
| - // they are to be pushed onto the stack. |
| - // -- rdi : the target to call (can be any Object). |
| - |
| - // Pop return address to allow tail-call after pushing arguments. |
| - __ Pop(rdx); |
| - |
| - // Find the address of the last argument. |
| - __ movp(rcx, rax); |
| - __ addp(rcx, Immediate(1)); // Add one for receiver. |
| - __ shlp(rcx, Immediate(kPointerSizeLog2)); |
| - __ negp(rcx); |
| - __ addp(rcx, rbx); |
| - |
| - // Push the arguments. |
| - Label loop_header, loop_check; |
| - __ j(always, &loop_check); |
| - __ bind(&loop_header); |
| - __ Push(Operand(rbx, 0)); |
| - __ subp(rbx, Immediate(kPointerSize)); |
| - __ bind(&loop_check); |
| - __ cmpp(rbx, rcx); |
| - __ j(greater, &loop_header, Label::kNear); |
| - |
| - // Call the target. |
| - __ Push(rdx); // Re-push return address. |
| - __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| -} |
| - |
| - |
| void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { |
| // Lookup the function in the JavaScript frame. |
| __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |