// -- 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;
}
+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
__ 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);
}
V(ProfileEntryHook) \
V(StoreGlobal) \
V(CallApiFunction) \
+ V(CallApiGetter) \
/* IC Handler stubs */ \
V(LoadField) \
V(KeyedLoadField) \
};
+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)
}
+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
__ 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);
}
}
+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
// 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);
}