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
This commit is contained in:
parent
2974f8e3bb
commit
d047afb4fe
@ -2876,7 +2876,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
|
||||
// v0:v1: result
|
||||
// sp: stack pointer
|
||||
// fp: frame pointer
|
||||
__ LeaveExitFrame(save_doubles_, s0, true);
|
||||
__ LeaveExitFrame(save_doubles_, s0, true, EMIT_RETURN);
|
||||
|
||||
// Check if we should retry or throw exception.
|
||||
Label retry;
|
||||
@ -4156,7 +4156,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
|
||||
DirectCEntryStub stub;
|
||||
stub.GenerateCall(masm, t9);
|
||||
|
||||
__ LeaveExitFrame(false, no_reg);
|
||||
__ LeaveExitFrame(false, no_reg, true);
|
||||
|
||||
// v0: result
|
||||
// subject: subject string (callee saved)
|
||||
|
@ -3847,12 +3847,14 @@ static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function,
|
||||
Address function_address,
|
||||
ExternalReference thunk_ref,
|
||||
Register thunk_last_arg,
|
||||
int stack_space,
|
||||
int return_value_offset_from_fp) {
|
||||
void MacroAssembler::CallApiFunctionAndReturn(
|
||||
ExternalReference function,
|
||||
Address function_address,
|
||||
ExternalReference thunk_ref,
|
||||
Register thunk_last_arg,
|
||||
int stack_space,
|
||||
MemOperand return_value_operand,
|
||||
MemOperand* context_restore_operand) {
|
||||
ExternalReference next_address =
|
||||
ExternalReference::handle_scope_next_address(isolate());
|
||||
const int kNextOffset = 0;
|
||||
@ -3915,12 +3917,13 @@ void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function,
|
||||
}
|
||||
|
||||
Label promote_scheduled_exception;
|
||||
Label exception_handled;
|
||||
Label delete_allocated_handles;
|
||||
Label leave_exit_frame;
|
||||
Label return_value_loaded;
|
||||
|
||||
// Load value from ReturnValue.
|
||||
lw(v0, MemOperand(fp, return_value_offset_from_fp*kPointerSize));
|
||||
lw(v0, return_value_operand);
|
||||
bind(&return_value_loaded);
|
||||
|
||||
// No more valid handles (the result handle was the last one). Restore
|
||||
@ -3941,14 +3944,23 @@ void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function,
|
||||
li(at, Operand(ExternalReference::scheduled_exception_address(isolate())));
|
||||
lw(t1, MemOperand(at));
|
||||
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));
|
||||
LeaveExitFrame(false, s0, true);
|
||||
LeaveExitFrame(false, s0, !restore_context, EMIT_RETURN);
|
||||
|
||||
bind(&promote_scheduled_exception);
|
||||
TailCallExternalReference(
|
||||
ExternalReference(Runtime::kPromoteScheduledException, isolate()),
|
||||
0,
|
||||
1);
|
||||
{
|
||||
FrameScope frame(this, StackFrame::INTERNAL);
|
||||
CallExternalReference(
|
||||
ExternalReference(Runtime::kPromoteScheduledException, isolate()),
|
||||
0);
|
||||
}
|
||||
jmp(&exception_handled);
|
||||
|
||||
// HandleScope limit has changed. Delete allocated extensions.
|
||||
bind(&delete_allocated_handles);
|
||||
@ -4684,6 +4696,7 @@ void MacroAssembler::EnterExitFrame(bool save_doubles,
|
||||
|
||||
void MacroAssembler::LeaveExitFrame(bool save_doubles,
|
||||
Register argument_count,
|
||||
bool restore_context,
|
||||
bool do_return) {
|
||||
// Optionally restore all double registers.
|
||||
if (save_doubles) {
|
||||
@ -4700,9 +4713,12 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles,
|
||||
sw(zero_reg, MemOperand(t8));
|
||||
|
||||
// Restore current context from top and clear it in debug mode.
|
||||
li(t8, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
|
||||
lw(cp, MemOperand(t8));
|
||||
if (restore_context) {
|
||||
li(t8, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
|
||||
lw(cp, MemOperand(t8));
|
||||
}
|
||||
#ifdef DEBUG
|
||||
li(t8, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
|
||||
sw(a3, MemOperand(t8));
|
||||
#endif
|
||||
|
||||
|
@ -51,6 +51,12 @@ class JumpTarget;
|
||||
// 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
|
||||
enum TaggingMode {
|
||||
// Tag the result.
|
||||
@ -848,7 +854,8 @@ class MacroAssembler: public Assembler {
|
||||
// Leave the current exit frame.
|
||||
void LeaveExitFrame(bool save_doubles,
|
||||
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.
|
||||
static int ActivationFrameAlignment();
|
||||
@ -1271,7 +1278,8 @@ class MacroAssembler: public Assembler {
|
||||
ExternalReference thunk_ref,
|
||||
Register thunk_last_arg,
|
||||
int stack_space,
|
||||
int return_value_offset_from_fp);
|
||||
MemOperand return_value_operand,
|
||||
MemOperand* context_restore_operand);
|
||||
|
||||
// Jump to the builtin routine.
|
||||
void JumpToExternalReference(const ExternalReference& builtin,
|
||||
|
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user