revert 16744 for breaking build
authordcarney@chromium.org <dcarney@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 17 Sep 2013 07:53:56 +0000 (07:53 +0000)
committerdcarney@chromium.org <dcarney@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 17 Sep 2013 07:53:56 +0000 (07:53 +0000)
TBR=mstarzinger@chromium.org
BUG=

Review URL: https://codereview.chromium.org/24196002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16746 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

14 files changed:
include/v8.h
src/arguments.h
src/arm/code-stubs-arm.cc
src/arm/macro-assembler-arm.cc
src/arm/macro-assembler-arm.h
src/arm/stub-cache-arm.cc
src/ia32/code-stubs-ia32.cc
src/ia32/macro-assembler-ia32.cc
src/ia32/macro-assembler-ia32.h
src/ia32/stub-cache-ia32.cc
src/x64/code-stubs-x64.cc
src/x64/macro-assembler-x64.cc
src/x64/macro-assembler-x64.h
src/x64/stub-cache-x64.cc

index 92bfa45..dceebeb 100644 (file)
@@ -2364,7 +2364,7 @@ class FunctionCallbackInfo {
   V8_INLINE Isolate* GetIsolate() const;
   V8_INLINE ReturnValue<T> GetReturnValue() const;
   // This shouldn't be public, but the arm compiler needs it.
-  static const int kArgsLength = 7;
+  static const int kArgsLength = 6;
 
  protected:
   friend class internal::FunctionCallbackArguments;
@@ -2375,7 +2375,6 @@ class FunctionCallbackInfo {
   static const int kDataIndex = -3;
   static const int kCalleeIndex = -4;
   static const int kHolderIndex = -5;
-  static const int kContextSaveIndex = -6;
 
   V8_INLINE FunctionCallbackInfo(internal::Object** implicit_args,
                    internal::Object** values,
index f291816..c1db98b 100644 (file)
@@ -237,7 +237,6 @@ class FunctionCallbackArguments
   typedef FunctionCallbackInfo<Value> T;
   typedef CustomArguments<T> Super;
   static const int kArgsLength = T::kArgsLength;
-  static const int kHolderIndex = T::kHolderIndex;
 
   FunctionCallbackArguments(internal::Isolate* isolate,
       internal::Object* data,
@@ -254,7 +253,6 @@ class FunctionCallbackArguments
     values[T::kDataIndex] = data;
     values[T::kCalleeIndex] = callee;
     values[T::kHolderIndex] = holder;
-    values[T::kContextSaveIndex] = isolate->heap()->the_hole_value();
     values[T::kIsolateIndex] = reinterpret_cast<internal::Object*>(isolate);
     // Here the hole is set as default value.
     // It cannot escape into js as it's remove in Call below.
index 7ec7df9..39b2dc5 100644 (file)
@@ -2842,7 +2842,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
   // sp: stack pointer
   // fp: frame pointer
   //  Callee-saved register r4 still holds argc.
-  __ LeaveExitFrame(save_doubles_, r4, true);
+  __ LeaveExitFrame(save_doubles_, r4);
   __ mov(pc, lr);
 
   // check if we should retry or throw exception
@@ -4071,7 +4071,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
   DirectCEntryStub stub;
   stub.GenerateCall(masm, r7);
 
-  __ LeaveExitFrame(false, no_reg, true);
+  __ LeaveExitFrame(false, no_reg);
 
   // r0: result
   // subject: subject string (callee saved)
index 07900d3..7df7857 100644 (file)
@@ -1020,8 +1020,7 @@ int MacroAssembler::ActivationFrameAlignment() {
 
 
 void MacroAssembler::LeaveExitFrame(bool save_doubles,
-                                    Register argument_count,
-                                    bool restore_context) {
+                                    Register argument_count) {
   // Optionally restore all double registers.
   if (save_doubles) {
     // Calculate the stack location of the saved doubles and restore them.
@@ -1036,14 +1035,10 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles,
   mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate())));
   str(r3, MemOperand(ip));
 
-
   // Restore current context from top and clear it in debug mode.
-  if (restore_context) {
-    mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
-    ldr(cp, MemOperand(ip));
-  }
-#ifdef DEBUG
   mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
+  ldr(cp, MemOperand(ip));
+#ifdef DEBUG
   str(r3, MemOperand(ip));
 #endif
 
@@ -2285,14 +2280,12 @@ static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
 }
 
 
-void MacroAssembler::CallApiFunctionAndReturn(
-    ExternalReference function,
-    Address function_address,
-    ExternalReference thunk_ref,
-    Register thunk_last_arg,
-    int stack_space,
-    MemOperand return_value_operand,
-    MemOperand* context_restore_operand) {
+void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function,
+                                              Address function_address,
+                                              ExternalReference thunk_ref,
+                                              Register thunk_last_arg,
+                                              int stack_space,
+                                              int return_value_offset) {
   ExternalReference next_address =
       ExternalReference::handle_scope_next_address(isolate());
   const int kNextOffset = 0;
@@ -2356,13 +2349,12 @@ void MacroAssembler::CallApiFunctionAndReturn(
   }
 
   Label promote_scheduled_exception;
-  Label exception_handled;
   Label delete_allocated_handles;
   Label leave_exit_frame;
   Label return_value_loaded;
 
   // load value from ReturnValue
-  ldr(r0, return_value_operand);
+  ldr(r0, MemOperand(fp, return_value_offset*kPointerSize));
   bind(&return_value_loaded);
   // No more valid handles (the result handle was the last one). Restore
   // previous handle scope.
@@ -2385,22 +2377,17 @@ void MacroAssembler::CallApiFunctionAndReturn(
   ldr(r5, MemOperand(ip));
   cmp(r4, r5);
   b(ne, &promote_scheduled_exception);
-  bind(&exception_handled);
 
-  bool restore_context = context_restore_operand != NULL;
-  if (restore_context) {
-    ldr(cp, *context_restore_operand);
-  }
   // LeaveExitFrame expects unwind space to be in a register.
   mov(r4, Operand(stack_space));
-  LeaveExitFrame(false, r4, !restore_context);
+  LeaveExitFrame(false, r4);
   mov(pc, lr);
 
   bind(&promote_scheduled_exception);
-  CallExternalReference(
+  TailCallExternalReference(
       ExternalReference(Runtime::kPromoteScheduledException, isolate()),
-      0);
-  jmp(&exception_handled);
+      0,
+      1);
 
   // HandleScope limit has changed. Delete allocated extensions.
   bind(&delete_allocated_handles);
index 0a7b53b..9abd5a0 100644 (file)
@@ -541,9 +541,7 @@ class MacroAssembler: public Assembler {
   // Leave the current exit frame. Expects the return value in r0.
   // Expect the number of values, pushed prior to the exit frame, to
   // remove in a register (or no_reg, if there is nothing to remove).
-  void LeaveExitFrame(bool save_doubles,
-                      Register argument_count,
-                      bool restore_context);
+  void LeaveExitFrame(bool save_doubles, Register argument_count);
 
   // Get the actual activation frame alignment for target environment.
   static int ActivationFrameAlignment();
@@ -1113,8 +1111,7 @@ class MacroAssembler: public Assembler {
                                 ExternalReference thunk_ref,
                                 Register thunk_last_arg,
                                 int stack_space,
-                                MemOperand return_value_operand,
-                                MemOperand* context_restore_operand);
+                                int return_value_offset_from_fp);
 
   // Jump to a runtime routine.
   void JumpToExternalReference(const ExternalReference& builtin);
index 567eb63..681299e 100644 (file)
@@ -839,28 +839,23 @@ static void FreeSpaceForFastApiCall(MacroAssembler* masm) {
 
 static void GenerateFastApiDirectCall(MacroAssembler* masm,
                                       const CallOptimization& optimization,
-                                      int argc,
-                                      bool restore_context) {
+                                      int argc) {
   // ----------- S t a t e -------------
-  //  -- sp[0]              : context
-  //  -- sp[4]              : holder (set by CheckPrototypes)
-  //  -- sp[8]              : callee JS function
-  //  -- sp[12]             : call data
-  //  -- sp[16]             : isolate
-  //  -- sp[20]             : ReturnValue default value
-  //  -- sp[24]             : ReturnValue
-  //  -- sp[28]             : last JS argument
+  //  -- sp[0]              : holder (set by CheckPrototypes)
+  //  -- sp[4]              : callee JS function
+  //  -- sp[8]              : call data
+  //  -- sp[12]             : isolate
+  //  -- sp[16]             : ReturnValue default value
+  //  -- sp[20]             : ReturnValue
+  //  -- sp[24]             : last JS argument
   //  -- ...
-  //  -- sp[(argc + 6) * 4] : first JS argument
-  //  -- sp[(argc + 7) * 4] : receiver
+  //  -- sp[(argc + 5) * 4] : first JS argument
+  //  -- sp[(argc + 6) * 4] : receiver
   // -----------------------------------
-  // Save calling context.
-  __ str(cp, MemOperand(sp));
   // Get the function and setup the context.
   Handle<JSFunction> function = optimization.constant_function();
   __ LoadHeapObject(r5, function);
   __ ldr(cp, FieldMemOperand(r5, JSFunction::kContextOffset));
-  __ str(r5, MemOperand(sp, 2 * kPointerSize));
 
   // Pass the additional arguments.
   Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
@@ -871,18 +866,15 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
   } else {
     __ Move(r6, call_data);
   }
-  // Store call data.
-  __ str(r6, MemOperand(sp, 3 * kPointerSize));
-  // Store isolate.
   __ mov(r7, Operand(ExternalReference::isolate_address(masm->isolate())));
-  __ str(r7, MemOperand(sp, 4 * kPointerSize));
-  // Store ReturnValue default and ReturnValue.
+  // Store JS function, call data, isolate ReturnValue default and ReturnValue.
+  __ stm(ib, sp, r5.bit() | r6.bit() | r7.bit());
   __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
+  __ str(r5, MemOperand(sp, 4 * kPointerSize));
   __ str(r5, MemOperand(sp, 5 * kPointerSize));
-  __ str(r5, MemOperand(sp, 6 * kPointerSize));
 
   // Prepare arguments.
-  __ add(r2, sp, Operand((kFastApiCallArguments - 1) * kPointerSize));
+  __ add(r2, sp, Operand(5 * kPointerSize));
 
   // Allocate the v8::Arguments structure in the arguments' space since
   // it's not controlled by GC.
@@ -920,18 +912,12 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
       masm->isolate());
 
   AllowExternalCallThatCantCauseGC scope(masm);
-  MemOperand context_restore_operand(
-      fp, 2 * kPointerSize);
-  MemOperand return_value_operand(
-      fp, (kFastApiCallArguments + 1) * kPointerSize);
   __ CallApiFunctionAndReturn(ref,
                               function_address,
                               thunk_ref,
                               r1,
                               kStackUnwindSpace,
-                              return_value_operand,
-                              restore_context ?
-                                  &context_restore_operand : NULL);
+                              kFastApiCallArguments + 1);
 }
 
 
@@ -946,12 +932,10 @@ static void GenerateFastApiCall(MacroAssembler* masm,
   ASSERT(!receiver.is(scratch));
 
   const int stack_space = kFastApiCallArguments + argc + 1;
-  const int kHolderIndex = kFastApiCallArguments +
-      FunctionCallbackArguments::kHolderIndex - 1;
   // Assign stack space for the call arguments.
   __ sub(sp, sp, Operand(stack_space * kPointerSize));
   // Write holder to stack frame.
-  __ str(receiver, MemOperand(sp, kHolderIndex * kPointerSize));
+  __ str(receiver, MemOperand(sp, 0));
   // Write receiver to stack frame.
   int index = stack_space - 1;
   __ str(receiver, MemOperand(sp, index * kPointerSize));
@@ -962,7 +946,7 @@ static void GenerateFastApiCall(MacroAssembler* masm,
     __ str(receiver, MemOperand(sp, index-- * kPointerSize));
   }
 
-  GenerateFastApiDirectCall(masm, optimization, argc, true);
+  GenerateFastApiDirectCall(masm, optimization, argc);
 }
 
 
@@ -1076,8 +1060,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
 
     // Invoke function.
     if (can_do_fast_api_call) {
-      GenerateFastApiDirectCall(
-          masm, optimization, arguments_.immediate(), false);
+      GenerateFastApiDirectCall(masm, optimization, arguments_.immediate());
     } else {
       CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
           ? CALL_AS_FUNCTION
@@ -1201,8 +1184,6 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
                                        int save_at_depth,
                                        Label* miss,
                                        PrototypeCheckType check) {
-  const int kHolderIndex = kFastApiCallArguments +
-      FunctionCallbackArguments::kHolderIndex - 1;
   // Make sure that the type feedback oracle harvests the receiver map.
   // TODO(svenpanne) Remove this hack when all ICs are reworked.
   __ mov(scratch1, Operand(Handle<Map>(object->map())));
@@ -1218,7 +1199,7 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
   int depth = 0;
 
   if (save_at_depth == depth) {
-    __ str(reg, MemOperand(sp, kHolderIndex * kPointerSize));
+    __ str(reg, MemOperand(sp));
   }
 
   // Check the maps in the prototype chain.
@@ -1277,7 +1258,7 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
     }
 
     if (save_at_depth == depth) {
-      __ str(reg, MemOperand(sp, kHolderIndex * kPointerSize));
+      __ str(reg, MemOperand(sp));
     }
 
     // Go to the next object in the prototype chain.
@@ -1472,7 +1453,7 @@ void BaseLoadStubCompiler::GenerateLoadCallback(
   __ str(scratch2(), MemOperand(sp, 1 * kPointerSize));
   __ add(r1, sp, Operand(1 * kPointerSize));  // r1 = AccessorInfo&
 
-  const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
+  const int kStackUnwindSpace = kFastApiCallArguments + 1;
   Address getter_address = v8::ToCData<Address>(callback->getter());
 
   ApiFunction fun(getter_address);
@@ -1490,8 +1471,7 @@ void BaseLoadStubCompiler::GenerateLoadCallback(
                               thunk_ref,
                               r2,
                               kStackUnwindSpace,
-                              MemOperand(fp, 6 * kPointerSize),
-                              NULL);
+                              6);
 }
 
 
@@ -2555,7 +2535,7 @@ Handle<Code> CallStubCompiler::CompileFastApiCall(
   CheckPrototypes(Handle<JSObject>::cast(object), r1, holder, r0, r3, r4, name,
                   depth, &miss);
 
-  GenerateFastApiDirectCall(masm(), optimization, argc, false);
+  GenerateFastApiDirectCall(masm(), optimization, argc);
 
   __ bind(&miss);
   FreeSpaceForFastApiCall(masm());
index c113dfb..3ea749f 100644 (file)
@@ -3494,7 +3494,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
   __ call(edx);
 
   // Drop arguments and come back to JS mode.
-  __ LeaveApiExitFrame(true);
+  __ LeaveApiExitFrame();
 
   // Check the result.
   Label success;
index f514f29..d8a475c 100644 (file)
@@ -1115,16 +1115,14 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles) {
   // Push the return address to get ready to return.
   push(ecx);
 
-  LeaveExitFrameEpilogue(true);
+  LeaveExitFrameEpilogue();
 }
 
 
-void MacroAssembler::LeaveExitFrameEpilogue(bool restore_context) {
+void MacroAssembler::LeaveExitFrameEpilogue() {
   // Restore current context from top and clear it in debug mode.
   ExternalReference context_address(Isolate::kContextAddress, isolate());
-  if (restore_context) {
-    mov(esi, Operand::StaticVariable(context_address));
-  }
+  mov(esi, Operand::StaticVariable(context_address));
 #ifdef DEBUG
   mov(Operand::StaticVariable(context_address), Immediate(0));
 #endif
@@ -1136,11 +1134,11 @@ void MacroAssembler::LeaveExitFrameEpilogue(bool restore_context) {
 }
 
 
-void MacroAssembler::LeaveApiExitFrame(bool restore_context) {
+void MacroAssembler::LeaveApiExitFrame() {
   mov(esp, ebp);
   pop(ebp);
 
-  LeaveExitFrameEpilogue(restore_context);
+  LeaveExitFrameEpilogue();
 }
 
 
@@ -2229,13 +2227,11 @@ void MacroAssembler::PrepareCallApiFunction(int argc) {
 }
 
 
-void MacroAssembler::CallApiFunctionAndReturn(
-    Address function_address,
-    Address thunk_address,
-    Operand thunk_last_arg,
-    int stack_space,
-    Operand return_value_operand,
-    Operand* context_restore_operand) {
+void MacroAssembler::CallApiFunctionAndReturn(Address function_address,
+                                              Address thunk_address,
+                                              Operand thunk_last_arg,
+                                              int stack_space,
+                                              int return_value_offset) {
   ExternalReference next_address =
       ExternalReference::handle_scope_next_address(isolate());
   ExternalReference limit_address =
@@ -2291,10 +2287,9 @@ void MacroAssembler::CallApiFunctionAndReturn(
 
   Label prologue;
   // Load the value from ReturnValue
-  mov(eax, return_value_operand);
+  mov(eax, Operand(ebp, return_value_offset * kPointerSize));
 
   Label promote_scheduled_exception;
-  Label exception_handled;
   Label delete_allocated_handles;
   Label leave_exit_frame;
 
@@ -2314,7 +2309,6 @@ void MacroAssembler::CallApiFunctionAndReturn(
   cmp(Operand::StaticVariable(scheduled_exception_address),
       Immediate(isolate()->factory()->the_hole_value()));
   j(not_equal, &promote_scheduled_exception);
-  bind(&exception_handled);
 
 #if ENABLE_EXTRA_CHECKS
   // Check if the function returned a valid JavaScript value.
@@ -2351,16 +2345,11 @@ void MacroAssembler::CallApiFunctionAndReturn(
   bind(&ok);
 #endif
 
-  bool restore_context = context_restore_operand != NULL;
-  if (restore_context) {
-    mov(esi, *context_restore_operand);
-  }
-  LeaveApiExitFrame(!restore_context);
+  LeaveApiExitFrame();
   ret(stack_space * kPointerSize);
 
   bind(&promote_scheduled_exception);
-  CallRuntime(Runtime::kPromoteScheduledException, 0);
-  jmp(&exception_handled);
+  TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
 
   // HandleScope limit has changed. Delete allocated extensions.
   ExternalReference delete_extensions =
index adda9fe..d813692 100644 (file)
@@ -240,7 +240,7 @@ class MacroAssembler: public Assembler {
 
   // Leave the current exit frame. Expects the return value in
   // register eax (untouched).
-  void LeaveApiExitFrame(bool restore_context);
+  void LeaveApiExitFrame();
 
   // Find the function context up the context chain.
   void LoadContext(Register dst, int context_chain_length);
@@ -813,8 +813,7 @@ class MacroAssembler: public Assembler {
                                 Address thunk_address,
                                 Operand thunk_last_arg,
                                 int stack_space,
-                                Operand return_value_operand,
-                                Operand* context_restore_operand);
+                                int return_value_offset_from_ebp);
 
   // Jump to a runtime routine.
   void JumpToExternalReference(const ExternalReference& ext);
@@ -964,7 +963,7 @@ class MacroAssembler: public Assembler {
   void EnterExitFramePrologue();
   void EnterExitFrameEpilogue(int argc, bool save_doubles);
 
-  void LeaveExitFrameEpilogue(bool restore_context);
+  void LeaveExitFrameEpilogue();
 
   // Allocation support helpers.
   void LoadAllocationTopHelper(Register result,
index d339da9..89ea6be 100644 (file)
@@ -458,54 +458,48 @@ static void FreeSpaceForFastApiCall(MacroAssembler* masm, Register scratch) {
 // Generates call to API function.
 static void GenerateFastApiCall(MacroAssembler* masm,
                                 const CallOptimization& optimization,
-                                int argc,
-                                bool restore_context) {
+                                int argc) {
   // ----------- S t a t e -------------
   //  -- esp[0]              : return address
-  //  -- esp[4]              : context
-  //  -- esp[8]              : object passing the type check
+  //  -- esp[4]              : object passing the type check
   //                           (last fast api call extra argument,
   //                            set by CheckPrototypes)
-  //  -- esp[12]             : api function
+  //  -- esp[8]              : api function
   //                           (first fast api call extra argument)
-  //  -- esp[16]             : api call data
-  //  -- esp[20]             : isolate
-  //  -- esp[24]             : ReturnValue default value
-  //  -- esp[28]             : ReturnValue
-  //  -- esp[32]             : last argument
+  //  -- esp[12]             : api call data
+  //  -- esp[16]             : isolate
+  //  -- esp[20]             : ReturnValue default value
+  //  -- esp[24]             : ReturnValue
+  //  -- esp[28]             : last argument
   //  -- ...
-  //  -- esp[(argc + 7) * 4] : first argument
-  //  -- esp[(argc + 8) * 4] : receiver
+  //  -- esp[(argc + 6) * 4] : first argument
+  //  -- esp[(argc + 7) * 4] : receiver
   // -----------------------------------
-
-  // Save calling context.
-  __ mov(Operand(esp, kPointerSize), esi);
-
   // Get the function and setup the context.
   Handle<JSFunction> function = optimization.constant_function();
   __ LoadHeapObject(edi, function);
   __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
 
   // Pass the additional arguments.
-  __ mov(Operand(esp, 3 * kPointerSize), edi);
+  __ mov(Operand(esp, 2 * kPointerSize), edi);
   Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
   Handle<Object> call_data(api_call_info->data(), masm->isolate());
   if (masm->isolate()->heap()->InNewSpace(*call_data)) {
     __ mov(ecx, api_call_info);
     __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset));
-    __ mov(Operand(esp, 4 * kPointerSize), ebx);
+    __ mov(Operand(esp, 3 * kPointerSize), ebx);
   } else {
-    __ mov(Operand(esp, 4 * kPointerSize), Immediate(call_data));
+    __ mov(Operand(esp, 3 * kPointerSize), Immediate(call_data));
   }
-  __ mov(Operand(esp, 5 * kPointerSize),
+  __ mov(Operand(esp, 4 * kPointerSize),
          Immediate(reinterpret_cast<int>(masm->isolate())));
-  __ mov(Operand(esp, 6 * kPointerSize),
+  __ mov(Operand(esp, 5 * kPointerSize),
          masm->isolate()->factory()->undefined_value());
-  __ mov(Operand(esp, 7 * kPointerSize),
+  __ mov(Operand(esp, 6 * kPointerSize),
          masm->isolate()->factory()->undefined_value());
 
   // Prepare arguments.
-  STATIC_ASSERT(kFastApiCallArguments == 7);
+  STATIC_ASSERT(kFastApiCallArguments == 6);
   __ lea(eax, Operand(esp, kFastApiCallArguments * kPointerSize));
 
 
@@ -539,16 +533,11 @@ static void GenerateFastApiCall(MacroAssembler* masm,
 
   Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
 
-  Operand context_restore_operand(ebp, 2 * kPointerSize);
-  Operand return_value_operand(
-      ebp, (kFastApiCallArguments + 1) * kPointerSize);
   __ CallApiFunctionAndReturn(function_address,
                               thunk_address,
                               ApiParameterOperand(1),
                               argc + kFastApiCallArguments + 1,
-                              return_value_operand,
-                              restore_context ?
-                                  &context_restore_operand : NULL);
+                              kFastApiCallArguments + 1);
 }
 
 
@@ -563,8 +552,6 @@ static void GenerateFastApiCall(MacroAssembler* masm,
   ASSERT(!receiver.is(scratch));
 
   const int stack_space = kFastApiCallArguments + argc + 1;
-  const int kHolderIndex = kFastApiCallArguments +
-      FunctionCallbackArguments::kHolderIndex;
   // Copy return value.
   __ mov(scratch, Operand(esp, 0));
   // Assign stack space for the call arguments.
@@ -572,7 +559,7 @@ static void GenerateFastApiCall(MacroAssembler* masm,
   // Move the return address on top of the stack.
   __ mov(Operand(esp, 0), scratch);
   // Write holder to stack frame.
-  __ mov(Operand(esp, kHolderIndex * kPointerSize), receiver);
+  __ mov(Operand(esp, 1 * kPointerSize), receiver);
   // Write receiver to stack frame.
   int index = stack_space;
   __ mov(Operand(esp, index-- * kPointerSize), receiver);
@@ -583,7 +570,7 @@ static void GenerateFastApiCall(MacroAssembler* masm,
     __ mov(Operand(esp, index-- * kPointerSize), values[i]);
   }
 
-  GenerateFastApiCall(masm, optimization, argc, true);
+  GenerateFastApiCall(masm, optimization, argc);
 }
 
 
@@ -697,7 +684,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
 
     // Invoke function.
     if (can_do_fast_api_call) {
-      GenerateFastApiCall(masm, optimization, arguments_.immediate(), false);
+      GenerateFastApiCall(masm, optimization, arguments_.immediate());
     } else {
       CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
           ? CALL_AS_FUNCTION
@@ -1169,8 +1156,6 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
                                        int save_at_depth,
                                        Label* miss,
                                        PrototypeCheckType check) {
-  const int kHolderIndex = kFastApiCallArguments +
-      FunctionCallbackArguments::kHolderIndex;
   // Make sure that the type feedback oracle harvests the receiver map.
   // TODO(svenpanne) Remove this hack when all ICs are reworked.
   __ mov(scratch1, Handle<Map>(object->map()));
@@ -1187,7 +1172,7 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
   int depth = 0;
 
   if (save_at_depth == depth) {
-    __ mov(Operand(esp, kHolderIndex * kPointerSize), reg);
+    __ mov(Operand(esp, kPointerSize), reg);
   }
 
   // Traverse the prototype chain and check the maps in the prototype chain for
@@ -1248,7 +1233,7 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
     }
 
     if (save_at_depth == depth) {
-      __ mov(Operand(esp, kHolderIndex * kPointerSize), reg);
+      __ mov(Operand(esp, kPointerSize), reg);
     }
 
     // Go to the next object in the prototype chain.
@@ -1471,8 +1456,7 @@ void BaseLoadStubCompiler::GenerateLoadCallback(
                               thunk_address,
                               ApiParameterOperand(2),
                               kStackSpace,
-                              Operand(ebp, 7 * kPointerSize),
-                              NULL);
+                              7);
 }
 
 
@@ -2635,7 +2619,7 @@ Handle<Code> CallStubCompiler::CompileFastApiCall(
 
   // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains
   // duplicate of return address and will be overwritten.
-  GenerateFastApiCall(masm(), optimization, argc, false);
+  GenerateFastApiCall(masm(), optimization, argc);
 
   __ bind(&miss);
   __ add(esp, Immediate(kFastApiCallArguments * kPointerSize));
index a201624..d1130ad 100644 (file)
@@ -2648,7 +2648,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
   __ addq(r11, Immediate(Code::kHeaderSize - kHeapObjectTag));
   __ call(r11);
 
-  __ LeaveApiExitFrame(true);
+  __ LeaveApiExitFrame();
 
   // Check the result.
   Label success;
index 4ff3791..fa8cf18 100644 (file)
@@ -691,16 +691,13 @@ void MacroAssembler::PrepareCallApiFunction(int arg_stack_space) {
 }
 
 
-void MacroAssembler::CallApiFunctionAndReturn(
-    Address function_address,
-    Address thunk_address,
-    Register thunk_last_arg,
-    int stack_space,
-    Operand return_value_operand,
-    Operand* context_restore_operand) {
+void MacroAssembler::CallApiFunctionAndReturn(Address function_address,
+                                              Address thunk_address,
+                                              Register thunk_last_arg,
+                                              int stack_space,
+                                              int return_value_offset) {
   Label prologue;
   Label promote_scheduled_exception;
-  Label exception_handled;
   Label delete_allocated_handles;
   Label leave_exit_frame;
   Label write_back;
@@ -771,7 +768,7 @@ void MacroAssembler::CallApiFunctionAndReturn(
   }
 
   // Load the value from ReturnValue
-  movq(rax, return_value_operand);
+  movq(rax, Operand(rbp, return_value_offset * kPointerSize));
   bind(&prologue);
 
   // No more valid handles (the result handle was the last one). Restore
@@ -786,7 +783,6 @@ void MacroAssembler::CallApiFunctionAndReturn(
   movq(rsi, scheduled_exception_address);
   Cmp(Operand(rsi, 0), factory->the_hole_value());
   j(not_equal, &promote_scheduled_exception);
-  bind(&exception_handled);
 
 #if ENABLE_EXTRA_CHECKS
   // Check if the function returned a valid JavaScript value.
@@ -823,16 +819,11 @@ void MacroAssembler::CallApiFunctionAndReturn(
   bind(&ok);
 #endif
 
-  bool restore_context = context_restore_operand != NULL;
-  if (restore_context) {
-    movq(rsi, *context_restore_operand);
-  }
-  LeaveApiExitFrame(!restore_context);
+  LeaveApiExitFrame();
   ret(stack_space * kPointerSize);
 
   bind(&promote_scheduled_exception);
-  CallRuntime(Runtime::kPromoteScheduledException, 0);
-  jmp(&exception_handled);
+  TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
 
   // HandleScope limit has changed. Delete allocated extensions.
   bind(&delete_allocated_handles);
@@ -3704,25 +3695,23 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles) {
 
   PushReturnAddressFrom(rcx);
 
-  LeaveExitFrameEpilogue(true);
+  LeaveExitFrameEpilogue();
 }
 
 
-void MacroAssembler::LeaveApiExitFrame(bool restore_context) {
+void MacroAssembler::LeaveApiExitFrame() {
   movq(rsp, rbp);
   pop(rbp);
 
-  LeaveExitFrameEpilogue(restore_context);
+  LeaveExitFrameEpilogue();
 }
 
 
-void MacroAssembler::LeaveExitFrameEpilogue(bool restore_context) {
+void MacroAssembler::LeaveExitFrameEpilogue() {
   // Restore current context from top and clear it in debug mode.
   ExternalReference context_address(Isolate::kContextAddress, isolate());
   Operand context_operand = ExternalOperand(context_address);
-  if (restore_context) {
-    movq(rsi, context_operand);
-  }
+  movq(rsi, context_operand);
 #ifdef DEBUG
   movq(context_operand, Immediate(0));
 #endif
index 9f8dafc..a1b04d5 100644 (file)
@@ -302,7 +302,7 @@ class MacroAssembler: public Assembler {
 
   // Leave the current exit frame. Expects/provides the return value in
   // register rax (untouched).
-  void LeaveApiExitFrame(bool restore_context);
+  void LeaveApiExitFrame();
 
   // Push and pop the registers that can hold pointers.
   void PushSafepointRegisters() { Pushad(); }
@@ -1280,8 +1280,7 @@ class MacroAssembler: public Assembler {
                                 Address thunk_address,
                                 Register thunk_last_arg,
                                 int stack_space,
-                                Operand return_value_operand,
-                                Operand* context_restore_operand);
+                                int return_value_offset_from_rbp);
 
   // Before calling a C-function from generated code, align arguments on stack.
   // After aligning the frame, arguments must be stored in rsp[0], rsp[8],
@@ -1437,7 +1436,7 @@ class MacroAssembler: public Assembler {
   // accessible via StackSpaceOperand.
   void EnterExitFrameEpilogue(int arg_stack_space, bool save_doubles);
 
-  void LeaveExitFrameEpilogue(bool restore_context);
+  void LeaveExitFrameEpilogue();
 
   // Allocation support helpers.
   // Loads the top of new-space into the result register.
index af8e55f..6cd2487 100644 (file)
@@ -443,61 +443,65 @@ static void FreeSpaceForFastApiCall(MacroAssembler* masm, Register scratch) {
 // Generates call to API function.
 static void GenerateFastApiCall(MacroAssembler* masm,
                                 const CallOptimization& optimization,
-                                int argc,
-                                bool restore_context) {
+                                int argc) {
   // ----------- S t a t e -------------
   //  -- rsp[0]              : return address
-  //  -- rsp[8]              : context save
-  //  -- rsp[16]             : object passing the type check
+  //  -- rsp[8]              : object passing the type check
   //                           (last fast api call extra argument,
   //                            set by CheckPrototypes)
-  //  -- rsp[24]             : api function
+  //  -- rsp[16]             : api function
   //                           (first fast api call extra argument)
-  //  -- rsp[32]             : api call data
-  //  -- rsp[40]             : isolate
-  //  -- rsp[48]             : ReturnValue default value
-  //  -- rsp[56]             : ReturnValue
+  //  -- rsp[24]             : api call data
+  //  -- rsp[32]             : isolate
+  //  -- rsp[40]             : ReturnValue default value
+  //  -- rsp[48]             : ReturnValue
   //
-  //  -- rsp[64]             : last argument
+  //  -- rsp[56]             : last argument
   //  -- ...
-  //  -- rsp[(argc + 7) * 8] : first argument
-  //  -- rsp[(argc + 8) * 8] : receiver
+  //  -- rsp[(argc + 6) * 8] : first argument
+  //  -- rsp[(argc + 7) * 8] : receiver
   // -----------------------------------
-  int api_call_argc = argc + kFastApiCallArguments;
-  StackArgumentsAccessor args(rsp, api_call_argc);
-
-  // Save calling context.
-  __ movq(args.GetArgumentOperand(api_call_argc), rsi);
-
   // Get the function and setup the context.
   Handle<JSFunction> function = optimization.constant_function();
   __ LoadHeapObject(rdi, function);
   __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
+
+  int api_call_argc = argc + kFastApiCallArguments;
+  StackArgumentsAccessor args(rsp, api_call_argc);
+
   // Pass the additional arguments.
-  __ movq(args.GetArgumentOperand(api_call_argc - 2), rdi);
+  __ movq(args.GetArgumentOperand(api_call_argc - 1), rdi);
   Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
   Handle<Object> call_data(api_call_info->data(), masm->isolate());
   if (masm->isolate()->heap()->InNewSpace(*call_data)) {
     __ Move(rcx, api_call_info);
     __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset));
-    __ movq(args.GetArgumentOperand(api_call_argc - 3), rbx);
+    __ movq(args.GetArgumentOperand(api_call_argc - 2), rbx);
   } else {
-    __ Move(args.GetArgumentOperand(api_call_argc - 3), call_data);
+    __ Move(args.GetArgumentOperand(api_call_argc - 2), call_data);
   }
   __ movq(kScratchRegister,
           ExternalReference::isolate_address(masm->isolate()));
-  __ movq(args.GetArgumentOperand(api_call_argc - 4), kScratchRegister);
+  __ movq(args.GetArgumentOperand(api_call_argc - 3), kScratchRegister);
   __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
+  __ movq(args.GetArgumentOperand(api_call_argc - 4), kScratchRegister);
   __ movq(args.GetArgumentOperand(api_call_argc - 5), kScratchRegister);
-  __ movq(args.GetArgumentOperand(api_call_argc - 6), kScratchRegister);
 
   // Prepare arguments.
-  STATIC_ASSERT(kFastApiCallArguments == 7);
+  STATIC_ASSERT(kFastApiCallArguments == 6);
   __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize));
 
   // Function address is a foreign pointer outside V8's heap.
   Address function_address = v8::ToCData<Address>(api_call_info->callback());
 
+#if defined(__MINGW64__) || defined(_WIN64)
+  Register arguments_arg = rcx;
+  Register callback_arg = rdx;
+#else
+  Register arguments_arg = rdi;
+  Register callback_arg = rsi;
+#endif
+
   // Allocate the v8::Arguments structure in the arguments' space since
   // it's not controlled by GC.
   const int kApiStackSpace = 4;
@@ -511,29 +515,16 @@ static void GenerateFastApiCall(MacroAssembler* masm,
   // v8::Arguments::is_construct_call_.
   __ Set(StackSpaceOperand(3), 0);
 
-#if defined(__MINGW64__) || defined(_WIN64)
-  Register arguments_arg = rcx;
-  Register callback_arg = rdx;
-#else
-  Register arguments_arg = rdi;
-  Register callback_arg = rsi;
-#endif
-
   // v8::InvocationCallback's argument.
   __ lea(arguments_arg, StackSpaceOperand(0));
 
   Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
 
-  Operand context_restore_operand(rbp, 2 * kPointerSize);
-  Operand return_value_operand(
-      rbp, (kFastApiCallArguments + 1) * kPointerSize);
   __ CallApiFunctionAndReturn(function_address,
                               thunk_address,
                               callback_arg,
                               api_call_argc + 1,
-                              return_value_operand,
-                              restore_context ?
-                                  &context_restore_operand : NULL);
+                              kFastApiCallArguments + 1);
 }
 
 
@@ -548,8 +539,6 @@ static void GenerateFastApiCall(MacroAssembler* masm,
   ASSERT(!receiver.is(scratch));
 
   const int stack_space = kFastApiCallArguments + argc + 1;
-  const int kHolderIndex = kFastApiCallArguments +
-      FunctionCallbackArguments::kHolderIndex;
   // Copy return value.
   __ movq(scratch, Operand(rsp, 0));
   // Assign stack space for the call arguments.
@@ -557,7 +546,7 @@ static void GenerateFastApiCall(MacroAssembler* masm,
   // Move the return address on top of the stack.
   __ movq(Operand(rsp, 0), scratch);
   // Write holder to stack frame.
-  __ movq(Operand(rsp, kHolderIndex * kPointerSize), receiver);
+  __ movq(Operand(rsp, 1 * kPointerSize), receiver);
   // Write receiver to stack frame.
   int index = stack_space;
   __ movq(Operand(rsp, index-- * kPointerSize), receiver);
@@ -568,7 +557,7 @@ static void GenerateFastApiCall(MacroAssembler* masm,
     __ movq(Operand(rsp, index-- * kPointerSize), values[i]);
   }
 
-  GenerateFastApiCall(masm, optimization, argc, true);
+  GenerateFastApiCall(masm, optimization, argc);
 }
 
 
@@ -682,7 +671,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
 
     // Invoke function.
     if (can_do_fast_api_call) {
-      GenerateFastApiCall(masm, optimization, arguments_.immediate(), false);
+      GenerateFastApiCall(masm, optimization, arguments_.immediate());
     } else {
       CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
           ? CALL_AS_FUNCTION
@@ -1098,8 +1087,6 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
                                        int save_at_depth,
                                        Label* miss,
                                        PrototypeCheckType check) {
-  const int kHolderIndex = kFastApiCallArguments +
-      FunctionCallbackArguments::kHolderIndex;
   // Make sure that the type feedback oracle harvests the receiver map.
   // TODO(svenpanne) Remove this hack when all ICs are reworked.
   __ Move(scratch1, Handle<Map>(object->map()));
@@ -1117,7 +1104,7 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
   int depth = 0;
 
   if (save_at_depth == depth) {
-    __ movq(Operand(rsp, kHolderIndex * kPointerSize), object_reg);
+    __ movq(Operand(rsp, kPCOnStackSize), object_reg);
   }
 
   // Check the maps in the prototype chain.
@@ -1177,7 +1164,7 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
     }
 
     if (save_at_depth == depth) {
-      __ movq(Operand(rsp, kHolderIndex * kPointerSize), reg);
+      __ movq(Operand(rsp, kPCOnStackSize), reg);
     }
 
     // Go to the next object in the prototype chain.
@@ -1399,8 +1386,7 @@ void BaseLoadStubCompiler::GenerateLoadCallback(
                               thunk_address,
                               getter_arg,
                               kStackSpace,
-                              Operand(rbp, 6 * kPointerSize),
-                              NULL);
+                              6);
 }
 
 
@@ -2518,7 +2504,7 @@ Handle<Code> CallStubCompiler::CompileFastApiCall(
           StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize));
   __ movq(StackOperandForReturnAddress(0), rax);
 
-  GenerateFastApiCall(masm(), optimization, argc, false);
+  GenerateFastApiCall(masm(), optimization, argc);
 
   __ bind(&miss);
   __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize));