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>(); |
} |