Unify computation of load stubs in stub cache.

R=verwaest@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16660 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
mstarzinger@chromium.org 2013-09-11 15:44:09 +00:00
parent 8bf91ffe71
commit 45a65d870d
3 changed files with 114 additions and 220 deletions

View File

@ -1318,7 +1318,7 @@ Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup,
switch (lookup->type()) { switch (lookup->type()) {
case FIELD: case FIELD:
return isolate()->stub_cache()->ComputeLoadField( return isolate()->stub_cache()->ComputeLoadField(
name, receiver, holder, name, receiver, holder, Code::LOAD_IC,
lookup->GetFieldIndex(), lookup->representation()); lookup->GetFieldIndex(), lookup->representation());
case CONSTANT: { case CONSTANT: {
Handle<Object> constant(lookup->GetConstant(), isolate()); Handle<Object> constant(lookup->GetConstant(), isolate());
@ -1326,7 +1326,7 @@ Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup,
// be embedded into code. // be embedded into code.
if (constant->IsConsString()) return Handle<Code>::null(); if (constant->IsConsString()) return Handle<Code>::null();
return isolate()->stub_cache()->ComputeLoadConstant( return isolate()->stub_cache()->ComputeLoadConstant(
name, receiver, holder, constant); name, receiver, holder, Code::LOAD_IC, constant);
} }
case NORMAL: case NORMAL:
if (holder->IsGlobalObject()) { if (holder->IsGlobalObject()) {
@ -1350,7 +1350,7 @@ Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup,
if (v8::ToCData<Address>(info->getter()) == 0) break; if (v8::ToCData<Address>(info->getter()) == 0) break;
if (!info->IsCompatibleReceiver(*receiver)) break; if (!info->IsCompatibleReceiver(*receiver)) break;
return isolate()->stub_cache()->ComputeLoadCallback( return isolate()->stub_cache()->ComputeLoadCallback(
name, receiver, holder, info); name, receiver, holder, Code::LOAD_IC, info);
} else if (callback->IsAccessorPair()) { } else if (callback->IsAccessorPair()) {
Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter(), Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter(),
isolate()); isolate());
@ -1363,7 +1363,7 @@ Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup,
call_optimization.IsCompatibleReceiver(*receiver) && call_optimization.IsCompatibleReceiver(*receiver) &&
FLAG_js_accessor_ics) { FLAG_js_accessor_ics) {
return isolate()->stub_cache()->ComputeLoadCallback( return isolate()->stub_cache()->ComputeLoadCallback(
name, receiver, holder, call_optimization); name, receiver, holder, Code::LOAD_IC, call_optimization);
} }
return isolate()->stub_cache()->ComputeLoadViaGetter( return isolate()->stub_cache()->ComputeLoadViaGetter(
name, receiver, holder, function); name, receiver, holder, function);
@ -1372,7 +1372,8 @@ Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup,
PropertyIndex lengthIndex = PropertyIndex lengthIndex =
PropertyIndex::NewHeaderIndex(JSArray::kLengthOffset / kPointerSize); PropertyIndex::NewHeaderIndex(JSArray::kLengthOffset / kPointerSize);
return isolate()->stub_cache()->ComputeLoadField( return isolate()->stub_cache()->ComputeLoadField(
name, receiver, holder, lengthIndex, Representation::Tagged()); name, receiver, holder, Code::LOAD_IC,
lengthIndex, Representation::Tagged());
} }
// TODO(dcarney): Handle correctly. // TODO(dcarney): Handle correctly.
if (callback->IsDeclaredAccessorInfo()) break; if (callback->IsDeclaredAccessorInfo()) break;
@ -1383,7 +1384,7 @@ Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup,
case INTERCEPTOR: case INTERCEPTOR:
ASSERT(HasInterceptorGetter(*holder)); ASSERT(HasInterceptorGetter(*holder));
return isolate()->stub_cache()->ComputeLoadInterceptor( return isolate()->stub_cache()->ComputeLoadInterceptor(
name, receiver, holder); name, receiver, holder, Code::LOAD_IC);
default: default:
break; break;
} }
@ -1538,16 +1539,16 @@ Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup,
Handle<JSObject> holder(lookup->holder(), isolate()); Handle<JSObject> holder(lookup->holder(), isolate());
switch (lookup->type()) { switch (lookup->type()) {
case FIELD: case FIELD:
return isolate()->stub_cache()->ComputeKeyedLoadField( return isolate()->stub_cache()->ComputeLoadField(
name, receiver, holder, name, receiver, holder, Code::KEYED_LOAD_IC,
lookup->GetFieldIndex(), lookup->representation()); lookup->GetFieldIndex(), lookup->representation());
case CONSTANT: { case CONSTANT: {
Handle<Object> constant(lookup->GetConstant(), isolate()); Handle<Object> constant(lookup->GetConstant(), isolate());
// TODO(2803): Don't compute a stub for cons strings because they cannot // TODO(2803): Don't compute a stub for cons strings because they cannot
// be embedded into code. // be embedded into code.
if (constant->IsConsString()) return Handle<Code>::null(); if (constant->IsConsString()) return Handle<Code>::null();
return isolate()->stub_cache()->ComputeKeyedLoadConstant( return isolate()->stub_cache()->ComputeLoadConstant(
name, receiver, holder, constant); name, receiver, holder, Code::KEYED_LOAD_IC, constant);
} }
case CALLBACKS: { case CALLBACKS: {
Handle<Object> callback_object(lookup->GetCallbackObject(), isolate()); Handle<Object> callback_object(lookup->GetCallbackObject(), isolate());
@ -1557,8 +1558,8 @@ Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup,
Handle<ExecutableAccessorInfo>::cast(callback_object); Handle<ExecutableAccessorInfo>::cast(callback_object);
if (v8::ToCData<Address>(callback->getter()) == 0) break; if (v8::ToCData<Address>(callback->getter()) == 0) break;
if (!callback->IsCompatibleReceiver(*receiver)) break; if (!callback->IsCompatibleReceiver(*receiver)) break;
return isolate()->stub_cache()->ComputeKeyedLoadCallback( return isolate()->stub_cache()->ComputeLoadCallback(
name, receiver, holder, callback); name, receiver, holder, Code::KEYED_LOAD_IC, callback);
} else if (callback_object->IsAccessorPair()) { } else if (callback_object->IsAccessorPair()) {
Handle<Object> getter( Handle<Object> getter(
Handle<AccessorPair>::cast(callback_object)->getter(), Handle<AccessorPair>::cast(callback_object)->getter(),
@ -1571,16 +1572,16 @@ Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup,
if (call_optimization.is_simple_api_call() && if (call_optimization.is_simple_api_call() &&
call_optimization.IsCompatibleReceiver(*receiver) && call_optimization.IsCompatibleReceiver(*receiver) &&
FLAG_js_accessor_ics) { FLAG_js_accessor_ics) {
return isolate()->stub_cache()->ComputeKeyedLoadCallback( return isolate()->stub_cache()->ComputeLoadCallback(
name, receiver, holder, call_optimization); name, receiver, holder, Code::KEYED_LOAD_IC, call_optimization);
} }
} }
break; break;
} }
case INTERCEPTOR: case INTERCEPTOR:
ASSERT(HasInterceptorGetter(lookup->holder())); ASSERT(HasInterceptorGetter(lookup->holder()));
return isolate()->stub_cache()->ComputeKeyedLoadInterceptor( return isolate()->stub_cache()->ComputeLoadInterceptor(
name, receiver, holder); name, receiver, holder, Code::KEYED_LOAD_IC);
default: default:
// Always rewrite to the generic case so that we do not // Always rewrite to the generic case so that we do not
// repeatedly try to rewrite. // repeatedly try to rewrite.

View File

@ -272,21 +272,29 @@ Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name,
Handle<Code> StubCache::ComputeLoadField(Handle<Name> name, Handle<Code> StubCache::ComputeLoadField(Handle<Name> name,
Handle<JSObject> receiver, Handle<JSObject> receiver,
Handle<JSObject> holder, Handle<JSObject> holder,
Code::Kind kind,
PropertyIndex field, PropertyIndex field,
Representation representation) { Representation representation) {
if (receiver.is_identical_to(holder)) { if (receiver.is_identical_to(holder)) {
LoadFieldStub stub(field.is_inobject(holder), if (kind == Code::LOAD_IC) {
field.translate(holder), LoadFieldStub stub(field.is_inobject(holder),
representation); field.translate(holder),
return stub.GetCode(isolate()); representation);
return stub.GetCode(isolate());
} else {
KeyedLoadFieldStub stub(field.is_inobject(holder),
field.translate(holder),
representation);
return stub.GetCode(isolate());
}
} }
Handle<JSObject> stub_holder = StubHolder(receiver, holder); Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindLoadHandler( Handle<Code> stub = FindLoadHandler(
name, receiver, stub_holder, Code::LOAD_IC, Code::FIELD); name, receiver, stub_holder, kind, Code::FIELD);
if (!stub.is_null()) return stub; if (!stub.is_null()) return stub;
LoadStubCompiler compiler(isolate_); BaseLoadStubCompiler compiler(isolate_, kind);
Handle<Code> handler = Handle<Code> handler =
compiler.CompileLoadField(receiver, holder, name, field, representation); compiler.CompileLoadField(receiver, holder, name, field, representation);
JSObject::UpdateMapCodeCache(stub_holder, name, handler); JSObject::UpdateMapCodeCache(stub_holder, name, handler);
@ -298,14 +306,15 @@ Handle<Code> StubCache::ComputeLoadCallback(
Handle<Name> name, Handle<Name> name,
Handle<JSObject> receiver, Handle<JSObject> receiver,
Handle<JSObject> holder, Handle<JSObject> holder,
Code::Kind kind,
Handle<ExecutableAccessorInfo> callback) { Handle<ExecutableAccessorInfo> callback) {
ASSERT(v8::ToCData<Address>(callback->getter()) != 0); ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
Handle<JSObject> stub_holder = StubHolder(receiver, holder); Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindLoadHandler( Handle<Code> stub = FindLoadHandler(
name, receiver, stub_holder, Code::LOAD_IC, Code::CALLBACKS); name, receiver, stub_holder, kind, Code::CALLBACKS);
if (!stub.is_null()) return stub; if (!stub.is_null()) return stub;
LoadStubCompiler compiler(isolate_); BaseLoadStubCompiler compiler(isolate_, kind);
Handle<Code> handler = Handle<Code> handler =
compiler.CompileLoadCallback(receiver, holder, name, callback); compiler.CompileLoadCallback(receiver, holder, name, callback);
JSObject::UpdateMapCodeCache(stub_holder, name, handler); JSObject::UpdateMapCodeCache(stub_holder, name, handler);
@ -317,13 +326,14 @@ Handle<Code> StubCache::ComputeLoadCallback(
Handle<Name> name, Handle<Name> name,
Handle<JSObject> receiver, Handle<JSObject> receiver,
Handle<JSObject> holder, Handle<JSObject> holder,
Code::Kind kind,
const CallOptimization& call_optimization) { const CallOptimization& call_optimization) {
Handle<JSObject> stub_holder = StubHolder(receiver, holder); Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindLoadHandler( Handle<Code> stub = FindLoadHandler(
name, receiver, stub_holder, Code::LOAD_IC, Code::CALLBACKS); name, receiver, stub_holder, kind, Code::CALLBACKS);
if (!stub.is_null()) return stub; if (!stub.is_null()) return stub;
LoadStubCompiler compiler(isolate_); BaseLoadStubCompiler compiler(isolate_, kind);
Handle<Code> handler = Handle<Code> handler =
compiler.CompileLoadCallback(receiver, holder, name, call_optimization); compiler.CompileLoadCallback(receiver, holder, name, call_optimization);
JSObject::UpdateMapCodeCache(stub_holder, name, handler); JSObject::UpdateMapCodeCache(stub_holder, name, handler);
@ -351,29 +361,30 @@ Handle<Code> StubCache::ComputeLoadViaGetter(Handle<Name> name,
Handle<Code> StubCache::ComputeLoadConstant(Handle<Name> name, Handle<Code> StubCache::ComputeLoadConstant(Handle<Name> name,
Handle<JSObject> receiver, Handle<JSObject> receiver,
Handle<JSObject> holder, Handle<JSObject> holder,
Code::Kind kind,
Handle<Object> value) { Handle<Object> value) {
Handle<JSObject> stub_holder = StubHolder(receiver, holder); Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> handler = FindLoadHandler( Handle<Code> handler = FindLoadHandler(
name, receiver, stub_holder, Code::LOAD_IC, Code::CONSTANT); name, receiver, stub_holder, kind, Code::CONSTANT);
if (!handler.is_null()) return handler; if (!handler.is_null()) return handler;
LoadStubCompiler compiler(isolate_); BaseLoadStubCompiler compiler(isolate_, kind);
handler = compiler.CompileLoadConstant(receiver, holder, name, value); handler = compiler.CompileLoadConstant(receiver, holder, name, value);
JSObject::UpdateMapCodeCache(stub_holder, name, handler); JSObject::UpdateMapCodeCache(stub_holder, name, handler);
return handler; return handler;
} }
Handle<Code> StubCache::ComputeLoadInterceptor(Handle<Name> name, Handle<Code> StubCache::ComputeLoadInterceptor(Handle<Name> name,
Handle<JSObject> receiver, Handle<JSObject> receiver,
Handle<JSObject> holder) { Handle<JSObject> holder,
Code::Kind kind) {
Handle<JSObject> stub_holder = StubHolder(receiver, holder); Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindLoadHandler( Handle<Code> stub = FindLoadHandler(
name, receiver, stub_holder, Code::LOAD_IC, Code::INTERCEPTOR); name, receiver, stub_holder, kind, Code::INTERCEPTOR);
if (!stub.is_null()) return stub; if (!stub.is_null()) return stub;
LoadStubCompiler compiler(isolate_); BaseLoadStubCompiler compiler(isolate_, kind);
Handle<Code> handler = Handle<Code> handler =
compiler.CompileLoadInterceptor(receiver, holder, name); compiler.CompileLoadInterceptor(receiver, holder, name);
JSObject::UpdateMapCodeCache(stub_holder, name, handler); JSObject::UpdateMapCodeCache(stub_holder, name, handler);
@ -404,101 +415,6 @@ Handle<Code> StubCache::ComputeLoadGlobal(Handle<Name> name,
} }
Handle<Code> StubCache::ComputeKeyedLoadField(Handle<Name> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
PropertyIndex field,
Representation representation) {
if (receiver.is_identical_to(holder)) {
// TODO(titzer): this should use an HObjectAccess
KeyedLoadFieldStub stub(field.is_inobject(holder),
field.translate(holder),
representation);
return stub.GetCode(isolate());
}
Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindLoadHandler(
name, receiver, stub_holder, Code::KEYED_LOAD_IC, Code::FIELD);
if (!stub.is_null()) return stub;
KeyedLoadStubCompiler compiler(isolate_);
Handle<Code> handler =
compiler.CompileLoadField(receiver, holder, name, field, representation);
JSObject::UpdateMapCodeCache(stub_holder, name, handler);
return handler;
}
Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<Name> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<Object> value) {
Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> handler = FindLoadHandler(
name, receiver, stub_holder, Code::KEYED_LOAD_IC,
Code::CONSTANT);
if (!handler.is_null()) return handler;
KeyedLoadStubCompiler compiler(isolate_);
handler = compiler.CompileLoadConstant(receiver, holder, name, value);
JSObject::UpdateMapCodeCache(stub_holder, name, handler);
return handler;
}
Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<Name> name,
Handle<JSObject> receiver,
Handle<JSObject> holder) {
Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindLoadHandler(
name, receiver, stub_holder, Code::KEYED_LOAD_IC, Code::INTERCEPTOR);
if (!stub.is_null()) return stub;
KeyedLoadStubCompiler compiler(isolate_);
Handle<Code> handler =
compiler.CompileLoadInterceptor(receiver, holder, name);
JSObject::UpdateMapCodeCache(stub_holder, name, handler);
return handler;
}
Handle<Code> StubCache::ComputeKeyedLoadCallback(
Handle<Name> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
Handle<ExecutableAccessorInfo> callback) {
Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindLoadHandler(
name, receiver, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS);
if (!stub.is_null()) return stub;
KeyedLoadStubCompiler compiler(isolate_);
Handle<Code> handler =
compiler.CompileLoadCallback(receiver, holder, name, callback);
JSObject::UpdateMapCodeCache(stub_holder, name, handler);
return handler;
}
Handle<Code> StubCache::ComputeKeyedLoadCallback(
Handle<Name> name,
Handle<JSObject> receiver,
Handle<JSObject> holder,
const CallOptimization& call_optimization) {
Handle<JSObject> stub_holder = StubHolder(receiver, holder);
Handle<Code> stub = FindLoadHandler(
name, receiver, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS);
if (!stub.is_null()) return stub;
KeyedLoadStubCompiler compiler(isolate_);
Handle<Code> handler =
compiler.CompileLoadCallback(receiver, holder, name, call_optimization);
JSObject::UpdateMapCodeCache(stub_holder, name, handler);
return handler;
}
Handle<Code> StubCache::ComputeStoreField(Handle<Name> name, Handle<Code> StubCache::ComputeStoreField(Handle<Name> name,
Handle<JSObject> receiver, Handle<JSObject> receiver,
LookupResult* lookup, LookupResult* lookup,
@ -1957,23 +1873,15 @@ void StubCompiler::TailCallBuiltin(MacroAssembler* masm, Builtins::Name name) {
} }
void LoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) { Register* BaseLoadStoreStubCompiler::GetRegisters(Code::Kind kind) {
GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); switch (kind) {
} case Code::LOAD_IC: return LoadStubCompiler::registers();
case Code::STORE_IC: return StoreStubCompiler::registers();
case Code::KEYED_LOAD_IC: return KeyedLoadStubCompiler::registers();
void KeyedLoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) { case Code::KEYED_STORE_IC: return KeyedStoreStubCompiler::registers();
GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); default: UNREACHABLE();
} }
return NULL;
void StoreStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) {
GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
}
void KeyedStoreStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) {
GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code));
} }

View File

@ -130,17 +130,20 @@ class StubCache {
Handle<Code> ComputeLoadField(Handle<Name> name, Handle<Code> ComputeLoadField(Handle<Name> name,
Handle<JSObject> object, Handle<JSObject> object,
Handle<JSObject> holder, Handle<JSObject> holder,
Code::Kind kind,
PropertyIndex field_index, PropertyIndex field_index,
Representation representation); Representation representation);
Handle<Code> ComputeLoadCallback(Handle<Name> name, Handle<Code> ComputeLoadCallback(Handle<Name> name,
Handle<JSObject> object, Handle<JSObject> object,
Handle<JSObject> holder, Handle<JSObject> holder,
Code::Kind kind,
Handle<ExecutableAccessorInfo> callback); Handle<ExecutableAccessorInfo> callback);
Handle<Code> ComputeLoadCallback(Handle<Name> name, Handle<Code> ComputeLoadCallback(Handle<Name> name,
Handle<JSObject> object, Handle<JSObject> object,
Handle<JSObject> holder, Handle<JSObject> holder,
Code::Kind kind,
const CallOptimization& call_optimization); const CallOptimization& call_optimization);
Handle<Code> ComputeLoadViaGetter(Handle<Name> name, Handle<Code> ComputeLoadViaGetter(Handle<Name> name,
@ -151,11 +154,13 @@ class StubCache {
Handle<Code> ComputeLoadConstant(Handle<Name> name, Handle<Code> ComputeLoadConstant(Handle<Name> name,
Handle<JSObject> object, Handle<JSObject> object,
Handle<JSObject> holder, Handle<JSObject> holder,
Code::Kind kind,
Handle<Object> value); Handle<Object> value);
Handle<Code> ComputeLoadInterceptor(Handle<Name> name, Handle<Code> ComputeLoadInterceptor(Handle<Name> name,
Handle<JSObject> object, Handle<JSObject> object,
Handle<JSObject> holder); Handle<JSObject> holder,
Code::Kind kind);
Handle<Code> ComputeLoadNormal(Handle<Name> name, Handle<Code> ComputeLoadNormal(Handle<Name> name,
Handle<JSObject> object); Handle<JSObject> object);
@ -168,35 +173,6 @@ class StubCache {
// --- // ---
Handle<Code> ComputeKeyedLoadField(Handle<Name> name,
Handle<JSObject> object,
Handle<JSObject> holder,
PropertyIndex field_index,
Representation representation);
Handle<Code> ComputeKeyedLoadCallback(
Handle<Name> name,
Handle<JSObject> object,
Handle<JSObject> holder,
Handle<ExecutableAccessorInfo> callback);
Handle<Code> ComputeKeyedLoadCallback(
Handle<Name> name,
Handle<JSObject> object,
Handle<JSObject> holder,
const CallOptimization& call_optimization);
Handle<Code> ComputeKeyedLoadConstant(Handle<Name> name,
Handle<JSObject> object,
Handle<JSObject> holder,
Handle<Object> value);
Handle<Code> ComputeKeyedLoadInterceptor(Handle<Name> name,
Handle<JSObject> object,
Handle<JSObject> holder);
// ---
Handle<Code> ComputeStoreField(Handle<Name> name, Handle<Code> ComputeStoreField(Handle<Name> name,
Handle<JSObject> object, Handle<JSObject> object,
LookupResult* lookup, LookupResult* lookup,
@ -642,8 +618,10 @@ enum FrontendCheckType { PERFORM_INITIAL_CHECKS, SKIP_INITIAL_CHECKS };
class BaseLoadStoreStubCompiler: public StubCompiler { class BaseLoadStoreStubCompiler: public StubCompiler {
public: public:
BaseLoadStoreStubCompiler(Isolate* isolate, Register* registers) BaseLoadStoreStubCompiler(Isolate* isolate,
: StubCompiler(isolate), registers_(registers) { } Code::Kind kind,
Register* registers)
: StubCompiler(isolate), kind_(kind), registers_(registers) { }
virtual ~BaseLoadStoreStubCompiler() { } virtual ~BaseLoadStoreStubCompiler() { }
Handle<Code> CompileMonomorphicIC(Handle<Map> receiver_map, Handle<Code> CompileMonomorphicIC(Handle<Map> receiver_map,
@ -671,6 +649,17 @@ class BaseLoadStoreStubCompiler: public StubCompiler {
return Builtins::kLoadIC_Miss; return Builtins::kLoadIC_Miss;
} }
static GDBJITInterface::CodeTag GetGDBJITCodeTag(Code::Kind kind) {
switch (kind) {
case Code::LOAD_IC: return GDBJITInterface::LOAD_IC;
case Code::STORE_IC: return GDBJITInterface::STORE_IC;
case Code::KEYED_LOAD_IC: return GDBJITInterface::KEYED_LOAD_IC;
case Code::KEYED_STORE_IC: return GDBJITInterface::KEYED_STORE_IC;
default: UNREACHABLE();
}
return static_cast<GDBJITInterface::CodeTag>(0);
}
protected: protected:
virtual Register HandlerFrontendHeader(Handle<JSObject> object, virtual Register HandlerFrontendHeader(Handle<JSObject> object,
Register object_reg, Register object_reg,
@ -693,24 +682,48 @@ class BaseLoadStoreStubCompiler: public StubCompiler {
Handle<Name> name, Handle<Name> name,
InlineCacheState state = MONOMORPHIC); InlineCacheState state = MONOMORPHIC);
virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) {
if (!code->is_inline_cache_stub()) return Logger::STUB_TAG;
switch (kind()) {
case Code::LOAD_IC: return code->ic_state() == MONOMORPHIC
? Logger::LOAD_IC_TAG : Logger::LOAD_POLYMORPHIC_IC_TAG;
case Code::STORE_IC: return code->ic_state() == MONOMORPHIC
? Logger::STORE_IC_TAG : Logger::STORE_POLYMORPHIC_IC_TAG;
case Code::KEYED_LOAD_IC: return code->ic_state() == MONOMORPHIC
? Logger::KEYED_LOAD_IC_TAG : Logger::KEYED_LOAD_POLYMORPHIC_IC_TAG;
case Code::KEYED_STORE_IC: return code->ic_state() == MONOMORPHIC
? Logger::KEYED_STORE_IC_TAG : Logger::KEYED_STORE_POLYMORPHIC_IC_TAG;
default: UNREACHABLE();
}
return static_cast<Logger::LogEventsAndTags>(0);
}
void JitEvent(Handle<Name> name, Handle<Code> code) {
GDBJIT(AddCode(GetGDBJITCodeTag(kind()), *name, *code));
}
Code::Kind kind() const { return kind_; }
virtual Code::ExtraICState extra_state() { return Code::kNoExtraICState; } virtual Code::ExtraICState extra_state() { return Code::kNoExtraICState; }
virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) = 0;
virtual void JitEvent(Handle<Name> name, Handle<Code> code) = 0;
virtual Code::Kind kind() = 0;
virtual Register receiver() = 0; virtual Register receiver() = 0;
virtual Register name() = 0; virtual Register name() = 0;
virtual Register scratch1() = 0; virtual Register scratch1() = 0;
virtual Register scratch2() = 0; virtual Register scratch2() = 0;
virtual Register scratch3() = 0; virtual Register scratch3() = 0;
static Register* GetRegisters(Code::Kind kind);
Code::Kind kind_;
Register* registers_; Register* registers_;
}; };
class BaseLoadStubCompiler: public BaseLoadStoreStubCompiler { class BaseLoadStubCompiler: public BaseLoadStoreStubCompiler {
public: public:
BaseLoadStubCompiler(Isolate* isolate, Register* registers) BaseLoadStubCompiler(Isolate* isolate, Code::Kind kind)
: BaseLoadStoreStubCompiler(isolate, registers) { } : BaseLoadStoreStubCompiler(isolate, kind, GetRegisters(kind)) { }
BaseLoadStubCompiler(Isolate* isolate, Code::Kind kind, Register* registers)
: BaseLoadStoreStubCompiler(isolate, kind, registers) { }
virtual ~BaseLoadStubCompiler() { } virtual ~BaseLoadStubCompiler() { }
Handle<Code> CompileLoadField(Handle<JSObject> object, Handle<Code> CompileLoadField(Handle<JSObject> object,
@ -795,7 +808,7 @@ class BaseLoadStubCompiler: public BaseLoadStoreStubCompiler {
class LoadStubCompiler: public BaseLoadStubCompiler { class LoadStubCompiler: public BaseLoadStubCompiler {
public: public:
explicit LoadStubCompiler(Isolate* isolate) explicit LoadStubCompiler(Isolate* isolate)
: BaseLoadStubCompiler(isolate, registers()) { } : BaseLoadStubCompiler(isolate, Code::LOAD_IC, registers()) { }
Handle<Code> CompileLoadNonexistent(Handle<JSObject> object, Handle<Code> CompileLoadNonexistent(Handle<JSObject> object,
Handle<JSObject> last, Handle<JSObject> last,
@ -816,22 +829,14 @@ class LoadStubCompiler: public BaseLoadStubCompiler {
Handle<Name> name, Handle<Name> name,
bool is_dont_delete); bool is_dont_delete);
private:
static Register* registers(); static Register* registers();
virtual Code::Kind kind() { return Code::LOAD_IC; }
virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) {
if (!code->is_inline_cache_stub()) return Logger::STUB_TAG;
return code->ic_state() == MONOMORPHIC
? Logger::LOAD_IC_TAG : Logger::LOAD_POLYMORPHIC_IC_TAG;
}
virtual void JitEvent(Handle<Name> name, Handle<Code> code);
}; };
class KeyedLoadStubCompiler: public BaseLoadStubCompiler { class KeyedLoadStubCompiler: public BaseLoadStubCompiler {
public: public:
explicit KeyedLoadStubCompiler(Isolate* isolate) explicit KeyedLoadStubCompiler(Isolate* isolate)
: BaseLoadStubCompiler(isolate, registers()) { } : BaseLoadStubCompiler(isolate, Code::KEYED_LOAD_IC, registers()) { }
Handle<Code> CompileLoadElement(Handle<Map> receiver_map); Handle<Code> CompileLoadElement(Handle<Map> receiver_map);
@ -840,15 +845,9 @@ class KeyedLoadStubCompiler: public BaseLoadStubCompiler {
static void GenerateLoadDictionaryElement(MacroAssembler* masm); static void GenerateLoadDictionaryElement(MacroAssembler* masm);
private:
static Register* registers(); static Register* registers();
virtual Code::Kind kind() { return Code::KEYED_LOAD_IC; }
virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) { private:
if (!code->is_inline_cache_stub()) return Logger::STUB_TAG;
return code->ic_state() == MONOMORPHIC
? Logger::KEYED_LOAD_IC_TAG : Logger::KEYED_LOAD_POLYMORPHIC_IC_TAG;
}
virtual void JitEvent(Handle<Name> name, Handle<Code> code);
virtual void GenerateNameCheck(Handle<Name> name, virtual void GenerateNameCheck(Handle<Name> name,
Register name_reg, Register name_reg,
Label* miss); Label* miss);
@ -858,9 +857,9 @@ class KeyedLoadStubCompiler: public BaseLoadStubCompiler {
class BaseStoreStubCompiler: public BaseLoadStoreStubCompiler { class BaseStoreStubCompiler: public BaseLoadStoreStubCompiler {
public: public:
BaseStoreStubCompiler(Isolate* isolate, BaseStoreStubCompiler(Isolate* isolate,
StrictModeFlag strict_mode, Code::Kind kind,
Register* registers) StrictModeFlag strict_mode)
: BaseLoadStoreStubCompiler(isolate, registers), : BaseLoadStoreStubCompiler(isolate, kind, GetRegisters(kind)),
strict_mode_(strict_mode) { } strict_mode_(strict_mode) { }
virtual ~BaseStoreStubCompiler() { } virtual ~BaseStoreStubCompiler() { }
@ -958,7 +957,7 @@ class BaseStoreStubCompiler: public BaseLoadStoreStubCompiler {
class StoreStubCompiler: public BaseStoreStubCompiler { class StoreStubCompiler: public BaseStoreStubCompiler {
public: public:
StoreStubCompiler(Isolate* isolate, StrictModeFlag strict_mode) StoreStubCompiler(Isolate* isolate, StrictModeFlag strict_mode)
: BaseStoreStubCompiler(isolate, strict_mode, registers()) { } : BaseStoreStubCompiler(isolate, Code::STORE_IC, strict_mode) { }
Handle<Code> CompileStoreCallback(Handle<JSObject> object, Handle<Code> CompileStoreCallback(Handle<JSObject> object,
@ -982,15 +981,7 @@ class StoreStubCompiler: public BaseStoreStubCompiler {
Handle<Code> CompileStoreInterceptor(Handle<JSObject> object, Handle<Code> CompileStoreInterceptor(Handle<JSObject> object,
Handle<Name> name); Handle<Name> name);
private:
static Register* registers(); static Register* registers();
virtual Code::Kind kind() { return Code::STORE_IC; }
virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) {
if (!code->is_inline_cache_stub()) return Logger::STUB_TAG;
return code->ic_state() == MONOMORPHIC
? Logger::STORE_IC_TAG : Logger::STORE_POLYMORPHIC_IC_TAG;
}
virtual void JitEvent(Handle<Name> name, Handle<Code> code);
}; };
@ -999,7 +990,7 @@ class KeyedStoreStubCompiler: public BaseStoreStubCompiler {
KeyedStoreStubCompiler(Isolate* isolate, KeyedStoreStubCompiler(Isolate* isolate,
StrictModeFlag strict_mode, StrictModeFlag strict_mode,
KeyedAccessStoreMode store_mode) KeyedAccessStoreMode store_mode)
: BaseStoreStubCompiler(isolate, strict_mode, registers()), : BaseStoreStubCompiler(isolate, Code::KEYED_STORE_IC, strict_mode),
store_mode_(store_mode) { } store_mode_(store_mode) { }
Handle<Code> CompileStoreElement(Handle<Map> receiver_map); Handle<Code> CompileStoreElement(Handle<Map> receiver_map);
@ -1012,6 +1003,8 @@ class KeyedStoreStubCompiler: public BaseStoreStubCompiler {
static void GenerateStoreDictionaryElement(MacroAssembler* masm); static void GenerateStoreDictionaryElement(MacroAssembler* masm);
static Register* registers();
protected: protected:
virtual Code::ExtraICState extra_state() { virtual Code::ExtraICState extra_state() {
return Code::ComputeExtraICState(store_mode_, strict_mode()); return Code::ComputeExtraICState(store_mode_, strict_mode());
@ -1022,14 +1015,6 @@ class KeyedStoreStubCompiler: public BaseStoreStubCompiler {
return registers()[3]; return registers()[3];
} }
static Register* registers();
virtual Code::Kind kind() { return Code::KEYED_STORE_IC; }
virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) {
if (!code->is_inline_cache_stub()) return Logger::STUB_TAG;
return code->ic_state() == MONOMORPHIC
? Logger::KEYED_STORE_IC_TAG : Logger::KEYED_STORE_POLYMORPHIC_IC_TAG;
}
virtual void JitEvent(Handle<Name> name, Handle<Code> code);
virtual void GenerateNameCheck(Handle<Name> name, virtual void GenerateNameCheck(Handle<Name> name,
Register name_reg, Register name_reg,
Label* miss); Label* miss);