Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index eb115613daced16427f55e78cd3a14424d5bc3e3..fad135e3a4bc0494d58ceda2172367ced6a55f17 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -4799,6 +4799,16 @@ static Handle<SeededNumberDictionary> CopyFastElementsToDictionary( |
} |
+void JSObject::RequireSlowElements(SeededNumberDictionary* dictionary) { |
+ if (dictionary->requires_slow_elements()) return; |
+ dictionary->set_requires_slow_elements(); |
+ // TODO(verwaest): Remove this hack. |
+ if (map()->is_prototype_map()) { |
+ GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC); |
+ } |
+} |
+ |
+ |
Handle<SeededNumberDictionary> JSObject::NormalizeElements( |
Handle<JSObject> object) { |
DCHECK(!object->HasExternalArrayElements() && |
@@ -5440,7 +5450,7 @@ MaybeHandle<Object> JSObject::PreventExtensions(Handle<JSObject> object) { |
DCHECK(object->HasDictionaryElements() || object->HasSlowArgumentsElements()); |
// Make sure that we never go back to fast case. |
- dictionary->set_requires_slow_elements(); |
+ object->RequireSlowElements(*dictionary); |
// Do a map transition, other objects with this map may still |
// be extensible. |
@@ -5613,7 +5623,7 @@ MaybeHandle<Object> JSObject::PreventExtensionsWithTransition( |
if (object->elements() != isolate->heap()->empty_slow_element_dictionary()) { |
SeededNumberDictionary* dictionary = object->element_dictionary(); |
// Make sure we never go back to the fast case |
- dictionary->set_requires_slow_elements(); |
+ object->RequireSlowElements(dictionary); |
if (attrs != NONE) { |
ApplyAttributesToDictionary(dictionary, attrs); |
} |
@@ -6234,11 +6244,20 @@ bool Map::DictionaryElementsInPrototypeChainOnly() { |
if (iter.GetCurrent()->IsJSProxy()) return true; |
// String wrappers have non-configurable, non-writable elements. |
if (iter.GetCurrent()->IsStringWrapper()) return true; |
+ JSObject* current = JSObject::cast(iter.GetCurrent()); |
- if (IsDictionaryElementsKind( |
- JSObject::cast(iter.GetCurrent())->map()->elements_kind())) { |
+ if (current->HasDictionaryElements() && |
+ current->element_dictionary()->requires_slow_elements()) { |
return true; |
} |
+ |
+ if (current->HasSlowArgumentsElements()) { |
+ FixedArray* parameter_map = FixedArray::cast(current->elements()); |
+ Object* arguments = parameter_map->get(1); |
+ if (SeededNumberDictionary::cast(arguments)->requires_slow_elements()) { |
+ return true; |
+ } |
+ } |
} |
return false; |
@@ -14670,6 +14689,8 @@ void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { |
// Check if this index is high enough that we should require slow |
// elements. |
if (key > kRequiresSlowElementsLimit) { |
+ // TODO(verwaest): Remove this hack. |
+ GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC); |
set_requires_slow_elements(); |
return; |
} |