Revision: 5831
Author: [email protected]
Date: Tue Nov 16 07:04:41 2010
Log: API call code refactoring (ia32).

Review URL: http://codereview.chromium.org/5055004
http://code.google.com/p/v8/source/detail?r=5831

Modified:
 /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc
 /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h
 /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc

=======================================
--- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Mon Nov 15 09:12:34 2010 +++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Tue Nov 16 07:04:41 2010
@@ -392,13 +392,8 @@
 }


-void MacroAssembler::EnterApiExitFrame(int stack_space,
-                                       int argc) {
+void MacroAssembler::EnterApiExitFrame(int argc) {
   EnterExitFramePrologue();
-
-  int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
-  lea(esi, Operand(ebp, (stack_space * kPointerSize) + offset));
-
   EnterExitFrameEpilogue(argc);
 }

@@ -411,6 +406,13 @@
   // Pop the arguments and the receiver from the caller stack.
   lea(esp, Operand(esi, 1 * kPointerSize));

+  // Push the return address to get ready to return.
+  push(ecx);
+
+  LeaveExitFrameEpilogue();
+}
+
+void MacroAssembler::LeaveExitFrameEpilogue() {
   // Restore current context from top and clear it in debug mode.
   ExternalReference context_address(Top::k_context_address);
   mov(esi, Operand::StaticVariable(context_address));
@@ -418,13 +420,18 @@
   mov(Operand::StaticVariable(context_address), Immediate(0));
 #endif

-  // Push the return address to get ready to return.
-  push(ecx);
-
   // Clear the top frame.
   ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address);
   mov(Operand::StaticVariable(c_entry_fp_address), Immediate(0));
 }
+
+
+void MacroAssembler::LeaveApiExitFrame() {
+  mov(esp, Operand(ebp));
+  pop(ebp);
+
+  LeaveExitFrameEpilogue();
+}


 void MacroAssembler::PushTryHandler(CodeLocation try_location,
@@ -1151,21 +1158,15 @@
 }


-void MacroAssembler::PrepareCallApiFunction(int stack_space, int argc) {
+void MacroAssembler::PrepareCallApiFunction(int argc, Register scratch) {
   if (kPassHandlesDirectly) {
-    EnterApiExitFrame(stack_space, argc);
+    EnterApiExitFrame(argc);
     // When handles as passed directly we don't have to allocate extra
     // space for and pass an out parameter.
   } else {
     // We allocate two additional slots: return value and pointer to it.
-    EnterApiExitFrame(stack_space, argc + 2);
-  }
-}
-
-
-MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn(ApiFunction* function,
-                                                         int argc) {
-  if (!kPassHandlesDirectly) {
+    EnterApiExitFrame(argc + 2);
+
     // The argument slots are filled as follows:
     //
     //   n + 1: output cell
@@ -1177,11 +1178,19 @@
     // Note that this is one more "argument" than the function expects
     // so the out cell will have to be popped explicitly after returning
     // from the function. The out cell contains Handle.
- lea(eax, Operand(esp, (argc + 1) * kPointerSize)); // pointer to out cell.
-    mov(Operand(esp, 0 * kPointerSize), eax);  // output.
- mov(Operand(esp, (argc + 1) * kPointerSize), Immediate(0)); // out cell.
-  }
-
+
+    // pointer to out cell.
+    lea(scratch, Operand(esp, (argc + 1) * kPointerSize));
+    mov(Operand(esp, 0 * kPointerSize), scratch);  // output.
+    if (FLAG_debug_code) {
+ mov(Operand(esp, (argc + 1) * kPointerSize), Immediate(0)); // out cell.
+    }
+  }
+}
+
+
+MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn(ApiFunction* function,
+                                                         int stack_space) {
   ExternalReference next_address =
       ExternalReference::handle_scope_next_address();
   ExternalReference limit_address =
@@ -1230,8 +1239,8 @@
   cmp(Operand::StaticVariable(scheduled_exception_address),
          Immediate(Factory::the_hole_value()));
   j(not_equal, &promote_scheduled_exception, not_taken);
-  LeaveExitFrame();
-  ret(0);
+  LeaveApiExitFrame();
+  ret(stack_space * kPointerSize);
   bind(&promote_scheduled_exception);
   MaybeObject* result =
       TryTailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
=======================================
--- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h Mon Nov 15 09:12:34 2010 +++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h Tue Nov 16 07:04:41 2010
@@ -123,13 +123,17 @@
   // to the first argument in register esi.
   void EnterExitFrame();

-  void EnterApiExitFrame(int stack_space, int argc);
+  void EnterApiExitFrame(int argc);

   // Leave the current exit frame. Expects the return value in
   // register eax:edx (untouched) and the pointer to the first
   // argument in register esi.
   void LeaveExitFrame();

+  // Leave the current exit frame. Expects the return value in
+  // register eax (untouched).
+  void LeaveApiExitFrame();
+
   // Find the function context up the context chain.
   void LoadContext(Register dst, int context_chain_length);

@@ -499,12 +503,14 @@
// Uses callee-saved esi to restore stack state after call. Arguments must be
   // stored in ApiParameterOperand(0), ApiParameterOperand(1) etc. Saves
   // context (esi).
-  void PrepareCallApiFunction(int stack_space, int argc);
+  void PrepareCallApiFunction(int argc, Register scratch);

   // Calls an API function. Allocates HandleScope, extracts
   // returned value from handle and propagates exceptions.
   // Clobbers ebx, edi and caller-save registers. Restores context.
- MaybeObject* TryCallApiFunctionAndReturn(ApiFunction* function, int argc);
+  // On return removes stack_space * kPointerSize (GCed).
+  MaybeObject* TryCallApiFunctionAndReturn(ApiFunction* function,
+                                           int stack_space);

   // Jump to a runtime routine.
   void JumpToExternalReference(const ExternalReference& ext);
@@ -603,6 +609,8 @@

   void EnterExitFramePrologue();
   void EnterExitFrameEpilogue(int argc);
+
+  void LeaveExitFrameEpilogue();

   // Allocation support helpers.
   void LoadAllocationTopHelper(Register result,
=======================================
--- /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Mon Nov 15 09:12:34 2010 +++ /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Tue Nov 16 07:04:41 2010
@@ -499,8 +499,7 @@
   // it's not controlled by GC.
   const int kApiStackSpace = 4;

-  __ PrepareCallApiFunction(argc + kFastApiCallArguments + 1,
-                            kApiArgc + kApiStackSpace);
+  __ PrepareCallApiFunction(kApiArgc + kApiStackSpace, ebx);

   __ mov(ApiParameterOperand(1), eax);  // v8::Arguments::implicit_args_.
   __ add(Operand(eax), Immediate(argc * kPointerSize));
@@ -518,7 +517,7 @@
   // garbage collection but instead return the allocation failure
   // object.
   MaybeObject* result =
-      masm->TryCallApiFunctionAndReturn(&fun, kApiArgc + kApiStackSpace);
+ masm->TryCallApiFunctionAndReturn(&fun, argc + kFastApiCallArguments + 1);
   if (result->IsFailure()) {
     *failure = Failure::cast(result);
     return false;
@@ -1109,7 +1108,7 @@
   const int kStackSpace = 5;
   const int kApiArgc = 2;

-  __ PrepareCallApiFunction(kStackSpace, kApiArgc);
+  __ PrepareCallApiFunction(kApiArgc, eax);
   __ mov(ApiParameterOperand(0), ebx);  // name.
   __ add(Operand(ebx), Immediate(kPointerSize));
   __ mov(ApiParameterOperand(1), ebx);  // arguments pointer.
@@ -1118,7 +1117,7 @@
   // already generated).  Do not allow the assembler to perform a
   // garbage collection but instead return the allocation failure
   // object.
- MaybeObject* result = masm()->TryCallApiFunctionAndReturn(&fun, kApiArgc); + MaybeObject* result = masm()->TryCallApiFunctionAndReturn(&fun, kStackSpace);
   if (result->IsFailure()) {
     *failure = Failure::cast(result);
     return false;
@@ -2169,7 +2168,10 @@

       if (depth != kInvalidProtoDepth) {
         __ IncrementCounter(&Counters::call_const_fast_api, 1);
-        ReserveSpaceForFastApiCall(masm(), eax);
+
+ // Allocate space for v8::Arguments implicit values. Must be initialized
+        // before to call any runtime function.
+ __ sub(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize));
       }

       // Check that the maps haven't changed.
@@ -2249,6 +2251,12 @@

   if (depth != kInvalidProtoDepth) {
     Failure* failure;
+    // Move the return address on top of the stack.
+    __ mov(eax, Operand(esp, 3 * kPointerSize));
+    __ mov(Operand(esp, 0 * kPointerSize), eax);
+
+ // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains
+    // duplicate of return address and will be overwritten.
bool success = GenerateFastApiCall(masm(), optimization, argc, &failure);
     if (!success) {
       return failure;
@@ -2260,7 +2268,7 @@
   // Handle call cache miss.
   __ bind(&miss);
   if (depth != kInvalidProtoDepth) {
-    FreeSpaceForFastApiCall(masm(), eax);
+    __ add(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize));
   }
   __ bind(&miss_in_smi_check);
   Object* obj;

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to