Revision: 6272
Author: [email protected]
Date: Tue Jan 11 06:11:03 2011
Log: 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
http://code.google.com/p/v8/source/detail?r=6272
Modified:
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/arm/macro-assembler-arm.cc
/branches/bleeding_edge/src/arm/macro-assembler-arm.h
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Jan 11
06:01:53 2011
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Jan 11
06:11:03 2011
@@ -1804,7 +1804,65 @@
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);
}
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Tue Jan 11
04:45:25 2011
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Tue Jan 11
06:11:03 2011
@@ -726,7 +726,8 @@
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 @@
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::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::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 @@
FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
ParameterCount expected(expected_reg);
- InvokeCode(code_reg, expected, actual, flag);
+ InvokeCode(code_reg, expected, actual, flag, post_call_generator);
}
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.h Tue Jan 11
04:45:25 2011
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.h Tue Jan 11
06:11:03 2011
@@ -36,7 +36,6 @@
// Forward declaration.
class PostCallGenerator;
-
//
----------------------------------------------------------------------------
// Static helper functions
@@ -309,7 +308,8 @@
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 @@
// 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 @@
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);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev