| Index: src/x64/stub-cache-x64.cc
|
| ===================================================================
|
| --- src/x64/stub-cache-x64.cc (revision 5834)
|
| +++ src/x64/stub-cache-x64.cc (working copy)
|
| @@ -500,7 +500,7 @@
|
| // Number of pointers to be reserved on stack for fast API call.
|
| static const int kFastApiCallArguments = 3;
|
|
|
| -// Reserves space for the extra arguments to FastHandleApiCall in the
|
| +// Reserves space for the extra arguments to API function in the
|
| // caller's frame.
|
| //
|
| // These arguments are set by CheckPrototypes and GenerateFastApiCall.
|
| @@ -535,7 +535,7 @@
|
| }
|
|
|
|
|
| -// Generates call to FastHandleApiCall builtin.
|
| +// Generates call to API function.
|
| static bool GenerateFastApiCall(MacroAssembler* masm,
|
| const CallOptimization& optimization,
|
| int argc,
|
| @@ -559,7 +559,7 @@
|
| __ Move(rdi, Handle<JSFunction>(function));
|
| __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
|
|
|
| - // Pass the additional arguments FastHandleApiCall expects.
|
| + // Pass the additional arguments.
|
| __ movq(Operand(rsp, 2 * kPointerSize), rdi);
|
| Object* call_data = optimization.api_call_info()->data();
|
| Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info());
|
| @@ -589,7 +589,7 @@
|
| // it's not controlled by GC.
|
| const int kApiStackSpace = 4;
|
|
|
| - __ PrepareCallApiFunction(argc + kFastApiCallArguments + 1, kApiStackSpace);
|
| + __ PrepareCallApiFunction(kApiStackSpace);
|
|
|
| __ movq(StackSpaceOperand(0), rbx); // v8::Arguments::implicit_args_.
|
| __ addq(rbx, Immediate(argc * kPointerSize));
|
| @@ -605,7 +605,7 @@
|
| // garbage collection but instead return the allocation failure
|
| // object.
|
| MaybeObject* result =
|
| - masm->TryCallApiFunctionAndReturn(&fun);
|
| + masm->TryCallApiFunctionAndReturn(&fun, argc + kFastApiCallArguments + 1);
|
| if (result->IsFailure()) {
|
| *failure = Failure::cast(result);
|
| return false;
|
| @@ -992,7 +992,9 @@
|
|
|
| if (depth != kInvalidProtoDepth) {
|
| __ IncrementCounter(&Counters::call_const_fast_api, 1);
|
| - ReserveSpaceForFastApiCall(masm(), rax);
|
| + // Allocate space for v8::Arguments implicit values. Must be initialized
|
| + // before to call any runtime function.
|
| + __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
|
| }
|
|
|
| // Check that the maps haven't changed.
|
| @@ -1071,6 +1073,12 @@
|
|
|
| if (depth != kInvalidProtoDepth) {
|
| Failure* failure;
|
| + // Move the return address on top of the stack.
|
| + __ movq(rax, Operand(rsp, 3 * kPointerSize));
|
| + __ movq(Operand(rsp, 0 * kPointerSize), rax);
|
| +
|
| + // rsp[2 * kPointerSize] is uninitialized, rsp[3 * kPointerSize] contains
|
| + // duplicate of return address and will be overwritten.
|
| bool success = GenerateFastApiCall(masm(), optimization, argc, &failure);
|
| if (!success) {
|
| return failure;
|
| @@ -1082,7 +1090,7 @@
|
| // Handle call cache miss.
|
| __ bind(&miss);
|
| if (depth != kInvalidProtoDepth) {
|
| - FreeSpaceForFastApiCall(masm(), rax);
|
| + __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
|
| }
|
|
|
| // Handle call cache miss.
|
| @@ -2633,8 +2641,6 @@
|
| __ pop(scratch2); // Get return address to place it below.
|
|
|
| __ push(receiver); // receiver
|
| - ASSERT(!scratch3.is(reg));
|
| - __ movq(scratch3, rsp);
|
| __ push(reg); // holder
|
| if (Heap::InNewSpace(callback_handle->data())) {
|
| __ Move(scratch1, callback_handle);
|
| @@ -2642,7 +2648,6 @@
|
| } else {
|
| __ Push(Handle<Object>(callback_handle->data()));
|
| }
|
| - __ push(scratch3);
|
| __ push(name_reg); // name
|
| // Save a pointer to where we pushed the arguments pointer.
|
| // This will be passed as the const AccessorInfo& to the C++ callback.
|
| @@ -2664,22 +2669,27 @@
|
| Address getter_address = v8::ToCData<Address>(callback->getter());
|
| ApiFunction fun(getter_address);
|
|
|
| - // 3 elements array for v8::Agruments::values_, handler for name and pointer
|
| - // to the values (it considered as smi in GC).
|
| - const int kStackSpace = 5;
|
| - const int kApiArgc = 2;
|
| + // 3 elements array for v8::Agruments::values_ and handler for name.
|
| + const int kStackSpace = 4;
|
|
|
| - __ PrepareCallApiFunction(kStackSpace, kApiArgc);
|
| + // Allocate v8::AccessorInfo in non-GCed stack space.
|
| + const int kArgStackSpace = 1;
|
|
|
| + __ PrepareCallApiFunction(kArgStackSpace);
|
| + __ lea(rax, Operand(name_arg, 3 * kPointerSize));
|
| +
|
| + // v8::AccessorInfo::args_.
|
| + __ movq(StackSpaceOperand(0), rax);
|
| +
|
| // The context register (rsi) has been saved in PrepareCallApiFunction and
|
| // could be used to pass arguments.
|
| - __ lea(accessor_info_arg, Operand(name_arg, 1 * kPointerSize));
|
| + __ lea(accessor_info_arg, StackSpaceOperand(0));
|
|
|
| // Emitting a stub call may try to allocate (if the code is not
|
| // already generated). Do not allow the assembler to perform a
|
| // garbage collection but instead return the allocation failure
|
| // object.
|
| - MaybeObject* result = masm()->TryCallApiFunctionAndReturn(&fun);
|
| + MaybeObject* result = masm()->TryCallApiFunctionAndReturn(&fun, kStackSpace);
|
| if (result->IsFailure()) {
|
| *failure = Failure::cast(result);
|
| return false;
|
|
|