Index: src/mips/stub-cache-mips.cc |
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc |
index 97bd87202e456faf65aafb01f82efc1b5ef232fa..e0cf1b6363bef44944454946c6f8d41c54b4a0cd 100644 |
--- a/src/mips/stub-cache-mips.cc |
+++ b/src/mips/stub-cache-mips.cc |
@@ -829,23 +829,28 @@ static void FreeSpaceForFastApiCall(MacroAssembler* masm) { |
static void GenerateFastApiDirectCall(MacroAssembler* masm, |
const CallOptimization& optimization, |
- int argc) { |
+ int argc, |
+ bool restore_context) { |
// ----------- S t a t e ------------- |
- // -- sp[0] : holder (set by CheckPrototypes) |
- // -- sp[4] : callee JS function |
- // -- sp[8] : call data |
- // -- sp[12] : isolate |
- // -- sp[16] : ReturnValue default value |
- // -- sp[20] : ReturnValue |
- // -- sp[24] : last JS argument |
+ // -- sp[0] : context |
+ // -- sp[4] : holder (set by CheckPrototypes) |
+ // -- sp[8] : callee JS function |
+ // -- sp[12] : call data |
+ // -- sp[16] : isolate |
+ // -- sp[20] : ReturnValue default value |
+ // -- sp[24] : ReturnValue |
+ // -- sp[28] : last JS argument |
// -- ... |
- // -- sp[(argc + 5) * 4] : first JS argument |
- // -- sp[(argc + 6) * 4] : receiver |
+ // -- sp[(argc + 6) * 4] : first JS argument |
+ // -- sp[(argc + 7) * 4] : receiver |
// ----------------------------------- |
+ // Save calling context. |
+ __ sw(cp, MemOperand(sp)); |
// Get the function and setup the context. |
Handle<JSFunction> function = optimization.constant_function(); |
__ LoadHeapObject(t1, function); |
__ lw(cp, FieldMemOperand(t1, JSFunction::kContextOffset)); |
+ __ sw(t1, MemOperand(sp, 2 * kPointerSize)); |
// Pass the additional arguments. |
Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); |
@@ -856,18 +861,18 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, |
} else { |
__ li(t2, call_data); |
} |
- |
+ // Store call data. |
+ __ sw(t2, MemOperand(sp, 3 * kPointerSize)); |
+ // Store isolate. |
__ li(t3, Operand(ExternalReference::isolate_address(masm->isolate()))); |
- // Store JS function, call data, isolate ReturnValue default and ReturnValue. |
- __ sw(t1, MemOperand(sp, 1 * kPointerSize)); |
- __ sw(t2, MemOperand(sp, 2 * kPointerSize)); |
- __ sw(t3, MemOperand(sp, 3 * kPointerSize)); |
+ __ sw(t3, MemOperand(sp, 4 * kPointerSize)); |
+ // Store ReturnValue default and ReturnValue. |
__ LoadRoot(t1, Heap::kUndefinedValueRootIndex); |
- __ sw(t1, MemOperand(sp, 4 * kPointerSize)); |
__ sw(t1, MemOperand(sp, 5 * kPointerSize)); |
+ __ sw(t1, MemOperand(sp, 6 * kPointerSize)); |
// Prepare arguments. |
- __ Addu(a2, sp, Operand(5 * kPointerSize)); |
+ __ Addu(a2, sp, Operand((kFastApiCallArguments - 1) * kPointerSize)); |
// Allocate the v8::Arguments structure in the arguments' space since |
// it's not controlled by GC. |
@@ -906,12 +911,18 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, |
masm->isolate()); |
AllowExternalCallThatCantCauseGC scope(masm); |
+ MemOperand context_restore_operand( |
+ fp, 2 * kPointerSize); |
+ MemOperand return_value_operand( |
+ fp, (kFastApiCallArguments + 1) * kPointerSize); |
__ CallApiFunctionAndReturn(ref, |
function_address, |
thunk_ref, |
a1, |
kStackUnwindSpace, |
- kFastApiCallArguments + 1); |
+ return_value_operand, |
+ restore_context ? |
+ &context_restore_operand : NULL); |
} |
@@ -926,10 +937,12 @@ static void GenerateFastApiCall(MacroAssembler* masm, |
ASSERT(!receiver.is(scratch)); |
const int stack_space = kFastApiCallArguments + argc + 1; |
+ const int kHolderIndex = kFastApiCallArguments + |
+ FunctionCallbackArguments::kHolderIndex - 1; |
// Assign stack space for the call arguments. |
__ Subu(sp, sp, Operand(stack_space * kPointerSize)); |
// Write holder to stack frame. |
- __ sw(receiver, MemOperand(sp, 0)); |
+ __ sw(receiver, MemOperand(sp, kHolderIndex * kPointerSize)); |
// Write receiver to stack frame. |
int index = stack_space - 1; |
__ sw(receiver, MemOperand(sp, index * kPointerSize)); |
@@ -940,7 +953,7 @@ static void GenerateFastApiCall(MacroAssembler* masm, |
__ sw(receiver, MemOperand(sp, index-- * kPointerSize)); |
} |
- GenerateFastApiDirectCall(masm, optimization, argc); |
+ GenerateFastApiDirectCall(masm, optimization, argc, true); |
} |
@@ -1054,7 +1067,8 @@ class CallInterceptorCompiler BASE_EMBEDDED { |
// Invoke function. |
if (can_do_fast_api_call) { |
- GenerateFastApiDirectCall(masm, optimization, arguments_.immediate()); |
+ GenerateFastApiDirectCall( |
+ masm, optimization, arguments_.immediate(), false); |
} else { |
CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) |
? CALL_AS_FUNCTION |
@@ -1181,6 +1195,8 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object, |
int save_at_depth, |
Label* miss, |
PrototypeCheckType check) { |
+ const int kHolderIndex = kFastApiCallArguments + |
+ FunctionCallbackArguments::kHolderIndex - 1; |
// Make sure that the type feedback oracle harvests the receiver map. |
// TODO(svenpanne) Remove this hack when all ICs are reworked. |
__ li(scratch1, Operand(Handle<Map>(object->map()))); |
@@ -1196,7 +1212,7 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object, |
int depth = 0; |
if (save_at_depth == depth) { |
- __ sw(reg, MemOperand(sp)); |
+ __ sw(reg, MemOperand(sp, kHolderIndex * kPointerSize)); |
} |
// Check the maps in the prototype chain. |
@@ -1254,7 +1270,7 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object, |
} |
if (save_at_depth == depth) { |
- __ sw(reg, MemOperand(sp)); |
+ __ sw(reg, MemOperand(sp, kHolderIndex * kPointerSize)); |
} |
// Go to the next object in the prototype chain. |
@@ -1454,7 +1470,7 @@ void BaseLoadStubCompiler::GenerateLoadCallback( |
// (second argument - a1) = AccessorInfo& |
__ Addu(a1, sp, kPointerSize); |
- const int kStackUnwindSpace = kFastApiCallArguments + 1; |
+ const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; |
Address getter_address = v8::ToCData<Address>(callback->getter()); |
ApiFunction fun(getter_address); |
ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; |
@@ -1471,7 +1487,8 @@ void BaseLoadStubCompiler::GenerateLoadCallback( |
thunk_ref, |
a2, |
kStackUnwindSpace, |
- 6); |
+ MemOperand(fp, 6 * kPointerSize), |
+ NULL); |
} |
@@ -2554,7 +2571,7 @@ Handle<Code> CallStubCompiler::CompileFastApiCall( |
CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, a0, a3, t0, name, |
depth, &miss); |
- GenerateFastApiDirectCall(masm(), optimization, argc); |
+ GenerateFastApiDirectCall(masm(), optimization, argc, false); |
__ bind(&miss); |
FreeSpaceForFastApiCall(masm()); |