Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Unified Diff: src/ic/ic.cc

Issue 1846963002: Use a dictionary-mode code cache on the map rather than a dual system. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comment Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ic/ic.h ('k') | src/ic/ic-compiler.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ic/ic.cc
diff --git a/src/ic/ic.cc b/src/ic/ic.cc
index 496b7d7249a3740596cbaa497f5b8b80a08af692..045c4593e15ffe7337dc94d82d03cafe8541e93c 100644
--- a/src/ic/ic.cc
+++ b/src/ic/ic.cc
@@ -38,7 +38,7 @@ char IC::TransitionMarkFromState(IC::State state) {
return '.';
case MONOMORPHIC:
return '1';
- case PROTOTYPE_FAILURE:
+ case RECOMPUTE_HANDLER:
return '^';
case POLYMORPHIC:
return 'P';
@@ -258,10 +258,8 @@ static void LookupForRead(LookupIterator* it) {
}
}
-
-bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
- Handle<String> name) {
- if (!IsNameCompatibleWithPrototypeFailure(name)) return false;
+bool IC::ShouldRecomputeHandler(Handle<Object> receiver, Handle<String> name) {
+ if (!RecomputeHandlerForName(name)) return false;
if (UseVector()) {
maybe_handler_ = nexus()->FindHandlerForMap(receiver_map());
} else {
@@ -283,20 +281,6 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
receiver_map()->elements_kind());
}
- CacheHolderFlag flag;
- Handle<Map> ic_holder_map(GetICCacheHolder(receiver_map(), isolate(), &flag));
-
- DCHECK(flag != kCacheOnReceiver || receiver->IsJSObject());
- DCHECK(flag != kCacheOnPrototype || !receiver->IsJSReceiver());
- DCHECK(flag != kCacheOnPrototypeReceiverIsDictionary);
-
- if (state() == MONOMORPHIC) {
- int index = ic_holder_map->IndexInCodeCache(*name, *target());
- if (index >= 0) {
- ic_holder_map->RemoveFromCodeCache(*name, *target(), index);
- }
- }
-
if (receiver->IsJSGlobalObject()) {
Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(receiver);
LookupIterator it(global, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
@@ -308,8 +292,7 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
return true;
}
-
-bool IC::IsNameCompatibleWithPrototypeFailure(Handle<Object> name) {
+bool IC::RecomputeHandlerForName(Handle<Object> name) {
if (target()->is_keyed_stub()) {
// Determine whether the failure is due to a name failure.
if (!name->IsName()) return false;
@@ -331,10 +314,8 @@ void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) {
// Remove the target from the code cache if it became invalid
// because of changes in the prototype chain to avoid hitting it
// again.
- if (TryRemoveInvalidPrototypeDependentStub(receiver,
- Handle<String>::cast(name))) {
- MarkPrototypeFailure(name);
- return;
+ if (ShouldRecomputeHandler(receiver, Handle<String>::cast(name))) {
+ MarkRecomputeHandler(name);
}
}
@@ -382,7 +363,7 @@ static void ComputeTypeInfoCountDelta(IC::State old_state, IC::State new_state,
*polymorphic_delta = 1;
}
break;
- case PROTOTYPE_FAILURE:
+ case RECOMPUTE_HANDLER:
case DEBUG_STUB:
UNREACHABLE();
}
@@ -460,15 +441,14 @@ void IC::Clear(Isolate* isolate, Address address, Address constant_pool) {
if (target->is_debug_stub()) return;
switch (target->kind()) {
- case Code::LOAD_IC:
- case Code::KEYED_LOAD_IC:
- case Code::STORE_IC:
- case Code::KEYED_STORE_IC:
- return;
case Code::COMPARE_IC:
return CompareIC::Clear(isolate, address, target, constant_pool);
- case Code::CALL_IC: // CallICs are vector-based and cleared differently.
case Code::BINARY_OP_IC:
+ case Code::CALL_IC: // CallICs are vector-based and cleared differently.
+ case Code::KEYED_LOAD_IC:
+ case Code::KEYED_STORE_IC:
+ case Code::LOAD_IC:
+ case Code::STORE_IC:
case Code::TO_BOOLEAN_IC:
// Clearing these is tricky and does not
// make any performance difference.
@@ -509,15 +489,6 @@ void LoadIC::Clear(Isolate* isolate, Code* host, LoadICNexus* nexus) {
}
-void StoreIC::Clear(Isolate* isolate, Address address, Code* target,
- Address constant_pool) {
- if (IsCleared(target)) return;
- Code* code = PropertyICCompiler::FindPreMonomorphic(isolate, Code::STORE_IC,
- target->extra_ic_state());
- SetTargetAtAddress(address, code, constant_pool);
-}
-
-
void StoreIC::Clear(Isolate* isolate, Code* host, StoreICNexus* nexus) {
if (IsCleared(nexus)) return;
nexus->ConfigurePremonomorphic();
@@ -525,15 +496,6 @@ void StoreIC::Clear(Isolate* isolate, Code* host, StoreICNexus* nexus) {
}
-void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target,
- Address constant_pool) {
- if (IsCleared(target)) return;
- Handle<Code> code = pre_monomorphic_stub(
- isolate, StoreICState::GetLanguageMode(target->extra_ic_state()));
- SetTargetAtAddress(address, *code, constant_pool);
-}
-
-
void KeyedStoreIC::Clear(Isolate* isolate, Code* host,
KeyedStoreICNexus* nexus) {
if (IsCleared(nexus)) return;
@@ -742,7 +704,7 @@ static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps,
bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code) {
if (!code->is_handler()) return false;
- if (target()->is_keyed_stub() && state() != PROTOTYPE_FAILURE) return false;
+ if (target()->is_keyed_stub() && state() != RECOMPUTE_HANDLER) return false;
Handle<Map> map = receiver_map();
MapHandleList maps;
CodeHandleList handlers;
@@ -843,10 +805,10 @@ void IC::PatchCache(Handle<Name> name, Handle<Code> code) {
case PREMONOMORPHIC:
UpdateMonomorphicIC(code, name);
break;
- case PROTOTYPE_FAILURE:
+ case RECOMPUTE_HANDLER:
case MONOMORPHIC:
case POLYMORPHIC:
- if (!target()->is_keyed_stub() || state() == PROTOTYPE_FAILURE) {
+ if (!target()->is_keyed_stub() || state() == RECOMPUTE_HANDLER) {
if (UpdatePolymorphicIC(name, code)) break;
// For keyed stubs, we can't know whether old handlers were for the
// same key.
@@ -907,14 +869,6 @@ static Handle<Code> KeyedStoreICInitializeStubHelper(
Isolate* isolate, LanguageMode language_mode,
InlineCacheState initialization_state) {
switch (initialization_state) {
- case UNINITIALIZED:
- return is_strict(language_mode)
- ? isolate->builtins()->KeyedStoreIC_Initialize_Strict()
- : isolate->builtins()->KeyedStoreIC_Initialize();
- case PREMONOMORPHIC:
- return is_strict(language_mode)
- ? isolate->builtins()->KeyedStoreIC_PreMonomorphic_Strict()
- : isolate->builtins()->KeyedStoreIC_PreMonomorphic();
case MEGAMORPHIC:
return is_strict(language_mode)
? isolate->builtins()->KeyedStoreIC_Megamorphic_Strict()
@@ -1069,16 +1023,14 @@ Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) {
receiver_map(), receiver_is_holder, isolate(), &flag);
Handle<Code> code = PropertyHandlerCompiler::Find(
- lookup->name(), stub_holder_map, kind(), flag,
- lookup->is_dictionary_holder() ? Code::NORMAL : Code::FAST);
+ lookup->name(), stub_holder_map, kind(), flag);
// Use the cached value if it exists, and if it is different from the
// handler that just missed.
if (!code.is_null()) {
- if (!maybe_handler_.is_null() &&
- !maybe_handler_.ToHandleChecked().is_identical_to(code)) {
- return code;
- }
- if (maybe_handler_.is_null()) {
+ Handle<Code> handler;
+ if (maybe_handler_.ToHandle(&handler)) {
+ if (!handler.is_identical_to(code)) return code;
+ } else {
// maybe_handler_ is only populated for MONOMORPHIC and POLYMORPHIC ICs.
// In MEGAMORPHIC case, check if the handler in the megamorphic stub
// cache (which just missed) is different from the cached handler.
@@ -1101,8 +1053,9 @@ Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) {
// code cache. We are also guarding against installing code with flags that
// don't match the desired CacheHolderFlag computed above, which would lead to
// invalid lookups later.
- if (code->type() != Code::NORMAL &&
- Code::ExtractCacheHolderFromFlags(code->flags()) == flag) {
+ bool is_normal = receiver_is_holder &&
+ !lookup->GetHolder<JSReceiver>()->HasFastProperties();
+ if (!is_normal && Code::ExtractCacheHolderFromFlags(code->flags()) == flag) {
Map::UpdateCodeCache(stub_holder_map, lookup->name(), code);
}
@@ -1641,13 +1594,6 @@ Handle<Code> StoreIC::slow_stub() const {
}
-Handle<Code> StoreIC::pre_monomorphic_stub(Isolate* isolate,
- LanguageMode language_mode) {
- ExtraICState state = ComputeExtraICState(language_mode);
- return PropertyICCompiler::ComputeStore(isolate, PREMONOMORPHIC, state);
-}
-
-
void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value,
JSReceiver::StoreFromKeyed store_mode) {
if (state() == UNINITIALIZED) {
@@ -1828,16 +1774,6 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
Handle<Code> KeyedStoreIC::StoreElementStub(Handle<Map> receiver_map,
KeyedAccessStoreMode store_mode) {
- Handle<Code> null_handle;
- // Don't handle megamorphic property accesses for INTERCEPTORS or
- // ACCESSOR_CONSTANT
- // via megamorphic stubs, since they don't have a map in their relocation info
- // and so the stubs can't be harvested for the object needed for a map check.
- if (target()->type() != Code::NORMAL) {
- TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-NORMAL target type");
- return megamorphic_stub();
- }
-
MapHandleList target_receiver_maps;
TargetMaps(&target_receiver_maps);
if (target_receiver_maps.length() == 0) {
@@ -1848,7 +1784,7 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<Map> receiver_map,
PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(
monomorphic_map, language_mode(), store_mode);
ConfigureVectorState(Handle<Name>::null(), monomorphic_map, handler);
- return null_handle;
+ return Handle<Code>();
}
// There are several special cases where an IC that is MONOMORPHIC can still
@@ -1876,7 +1812,7 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<Map> receiver_map,
transitioned_receiver_map, language_mode(), store_mode);
ConfigureVectorState(Handle<Name>::null(), transitioned_receiver_map,
handler);
- return null_handle;
+ return Handle<Code>();
} else if (receiver_map.is_identical_to(previous_receiver_map) &&
old_store_mode == STANDARD_STORE &&
(store_mode == STORE_AND_GROW_NO_TRANSITION ||
@@ -1889,7 +1825,7 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<Map> receiver_map,
PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(
receiver_map, language_mode(), store_mode);
ConfigureVectorState(Handle<Name>::null(), receiver_map, handler);
- return null_handle;
+ return Handle<Code>();
}
}
@@ -1954,7 +1890,7 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<Map> receiver_map,
&target_receiver_maps, &transitioned_maps, &handlers, store_mode,
language_mode());
ConfigureVectorState(&target_receiver_maps, &transitioned_maps, &handlers);
- return null_handle;
+ return Handle<Code>();
}
« no previous file with comments | « src/ic/ic.h ('k') | src/ic/ic-compiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698