stub api getters
authordcarney@chromium.org <dcarney@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 30 Jan 2014 12:15:51 +0000 (12:15 +0000)
committerdcarney@chromium.org <dcarney@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 30 Jan 2014 12:15:51 +0000 (12:15 +0000)
R=verwaest@chromium.org

BUG=

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

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

src/arm/code-stubs-arm.cc
src/arm/stub-cache-arm.cc
src/code-stubs.h
src/ia32/code-stubs-ia32.cc
src/ia32/stub-cache-ia32.cc
src/x64/code-stubs-x64.cc
src/x64/stub-cache-x64.cc

index 7474e4aa79537b6b9a81d922c23e6b6813a3f9a3..fac8110f7c3952548f42e7a987e1af9dc59de224 100644 (file)
@@ -5383,10 +5383,10 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
   //  -- r1                  : thunk_arg
   //  -- cp                  : context
   //  --
-  //  -- esp[0]              : last argument
+  //  -- sp[0]               : last argument
   //  -- ...
-  //  -- esp[(argc - 1)* 4]  : first argument
-  //  -- esp[argc * 4]       : receiver
+  //  -- sp[(argc - 1)* 4]   : first argument
+  //  -- sp[argc * 4]        : receiver
   // -----------------------------------
 
   Register callee = r0;
@@ -5488,6 +5488,47 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
 }
 
 
+void CallApiGetterStub::Generate(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- sp[0]                  : name
+  //  -- sp[4 - kArgsLength*4]  : PropertyCallbackArguments object
+  //  -- ...
+  //  -- r3                    : api_function_address
+  //  -- r2                    : thunk_last_arg
+  // -----------------------------------
+
+  Register api_function_address = r3;
+  Register thunk_last_arg = r2;
+
+  __ mov(r0, sp);  // r0 = Handle<Name>
+  __ add(r1, r0, Operand(1 * kPointerSize));  // r1 = PCA
+
+  const int kApiStackSpace = 1;
+  FrameScope frame_scope(masm, StackFrame::MANUAL);
+  __ EnterExitFrame(false, kApiStackSpace);
+
+  // Create PropertyAccessorInfo instance on the stack above the exit frame with
+  // r1 (internal::Object** args_) as the data.
+  __ str(r1, MemOperand(sp, 1 * kPointerSize));
+  __ add(r1, sp, Operand(1 * kPointerSize));  // r1 = AccessorInfo&
+
+  const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
+
+  Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
+  ExternalReference::Type thunk_type =
+      ExternalReference::PROFILING_GETTER_CALL;
+  ApiFunction thunk_fun(thunk_address);
+  ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
+      masm->isolate());
+  __ CallApiFunctionAndReturn(api_function_address,
+                              thunk_ref,
+                              thunk_last_arg,
+                              kStackUnwindSpace,
+                              MemOperand(fp, 6 * kPointerSize),
+                              NULL);
+}
+
+
 #undef __
 
 } }  // namespace v8::internal
index 9ad7d2a0363b3df768abab0162c2a1143488f2ae..ab6e1d7ef5193ff2af66cb5ffbc16269ef8735cc 100644 (file)
@@ -1322,40 +1322,20 @@ void LoadStubCompiler::GenerateLoadCallback(
   __ Push(scratch4(), reg);
   __ mov(scratch2(), sp);  // scratch2 = PropertyAccessorInfo::args_
   __ push(name());
-  __ mov(r0, sp);  // r0 = Handle<Name>
 
-  const int kApiStackSpace = 1;
-  FrameScope frame_scope(masm(), StackFrame::MANUAL);
-  __ EnterExitFrame(false, kApiStackSpace);
-
-  // Create PropertyAccessorInfo instance on the stack above the exit frame with
-  // scratch2 (internal::Object** args_) as the data.
-  __ str(scratch2(), MemOperand(sp, 1 * kPointerSize));
-  __ add(r1, sp, Operand(1 * kPointerSize));  // r1 = AccessorInfo&
+  // Abi for CallApiGetter
+  Register getter_address_reg = r3;
+  Register thunk_last_arg = r2;
 
-  const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
   Address getter_address = v8::ToCData<Address>(callback->getter());
-
   ApiFunction fun(getter_address);
   ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
   ExternalReference ref = ExternalReference(&fun, type, isolate());
-  Register getter_address_reg = r3;
-  Register thunk_last_arg = r2;
   __ mov(getter_address_reg, Operand(ref));
   __ mov(thunk_last_arg, Operand(reinterpret_cast<int32_t>(getter_address)));
 
-  Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
-  ExternalReference::Type thunk_type =
-      ExternalReference::PROFILING_GETTER_CALL;
-  ApiFunction thunk_fun(thunk_address);
-  ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
-      isolate());
-  __ CallApiFunctionAndReturn(getter_address_reg,
-                              thunk_ref,
-                              thunk_last_arg,
-                              kStackUnwindSpace,
-                              MemOperand(fp, 6 * kPointerSize),
-                              NULL);
+  CallApiGetterStub stub;
+  __ TailCallStub(&stub);
 }
 
 
index 91104599d5b7c098560d195c1b46cbcc34a2c84b..94d2e2dbacf607cd4b5a743f3d384354d64348c2 100644 (file)
@@ -96,6 +96,7 @@ namespace internal {
   V(ProfileEntryHook)                    \
   V(StoreGlobal)                         \
   V(CallApiFunction)                     \
+  V(CallApiGetter)                       \
   /* IC Handler stubs */                 \
   V(LoadField)                           \
   V(KeyedLoadField)                      \
@@ -1044,6 +1045,19 @@ class CallApiFunctionStub : public PlatformCodeStub {
 };
 
 
+class CallApiGetterStub : public PlatformCodeStub {
+ public:
+  CallApiGetterStub() {}
+
+ private:
+  virtual void Generate(MacroAssembler* masm) V8_OVERRIDE;
+  virtual Major MajorKey() V8_OVERRIDE { return CallApiGetter; }
+  virtual int MinorKey() V8_OVERRIDE { return 0; }
+
+  DISALLOW_COPY_AND_ASSIGN(CallApiGetterStub);
+};
+
+
 class KeyedLoadFieldStub: public LoadFieldStub {
  public:
   KeyedLoadFieldStub(bool inobject, int index, Representation representation)
index 0bd39308abc1abbd3e80f81e0db3ca8fa8f62a31..07b01c6349c75773bbfec940a35402a622185fa7 100644 (file)
@@ -5358,6 +5358,44 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
 }
 
 
+void CallApiGetterStub::Generate(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- esp[0]                  : return address
+  //  -- esp[4]                  : name
+  //  -- esp[8 - kArgsLength*4]  : PropertyCallbackArguments object
+  //  -- ...
+  //  -- edx                    : api_function_address
+  // -----------------------------------
+
+  // array for v8::Arguments::values_, handler for name and pointer
+  // to the values (it considered as smi in GC).
+  const int kStackSpace = PropertyCallbackArguments::kArgsLength + 2;
+  // Allocate space for opional callback address parameter in case
+  // CPU profiler is active.
+  const int kApiArgc = 2 + 1;
+
+  Register api_function_address = edx;
+  Register scratch = ebx;
+
+  // load address of name
+  __ lea(scratch, Operand(esp, 1 * kPointerSize));
+
+  __ PrepareCallApiFunction(kApiArgc);
+  __ mov(ApiParameterOperand(0), scratch);  // name.
+  __ add(scratch, Immediate(kPointerSize));
+  __ mov(ApiParameterOperand(1), scratch);  // arguments pointer.
+
+  Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
+
+  __ CallApiFunctionAndReturn(api_function_address,
+                              thunk_address,
+                              ApiParameterOperand(2),
+                              kStackSpace,
+                              Operand(ebp, 7 * kPointerSize),
+                              NULL);
+}
+
+
 #undef __
 
 } }  // namespace v8::internal
index d7f68457ee43e4c2a242d6153b0034f5ce3f338b..49b9857a263271d4f59858602459be5e19ffd2c7 100644 (file)
@@ -1313,39 +1313,16 @@ void LoadStubCompiler::GenerateLoadCallback(
   __ push(esp);
 
   __ push(name());  // name
-  __ mov(ebx, esp);  // esp points to reference to name (handler).
 
   __ push(scratch3());  // Restore return address.
 
-  // array for v8::Arguments::values_, handler for name and pointer
-  // to the values (it considered as smi in GC).
-  const int kStackSpace = PropertyCallbackArguments::kArgsLength + 2;
-  // Allocate space for opional callback address parameter in case
-  // CPU profiler is active.
-  const int kApiArgc = 2 + 1;
-
-  __ PrepareCallApiFunction(kApiArgc);
-  __ mov(ApiParameterOperand(0), ebx);  // name.
-  __ add(ebx, Immediate(kPointerSize));
-  __ mov(ApiParameterOperand(1), ebx);  // arguments pointer.
-
-  // Emitting a stub call may try to allocate (if the code is not
-  // already generated).  Do not allow the assembler to perform a
-  // garbage collection but instead return the allocation failure
-  // object.
-
+  // Abi for CallApiGetter
   Register getter_address = edx;
   Address function_address = v8::ToCData<Address>(callback->getter());
   __ mov(getter_address, Immediate(function_address));
 
-  Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
-
-  __ CallApiFunctionAndReturn(getter_address,
-                              thunk_address,
-                              ApiParameterOperand(2),
-                              kStackSpace,
-                              Operand(ebp, 7 * kPointerSize),
-                              NULL);
+  CallApiGetterStub stub;
+  __ TailCallStub(&stub);
 }
 
 
index 5cdd12741604dcdf565cb9e0d5024550e4444e78..7aee40b6cd8282084f8764d05cb7ddd916a95b7d 100644 (file)
@@ -5200,6 +5200,66 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
 }
 
 
+void CallApiGetterStub::Generate(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- rsp[0]                  : return address
+  //  -- rsp[8]                  : name
+  //  -- rsp[16 - kArgsLength*8] : PropertyCallbackArguments object
+  //  -- ...
+  //  -- r8                    : api_function_address
+  // -----------------------------------
+
+#if defined(__MINGW64__) || defined(_WIN64)
+  Register getter_arg = r8;
+  Register accessor_info_arg = rdx;
+  Register name_arg = rcx;
+#else
+  Register getter_arg = rdx;
+  Register accessor_info_arg = rsi;
+  Register name_arg = rdi;
+#endif
+  Register api_function_address = r8;
+  Register scratch = rax;
+
+  // v8::Arguments::values_ and handler for name.
+  const int kStackSpace = PropertyCallbackArguments::kArgsLength + 1;
+
+  // Allocate v8::AccessorInfo in non-GCed stack space.
+  const int kArgStackSpace = 1;
+
+  __ lea(name_arg, Operand(rsp, 1 * kPointerSize));
+
+  __ PrepareCallApiFunction(kArgStackSpace);
+  __ lea(scratch, Operand(name_arg, 1 * kPointerSize));
+
+  // v8::PropertyAccessorInfo::args_.
+  __ movp(StackSpaceOperand(0), scratch);
+
+  // The context register (rsi) has been saved in PrepareCallApiFunction and
+  // could be used to pass arguments.
+  __ lea(accessor_info_arg, StackSpaceOperand(0));
+
+  Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
+
+  // It's okay if api_function_address == getter_arg
+  // but not accessor_info_arg or name_arg
+  ASSERT(!api_function_address.is(accessor_info_arg) &&
+         !api_function_address.is(name_arg));
+
+  // The name handler is counted as an argument.
+  StackArgumentsAccessor args(rbp, PropertyCallbackArguments::kArgsLength);
+  Operand return_value_operand = args.GetArgumentOperand(
+      PropertyCallbackArguments::kArgsLength - 1 -
+      PropertyCallbackArguments::kReturnValueOffset);
+  __ CallApiFunctionAndReturn(api_function_address,
+                              thunk_address,
+                              getter_arg,
+                              kStackSpace,
+                              return_value_operand,
+                              NULL);
+}
+
+
 #undef __
 
 } }  // namespace v8::internal
index a84eb1f63ba12f5cef3f2ee10c1a4cebab28a363..811b20c32d24a1d167523ea1815044fa9000e01d 100644 (file)
@@ -1218,59 +1218,15 @@ void LoadStubCompiler::GenerateLoadCallback(
   // Save a pointer to where we pushed the arguments pointer.  This will be
   // passed as the const PropertyAccessorInfo& to the C++ callback.
 
-  Address getter_address = v8::ToCData<Address>(callback->getter());
-
-#if defined(__MINGW64__) || defined(_WIN64)
-  Register getter_arg = r8;
-  Register accessor_info_arg = rdx;
-  Register name_arg = rcx;
-#else
-  Register getter_arg = rdx;
-  Register accessor_info_arg = rsi;
-  Register name_arg = rdi;
-#endif
-
-  ASSERT(!name_arg.is(scratch4()));
-  __ movp(name_arg, rsp);
   __ PushReturnAddressFrom(scratch4());
 
-  // v8::Arguments::values_ and handler for name.
-  const int kStackSpace = PropertyCallbackArguments::kArgsLength + 1;
-
-  // Allocate v8::AccessorInfo in non-GCed stack space.
-  const int kArgStackSpace = 1;
-
-  __ PrepareCallApiFunction(kArgStackSpace);
-  __ lea(rax, Operand(name_arg, 1 * kPointerSize));
-
-  // v8::PropertyAccessorInfo::args_.
-  __ movp(StackSpaceOperand(0), rax);
-
-  // The context register (rsi) has been saved in PrepareCallApiFunction and
-  // could be used to pass arguments.
-  __ lea(accessor_info_arg, StackSpaceOperand(0));
-
-  Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
-
+  // Abi for CallApiGetter
   Register api_function_address = r8;
-  // It's okay if api_function_address == getter_arg
-  // but not accessor_info_arg or name_arg
-  ASSERT(!api_function_address.is(accessor_info_arg) &&
-         !api_function_address.is(name_arg));
-
+  Address getter_address = v8::ToCData<Address>(callback->getter());
   __ Move(api_function_address, getter_address, RelocInfo::EXTERNAL_REFERENCE);
 
-  // The name handler is counted as an argument.
-  StackArgumentsAccessor args(rbp, PropertyCallbackArguments::kArgsLength);
-  Operand return_value_operand = args.GetArgumentOperand(
-      PropertyCallbackArguments::kArgsLength - 1 -
-      PropertyCallbackArguments::kReturnValueOffset);
-  __ CallApiFunctionAndReturn(api_function_address,
-                              thunk_address,
-                              getter_arg,
-                              kStackSpace,
-                              return_value_operand,
-                              NULL);
+  CallApiGetterStub stub;
+  __ TailCallStub(&stub);
 }