Centralize handler caching and probing in ic.cc.
Also purge invalid POLYMORPHIC stubs. In a next step the compilers should probably be merged and the "Compute*" on the stub-cache removed. BUG= R=ulan@chromium.org Review URL: https://chromiumcodereview.appspot.com/25548009 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17161 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
6ab8977e73
commit
04e1462f9e
88
src/ic.cc
88
src/ic.cc
@ -300,7 +300,8 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map* map = IC::GetCodeCacheHolder(isolate(), *receiver, cache_holder)->map();
|
Handle<Map> map(
|
||||||
|
IC::GetCodeCacheHolder(isolate(), *receiver, cache_holder)->map());
|
||||||
|
|
||||||
// Decide whether the inline cache failed because of changes to the
|
// Decide whether the inline cache failed because of changes to the
|
||||||
// receiver itself or changes to one of its prototypes.
|
// receiver itself or changes to one of its prototypes.
|
||||||
@ -314,13 +315,7 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
|
|||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
map->RemoveFromCodeCache(*name, *target(), index);
|
map->RemoveFromCodeCache(*name, *target(), index);
|
||||||
// Handlers are stored in addition to the ICs on the map. Remove those, too.
|
// Handlers are stored in addition to the ICs on the map. Remove those, too.
|
||||||
Code* handler = target()->FindFirstHandler();
|
TryRemoveInvalidHandlers(map, name);
|
||||||
if (handler != NULL) {
|
|
||||||
index = map->IndexInCodeCache(*name, handler);
|
|
||||||
if (index >= 0) {
|
|
||||||
map->RemoveFromCodeCache(*name, handler, index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,7 +329,7 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
|
|||||||
// the map cannot be deprecated and the stub invalidated.
|
// the map cannot be deprecated and the stub invalidated.
|
||||||
if (cache_holder == OWN_MAP) {
|
if (cache_holder == OWN_MAP) {
|
||||||
Map* old_map = target()->FindFirstMap();
|
Map* old_map = target()->FindFirstMap();
|
||||||
if (old_map == map) return true;
|
if (old_map == *map) return true;
|
||||||
if (old_map != NULL) {
|
if (old_map != NULL) {
|
||||||
if (old_map->is_deprecated()) return true;
|
if (old_map->is_deprecated()) return true;
|
||||||
if (IsMoreGeneralElementsKindTransition(old_map->elements_kind(),
|
if (IsMoreGeneralElementsKindTransition(old_map->elements_kind(),
|
||||||
@ -357,8 +352,30 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IC::TryRemoveInvalidHandlers(Handle<Map> map, Handle<String> name) {
|
||||||
|
CodeHandleList handlers;
|
||||||
|
target()->FindHandlers(&handlers);
|
||||||
|
for (int i = 0; i < handlers.length(); i++) {
|
||||||
|
Handle<Code> handler = handlers.at(i);
|
||||||
|
int index = map->IndexInCodeCache(*name, *handler);
|
||||||
|
if (index >= 0) {
|
||||||
|
map->RemoveFromCodeCache(*name, *handler, index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) {
|
void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) {
|
||||||
if (state() != MONOMORPHIC || !name->IsString()) return;
|
if (!name->IsString()) return;
|
||||||
|
if (state() != MONOMORPHIC) {
|
||||||
|
if (state() == POLYMORPHIC && receiver->IsHeapObject()) {
|
||||||
|
TryRemoveInvalidHandlers(
|
||||||
|
handle(Handle<HeapObject>::cast(receiver)->map()),
|
||||||
|
Handle<String>::cast(name));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (receiver->IsUndefined() || receiver->IsNull()) return;
|
if (receiver->IsUndefined() || receiver->IsNull()) return;
|
||||||
|
|
||||||
// Remove the target from the code cache if it became invalid
|
// Remove the target from the code cache if it became invalid
|
||||||
@ -1122,7 +1139,6 @@ void LoadIC::UpdateCaches(LookupResult* lookup,
|
|||||||
code = slow_stub();
|
code = slow_stub();
|
||||||
} else {
|
} else {
|
||||||
code = ComputeLoadHandler(lookup, Handle<JSObject>::cast(receiver), name);
|
code = ComputeLoadHandler(lookup, Handle<JSObject>::cast(receiver), name);
|
||||||
if (code.is_null()) code = slow_stub();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PatchCache(receiver, name, code);
|
PatchCache(receiver, name, code);
|
||||||
@ -1141,11 +1157,29 @@ Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup,
|
|||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
Handle<String> name) {
|
Handle<String> name) {
|
||||||
if (!lookup->IsProperty()) {
|
if (!lookup->IsProperty()) {
|
||||||
// Nonexistent property. The result is undefined.
|
return kind() == Code::LOAD_IC
|
||||||
return isolate()->stub_cache()->ComputeLoadNonexistent(name, receiver);
|
? isolate()->stub_cache()->ComputeLoadNonexistent(name, receiver)
|
||||||
|
: generic_stub();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute monomorphic stub.
|
Handle<Code> code = isolate()->stub_cache()->FindHandler(
|
||||||
|
name, receiver, kind());
|
||||||
|
if (!code.is_null()) return code;
|
||||||
|
|
||||||
|
code = CompileLoadHandler(lookup, receiver, name);
|
||||||
|
if (code.is_null()) return slow_stub();
|
||||||
|
|
||||||
|
if (code->is_handler() && code->type() != Code::NORMAL) {
|
||||||
|
HeapObject::UpdateMapCodeCache(receiver, name, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Handle<Code> LoadIC::CompileLoadHandler(LookupResult* lookup,
|
||||||
|
Handle<JSObject> receiver,
|
||||||
|
Handle<String> name) {
|
||||||
Handle<JSObject> holder(lookup->holder());
|
Handle<JSObject> holder(lookup->holder());
|
||||||
switch (lookup->type()) {
|
switch (lookup->type()) {
|
||||||
case FIELD:
|
case FIELD:
|
||||||
@ -1356,12 +1390,9 @@ MaybeObject* KeyedLoadIC::Load(Handle<Object> object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup,
|
Handle<Code> KeyedLoadIC::CompileLoadHandler(LookupResult* lookup,
|
||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
Handle<String> name) {
|
Handle<String> name) {
|
||||||
// Bail out if we didn't find a result.
|
|
||||||
if (!lookup->IsProperty()) return Handle<Code>::null();
|
|
||||||
|
|
||||||
// Compute a monomorphic stub.
|
// Compute a monomorphic stub.
|
||||||
Handle<JSObject> holder(lookup->holder(), isolate());
|
Handle<JSObject> holder(lookup->holder(), isolate());
|
||||||
switch (lookup->type()) {
|
switch (lookup->type()) {
|
||||||
@ -1614,6 +1645,25 @@ Handle<Code> StoreIC::ComputeStoreHandler(LookupResult* lookup,
|
|||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
Handle<String> name,
|
Handle<String> name,
|
||||||
Handle<Object> value) {
|
Handle<Object> value) {
|
||||||
|
Handle<Code> code = isolate()->stub_cache()->FindHandler(
|
||||||
|
name, receiver, kind(), strict_mode());
|
||||||
|
if (!code.is_null()) return code;
|
||||||
|
|
||||||
|
code = CompileStoreHandler(lookup, receiver, name, value);
|
||||||
|
if (code.is_null()) return generic_stub();
|
||||||
|
|
||||||
|
if (code->is_handler() && code->type() != Code::NORMAL) {
|
||||||
|
HeapObject::UpdateMapCodeCache(receiver, name, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Handle<Code> StoreIC::CompileStoreHandler(LookupResult* lookup,
|
||||||
|
Handle<JSObject> receiver,
|
||||||
|
Handle<String> name,
|
||||||
|
Handle<Object> value) {
|
||||||
Handle<JSObject> holder(lookup->holder());
|
Handle<JSObject> holder(lookup->holder());
|
||||||
switch (lookup->type()) {
|
switch (lookup->type()) {
|
||||||
case FIELD:
|
case FIELD:
|
||||||
@ -2002,7 +2052,7 @@ MaybeObject* KeyedStoreIC::Store(Handle<Object> object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Handle<Code> KeyedStoreIC::ComputeStoreHandler(LookupResult* lookup,
|
Handle<Code> KeyedStoreIC::CompileStoreHandler(LookupResult* lookup,
|
||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
Handle<String> name,
|
Handle<String> name,
|
||||||
Handle<Object> value) {
|
Handle<Object> value) {
|
||||||
|
17
src/ic.h
17
src/ic.h
@ -198,6 +198,7 @@ class IC {
|
|||||||
virtual StrictModeFlag strict_mode() const { return kNonStrictMode; }
|
virtual StrictModeFlag strict_mode() const { return kNonStrictMode; }
|
||||||
bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
|
bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
|
||||||
Handle<String> name);
|
Handle<String> name);
|
||||||
|
void TryRemoveInvalidHandlers(Handle<Map> map, Handle<String> name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Frame pointer for the frame that uses (calls) the IC.
|
// Frame pointer for the frame that uses (calls) the IC.
|
||||||
@ -394,7 +395,10 @@ class LoadIC: public IC {
|
|||||||
Handle<Object> object,
|
Handle<Object> object,
|
||||||
Handle<String> name);
|
Handle<String> name);
|
||||||
|
|
||||||
virtual Handle<Code> ComputeLoadHandler(LookupResult* lookup,
|
Handle<Code> ComputeLoadHandler(LookupResult* lookup,
|
||||||
|
Handle<JSObject> receiver,
|
||||||
|
Handle<String> name);
|
||||||
|
virtual Handle<Code> CompileLoadHandler(LookupResult* lookup,
|
||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
Handle<String> name);
|
Handle<String> name);
|
||||||
|
|
||||||
@ -471,8 +475,7 @@ class KeyedLoadIC: public LoadIC {
|
|||||||
return isolate()->builtins()->KeyedLoadIC_Slow();
|
return isolate()->builtins()->KeyedLoadIC_Slow();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the inline cache.
|
virtual Handle<Code> CompileLoadHandler(LookupResult* lookup,
|
||||||
virtual Handle<Code> ComputeLoadHandler(LookupResult* lookup,
|
|
||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
Handle<String> name);
|
Handle<String> name);
|
||||||
virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code) { }
|
virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code) { }
|
||||||
@ -590,7 +593,11 @@ class StoreIC: public IC {
|
|||||||
// Compute the code stub for this store; used for rewriting to
|
// Compute the code stub for this store; used for rewriting to
|
||||||
// monomorphic state and making sure that the code stub is in the
|
// monomorphic state and making sure that the code stub is in the
|
||||||
// stub cache.
|
// stub cache.
|
||||||
virtual Handle<Code> ComputeStoreHandler(LookupResult* lookup,
|
Handle<Code> ComputeStoreHandler(LookupResult* lookup,
|
||||||
|
Handle<JSObject> receiver,
|
||||||
|
Handle<String> name,
|
||||||
|
Handle<Object> value);
|
||||||
|
virtual Handle<Code> CompileStoreHandler(LookupResult* lookup,
|
||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
Handle<String> name,
|
Handle<String> name,
|
||||||
Handle<Object> value);
|
Handle<Object> value);
|
||||||
@ -661,7 +668,7 @@ class KeyedStoreIC: public StoreIC {
|
|||||||
protected:
|
protected:
|
||||||
virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; }
|
virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; }
|
||||||
|
|
||||||
virtual Handle<Code> ComputeStoreHandler(LookupResult* lookup,
|
virtual Handle<Code> CompileStoreHandler(LookupResult* lookup,
|
||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
Handle<String> name,
|
Handle<String> name,
|
||||||
Handle<Object> value);
|
Handle<Object> value);
|
||||||
|
@ -5073,7 +5073,7 @@ class Code: public HeapObject {
|
|||||||
|
|
||||||
// Find |length| handlers and put them into |code_list|. Returns false if not
|
// Find |length| handlers and put them into |code_list|. Returns false if not
|
||||||
// enough handlers can be found.
|
// enough handlers can be found.
|
||||||
MUST_USE_RESULT bool FindHandlers(CodeHandleList* code_list, int length);
|
bool FindHandlers(CodeHandleList* code_list, int length = -1);
|
||||||
|
|
||||||
// Find the first name in an IC stub.
|
// Find the first name in an IC stub.
|
||||||
Name* FindFirstName();
|
Name* FindFirstName();
|
||||||
|
@ -119,24 +119,15 @@ Handle<Code> StubCache::FindIC(Handle<Name> name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Handle<Code> StubCache::FindLoadHandler(Handle<Name> name,
|
Handle<Code> StubCache::FindHandler(Handle<Name> name,
|
||||||
Handle<JSObject> receiver,
|
|
||||||
Code::Kind kind) {
|
|
||||||
Code::Flags flags = Code::ComputeMonomorphicFlags(
|
|
||||||
Code::HANDLER, Code::kNoExtraICState, Code::NORMAL, kind);
|
|
||||||
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
|
|
||||||
isolate_);
|
|
||||||
if (probe->IsCode()) return Handle<Code>::cast(probe);
|
|
||||||
return Handle<Code>::null();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Handle<Code> StubCache::FindStoreHandler(Handle<Name> name,
|
|
||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
Code::Kind kind,
|
Code::Kind kind,
|
||||||
StrictModeFlag strict_mode) {
|
StrictModeFlag strict_mode) {
|
||||||
Code::ExtraICState extra_ic_state = Code::ComputeExtraICState(
|
Code::ExtraICState extra_ic_state = Code::kNoExtraICState;
|
||||||
|
if (kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC) {
|
||||||
|
extra_ic_state = Code::ComputeExtraICState(
|
||||||
STANDARD_STORE, strict_mode);
|
STANDARD_STORE, strict_mode);
|
||||||
|
}
|
||||||
Code::Flags flags = Code::ComputeMonomorphicFlags(
|
Code::Flags flags = Code::ComputeMonomorphicFlags(
|
||||||
Code::HANDLER, extra_ic_state, Code::NORMAL, kind);
|
Code::HANDLER, extra_ic_state, Code::NORMAL, kind);
|
||||||
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
|
Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
|
||||||
@ -200,7 +191,7 @@ Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name,
|
|||||||
|
|
||||||
// Compile the stub that is either shared for all names or
|
// Compile the stub that is either shared for all names or
|
||||||
// name specific if there are global objects involved.
|
// name specific if there are global objects involved.
|
||||||
Handle<Code> handler = FindLoadHandler(cache_name, receiver, Code::LOAD_IC);
|
Handle<Code> handler = FindHandler(cache_name, receiver, Code::LOAD_IC);
|
||||||
if (!handler.is_null()) return handler;
|
if (!handler.is_null()) return handler;
|
||||||
|
|
||||||
LoadStubCompiler compiler(isolate_);
|
LoadStubCompiler compiler(isolate_);
|
||||||
@ -223,14 +214,9 @@ Handle<Code> StubCache::ComputeLoadField(Handle<Name> name,
|
|||||||
return stub.GetCode(isolate());
|
return stub.GetCode(isolate());
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Code> stub = FindLoadHandler(name, receiver, Code::LOAD_IC);
|
|
||||||
if (!stub.is_null()) return stub;
|
|
||||||
|
|
||||||
LoadStubCompiler compiler(isolate_);
|
LoadStubCompiler compiler(isolate_);
|
||||||
Handle<Code> handler =
|
return compiler.CompileLoadField(
|
||||||
compiler.CompileLoadField(receiver, holder, name, field, representation);
|
receiver, holder, name, field, representation);
|
||||||
HeapObject::UpdateMapCodeCache(receiver, name, handler);
|
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -240,14 +226,8 @@ Handle<Code> StubCache::ComputeLoadCallback(
|
|||||||
Handle<JSObject> holder,
|
Handle<JSObject> holder,
|
||||||
Handle<ExecutableAccessorInfo> callback) {
|
Handle<ExecutableAccessorInfo> callback) {
|
||||||
ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
|
ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
|
||||||
Handle<Code> stub = FindLoadHandler(name, receiver, Code::LOAD_IC);
|
|
||||||
if (!stub.is_null()) return stub;
|
|
||||||
|
|
||||||
LoadStubCompiler compiler(isolate_);
|
LoadStubCompiler compiler(isolate_);
|
||||||
Handle<Code> handler =
|
return compiler.CompileLoadCallback(receiver, holder, name, callback);
|
||||||
compiler.CompileLoadCallback(receiver, holder, name, callback);
|
|
||||||
HeapObject::UpdateMapCodeCache(receiver, name, handler);
|
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -256,14 +236,9 @@ Handle<Code> StubCache::ComputeLoadCallback(
|
|||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
Handle<JSObject> holder,
|
Handle<JSObject> holder,
|
||||||
const CallOptimization& call_optimization) {
|
const CallOptimization& call_optimization) {
|
||||||
Handle<Code> stub = FindLoadHandler(name, receiver, Code::LOAD_IC);
|
|
||||||
if (!stub.is_null()) return stub;
|
|
||||||
|
|
||||||
LoadStubCompiler compiler(isolate_);
|
LoadStubCompiler compiler(isolate_);
|
||||||
Handle<Code> handler =
|
return compiler.CompileLoadCallback(
|
||||||
compiler.CompileLoadCallback(receiver, holder, name, call_optimization);
|
receiver, holder, name, call_optimization);
|
||||||
HeapObject::UpdateMapCodeCache(receiver, name, handler);
|
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -271,14 +246,8 @@ Handle<Code> StubCache::ComputeLoadViaGetter(Handle<Name> name,
|
|||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
Handle<JSObject> holder,
|
Handle<JSObject> holder,
|
||||||
Handle<JSFunction> getter) {
|
Handle<JSFunction> getter) {
|
||||||
Handle<Code> stub = FindLoadHandler(name, receiver, Code::LOAD_IC);
|
|
||||||
if (!stub.is_null()) return stub;
|
|
||||||
|
|
||||||
LoadStubCompiler compiler(isolate_);
|
LoadStubCompiler compiler(isolate_);
|
||||||
Handle<Code> handler =
|
return compiler.CompileLoadViaGetter(receiver, holder, name, getter);
|
||||||
compiler.CompileLoadViaGetter(receiver, holder, name, getter);
|
|
||||||
HeapObject::UpdateMapCodeCache(receiver, name, handler);
|
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -286,28 +255,16 @@ Handle<Code> StubCache::ComputeLoadConstant(Handle<Name> name,
|
|||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
Handle<JSObject> holder,
|
Handle<JSObject> holder,
|
||||||
Handle<Object> value) {
|
Handle<Object> value) {
|
||||||
Handle<Code> handler = FindLoadHandler(name, receiver, Code::LOAD_IC);
|
|
||||||
if (!handler.is_null()) return handler;
|
|
||||||
|
|
||||||
LoadStubCompiler compiler(isolate_);
|
LoadStubCompiler compiler(isolate_);
|
||||||
handler = compiler.CompileLoadConstant(receiver, holder, name, value);
|
return compiler.CompileLoadConstant(receiver, holder, name, value);
|
||||||
HeapObject::UpdateMapCodeCache(receiver, name, 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) {
|
||||||
Handle<Code> stub = FindLoadHandler(name, receiver, Code::LOAD_IC);
|
|
||||||
if (!stub.is_null()) return stub;
|
|
||||||
|
|
||||||
LoadStubCompiler compiler(isolate_);
|
LoadStubCompiler compiler(isolate_);
|
||||||
Handle<Code> handler =
|
return compiler.CompileLoadInterceptor(receiver, holder, name);
|
||||||
compiler.CompileLoadInterceptor(receiver, holder, name);
|
|
||||||
HeapObject::UpdateMapCodeCache(receiver, name, handler);
|
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -346,14 +303,9 @@ Handle<Code> StubCache::ComputeKeyedLoadField(Handle<Name> name,
|
|||||||
return stub.GetCode(isolate());
|
return stub.GetCode(isolate());
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Code> stub = FindLoadHandler(name, receiver, Code::KEYED_LOAD_IC);
|
|
||||||
if (!stub.is_null()) return stub;
|
|
||||||
|
|
||||||
KeyedLoadStubCompiler compiler(isolate_);
|
KeyedLoadStubCompiler compiler(isolate_);
|
||||||
Handle<Code> handler =
|
return compiler.CompileLoadField(
|
||||||
compiler.CompileLoadField(receiver, holder, name, field, representation);
|
receiver, holder, name, field, representation);
|
||||||
HeapObject::UpdateMapCodeCache(receiver, name, handler);
|
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -361,27 +313,17 @@ Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<Name> name,
|
|||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
Handle<JSObject> holder,
|
Handle<JSObject> holder,
|
||||||
Handle<Object> value) {
|
Handle<Object> value) {
|
||||||
Handle<Code> handler = FindLoadHandler(name, receiver, Code::KEYED_LOAD_IC);
|
|
||||||
if (!handler.is_null()) return handler;
|
|
||||||
|
|
||||||
KeyedLoadStubCompiler compiler(isolate_);
|
KeyedLoadStubCompiler compiler(isolate_);
|
||||||
handler = compiler.CompileLoadConstant(receiver, holder, name, value);
|
return compiler.CompileLoadConstant(
|
||||||
HeapObject::UpdateMapCodeCache(receiver, name, handler);
|
receiver, holder, name, value);
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<Name> name,
|
Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<Name> name,
|
||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
Handle<JSObject> holder) {
|
Handle<JSObject> holder) {
|
||||||
Handle<Code> stub = FindLoadHandler(name, receiver, Code::KEYED_LOAD_IC);
|
|
||||||
if (!stub.is_null()) return stub;
|
|
||||||
|
|
||||||
KeyedLoadStubCompiler compiler(isolate_);
|
KeyedLoadStubCompiler compiler(isolate_);
|
||||||
Handle<Code> handler =
|
return compiler.CompileLoadInterceptor(receiver, holder, name);
|
||||||
compiler.CompileLoadInterceptor(receiver, holder, name);
|
|
||||||
HeapObject::UpdateMapCodeCache(receiver, name, handler);
|
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -390,14 +332,8 @@ Handle<Code> StubCache::ComputeKeyedLoadCallback(
|
|||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
Handle<JSObject> holder,
|
Handle<JSObject> holder,
|
||||||
Handle<ExecutableAccessorInfo> callback) {
|
Handle<ExecutableAccessorInfo> callback) {
|
||||||
Handle<Code> stub = FindLoadHandler(name, receiver, Code::KEYED_LOAD_IC);
|
|
||||||
if (!stub.is_null()) return stub;
|
|
||||||
|
|
||||||
KeyedLoadStubCompiler compiler(isolate_);
|
KeyedLoadStubCompiler compiler(isolate_);
|
||||||
Handle<Code> handler =
|
return compiler.CompileLoadCallback(receiver, holder, name, callback);
|
||||||
compiler.CompileLoadCallback(receiver, holder, name, callback);
|
|
||||||
HeapObject::UpdateMapCodeCache(receiver, name, handler);
|
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -406,14 +342,9 @@ Handle<Code> StubCache::ComputeKeyedLoadCallback(
|
|||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
Handle<JSObject> holder,
|
Handle<JSObject> holder,
|
||||||
const CallOptimization& call_optimization) {
|
const CallOptimization& call_optimization) {
|
||||||
Handle<Code> stub = FindLoadHandler(name, receiver, Code::KEYED_LOAD_IC);
|
|
||||||
if (!stub.is_null()) return stub;
|
|
||||||
|
|
||||||
KeyedLoadStubCompiler compiler(isolate_);
|
KeyedLoadStubCompiler compiler(isolate_);
|
||||||
Handle<Code> handler =
|
return compiler.CompileLoadCallback(
|
||||||
compiler.CompileLoadCallback(receiver, holder, name, call_optimization);
|
receiver, holder, name, call_optimization);
|
||||||
HeapObject::UpdateMapCodeCache(receiver, name, handler);
|
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -421,14 +352,8 @@ Handle<Code> StubCache::ComputeStoreField(Handle<Name> name,
|
|||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
LookupResult* lookup,
|
LookupResult* lookup,
|
||||||
StrictModeFlag strict_mode) {
|
StrictModeFlag strict_mode) {
|
||||||
Handle<Code> stub = FindStoreHandler(
|
|
||||||
name, receiver, Code::STORE_IC, strict_mode);
|
|
||||||
if (!stub.is_null()) return stub;
|
|
||||||
|
|
||||||
StoreStubCompiler compiler(isolate_, strict_mode);
|
StoreStubCompiler compiler(isolate_, strict_mode);
|
||||||
Handle<Code> handler = compiler.CompileStoreField(receiver, lookup, name);
|
return compiler.CompileStoreField(receiver, lookup, name);
|
||||||
HeapObject::UpdateMapCodeCache(receiver, name, handler);
|
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -437,15 +362,8 @@ Handle<Code> StubCache::ComputeStoreTransition(Handle<Name> name,
|
|||||||
LookupResult* lookup,
|
LookupResult* lookup,
|
||||||
Handle<Map> transition,
|
Handle<Map> transition,
|
||||||
StrictModeFlag strict_mode) {
|
StrictModeFlag strict_mode) {
|
||||||
Handle<Code> stub = FindStoreHandler(
|
|
||||||
name, receiver, Code::STORE_IC, strict_mode);
|
|
||||||
if (!stub.is_null()) return stub;
|
|
||||||
|
|
||||||
StoreStubCompiler compiler(isolate_, strict_mode);
|
StoreStubCompiler compiler(isolate_, strict_mode);
|
||||||
Handle<Code> handler =
|
return compiler.CompileStoreTransition(receiver, lookup, transition, name);
|
||||||
compiler.CompileStoreTransition(receiver, lookup, transition, name);
|
|
||||||
HeapObject::UpdateMapCodeCache(receiver, name, handler);
|
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -537,15 +455,8 @@ Handle<Code> StubCache::ComputeStoreCallback(
|
|||||||
Handle<ExecutableAccessorInfo> callback,
|
Handle<ExecutableAccessorInfo> callback,
|
||||||
StrictModeFlag strict_mode) {
|
StrictModeFlag strict_mode) {
|
||||||
ASSERT(v8::ToCData<Address>(callback->setter()) != 0);
|
ASSERT(v8::ToCData<Address>(callback->setter()) != 0);
|
||||||
Handle<Code> stub = FindStoreHandler(
|
|
||||||
name, receiver, Code::STORE_IC, strict_mode);
|
|
||||||
if (!stub.is_null()) return stub;
|
|
||||||
|
|
||||||
StoreStubCompiler compiler(isolate_, strict_mode);
|
StoreStubCompiler compiler(isolate_, strict_mode);
|
||||||
Handle<Code> handler = compiler.CompileStoreCallback(
|
return compiler.CompileStoreCallback(receiver, holder, name, callback);
|
||||||
receiver, holder, name, callback);
|
|
||||||
HeapObject::UpdateMapCodeCache(receiver, name, handler);
|
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -555,15 +466,9 @@ Handle<Code> StubCache::ComputeStoreCallback(
|
|||||||
Handle<JSObject> holder,
|
Handle<JSObject> holder,
|
||||||
const CallOptimization& call_optimization,
|
const CallOptimization& call_optimization,
|
||||||
StrictModeFlag strict_mode) {
|
StrictModeFlag strict_mode) {
|
||||||
Handle<Code> stub = FindStoreHandler(
|
|
||||||
name, receiver, Code::STORE_IC, strict_mode);
|
|
||||||
if (!stub.is_null()) return stub;
|
|
||||||
|
|
||||||
StoreStubCompiler compiler(isolate_, strict_mode);
|
StoreStubCompiler compiler(isolate_, strict_mode);
|
||||||
Handle<Code> handler = compiler.CompileStoreCallback(
|
return compiler.CompileStoreCallback(
|
||||||
receiver, holder, name, call_optimization);
|
receiver, holder, name, call_optimization);
|
||||||
HeapObject::UpdateMapCodeCache(receiver, name, handler);
|
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -572,29 +477,16 @@ Handle<Code> StubCache::ComputeStoreViaSetter(Handle<Name> name,
|
|||||||
Handle<JSObject> holder,
|
Handle<JSObject> holder,
|
||||||
Handle<JSFunction> setter,
|
Handle<JSFunction> setter,
|
||||||
StrictModeFlag strict_mode) {
|
StrictModeFlag strict_mode) {
|
||||||
Handle<Code> stub = FindStoreHandler(
|
|
||||||
name, receiver, Code::STORE_IC, strict_mode);
|
|
||||||
if (!stub.is_null()) return stub;
|
|
||||||
|
|
||||||
StoreStubCompiler compiler(isolate_, strict_mode);
|
StoreStubCompiler compiler(isolate_, strict_mode);
|
||||||
Handle<Code> handler = compiler.CompileStoreViaSetter(
|
return compiler.CompileStoreViaSetter(receiver, holder, name, setter);
|
||||||
receiver, holder, name, setter);
|
|
||||||
HeapObject::UpdateMapCodeCache(receiver, name, handler);
|
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Handle<Code> StubCache::ComputeStoreInterceptor(Handle<Name> name,
|
Handle<Code> StubCache::ComputeStoreInterceptor(Handle<Name> name,
|
||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
StrictModeFlag strict_mode) {
|
StrictModeFlag strict_mode) {
|
||||||
Handle<Code> stub = FindStoreHandler(
|
|
||||||
name, receiver, Code::STORE_IC, strict_mode);
|
|
||||||
if (!stub.is_null()) return stub;
|
|
||||||
|
|
||||||
StoreStubCompiler compiler(isolate_, strict_mode);
|
StoreStubCompiler compiler(isolate_, strict_mode);
|
||||||
Handle<Code> handler = compiler.CompileStoreInterceptor(receiver, name);
|
return compiler.CompileStoreInterceptor(receiver, name);
|
||||||
HeapObject::UpdateMapCodeCache(receiver, name, handler);
|
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -602,14 +494,8 @@ Handle<Code> StubCache::ComputeKeyedStoreField(Handle<Name> name,
|
|||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
LookupResult* lookup,
|
LookupResult* lookup,
|
||||||
StrictModeFlag strict_mode) {
|
StrictModeFlag strict_mode) {
|
||||||
Handle<Code> stub = FindStoreHandler(
|
|
||||||
name, receiver, Code::KEYED_STORE_IC, strict_mode);
|
|
||||||
if (!stub.is_null()) return stub;
|
|
||||||
|
|
||||||
KeyedStoreStubCompiler compiler(isolate(), strict_mode, STANDARD_STORE);
|
KeyedStoreStubCompiler compiler(isolate(), strict_mode, STANDARD_STORE);
|
||||||
Handle<Code> handler = compiler.CompileStoreField(receiver, lookup, name);
|
return compiler.CompileStoreField(receiver, lookup, name);
|
||||||
HeapObject::UpdateMapCodeCache(receiver, name, handler);
|
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -619,15 +505,8 @@ Handle<Code> StubCache::ComputeKeyedStoreTransition(
|
|||||||
LookupResult* lookup,
|
LookupResult* lookup,
|
||||||
Handle<Map> transition,
|
Handle<Map> transition,
|
||||||
StrictModeFlag strict_mode) {
|
StrictModeFlag strict_mode) {
|
||||||
Handle<Code> stub = FindStoreHandler(
|
|
||||||
name, receiver, Code::KEYED_STORE_IC, strict_mode);
|
|
||||||
if (!stub.is_null()) return stub;
|
|
||||||
|
|
||||||
KeyedStoreStubCompiler compiler(isolate(), strict_mode, STANDARD_STORE);
|
KeyedStoreStubCompiler compiler(isolate(), strict_mode, STANDARD_STORE);
|
||||||
Handle<Code> handler =
|
return compiler.CompileStoreTransition(receiver, lookup, transition, name);
|
||||||
compiler.CompileStoreTransition(receiver, lookup, transition, name);
|
|
||||||
HeapObject::UpdateMapCodeCache(receiver, name, handler);
|
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,14 +90,10 @@ class StubCache {
|
|||||||
Code::Kind kind,
|
Code::Kind kind,
|
||||||
Code::ExtraICState extra_state = Code::kNoExtraICState);
|
Code::ExtraICState extra_state = Code::kNoExtraICState);
|
||||||
|
|
||||||
Handle<Code> FindLoadHandler(Handle<Name> name,
|
Handle<Code> FindHandler(Handle<Name> name,
|
||||||
Handle<JSObject> receiver,
|
|
||||||
Code::Kind kind);
|
|
||||||
|
|
||||||
Handle<Code> FindStoreHandler(Handle<Name> name,
|
|
||||||
Handle<JSObject> receiver,
|
Handle<JSObject> receiver,
|
||||||
Code::Kind kind,
|
Code::Kind kind,
|
||||||
StrictModeFlag strict_mode);
|
StrictModeFlag strict_mode = kNonStrictMode);
|
||||||
|
|
||||||
Handle<Code> ComputeMonomorphicIC(Handle<HeapObject> receiver,
|
Handle<Code> ComputeMonomorphicIC(Handle<HeapObject> receiver,
|
||||||
Handle<Code> handler,
|
Handle<Code> handler,
|
||||||
|
Loading…
Reference in New Issue
Block a user