Reviewers: Søren Gjesse,
Description:
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=
Please review this at http://codereview.chromium.org/6164003/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge/benchmarks
Affected files:
M src/arm/lithium-codegen-arm.cc
M src/arm/macro-assembler-arm.h
M src/arm/macro-assembler-arm.cc
Index: src/arm/lithium-codegen-arm.cc
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index
dd740c2c60c565aa99dc29e570c81dd6a33bf4b9..27c32eb6006821e1d0a37e62763cd95d9535776d
100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -1705,7 +1705,62 @@ 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(receiver);
+ __ mov(receiver, length);
+ __ add(elements, elements, Operand(4));
+
+ // 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);
+
+ // Invoke the function.
+ __ bind(&invoke);
+ v8::internal::ParameterCount actual(receiver);
+
+ SafepointGenerator safepoint_generator(this,
+ instr->pointer_map(),
+
Safepoint::kNoDeoptimizationIndex);
+ __ InvokeFunction(function, actual, CALL_FUNCTION, &safepoint_generator);
}
Index: src/arm/macro-assembler-arm.cc
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index
6bb08198ae8f64a5335592b9a254cf8f07ceb4d3..d1b6f3696fcb9f64503093b68d8a439eecaddef1
100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -675,7 +675,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;
@@ -731,6 +732,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);
@@ -743,12 +745,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);
@@ -782,7 +787,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));
@@ -799,7 +805,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);
}
Index: src/arm/macro-assembler-arm.h
diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h
index
36b0cee2951c17e9f1689e8f19d395c9e9a01c93..7b95d69154c0046d0c5aa64fdd7f8b00335ca629
100644
--- a/src/arm/macro-assembler-arm.h
+++ b/src/arm/macro-assembler-arm.h
@@ -33,6 +33,9 @@
namespace v8 {
namespace internal {
+// Forward declaration.
+class PostCallGenerator;
+
//
----------------------------------------------------------------------------
// Static helper functions
@@ -281,7 +284,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,
@@ -293,7 +297,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,
@@ -742,7 +747,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);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev