Revert r18144, r18143.

MIPS: Fix register usage.

MIPS: Cleanup in the CallStubCompiler.

The original revisions r18131 and r18139 have been reverted.

TBR=palfia@homejinni.com

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18154 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
yangguo@chromium.org 2013-11-29 10:31:49 +00:00
parent 833ee3cdb7
commit 21ce6100fb
3 changed files with 119 additions and 64 deletions

View File

@ -3728,7 +3728,7 @@ void MacroAssembler::InvokeFunction(Register function,
}
void MacroAssembler::InvokeFunction(Register function,
void MacroAssembler::InvokeFunction(Handle<JSFunction> function,
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag,
@ -3737,10 +3737,8 @@ void MacroAssembler::InvokeFunction(Register function,
// You can't call a function without a valid frame.
ASSERT(flag == JUMP_FUNCTION || has_frame());
// Contract with called JS functions requires that function is passed in a1.
ASSERT(function.is(a1));
// Get the function and setup the context.
li(a1, function);
lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
// We call indirectly through the code field in the function to
@ -3751,17 +3749,6 @@ void MacroAssembler::InvokeFunction(Register function,
}
void MacroAssembler::InvokeFunction(Handle<JSFunction> function,
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag,
const CallWrapper& call_wrapper,
CallKind call_kind) {
li(a1, function);
InvokeFunction(a1, expected, actual, flag, call_wrapper, call_kind);
}
void MacroAssembler::IsObjectJSObjectType(Register heap_object,
Register map,
Register scratch,

View File

@ -917,13 +917,6 @@ class MacroAssembler: public Assembler {
const CallWrapper& call_wrapper,
CallKind call_kind);
void InvokeFunction(Register function,
const ParameterCount& expected,
const ParameterCount& actual,
InvokeFlag flag,
const CallWrapper& call_wrapper,
CallKind call_kind);
void InvokeFunction(Handle<JSFunction> function,
const ParameterCount& expected,
const ParameterCount& actual,

View File

@ -732,6 +732,35 @@ void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
}
static void GenerateCallFunction(MacroAssembler* masm,
Handle<Object> object,
const ParameterCount& arguments,
Label* miss,
ExtraICState extra_ic_state) {
// ----------- S t a t e -------------
// -- a0: receiver
// -- a1: function to call
// -----------------------------------
// Check that the function really is a function.
__ JumpIfSmi(a1, miss);
__ GetObjectType(a1, a3, a3);
__ Branch(miss, ne, a3, Operand(JS_FUNCTION_TYPE));
if (object->IsGlobalObject()) {
const int argc = arguments.immediate();
const int receiver_offset = argc * kPointerSize;
__ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset));
__ sw(a3, MemOperand(sp, receiver_offset));
}
// Invoke the function.
CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state)
? CALL_AS_FUNCTION
: CALL_AS_METHOD;
__ InvokeFunction(a1, arguments, JUMP_FUNCTION, NullCallWrapper(), call_kind);
}
static void PushInterceptorArguments(MacroAssembler* masm,
Register receiver,
Register holder,
@ -913,7 +942,7 @@ static void GenerateFastApiCall(MacroAssembler* masm,
class CallInterceptorCompiler BASE_EMBEDDED {
public:
CallInterceptorCompiler(CallStubCompiler* stub_compiler,
CallInterceptorCompiler(StubCompiler* stub_compiler,
const ParameterCount& arguments,
Register name,
ExtraICState extra_ic_state)
@ -1025,8 +1054,13 @@ class CallInterceptorCompiler BASE_EMBEDDED {
GenerateFastApiDirectCall(
masm, optimization, arguments_.immediate(), false);
} else {
CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
? CALL_AS_FUNCTION
: CALL_AS_METHOD;
Handle<JSFunction> function = optimization.constant_function();
stub_compiler_->GenerateJumpFunction(object, function);
ParameterCount expected(function);
__ InvokeFunction(function, expected, arguments_,
JUMP_FUNCTION, NullCallWrapper(), call_kind);
}
// Deferred code for fast API call case---clean preallocated space.
@ -1092,7 +1126,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
__ Branch(interceptor_succeeded, ne, v0, Operand(scratch));
}
CallStubCompiler* stub_compiler_;
StubCompiler* stub_compiler_;
const ParameterCount& arguments_;
Register name_;
ExtraICState extra_ic_state_;
@ -1493,15 +1527,6 @@ void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) {
}
void CallStubCompiler::GenerateFunctionCheck(Register function,
Register scratch,
Label* miss) {
__ JumpIfSmi(function, miss);
__ GetObjectType(function, scratch, scratch);
__ Branch(miss, ne, scratch, Operand(JS_FUNCTION_TYPE));
}
void CallStubCompiler::GenerateLoadFunctionFromCell(
Handle<Cell> cell,
Handle<JSFunction> function,
@ -1517,7 +1542,9 @@ void CallStubCompiler::GenerateLoadFunctionFromCell(
// the nice side effect that multiple closures based on the same
// function can all use this call IC. Before we load through the
// function, we have to verify that it still is a function.
GenerateFunctionCheck(a1, a3, miss);
__ JumpIfSmi(a1, miss);
__ GetObjectType(a1, a3, a3);
__ Branch(miss, ne, a3, Operand(JS_FUNCTION_TYPE));
// Check the shared function info. Make sure it hasn't changed.
__ li(a3, Handle<SharedFunctionInfo>(function->shared()));
@ -1548,7 +1575,8 @@ Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
object, holder, name, RECEIVER_MAP_CHECK, &miss);
GenerateFastPropertyLoad(masm(), a1, reg, index.is_inobject(holder),
index.translate(holder), Representation::Tagged());
GenerateJumpFunction(object, a1, &miss);
GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_);
HandlerFrontendFooter(&miss);
@ -1960,7 +1988,8 @@ Handle<Code> CallStubCompiler::CompileStringCharCodeAtCall(
__ bind(&miss);
// Restore function name in a2.
__ li(a2, name);
HandlerFrontendFooter(&name_miss);
__ bind(&name_miss);
GenerateMissBranch();
// Return the generated code.
return GetCode(type, name);
@ -2024,7 +2053,8 @@ Handle<Code> CallStubCompiler::CompileStringCharAtCall(
__ bind(&miss);
// Restore function name in a2.
__ li(a2, name);
HandlerFrontendFooter(&name_miss);
__ bind(&name_miss);
GenerateMissBranch();
// Return the generated code.
return GetCode(type, name);
@ -2070,10 +2100,12 @@ Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall(
StubRuntimeCallHelper call_helper;
generator.GenerateSlow(masm(), call_helper);
// Tail call the full function. We do not have to patch the receiver
// because the function makes no use of it.
__ bind(&slow);
// We do not have to patch the receiver because the function makes no use of
// it.
GenerateJumpFunctionIgnoreReceiver(function);
ParameterCount expected(function);
__ InvokeFunction(function, expected, arguments(),
JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
HandlerFrontendFooter(&miss);
@ -2179,9 +2211,11 @@ Handle<Code> CallStubCompiler::CompileMathFloorCall(
__ ctc1(a3, FCSR);
__ bind(&slow);
// We do not have to patch the receiver because the function makes no use of
// it.
GenerateJumpFunctionIgnoreReceiver(function);
// Tail call the full function. We do not have to patch the receiver
// because the function makes no use of it.
ParameterCount expected(function);
__ InvokeFunction(function, expected, arguments(),
JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
HandlerFrontendFooter(&miss);
@ -2258,10 +2292,12 @@ Handle<Code> CallStubCompiler::CompileMathAbsCall(
__ sw(a3, FieldMemOperand(v0, HeapNumber::kMantissaOffset));
__ DropAndRet(argc + 1);
// Tail call the full function. We do not have to patch the receiver
// because the function makes no use of it.
__ bind(&slow);
// We do not have to patch the receiver because the function makes no use of
// it.
GenerateJumpFunctionIgnoreReceiver(function);
ParameterCount expected(function);
__ InvokeFunction(function, expected, arguments(),
JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
HandlerFrontendFooter(&miss);
@ -2316,7 +2352,8 @@ Handle<Code> CallStubCompiler::CompileFastApiCall(
__ bind(&miss);
FreeSpaceForFastApiCall(masm());
HandlerFrontendFooter(&miss_before_stack_reserved);
__ bind(&miss_before_stack_reserved);
GenerateMissBranch();
// Return the generated code.
return GetCode(function);
@ -2335,7 +2372,7 @@ void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) {
if (!object.is_null() && object->IsGlobalObject()) {
if (object->IsGlobalObject()) {
const int argc = arguments().immediate();
const int receiver_offset = argc * kPointerSize;
__ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset));
@ -2431,17 +2468,39 @@ Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object,
}
void CallStubCompiler::GenerateJumpFunction(Handle<Object> object,
Register function,
Label* miss) {
ASSERT(function.is(a1));
// Check that the function really is a function.
GenerateFunctionCheck(function, a3, miss);
if (!function.is(a1)) __ mov(a1, function);
void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) {
CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
? CALL_AS_FUNCTION
: CALL_AS_METHOD;
ParameterCount expected(function);
__ InvokeFunction(function, expected, arguments(),
JUMP_FUNCTION, NullCallWrapper(), call_kind);
}
Handle<Code> CallStubCompiler::CompileCallConstant(
Handle<Object> object,
Handle<JSObject> holder,
Handle<Name> name,
CheckType check,
Handle<JSFunction> function) {
if (HasCustomCallGenerator(function)) {
Handle<Code> code = CompileCustomCall(object, holder,
Handle<Cell>::null(),
function, Handle<String>::cast(name),
Code::FAST);
// A null handle means bail out to the regular compiler code below.
if (!code.is_null()) return code;
}
Label miss;
HandlerFrontendHeader(object, holder, name, check, &miss);
PatchGlobalProxy(object);
// Invoke the function.
__ InvokeFunction(a1, arguments(), JUMP_FUNCTION,
NullCallWrapper(), call_kind());
CompileHandlerBackend(function);
HandlerFrontendFooter(&miss);
// Return the generated code.
return GetCode(function);
}
@ -2469,9 +2528,11 @@ Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
// Restore receiver.
__ lw(a0, MemOperand(sp, argc * kPointerSize));
GenerateJumpFunction(object, a1, &miss);
GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_);
HandlerFrontendFooter(&miss);
// Handle call cache miss.
__ bind(&miss);
GenerateMissBranch();
// Return the generated code.
return GetCode(Code::FAST, name);
@ -2494,12 +2555,26 @@ Handle<Code> CallStubCompiler::CompileCallGlobal(
Label miss;
HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
// Potentially loads a closure that matches the shared function info of the
// function, rather than function.
GenerateLoadFunctionFromCell(cell, function, &miss);
PatchGlobalProxy(object);
// Set up the context (function already in r1).
__ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
// Jump to the cached code (tail call).
Counters* counters = isolate()->counters();
__ IncrementCounter(counters->call_global_inline(), 1, a3, t0);
GenerateJumpFunction(object, a1, function);
ParameterCount expected(function->shared()->formal_parameter_count());
CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
? CALL_AS_FUNCTION
: CALL_AS_METHOD;
// We call indirectly through the code field in the function to
// allow recompilation to take effect without changing any of the
// call sites.
__ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
__ InvokeCode(a3, expected, arguments(), JUMP_FUNCTION,
NullCallWrapper(), call_kind);
HandlerFrontendFooter(&miss);
// Return the generated code.