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
parent 59c158e4
...@@ -1804,7 +1804,65 @@ void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { ...@@ -1804,7 +1804,65 @@ void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
void LCodeGen::DoApplyArguments(LApplyArguments* 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, ...@@ -726,7 +726,8 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
Handle<Code> code_constant, Handle<Code> code_constant,
Register code_reg, Register code_reg,
Label* done, Label* done,
InvokeFlag flag) { InvokeFlag flag,
PostCallGenerator* post_call_generator) {
bool definitely_matches = false; bool definitely_matches = false;
Label regular_invoke; Label regular_invoke;
...@@ -782,6 +783,7 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected, ...@@ -782,6 +783,7 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)); Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline));
if (flag == CALL_FUNCTION) { if (flag == CALL_FUNCTION) {
Call(adaptor, RelocInfo::CODE_TARGET); Call(adaptor, RelocInfo::CODE_TARGET);
if (post_call_generator != NULL) post_call_generator->Generate();
b(done); b(done);
} else { } else {
Jump(adaptor, RelocInfo::CODE_TARGET); Jump(adaptor, RelocInfo::CODE_TARGET);
...@@ -794,12 +796,15 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected, ...@@ -794,12 +796,15 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
void MacroAssembler::InvokeCode(Register code, void MacroAssembler::InvokeCode(Register code,
const ParameterCount& expected, const ParameterCount& expected,
const ParameterCount& actual, const ParameterCount& actual,
InvokeFlag flag) { InvokeFlag flag,
PostCallGenerator* post_call_generator) {
Label done; 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) { if (flag == CALL_FUNCTION) {
Call(code); Call(code);
if (post_call_generator != NULL) post_call_generator->Generate();
} else { } else {
ASSERT(flag == JUMP_FUNCTION); ASSERT(flag == JUMP_FUNCTION);
Jump(code); Jump(code);
...@@ -833,7 +838,8 @@ void MacroAssembler::InvokeCode(Handle<Code> code, ...@@ -833,7 +838,8 @@ void MacroAssembler::InvokeCode(Handle<Code> code,
void MacroAssembler::InvokeFunction(Register fun, void MacroAssembler::InvokeFunction(Register fun,
const ParameterCount& actual, const ParameterCount& actual,
InvokeFlag flag) { InvokeFlag flag,
PostCallGenerator* post_call_generator) {
// Contract with called JS functions requires that function is passed in r1. // Contract with called JS functions requires that function is passed in r1.
ASSERT(fun.is(r1)); ASSERT(fun.is(r1));
...@@ -850,7 +856,7 @@ void MacroAssembler::InvokeFunction(Register fun, ...@@ -850,7 +856,7 @@ void MacroAssembler::InvokeFunction(Register fun,
FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
ParameterCount expected(expected_reg); 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 { ...@@ -36,7 +36,6 @@ namespace internal {
// Forward declaration. // Forward declaration.
class PostCallGenerator; class PostCallGenerator;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Static helper functions // Static helper functions
...@@ -309,7 +308,8 @@ class MacroAssembler: public Assembler { ...@@ -309,7 +308,8 @@ class MacroAssembler: public Assembler {
void InvokeCode(Register code, void InvokeCode(Register code,
const ParameterCount& expected, const ParameterCount& expected,
const ParameterCount& actual, const ParameterCount& actual,
InvokeFlag flag); InvokeFlag flag,
PostCallGenerator* post_call_generator = NULL);
void InvokeCode(Handle<Code> code, void InvokeCode(Handle<Code> code,
const ParameterCount& expected, const ParameterCount& expected,
...@@ -321,7 +321,8 @@ class MacroAssembler: public Assembler { ...@@ -321,7 +321,8 @@ class MacroAssembler: public Assembler {
// current context to the context in the function before invoking. // current context to the context in the function before invoking.
void InvokeFunction(Register function, void InvokeFunction(Register function,
const ParameterCount& actual, const ParameterCount& actual,
InvokeFlag flag); InvokeFlag flag,
PostCallGenerator* post_call_generator = NULL);
void InvokeFunction(JSFunction* function, void InvokeFunction(JSFunction* function,
const ParameterCount& actual, const ParameterCount& actual,
...@@ -772,7 +773,8 @@ class MacroAssembler: public Assembler { ...@@ -772,7 +773,8 @@ class MacroAssembler: public Assembler {
Handle<Code> code_constant, Handle<Code> code_constant,
Register code_reg, Register code_reg,
Label* done, Label* done,
InvokeFlag flag); InvokeFlag flag,
PostCallGenerator* post_call_generator = NULL);
// Activation support. // Activation support.
void EnterFrame(StackFrame::Type type); void EnterFrame(StackFrame::Type type);
......
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