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

Reply via email to