| Index: src/mips/stub-cache-mips.cc
|
| diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
|
| index ef98db59bb8288a52e746dbb9d0a79c9456a5acf..f90db7cdcd3ebda3154a30f218adbc3eaab01767 100644
|
| --- a/src/mips/stub-cache-mips.cc
|
| +++ b/src/mips/stub-cache-mips.cc
|
| @@ -765,98 +765,43 @@ static void CompileCallLoadPropertyWithInterceptor(
|
| }
|
|
|
|
|
| -static const int kFastApiCallArguments = FunctionCallbackArguments::kArgsLength;
|
| -
|
| -
|
| static void GenerateFastApiCallBody(MacroAssembler* masm,
|
| const CallOptimization& optimization,
|
| int argc,
|
| - Register holder,
|
| - Register scratch1,
|
| - Register scratch2,
|
| - Register scratch3,
|
| + Register holder_in,
|
| bool restore_context) {
|
| - // ----------- S t a t e -------------
|
| - // -- sp[0] : last JS argument
|
| - // -- ...
|
| - // -- sp[(argc - 1) * 4] : first JS argument
|
| - // -- sp[argc * 4] : receiver
|
| - // -----------------------------------
|
| ASSERT(optimization.is_simple_api_call());
|
|
|
| - typedef FunctionCallbackArguments FCA;
|
| -
|
| - STATIC_ASSERT(FCA::kHolderIndex == 0);
|
| - STATIC_ASSERT(FCA::kIsolateIndex == 1);
|
| - STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2);
|
| - STATIC_ASSERT(FCA::kReturnValueOffset == 3);
|
| - STATIC_ASSERT(FCA::kDataIndex == 4);
|
| - STATIC_ASSERT(FCA::kCalleeIndex == 5);
|
| - STATIC_ASSERT(FCA::kContextSaveIndex == 6);
|
| - STATIC_ASSERT(FCA::kArgsLength == 7);
|
| + // Abi for CallApiFunctionStub.
|
| + Register callee = a0;
|
| + Register call_data = t0;
|
| + Register holder = a2;
|
| + Register api_function_address = a3;
|
| + Register thunk_arg = a1;
|
|
|
| - ASSERT(!holder.is(cp));
|
| + // Put holder in place.
|
| + __ mov(holder, holder_in);
|
|
|
| - // Save calling context.
|
| - __ push(cp);
|
| - // Get the function and setup the context.
|
| + Isolate* isolate = masm->isolate();
|
| Handle<JSFunction> function = optimization.constant_function();
|
| - __ li(scratch1, function);
|
| - __ lw(cp, FieldMemOperand(scratch1, JSFunction::kContextOffset));
|
| - __ push(scratch1);
|
| -
|
| - // Construct the FunctionCallbackInfo.
|
| Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
|
| - Handle<Object> call_data(api_call_info->data(), masm->isolate());
|
| + Handle<Object> call_data_obj(api_call_info->data(), isolate);
|
| +
|
| + // Put callee in place.
|
| + __ li(callee, function);
|
| +
|
| bool call_data_undefined = false;
|
| - if (masm->isolate()->heap()->InNewSpace(*call_data)) {
|
| - __ li(scratch1, api_call_info);
|
| - __ lw(scratch1, FieldMemOperand(scratch1, CallHandlerInfo::kDataOffset));
|
| - } else if (call_data->IsUndefined()) {
|
| + // Put call_data in place.
|
| + if (isolate->heap()->InNewSpace(*call_data_obj)) {
|
| + __ li(call_data, api_call_info);
|
| + __ lw(call_data, FieldMemOperand(call_data, CallHandlerInfo::kDataOffset));
|
| + } else if (call_data_obj->IsUndefined()) {
|
| call_data_undefined = true;
|
| - __ LoadRoot(scratch3, Heap::kUndefinedValueRootIndex);
|
| + __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
|
| } else {
|
| - __ li(scratch1, call_data);
|
| - }
|
| - // Store call data.
|
| - __ push(scratch1);
|
| - if (!call_data_undefined) {
|
| - __ LoadRoot(scratch1, Heap::kUndefinedValueRootIndex);
|
| + __ li(call_data, call_data_obj);
|
| }
|
| - // Store ReturnValue default and ReturnValue.
|
| - __ LoadRoot(scratch1, Heap::kUndefinedValueRootIndex);
|
| - __ Push(scratch1, scratch1);
|
| - // Store isolate.
|
| - __ li(scratch1, Operand(ExternalReference::isolate_address(masm->isolate())));
|
| - __ push(scratch1);
|
| - // Store holder.
|
| - __ push(holder);
|
| -
|
| - // Prepare arguments.
|
| - __ Move(a2, sp);
|
| -
|
| - // Allocate the v8::Arguments structure in the arguments' space since
|
| - // it's not controlled by GC.
|
| - const int kApiStackSpace = 4;
|
| -
|
| - FrameScope frame_scope(masm, StackFrame::MANUAL);
|
| - __ EnterExitFrame(false, kApiStackSpace);
|
| -
|
| - // a0 = FunctionCallbackInfo&
|
| - // Arguments is built at sp + 1 (sp is a reserved spot for ra).
|
| - __ Addu(a0, sp, kPointerSize);
|
| - // FunctionCallbackInfo::implicit_args_
|
| - __ sw(a2, MemOperand(a0, 0 * kPointerSize));
|
| - // FunctionCallbackInfo::values_
|
| - __ Addu(t0, a2, Operand((kFastApiCallArguments - 1 + argc) * kPointerSize));
|
| - __ sw(t0, MemOperand(a0, 1 * kPointerSize));
|
| - // FunctionCallbackInfo::length_ = argc
|
| - __ li(t0, Operand(argc));
|
| - __ sw(t0, MemOperand(a0, 2 * kPointerSize));
|
| - // FunctionCallbackInfo::is_construct_call = 0
|
| - __ sw(zero_reg, MemOperand(a0, 3 * kPointerSize));
|
| -
|
| - const int kStackUnwindSpace = argc + kFastApiCallArguments + 1;
|
| + // Put api_function_address in place.
|
| Address function_address = v8::ToCData<Address>(api_call_info->callback());
|
| ApiFunction fun(function_address);
|
| ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
|
| @@ -864,26 +809,12 @@ static void GenerateFastApiCallBody(MacroAssembler* masm,
|
| ExternalReference(&fun,
|
| type,
|
| masm->isolate());
|
| - Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
|
| - ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL;
|
| - ApiFunction thunk_fun(thunk_address);
|
| - ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
|
| - masm->isolate());
|
| -
|
| - AllowExternalCallThatCantCauseGC scope(masm);
|
| - MemOperand context_restore_operand(
|
| - fp, (2 + FCA::kContextSaveIndex) * kPointerSize);
|
| - MemOperand return_value_operand(
|
| - fp, (2 + FCA::kReturnValueOffset) * kPointerSize);
|
| + __ li(api_function_address, Operand(ref));
|
| + __ li(thunk_arg, Operand(reinterpret_cast<int32_t>(function_address)));
|
|
|
| - __ CallApiFunctionAndReturn(ref,
|
| - function_address,
|
| - thunk_ref,
|
| - a1,
|
| - kStackUnwindSpace,
|
| - return_value_operand,
|
| - restore_context ?
|
| - &context_restore_operand : NULL);
|
| + // Jump to stub.
|
| + CallApiFunctionStub stub(restore_context, call_data_undefined, argc);
|
| + __ TailCallStub(&stub);
|
| }
|
|
|
|
|
| @@ -897,7 +828,7 @@ static void GenerateFastApiCall(MacroAssembler* masm,
|
| __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a1);
|
|
|
| // Move holder to a register.
|
| - Register holder_reg = a0;
|
| + Register holder_reg = a2;
|
| switch (holder_lookup) {
|
| case CallOptimization::kHolderIsReceiver:
|
| {
|
| @@ -924,9 +855,6 @@ static void GenerateFastApiCall(MacroAssembler* masm,
|
| optimization,
|
| argc,
|
| holder_reg,
|
| - a1,
|
| - a2,
|
| - a3,
|
| false);
|
| }
|
|
|
| @@ -948,21 +876,11 @@ static void GenerateFastApiCall(MacroAssembler* masm,
|
| __ push(arg);
|
| }
|
|
|
| - Register scratch1 = a0;
|
| - Register scratch2 = a1;
|
| - Register scratch3 = a2;
|
| - if (!a3.is(receiver)) {
|
| - __ mov(a3, receiver);
|
| - receiver = a3;
|
| - }
|
| // Stack now matches JSFunction abi.
|
| GenerateFastApiCallBody(masm,
|
| optimization,
|
| argc,
|
| receiver,
|
| - scratch1,
|
| - scratch2,
|
| - scratch3,
|
| true);
|
| }
|
|
|
| @@ -1412,6 +1330,10 @@ void LoadStubCompiler::GenerateLoadCallback(
|
| ApiFunction fun(getter_address);
|
| ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
|
| ExternalReference ref = ExternalReference(&fun, type, isolate());
|
| + Register getter_address_reg = a3;
|
| + Register thunk_last_arg = a2;
|
| + __ li(getter_address_reg, Operand(ref));
|
| + __ li(thunk_last_arg, Operand(reinterpret_cast<int32_t>(getter_address)));
|
|
|
| Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
|
| ExternalReference::Type thunk_type =
|
| @@ -1419,10 +1341,9 @@ void LoadStubCompiler::GenerateLoadCallback(
|
| ApiFunction thunk_fun(thunk_address);
|
| ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
|
| isolate());
|
| - __ CallApiFunctionAndReturn(ref,
|
| - getter_address,
|
| + __ CallApiFunctionAndReturn(getter_address_reg,
|
| thunk_ref,
|
| - a2,
|
| + thunk_last_arg,
|
| kStackUnwindSpace,
|
| MemOperand(fp, 6 * kPointerSize),
|
| NULL);
|
|
|