Implement DoApplyArguments.
ARM: Implement DoApplyArguments in the lithium code generator. This patch also introduces an optional SafepointGenerator argument to InvokeFunction, InvokeCode and InvokeProloque. BUG= TEST= Review URL: http://codereview.chromium.org/6164003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6272 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
59c158e43f
commit
43b0399505
@ -1804,7 +1804,65 @@ void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
|
||||
|
||||
|
||||
void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
|
||||
Abort("DoApplyArguments unimplemented.");
|
||||
Register receiver = ToRegister(instr->receiver());
|
||||
Register function = ToRegister(instr->function());
|
||||
Register scratch = scratch0();
|
||||
|
||||
ASSERT(receiver.is(r0));
|
||||
ASSERT(function.is(r1));
|
||||
ASSERT(ToRegister(instr->result()).is(r0));
|
||||
|
||||
// If the receiver is null or undefined, we have to pass the
|
||||
// global object as a receiver.
|
||||
Label global_receiver, receiver_ok;
|
||||
__ LoadRoot(scratch, Heap::kNullValueRootIndex);
|
||||
__ cmp(receiver, scratch);
|
||||
__ b(eq, &global_receiver);
|
||||
__ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
|
||||
__ cmp(receiver, scratch);
|
||||
__ b(ne, &receiver_ok);
|
||||
__ bind(&global_receiver);
|
||||
__ ldr(receiver, GlobalObjectOperand());
|
||||
__ bind(&receiver_ok);
|
||||
|
||||
Register length = ToRegister(instr->length());
|
||||
Register elements = ToRegister(instr->elements());
|
||||
|
||||
Label invoke;
|
||||
|
||||
// Copy the arguments to this function possibly from the
|
||||
// adaptor frame below it.
|
||||
const uint32_t kArgumentsLimit = 1 * KB;
|
||||
__ cmp(length, Operand(kArgumentsLimit));
|
||||
DeoptimizeIf(hi, instr->environment());
|
||||
|
||||
// Push the receiver and use the register to keep the original
|
||||
// number of arguments.
|
||||
__ push(receiver);
|
||||
__ mov(receiver, length);
|
||||
// The arguments are at a one pointer size offset from elements.
|
||||
__ add(elements, elements, Operand(1 * kPointerSize));
|
||||
|
||||
// Loop through the arguments pushing them onto the execution
|
||||
// stack.
|
||||
Label loop;
|
||||
// length is a small non-negative integer, due to the test above.
|
||||
__ tst(length, Operand(length));
|
||||
__ b(eq, &invoke);
|
||||
__ bind(&loop);
|
||||
__ ldr(scratch, MemOperand(elements, length, LSL, 2));
|
||||
__ push(scratch);
|
||||
__ sub(length, length, Operand(1), SetCC);
|
||||
__ b(ne, &loop);
|
||||
|
||||
__ bind(&invoke);
|
||||
// Invoke the function. The number of arguments is stored in receiver
|
||||
// which is r0, as expected by InvokeFunction.
|
||||
v8::internal::ParameterCount actual(receiver);
|
||||
SafepointGenerator safepoint_generator(this,
|
||||
instr->pointer_map(),
|
||||
Safepoint::kNoDeoptimizationIndex);
|
||||
__ InvokeFunction(function, actual, CALL_FUNCTION, &safepoint_generator);
|
||||
}
|
||||
|
||||
|
||||
|
@ -726,7 +726,8 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
|
||||
Handle<Code> code_constant,
|
||||
Register code_reg,
|
||||
Label* done,
|
||||
InvokeFlag flag) {
|
||||
InvokeFlag flag,
|
||||
PostCallGenerator* post_call_generator) {
|
||||
bool definitely_matches = false;
|
||||
Label regular_invoke;
|
||||
|
||||
@ -782,6 +783,7 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
|
||||
Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline));
|
||||
if (flag == CALL_FUNCTION) {
|
||||
Call(adaptor, RelocInfo::CODE_TARGET);
|
||||
if (post_call_generator != NULL) post_call_generator->Generate();
|
||||
b(done);
|
||||
} else {
|
||||
Jump(adaptor, RelocInfo::CODE_TARGET);
|
||||
@ -794,12 +796,15 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
|
||||
void MacroAssembler::InvokeCode(Register code,
|
||||
const ParameterCount& expected,
|
||||
const ParameterCount& actual,
|
||||
InvokeFlag flag) {
|
||||
InvokeFlag flag,
|
||||
PostCallGenerator* post_call_generator) {
|
||||
Label done;
|
||||
|
||||
InvokePrologue(expected, actual, Handle<Code>::null(), code, &done, flag);
|
||||
InvokePrologue(expected, actual, Handle<Code>::null(), code, &done, flag,
|
||||
post_call_generator);
|
||||
if (flag == CALL_FUNCTION) {
|
||||
Call(code);
|
||||
if (post_call_generator != NULL) post_call_generator->Generate();
|
||||
} else {
|
||||
ASSERT(flag == JUMP_FUNCTION);
|
||||
Jump(code);
|
||||
@ -833,7 +838,8 @@ void MacroAssembler::InvokeCode(Handle<Code> code,
|
||||
|
||||
void MacroAssembler::InvokeFunction(Register fun,
|
||||
const ParameterCount& actual,
|
||||
InvokeFlag flag) {
|
||||
InvokeFlag flag,
|
||||
PostCallGenerator* post_call_generator) {
|
||||
// Contract with called JS functions requires that function is passed in r1.
|
||||
ASSERT(fun.is(r1));
|
||||
|
||||
@ -850,7 +856,7 @@ void MacroAssembler::InvokeFunction(Register fun,
|
||||
FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
|
||||
|
||||
ParameterCount expected(expected_reg);
|
||||
InvokeCode(code_reg, expected, actual, flag);
|
||||
InvokeCode(code_reg, expected, actual, flag, post_call_generator);
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,7 +36,6 @@ namespace internal {
|
||||
// Forward declaration.
|
||||
class PostCallGenerator;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Static helper functions
|
||||
|
||||
@ -309,7 +308,8 @@ class MacroAssembler: public Assembler {
|
||||
void InvokeCode(Register code,
|
||||
const ParameterCount& expected,
|
||||
const ParameterCount& actual,
|
||||
InvokeFlag flag);
|
||||
InvokeFlag flag,
|
||||
PostCallGenerator* post_call_generator = NULL);
|
||||
|
||||
void InvokeCode(Handle<Code> code,
|
||||
const ParameterCount& expected,
|
||||
@ -321,7 +321,8 @@ class MacroAssembler: public Assembler {
|
||||
// current context to the context in the function before invoking.
|
||||
void InvokeFunction(Register function,
|
||||
const ParameterCount& actual,
|
||||
InvokeFlag flag);
|
||||
InvokeFlag flag,
|
||||
PostCallGenerator* post_call_generator = NULL);
|
||||
|
||||
void InvokeFunction(JSFunction* function,
|
||||
const ParameterCount& actual,
|
||||
@ -772,7 +773,8 @@ class MacroAssembler: public Assembler {
|
||||
Handle<Code> code_constant,
|
||||
Register code_reg,
|
||||
Label* done,
|
||||
InvokeFlag flag);
|
||||
InvokeFlag flag,
|
||||
PostCallGenerator* post_call_generator = NULL);
|
||||
|
||||
// Activation support.
|
||||
void EnterFrame(StackFrame::Type type);
|
||||
|
Loading…
Reference in New Issue
Block a user