Commit 82fc8fe3 authored by serya@chromium.org's avatar serya@chromium.org

Direct call API functions (ia32 implementation).

Review URL: http://codereview.chromium.org/4456002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5791 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 8ebe8e47
...@@ -542,7 +542,7 @@ class ApiGetterEntryStub : public CodeStub { ...@@ -542,7 +542,7 @@ class ApiGetterEntryStub : public CodeStub {
ApiFunction* fun() { return fun_; } ApiFunction* fun() { return fun_; }
Major MajorKey() { return NoCache; } Major MajorKey() { return NoCache; }
int MinorKey() { return 0; } int MinorKey() { return 0; }
const char* GetName() { return "ApiEntryStub"; } const char* GetName() { return "ApiGetterEntryStub"; }
// The accessor info associated with the function. // The accessor info associated with the function.
Handle<AccessorInfo> info_; Handle<AccessorInfo> info_;
// The function to be called. // The function to be called.
...@@ -550,6 +550,32 @@ class ApiGetterEntryStub : public CodeStub { ...@@ -550,6 +550,32 @@ class ApiGetterEntryStub : public CodeStub {
}; };
class ApiCallEntryStub : public CodeStub {
public:
ApiCallEntryStub(Handle<CallHandlerInfo> info,
ApiFunction* fun)
: info_(info),
fun_(fun) { }
void Generate(MacroAssembler* masm);
virtual bool has_custom_cache() { return true; }
virtual bool GetCustomCache(Code** code_out);
virtual void SetCustomCache(Code* value);
static const int kStackSpace = 0;
static const int kArgc = 5;
private:
Handle<CallHandlerInfo> info() { return info_; }
ApiFunction* fun() { return fun_; }
Major MajorKey() { return NoCache; }
int MinorKey() { return 0; }
const char* GetName() { return "ApiCallEntryStub"; }
// The call handler info associated with the function.
Handle<CallHandlerInfo> info_;
// The function to be called.
ApiFunction* fun_;
};
class JSEntryStub : public CodeStub { class JSEntryStub : public CodeStub {
public: public:
JSEntryStub() { } JSEntryStub() { }
......
...@@ -482,8 +482,8 @@ int CEntryStub::MinorKey() { ...@@ -482,8 +482,8 @@ int CEntryStub::MinorKey() {
} }
bool ApiGetterEntryStub::GetCustomCache(Code** code_out) { // Implementation of CodeStub::GetCustomCache.
Object* cache = info()->load_stub_cache(); static bool GetCustomCacheHelper(Object* cache, Code** code_out) {
if (cache->IsUndefined()) { if (cache->IsUndefined()) {
return false; return false;
} else { } else {
...@@ -493,9 +493,24 @@ bool ApiGetterEntryStub::GetCustomCache(Code** code_out) { ...@@ -493,9 +493,24 @@ bool ApiGetterEntryStub::GetCustomCache(Code** code_out) {
} }
bool ApiGetterEntryStub::GetCustomCache(Code** code_out) {
return GetCustomCacheHelper(info()->load_stub_cache(), code_out);
}
void ApiGetterEntryStub::SetCustomCache(Code* value) { void ApiGetterEntryStub::SetCustomCache(Code* value) {
info()->set_load_stub_cache(value); info()->set_load_stub_cache(value);
} }
bool ApiCallEntryStub::GetCustomCache(Code** code_out) {
return GetCustomCacheHelper(info()->call_stub_cache(), code_out);
}
void ApiCallEntryStub::SetCustomCache(Code* value) {
info()->set_call_stub_cache(value);
}
} } // namespace v8::internal } } // namespace v8::internal
...@@ -521,7 +521,6 @@ class Assembler : public Malloced { ...@@ -521,7 +521,6 @@ class Assembler : public Malloced {
void push(const Immediate& x); void push(const Immediate& x);
void push(Register src); void push(Register src);
void push(const Operand& src); void push(const Operand& src);
void push(Label* label, RelocInfo::Mode relocation_mode);
void pop(Register dst); void pop(Register dst);
void pop(const Operand& dst); void pop(const Operand& dst);
......
...@@ -3067,6 +3067,26 @@ void ApiGetterEntryStub::Generate(MacroAssembler* masm) { ...@@ -3067,6 +3067,26 @@ void ApiGetterEntryStub::Generate(MacroAssembler* masm) {
} }
void ApiCallEntryStub::Generate(MacroAssembler* masm) {
__ PrepareCallApiFunction(kStackSpace, kArgc);
STATIC_ASSERT(kArgc == 5);
// Allocate the v8::Arguments structure in the arguments' space since
// it's not controlled by GC.
__ mov(ApiParameterOperand(1), eax); // v8::Arguments::implicit_args_.
__ mov(ApiParameterOperand(2), ebx); // v8::Arguments::values_.
__ mov(ApiParameterOperand(3), edx); // v8::Arguments::length_.
// v8::Arguments::is_construct_call_.
__ mov(ApiParameterOperand(4), Immediate(0));
// v8::InvocationCallback's argument.
__ lea(eax, ApiParameterOperand(1));
__ mov(ApiParameterOperand(0), eax);
__ CallApiFunctionAndReturn(fun(), kArgc);
}
void CEntryStub::GenerateCore(MacroAssembler* masm, void CEntryStub::GenerateCore(MacroAssembler* masm,
Label* throw_normal_exception, Label* throw_normal_exception,
Label* throw_termination_exception, Label* throw_termination_exception,
......
...@@ -488,7 +488,7 @@ class MacroAssembler: public Assembler { ...@@ -488,7 +488,7 @@ class MacroAssembler: public Assembler {
// stored in ApiParameterOperand(0), ApiParameterOperand(1) etc. // stored in ApiParameterOperand(0), ApiParameterOperand(1) etc.
void PrepareCallApiFunction(int stack_space, int argc); void PrepareCallApiFunction(int stack_space, int argc);
// Tail call an API function (jump). Allocates HandleScope, extracts // Calls an API function. Allocates HandleScope, extracts
// returned value from handle and propagates exceptions. // returned value from handle and propagates exceptions.
// Clobbers ebx, esi, edi and caller-save registers. // Clobbers ebx, esi, edi and caller-save registers.
void CallApiFunctionAndReturn(ApiFunction* function, int argc); void CallApiFunctionAndReturn(ApiFunction* function, int argc);
......
...@@ -413,6 +413,10 @@ static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm, ...@@ -413,6 +413,10 @@ static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
} }
// Number of pointers to be reserved on stack for fast API call.
static const int kFastApiCallArguments = 3;
// Reserves space for the extra arguments to FastHandleApiCall in the // Reserves space for the extra arguments to FastHandleApiCall in the
// caller's frame. // caller's frame.
// //
...@@ -423,10 +427,9 @@ static void ReserveSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { ...@@ -423,10 +427,9 @@ static void ReserveSpaceForFastApiCall(MacroAssembler* masm, Register scratch) {
// -- esp[4] : last argument in the internal frame of the caller // -- esp[4] : last argument in the internal frame of the caller
// ----------------------------------- // -----------------------------------
__ pop(scratch); __ pop(scratch);
__ push(Immediate(Smi::FromInt(0))); for (int i = 0; i < kFastApiCallArguments; i++) {
__ push(Immediate(Smi::FromInt(0))); __ push(Immediate(Smi::FromInt(0)));
__ push(Immediate(Smi::FromInt(0))); }
__ push(Immediate(Smi::FromInt(0)));
__ push(scratch); __ push(scratch);
} }
...@@ -434,75 +437,81 @@ static void ReserveSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { ...@@ -434,75 +437,81 @@ static void ReserveSpaceForFastApiCall(MacroAssembler* masm, Register scratch) {
// Undoes the effects of ReserveSpaceForFastApiCall. // Undoes the effects of ReserveSpaceForFastApiCall.
static void FreeSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { static void FreeSpaceForFastApiCall(MacroAssembler* masm, Register scratch) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- esp[0] : return address // -- esp[0] : return address.
// -- esp[4] : last fast api call extra argument // -- esp[4] : last fast api call extra argument.
// -- ... // -- ...
// -- esp[16] : first fast api call extra argument // -- esp[kFastApiCallArguments * 4] : first fast api call extra argument.
// -- esp[20] : last argument in the internal frame // -- esp[kFastApiCallArguments * 4 + 4] : last argument in the internal
// frame.
// ----------------------------------- // -----------------------------------
__ pop(scratch); __ pop(scratch);
__ add(Operand(esp), Immediate(kPointerSize * 4)); __ add(Operand(esp), Immediate(kPointerSize * kFastApiCallArguments));
__ push(scratch); __ push(scratch);
} }
// Generates call to FastHandleApiCall builtin. // Generates call to FastHandleApiCall builtin.
static void GenerateFastApiCall(MacroAssembler* masm, static bool GenerateFastApiCall(MacroAssembler* masm,
const CallOptimization& optimization, const CallOptimization& optimization,
int argc) { int argc,
Failure** failure) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- esp[0] : return address // -- esp[0] : return address
// -- esp[4] : object passing the type check // -- esp[4] : object passing the type check
// (last fast api call extra argument, // (last fast api call extra argument,
// set by CheckPrototypes) // set by CheckPrototypes)
// -- esp[8] : api call data // -- esp[8] : api function
// -- esp[12] : api callback
// -- esp[16] : api function
// (first fast api call extra argument) // (first fast api call extra argument)
// -- esp[20] : last argument // -- esp[12] : api call data
// -- esp[16] : last argument
// -- ... // -- ...
// -- esp[(argc + 5) * 4] : first argument // -- esp[(argc + 3) * 4] : first argument
// -- esp[(argc + 6) * 4] : receiver // -- esp[(argc + 4) * 4] : receiver
// ----------------------------------- // -----------------------------------
// Get the function and setup the context. // Get the function and setup the context.
JSFunction* function = optimization.constant_function(); JSFunction* function = optimization.constant_function();
__ mov(edi, Immediate(Handle<JSFunction>(function))); __ mov(edi, Immediate(Handle<JSFunction>(function)));
__ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
// Pass the additional arguments FastHandleApiCall expects. // Pass the additional arguments FastHandleApiCall expects.
__ mov(Operand(esp, 4 * kPointerSize), edi); __ mov(Operand(esp, 2 * kPointerSize), edi);
bool info_loaded = false;
Object* callback = optimization.api_call_info()->callback();
if (Heap::InNewSpace(callback)) {
info_loaded = true;
__ mov(ecx, Handle<CallHandlerInfo>(optimization.api_call_info()));
__ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kCallbackOffset));
__ mov(Operand(esp, 3 * kPointerSize), ebx);
} else {
__ mov(Operand(esp, 3 * kPointerSize), Immediate(Handle<Object>(callback)));
}
Object* call_data = optimization.api_call_info()->data(); Object* call_data = optimization.api_call_info()->data();
Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info());
if (Heap::InNewSpace(call_data)) { if (Heap::InNewSpace(call_data)) {
if (!info_loaded) { __ mov(ecx, api_call_info_handle);
__ mov(ecx, Handle<CallHandlerInfo>(optimization.api_call_info()));
}
__ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset)); __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset));
__ mov(Operand(esp, 2 * kPointerSize), ebx); __ mov(Operand(esp, 3 * kPointerSize), ebx);
} else { } else {
__ mov(Operand(esp, 2 * kPointerSize), __ mov(Operand(esp, 3 * kPointerSize),
Immediate(Handle<Object>(call_data))); Immediate(Handle<Object>(call_data)));
} }
// Set the number of arguments. // Prepare arguments for ApiCallEntryStub.
__ mov(eax, Immediate(argc + 4)); __ lea(eax, Operand(esp, 3 * kPointerSize));
__ lea(ebx, Operand(esp, (argc + 3) * kPointerSize));
__ Set(edx, Immediate(argc));
// Jump to the fast api call builtin (tail call). Object* callback = optimization.api_call_info()->callback();
Handle<Code> code = Handle<Code>( Address api_function_address = v8::ToCData<Address>(callback);
Builtins::builtin(Builtins::FastHandleApiCall)); ApiFunction fun(api_function_address);
ParameterCount expected(0);
__ InvokeCode(code, expected, expected, ApiCallEntryStub stub(api_call_info_handle, &fun);
RelocInfo::CODE_TARGET, JUMP_FUNCTION);
__ EnterInternalFrame();
// 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.
MaybeObject* result = masm->TryCallStub(&stub);
if (result->IsFailure()) {
*failure = Failure::cast(result);
return false;
}
__ LeaveInternalFrame();
__ ret((argc + 4) * kPointerSize);
return true;
} }
...@@ -515,7 +524,7 @@ class CallInterceptorCompiler BASE_EMBEDDED { ...@@ -515,7 +524,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
arguments_(arguments), arguments_(arguments),
name_(name) {} name_(name) {}
void Compile(MacroAssembler* masm, bool Compile(MacroAssembler* masm,
JSObject* object, JSObject* object,
JSObject* holder, JSObject* holder,
String* name, String* name,
...@@ -524,7 +533,8 @@ class CallInterceptorCompiler BASE_EMBEDDED { ...@@ -524,7 +533,8 @@ class CallInterceptorCompiler BASE_EMBEDDED {
Register scratch1, Register scratch1,
Register scratch2, Register scratch2,
Register scratch3, Register scratch3,
Label* miss) { Label* miss,
Failure** failure) {
ASSERT(holder->HasNamedInterceptor()); ASSERT(holder->HasNamedInterceptor());
ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined());
...@@ -535,17 +545,18 @@ class CallInterceptorCompiler BASE_EMBEDDED { ...@@ -535,17 +545,18 @@ class CallInterceptorCompiler BASE_EMBEDDED {
CallOptimization optimization(lookup); CallOptimization optimization(lookup);
if (optimization.is_constant_call()) { if (optimization.is_constant_call()) {
CompileCacheable(masm, return CompileCacheable(masm,
object, object,
receiver, receiver,
scratch1, scratch1,
scratch2, scratch2,
scratch3, scratch3,
holder, holder,
lookup, lookup,
name, name,
optimization, optimization,
miss); miss,
failure);
} else { } else {
CompileRegular(masm, CompileRegular(masm,
object, object,
...@@ -556,11 +567,12 @@ class CallInterceptorCompiler BASE_EMBEDDED { ...@@ -556,11 +567,12 @@ class CallInterceptorCompiler BASE_EMBEDDED {
name, name,
holder, holder,
miss); miss);
return true;
} }
} }
private: private:
void CompileCacheable(MacroAssembler* masm, bool CompileCacheable(MacroAssembler* masm,
JSObject* object, JSObject* object,
Register receiver, Register receiver,
Register scratch1, Register scratch1,
...@@ -570,7 +582,8 @@ class CallInterceptorCompiler BASE_EMBEDDED { ...@@ -570,7 +582,8 @@ class CallInterceptorCompiler BASE_EMBEDDED {
LookupResult* lookup, LookupResult* lookup,
String* name, String* name,
const CallOptimization& optimization, const CallOptimization& optimization,
Label* miss_label) { Label* miss_label,
Failure** failure) {
ASSERT(optimization.is_constant_call()); ASSERT(optimization.is_constant_call());
ASSERT(!lookup->holder()->IsGlobalObject()); ASSERT(!lookup->holder()->IsGlobalObject());
...@@ -632,7 +645,11 @@ class CallInterceptorCompiler BASE_EMBEDDED { ...@@ -632,7 +645,11 @@ class CallInterceptorCompiler BASE_EMBEDDED {
// Invoke function. // Invoke function.
if (can_do_fast_api_call) { if (can_do_fast_api_call) {
GenerateFastApiCall(masm, optimization, arguments_.immediate()); bool success = GenerateFastApiCall(masm, optimization,
arguments_.immediate(), failure);
if (!success) {
return false;
}
} else { } else {
__ InvokeFunction(optimization.constant_function(), arguments_, __ InvokeFunction(optimization.constant_function(), arguments_,
JUMP_FUNCTION); JUMP_FUNCTION);
...@@ -650,6 +667,8 @@ class CallInterceptorCompiler BASE_EMBEDDED { ...@@ -650,6 +667,8 @@ class CallInterceptorCompiler BASE_EMBEDDED {
if (can_do_fast_api_call) { if (can_do_fast_api_call) {
FreeSpaceForFastApiCall(masm, scratch1); FreeSpaceForFastApiCall(masm, scratch1);
} }
return true;
} }
void CompileRegular(MacroAssembler* masm, void CompileRegular(MacroAssembler* masm,
...@@ -1046,8 +1065,7 @@ bool StubCompiler::GenerateLoadCallback(JSObject* object, ...@@ -1046,8 +1065,7 @@ bool StubCompiler::GenerateLoadCallback(JSObject* object,
__ EnterInternalFrame(); __ EnterInternalFrame();
// Push the stack address where the list of arguments ends. // Push the stack address where the list of arguments ends.
__ mov(scratch2, esp); __ lea(scratch2, Operand(esp, -2 * kPointerSize));
__ sub(Operand(scratch2), Immediate(2 * kPointerSize));
__ push(scratch2); __ push(scratch2);
__ push(receiver); // receiver __ push(receiver); // receiver
__ push(reg); // holder __ push(reg); // holder
...@@ -1061,12 +1079,11 @@ bool StubCompiler::GenerateLoadCallback(JSObject* object, ...@@ -1061,12 +1079,11 @@ bool StubCompiler::GenerateLoadCallback(JSObject* object,
__ push(name_reg); // name __ push(name_reg); // name
// Save a pointer to where we pushed the arguments pointer. // Save a pointer to where we pushed the arguments pointer.
// This will be passed as the const AccessorInfo& to the C++ callback. // This will be passed as the const AccessorInfo& to the C++ callback.
__ mov(eax, esp); STATIC_ASSERT(ApiGetterEntryStub::kStackSpace == 5);
__ add(Operand(eax), Immediate(4 * kPointerSize)); __ lea(eax, Operand(esp, 4 * kPointerSize));
__ mov(ebx, esp); __ mov(ebx, esp);
// Do call through the api. // Do call through the api.
ASSERT_EQ(5, ApiGetterEntryStub::kStackSpace);
Address getter_address = v8::ToCData<Address>(callback->getter()); Address getter_address = v8::ToCData<Address>(callback->getter());
ApiFunction fun(getter_address); ApiFunction fun(getter_address);
ApiGetterEntryStub stub(callback_handle, &fun); ApiGetterEntryStub stub(callback_handle, &fun);
...@@ -2208,7 +2225,11 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, ...@@ -2208,7 +2225,11 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object,
} }
if (depth != kInvalidProtoDepth) { if (depth != kInvalidProtoDepth) {
GenerateFastApiCall(masm(), optimization, argc); Failure* failure;
bool success = GenerateFastApiCall(masm(), optimization, argc, &failure);
if (!success) {
return failure;
}
} else { } else {
__ InvokeFunction(function, arguments(), JUMP_FUNCTION); __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
} }
...@@ -2253,16 +2274,21 @@ MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, ...@@ -2253,16 +2274,21 @@ MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object,
__ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
CallInterceptorCompiler compiler(this, arguments(), ecx); CallInterceptorCompiler compiler(this, arguments(), ecx);
compiler.Compile(masm(), Failure* failure;
object, bool success = compiler.Compile(masm(),
holder, object,
name, holder,
&lookup, name,
edx, &lookup,
ebx, edx,
edi, ebx,
eax, edi,
&miss); eax,
&miss,
&failure);
if (!success) {
return false;
}
// Restore receiver. // Restore receiver.
__ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
......
...@@ -997,6 +997,8 @@ void AccessorInfo::AccessorInfoPrint() { ...@@ -997,6 +997,8 @@ void AccessorInfo::AccessorInfoPrint() {
data()->ShortPrint(); data()->ShortPrint();
PrintF("\n - flag: "); PrintF("\n - flag: ");
flag()->ShortPrint(); flag()->ShortPrint();
PrintF("\n - load_stub_cache: ");
load_stub_cache()->ShortPrint();
} }
void AccessCheckInfo::AccessCheckInfoVerify() { void AccessCheckInfo::AccessCheckInfoVerify() {
...@@ -1046,6 +1048,7 @@ void CallHandlerInfo::CallHandlerInfoVerify() { ...@@ -1046,6 +1048,7 @@ void CallHandlerInfo::CallHandlerInfoVerify() {
CHECK(IsCallHandlerInfo()); CHECK(IsCallHandlerInfo());
VerifyPointer(callback()); VerifyPointer(callback());
VerifyPointer(data()); VerifyPointer(data());
VerifyPointer(call_stub_cache());
} }
void CallHandlerInfo::CallHandlerInfoPrint() { void CallHandlerInfo::CallHandlerInfoPrint() {
...@@ -1054,6 +1057,8 @@ void CallHandlerInfo::CallHandlerInfoPrint() { ...@@ -1054,6 +1057,8 @@ void CallHandlerInfo::CallHandlerInfoPrint() {
callback()->ShortPrint(); callback()->ShortPrint();
PrintF("\n - data: "); PrintF("\n - data: ");
data()->ShortPrint(); data()->ShortPrint();
PrintF("\n - call_stub_cache: ");
call_stub_cache()->ShortPrint();
} }
void TemplateInfo::TemplateInfoVerify() { void TemplateInfo::TemplateInfoVerify() {
......
...@@ -2557,6 +2557,7 @@ ACCESSORS(InterceptorInfo, data, Object, kDataOffset) ...@@ -2557,6 +2557,7 @@ ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset) ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
ACCESSORS(CallHandlerInfo, data, Object, kDataOffset) ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
ACCESSORS(CallHandlerInfo, call_stub_cache, Object, kCallStubCacheOffset)
ACCESSORS(TemplateInfo, tag, Object, kTagOffset) ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset) ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
......
...@@ -5423,6 +5423,7 @@ class CallHandlerInfo: public Struct { ...@@ -5423,6 +5423,7 @@ class CallHandlerInfo: public Struct {
public: public:
DECL_ACCESSORS(callback, Object) DECL_ACCESSORS(callback, Object)
DECL_ACCESSORS(data, Object) DECL_ACCESSORS(data, Object)
DECL_ACCESSORS(call_stub_cache, Object)
static inline CallHandlerInfo* cast(Object* obj); static inline CallHandlerInfo* cast(Object* obj);
...@@ -5433,7 +5434,8 @@ class CallHandlerInfo: public Struct { ...@@ -5433,7 +5434,8 @@ class CallHandlerInfo: public Struct {
static const int kCallbackOffset = HeapObject::kHeaderSize; static const int kCallbackOffset = HeapObject::kHeaderSize;
static const int kDataOffset = kCallbackOffset + kPointerSize; static const int kDataOffset = kCallbackOffset + kPointerSize;
static const int kSize = kDataOffset + kPointerSize; static const int kCallStubCacheOffset = kDataOffset + kPointerSize;
static const int kSize = kCallStubCacheOffset + kPointerSize;
private: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(CallHandlerInfo); DISALLOW_IMPLICIT_CONSTRUCTORS(CallHandlerInfo);
......
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