Push version 2.5.7 to trunk.

Fixed obscure evaluation order bug (issue 931).

Split the random number state between JavaScript and the private API.

Fixed performance bug causing GCs when generating stack traces on
code from very large scripts.

Fixed bug in parser that allowed (foo):42 as a labelled statement
(issue 918).

Provide more accurate results about used heap size via
GetHeapStatistics.

Allow build-time customization of the max semispace size.

Made String.prototype.split honor limit when separator is empty
(issue 929).

Added missing failure check after expecting an identifier in
preparser (Chromium issue 62639).
Review URL: http://codereview.chromium.org/5188006

git-svn-id: http://v8.googlecode.com/svn/trunk@5853 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index b72f4df..db26c10 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -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,15 +420,20 @@
   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,
                                     HandlerType type) {
   // Adjust this code if not the case.
@@ -1110,6 +1117,17 @@
 }
 
 
+MaybeObject* MacroAssembler::TryTailCallExternalReference(
+    const ExternalReference& ext, int num_arguments, int result_size) {
+  // TODO(1236192): Most runtime routines don't need the number of
+  // arguments passed in because it is constant. At some point we
+  // should remove this need and make the runtime routine entry code
+  // smarter.
+  Set(eax, Immediate(num_arguments));
+  return TryJumpToExternalReference(ext);
+}
+
+
 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid,
                                      int num_arguments,
                                      int result_size) {
@@ -1117,6 +1135,14 @@
 }
 
 
+MaybeObject* MacroAssembler::TryTailCallRuntime(Runtime::FunctionId fid,
+                                                int num_arguments,
+                                                int result_size) {
+  return TryTailCallExternalReference(
+      ExternalReference(fid), num_arguments, result_size);
+}
+
+
 // If true, a Handle<T> passed by value is passed and returned by
 // using the location_ field directly.  If false, it is passed and
 // returned as a pointer to a handle.
@@ -1132,20 +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);
-  }
-}
+    EnterApiExitFrame(argc + 2);
 
-
-void MacroAssembler::CallApiFunctionAndReturn(ApiFunction* function, int argc) {
-  if (!kPassHandlesDirectly) {
     // The argument slots are filled as follows:
     //
     //   n + 1: output cell
@@ -1157,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 =
@@ -1210,10 +1239,14 @@
   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);
-  TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
+  MaybeObject* result =
+      TryTailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
+  if (result->IsFailure()) {
+    return result;
+  }
   bind(&empty_handle);
   // It was zero; the result is undefined.
   mov(eax, Factory::undefined_value());
@@ -1227,6 +1260,8 @@
   call(Operand(eax));
   mov(eax, edi);
   jmp(&leave_exit_frame);
+
+  return result;
 }
 
 
@@ -1238,6 +1273,15 @@
 }
 
 
+MaybeObject* MacroAssembler::TryJumpToExternalReference(
+    const ExternalReference& ext) {
+  // Set the entry point and jump to the C entry runtime stub.
+  mov(ebx, Immediate(ext));
+  CEntryStub ces(1);
+  return TryTailCallStub(&ces);
+}
+
+
 void MacroAssembler::InvokePrologue(const ParameterCount& expected,
                                     const ParameterCount& actual,
                                     Handle<Code> code_constant,