Commit a1f55c10 authored by dcarney@chromium.org's avatar dcarney@chromium.org

stub api getters

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
parent 846b6cef
......@@ -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
......
......@@ -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);
}
......
......@@ -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)
......
......@@ -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
......
......@@ -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);
}
......
......@@ -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
......
......@@ -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);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment