Commit d047afb4 authored by plind44@gmail.com's avatar plind44@gmail.com

MIPS: reland 16744: add context save for GenerateFastApiCall.

Port r16763 (968acfa)

BUG=
R=plind44@gmail.com

Review URL: https://codereview.chromium.org/23475052

Patch from Balazs Kilvady <kilvadyb@homejinni.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16778 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 2974f8e3
...@@ -2876,7 +2876,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, ...@@ -2876,7 +2876,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
// v0:v1: result // v0:v1: result
// sp: stack pointer // sp: stack pointer
// fp: frame pointer // fp: frame pointer
__ LeaveExitFrame(save_doubles_, s0, true); __ LeaveExitFrame(save_doubles_, s0, true, EMIT_RETURN);
// Check if we should retry or throw exception. // Check if we should retry or throw exception.
Label retry; Label retry;
...@@ -4156,7 +4156,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { ...@@ -4156,7 +4156,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
DirectCEntryStub stub; DirectCEntryStub stub;
stub.GenerateCall(masm, t9); stub.GenerateCall(masm, t9);
__ LeaveExitFrame(false, no_reg); __ LeaveExitFrame(false, no_reg, true);
// v0: result // v0: result
// subject: subject string (callee saved) // subject: subject string (callee saved)
......
...@@ -3847,12 +3847,14 @@ static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { ...@@ -3847,12 +3847,14 @@ static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
} }
void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function, void MacroAssembler::CallApiFunctionAndReturn(
Address function_address, ExternalReference function,
ExternalReference thunk_ref, Address function_address,
Register thunk_last_arg, ExternalReference thunk_ref,
int stack_space, Register thunk_last_arg,
int return_value_offset_from_fp) { int stack_space,
MemOperand return_value_operand,
MemOperand* context_restore_operand) {
ExternalReference next_address = ExternalReference next_address =
ExternalReference::handle_scope_next_address(isolate()); ExternalReference::handle_scope_next_address(isolate());
const int kNextOffset = 0; const int kNextOffset = 0;
...@@ -3915,12 +3917,13 @@ void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function, ...@@ -3915,12 +3917,13 @@ void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function,
} }
Label promote_scheduled_exception; Label promote_scheduled_exception;
Label exception_handled;
Label delete_allocated_handles; Label delete_allocated_handles;
Label leave_exit_frame; Label leave_exit_frame;
Label return_value_loaded; Label return_value_loaded;
// Load value from ReturnValue. // Load value from ReturnValue.
lw(v0, MemOperand(fp, return_value_offset_from_fp*kPointerSize)); lw(v0, return_value_operand);
bind(&return_value_loaded); bind(&return_value_loaded);
// No more valid handles (the result handle was the last one). Restore // No more valid handles (the result handle was the last one). Restore
...@@ -3941,14 +3944,23 @@ void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function, ...@@ -3941,14 +3944,23 @@ void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function,
li(at, Operand(ExternalReference::scheduled_exception_address(isolate()))); li(at, Operand(ExternalReference::scheduled_exception_address(isolate())));
lw(t1, MemOperand(at)); lw(t1, MemOperand(at));
Branch(&promote_scheduled_exception, ne, t0, Operand(t1)); Branch(&promote_scheduled_exception, ne, t0, Operand(t1));
bind(&exception_handled);
bool restore_context = context_restore_operand != NULL;
if (restore_context) {
lw(cp, *context_restore_operand);
}
li(s0, Operand(stack_space)); li(s0, Operand(stack_space));
LeaveExitFrame(false, s0, true); LeaveExitFrame(false, s0, !restore_context, EMIT_RETURN);
bind(&promote_scheduled_exception); bind(&promote_scheduled_exception);
TailCallExternalReference( {
ExternalReference(Runtime::kPromoteScheduledException, isolate()), FrameScope frame(this, StackFrame::INTERNAL);
0, CallExternalReference(
1); ExternalReference(Runtime::kPromoteScheduledException, isolate()),
0);
}
jmp(&exception_handled);
// HandleScope limit has changed. Delete allocated extensions. // HandleScope limit has changed. Delete allocated extensions.
bind(&delete_allocated_handles); bind(&delete_allocated_handles);
...@@ -4684,6 +4696,7 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, ...@@ -4684,6 +4696,7 @@ void MacroAssembler::EnterExitFrame(bool save_doubles,
void MacroAssembler::LeaveExitFrame(bool save_doubles, void MacroAssembler::LeaveExitFrame(bool save_doubles,
Register argument_count, Register argument_count,
bool restore_context,
bool do_return) { bool do_return) {
// Optionally restore all double registers. // Optionally restore all double registers.
if (save_doubles) { if (save_doubles) {
...@@ -4700,9 +4713,12 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, ...@@ -4700,9 +4713,12 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles,
sw(zero_reg, MemOperand(t8)); sw(zero_reg, MemOperand(t8));
// Restore current context from top and clear it in debug mode. // Restore current context from top and clear it in debug mode.
li(t8, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); if (restore_context) {
lw(cp, MemOperand(t8)); li(t8, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
lw(cp, MemOperand(t8));
}
#ifdef DEBUG #ifdef DEBUG
li(t8, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
sw(a3, MemOperand(t8)); sw(a3, MemOperand(t8));
#endif #endif
......
...@@ -51,6 +51,12 @@ class JumpTarget; ...@@ -51,6 +51,12 @@ class JumpTarget;
// MIPS generated code calls C code, it must be via t9 register. // MIPS generated code calls C code, it must be via t9 register.
// Flags used for LeaveExitFrame function.
enum LeaveExitFrameMode {
EMIT_RETURN = true,
NO_EMIT_RETURN = false
};
// Flags used for AllocateHeapNumber // Flags used for AllocateHeapNumber
enum TaggingMode { enum TaggingMode {
// Tag the result. // Tag the result.
...@@ -848,7 +854,8 @@ class MacroAssembler: public Assembler { ...@@ -848,7 +854,8 @@ class MacroAssembler: public Assembler {
// Leave the current exit frame. // Leave the current exit frame.
void LeaveExitFrame(bool save_doubles, void LeaveExitFrame(bool save_doubles,
Register arg_count, Register arg_count,
bool do_return = false); bool restore_context,
bool do_return = NO_EMIT_RETURN);
// Get the actual activation frame alignment for target environment. // Get the actual activation frame alignment for target environment.
static int ActivationFrameAlignment(); static int ActivationFrameAlignment();
...@@ -1271,7 +1278,8 @@ class MacroAssembler: public Assembler { ...@@ -1271,7 +1278,8 @@ class MacroAssembler: public Assembler {
ExternalReference thunk_ref, ExternalReference thunk_ref,
Register thunk_last_arg, Register thunk_last_arg,
int stack_space, int stack_space,
int return_value_offset_from_fp); MemOperand return_value_operand,
MemOperand* context_restore_operand);
// Jump to the builtin routine. // Jump to the builtin routine.
void JumpToExternalReference(const ExternalReference& builtin, void JumpToExternalReference(const ExternalReference& builtin,
......
...@@ -829,23 +829,28 @@ static void FreeSpaceForFastApiCall(MacroAssembler* masm) { ...@@ -829,23 +829,28 @@ static void FreeSpaceForFastApiCall(MacroAssembler* masm) {
static void GenerateFastApiDirectCall(MacroAssembler* masm, static void GenerateFastApiDirectCall(MacroAssembler* masm,
const CallOptimization& optimization, const CallOptimization& optimization,
int argc) { int argc,
bool restore_context) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- sp[0] : holder (set by CheckPrototypes) // -- sp[0] : context
// -- sp[4] : callee JS function // -- sp[4] : holder (set by CheckPrototypes)
// -- sp[8] : call data // -- sp[8] : callee JS function
// -- sp[12] : isolate // -- sp[12] : call data
// -- sp[16] : ReturnValue default value // -- sp[16] : isolate
// -- sp[20] : ReturnValue // -- sp[20] : ReturnValue default value
// -- sp[24] : last JS argument // -- sp[24] : ReturnValue
// -- sp[28] : last JS argument
// -- ... // -- ...
// -- sp[(argc + 5) * 4] : first JS argument // -- sp[(argc + 6) * 4] : first JS argument
// -- sp[(argc + 6) * 4] : receiver // -- sp[(argc + 7) * 4] : receiver
// ----------------------------------- // -----------------------------------
// Save calling context.
__ sw(cp, MemOperand(sp));
// Get the function and setup the context. // Get the function and setup the context.
Handle<JSFunction> function = optimization.constant_function(); Handle<JSFunction> function = optimization.constant_function();
__ LoadHeapObject(t1, function); __ LoadHeapObject(t1, function);
__ lw(cp, FieldMemOperand(t1, JSFunction::kContextOffset)); __ lw(cp, FieldMemOperand(t1, JSFunction::kContextOffset));
__ sw(t1, MemOperand(sp, 2 * kPointerSize));
// Pass the additional arguments. // Pass the additional arguments.
Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
...@@ -856,18 +861,18 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, ...@@ -856,18 +861,18 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
} else { } else {
__ li(t2, call_data); __ li(t2, call_data);
} }
// Store call data.
__ sw(t2, MemOperand(sp, 3 * kPointerSize));
// Store isolate.
__ li(t3, Operand(ExternalReference::isolate_address(masm->isolate()))); __ li(t3, Operand(ExternalReference::isolate_address(masm->isolate())));
// Store JS function, call data, isolate ReturnValue default and ReturnValue. __ sw(t3, MemOperand(sp, 4 * kPointerSize));
__ sw(t1, MemOperand(sp, 1 * kPointerSize)); // Store ReturnValue default and ReturnValue.
__ sw(t2, MemOperand(sp, 2 * kPointerSize));
__ sw(t3, MemOperand(sp, 3 * kPointerSize));
__ LoadRoot(t1, Heap::kUndefinedValueRootIndex); __ LoadRoot(t1, Heap::kUndefinedValueRootIndex);
__ sw(t1, MemOperand(sp, 4 * kPointerSize));
__ sw(t1, MemOperand(sp, 5 * kPointerSize)); __ sw(t1, MemOperand(sp, 5 * kPointerSize));
__ sw(t1, MemOperand(sp, 6 * kPointerSize));
// Prepare arguments. // 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 // Allocate the v8::Arguments structure in the arguments' space since
// it's not controlled by GC. // it's not controlled by GC.
...@@ -906,12 +911,18 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, ...@@ -906,12 +911,18 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
masm->isolate()); masm->isolate());
AllowExternalCallThatCantCauseGC scope(masm); AllowExternalCallThatCantCauseGC scope(masm);
MemOperand context_restore_operand(
fp, 2 * kPointerSize);
MemOperand return_value_operand(
fp, (kFastApiCallArguments + 1) * kPointerSize);
__ CallApiFunctionAndReturn(ref, __ CallApiFunctionAndReturn(ref,
function_address, function_address,
thunk_ref, thunk_ref,
a1, a1,
kStackUnwindSpace, kStackUnwindSpace,
kFastApiCallArguments + 1); return_value_operand,
restore_context ?
&context_restore_operand : NULL);
} }
...@@ -926,10 +937,12 @@ static void GenerateFastApiCall(MacroAssembler* masm, ...@@ -926,10 +937,12 @@ static void GenerateFastApiCall(MacroAssembler* masm,
ASSERT(!receiver.is(scratch)); ASSERT(!receiver.is(scratch));
const int stack_space = kFastApiCallArguments + argc + 1; const int stack_space = kFastApiCallArguments + argc + 1;
const int kHolderIndex = kFastApiCallArguments +
FunctionCallbackArguments::kHolderIndex - 1;
// Assign stack space for the call arguments. // Assign stack space for the call arguments.
__ Subu(sp, sp, Operand(stack_space * kPointerSize)); __ Subu(sp, sp, Operand(stack_space * kPointerSize));
// Write holder to stack frame. // Write holder to stack frame.
__ sw(receiver, MemOperand(sp, 0)); __ sw(receiver, MemOperand(sp, kHolderIndex * kPointerSize));
// Write receiver to stack frame. // Write receiver to stack frame.
int index = stack_space - 1; int index = stack_space - 1;
__ sw(receiver, MemOperand(sp, index * kPointerSize)); __ sw(receiver, MemOperand(sp, index * kPointerSize));
...@@ -940,7 +953,7 @@ static void GenerateFastApiCall(MacroAssembler* masm, ...@@ -940,7 +953,7 @@ static void GenerateFastApiCall(MacroAssembler* masm,
__ sw(receiver, MemOperand(sp, index-- * kPointerSize)); __ sw(receiver, MemOperand(sp, index-- * kPointerSize));
} }
GenerateFastApiDirectCall(masm, optimization, argc); GenerateFastApiDirectCall(masm, optimization, argc, true);
} }
...@@ -1054,7 +1067,8 @@ class CallInterceptorCompiler BASE_EMBEDDED { ...@@ -1054,7 +1067,8 @@ class CallInterceptorCompiler BASE_EMBEDDED {
// Invoke function. // Invoke function.
if (can_do_fast_api_call) { if (can_do_fast_api_call) {
GenerateFastApiDirectCall(masm, optimization, arguments_.immediate()); GenerateFastApiDirectCall(
masm, optimization, arguments_.immediate(), false);
} else { } else {
CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
? CALL_AS_FUNCTION ? CALL_AS_FUNCTION
...@@ -1181,6 +1195,8 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object, ...@@ -1181,6 +1195,8 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
int save_at_depth, int save_at_depth,
Label* miss, Label* miss,
PrototypeCheckType check) { PrototypeCheckType check) {
const int kHolderIndex = kFastApiCallArguments +
FunctionCallbackArguments::kHolderIndex - 1;
// Make sure that the type feedback oracle harvests the receiver map. // Make sure that the type feedback oracle harvests the receiver map.
// TODO(svenpanne) Remove this hack when all ICs are reworked. // TODO(svenpanne) Remove this hack when all ICs are reworked.
__ li(scratch1, Operand(Handle<Map>(object->map()))); __ li(scratch1, Operand(Handle<Map>(object->map())));
...@@ -1196,7 +1212,7 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object, ...@@ -1196,7 +1212,7 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
int depth = 0; int depth = 0;
if (save_at_depth == depth) { if (save_at_depth == depth) {
__ sw(reg, MemOperand(sp)); __ sw(reg, MemOperand(sp, kHolderIndex * kPointerSize));
} }
// Check the maps in the prototype chain. // Check the maps in the prototype chain.
...@@ -1254,7 +1270,7 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object, ...@@ -1254,7 +1270,7 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
} }
if (save_at_depth == depth) { if (save_at_depth == depth) {
__ sw(reg, MemOperand(sp)); __ sw(reg, MemOperand(sp, kHolderIndex * kPointerSize));
} }
// Go to the next object in the prototype chain. // Go to the next object in the prototype chain.
...@@ -1454,7 +1470,7 @@ void BaseLoadStubCompiler::GenerateLoadCallback( ...@@ -1454,7 +1470,7 @@ void BaseLoadStubCompiler::GenerateLoadCallback(
// (second argument - a1) = AccessorInfo& // (second argument - a1) = AccessorInfo&
__ Addu(a1, sp, kPointerSize); __ Addu(a1, sp, kPointerSize);
const int kStackUnwindSpace = kFastApiCallArguments + 1; const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
Address getter_address = v8::ToCData<Address>(callback->getter()); Address getter_address = v8::ToCData<Address>(callback->getter());
ApiFunction fun(getter_address); ApiFunction fun(getter_address);
ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
...@@ -1471,7 +1487,8 @@ void BaseLoadStubCompiler::GenerateLoadCallback( ...@@ -1471,7 +1487,8 @@ void BaseLoadStubCompiler::GenerateLoadCallback(
thunk_ref, thunk_ref,
a2, a2,
kStackUnwindSpace, kStackUnwindSpace,
6); MemOperand(fp, 6 * kPointerSize),
NULL);
} }
...@@ -2554,7 +2571,7 @@ Handle<Code> CallStubCompiler::CompileFastApiCall( ...@@ -2554,7 +2571,7 @@ Handle<Code> CallStubCompiler::CompileFastApiCall(
CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, a0, a3, t0, name, CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, a0, a3, t0, name,
depth, &miss); depth, &miss);
GenerateFastApiDirectCall(masm(), optimization, argc); GenerateFastApiDirectCall(masm(), optimization, argc, false);
__ bind(&miss); __ bind(&miss);
FreeSpaceForFastApiCall(masm()); FreeSpaceForFastApiCall(masm());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment