Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 11114f9c04d007dc7c4309a23b43230135fbfedd..49a1f0f6ef555b96a6e2bbf00c71c4d70b525134 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -6163,9 +6163,10 @@ void JSObject::ResetElements(Handle<JSObject> object) { |
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()) { |
- TypeFeedbackVector::ClearAllKeyedStoreICs(GetIsolate()); |
+ // If this object is a prototype (the callee will check), invalidate any |
+ // prototype chains involving it. |
+ InvalidatePrototypeChains(map()); |
} |
} |
@@ -15592,9 +15593,6 @@ Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object, |
// SpiderMonkey behaves this way. |
if (!value->IsJSReceiver() && !value->IsNull(isolate)) return Just(true); |
- bool dictionary_elements_in_chain = |
- object->map()->DictionaryElementsInPrototypeChainOnly(); |
- |
bool all_extensible = object->map()->is_extensible(); |
Handle<JSObject> real_receiver = object; |
if (from_javascript) { |
@@ -15660,14 +15658,6 @@ Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object, |
DCHECK(new_map->prototype() == *value); |
JSObject::MigrateToMap(real_receiver, new_map); |
- if (from_javascript && !dictionary_elements_in_chain && |
- new_map->DictionaryElementsInPrototypeChainOnly()) { |
- // If the prototype chain didn't previously have element callbacks, then |
- // KeyedStoreICs need to be cleared to ensure any that involve this |
- // map go generic. |
- TypeFeedbackVector::ClearAllKeyedStoreICs(isolate); |
- } |
- |
heap->ClearInstanceofCache(); |
DCHECK(size == object->Size()); |
return Just(true); |
@@ -17364,7 +17354,7 @@ Handle<Object> JSObject::PrepareSlowElementsForSort( |
return bailout; |
} else { |
Handle<Object> result = SeededNumberDictionary::AddNumberEntry( |
- new_dict, pos, value, details, object->map()->is_prototype_map()); |
+ new_dict, pos, value, details, object); |
DCHECK(result.is_identical_to(new_dict)); |
USE(result); |
pos++; |
@@ -17375,7 +17365,7 @@ Handle<Object> JSObject::PrepareSlowElementsForSort( |
return bailout; |
} else { |
Handle<Object> result = SeededNumberDictionary::AddNumberEntry( |
- new_dict, key, value, details, object->map()->is_prototype_map()); |
+ new_dict, key, value, details, object); |
DCHECK(result.is_identical_to(new_dict)); |
USE(result); |
} |
@@ -17392,7 +17382,7 @@ Handle<Object> JSObject::PrepareSlowElementsForSort( |
HandleScope scope(isolate); |
Handle<Object> result = SeededNumberDictionary::AddNumberEntry( |
new_dict, pos, isolate->factory()->undefined_value(), no_details, |
- object->map()->is_prototype_map()); |
+ object); |
DCHECK(result.is_identical_to(new_dict)); |
USE(result); |
pos++; |
@@ -18260,8 +18250,8 @@ bool SeededNumberDictionary::HasComplexElements() { |
return false; |
} |
-void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key, |
- bool used_as_prototype) { |
+void SeededNumberDictionary::UpdateMaxNumberKey( |
+ uint32_t key, Handle<JSObject> dictionary_holder) { |
DisallowHeapAllocation no_allocation; |
// If the dictionary requires slow elements an element has already |
// been added at a high index. |
@@ -18269,9 +18259,8 @@ void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key, |
// Check if this index is high enough that we should require slow |
// elements. |
if (key > kRequiresSlowElementsLimit) { |
- if (used_as_prototype) { |
- // TODO(verwaest): Remove this hack. |
- TypeFeedbackVector::ClearAllKeyedStoreICs(GetIsolate()); |
+ if (!dictionary_holder.is_null()) { |
+ dictionary_holder->RequireSlowElements(this); |
} |
set_requires_slow_elements(); |
return; |
@@ -18284,11 +18273,11 @@ void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key, |
} |
} |
- |
Handle<SeededNumberDictionary> SeededNumberDictionary::AddNumberEntry( |
Handle<SeededNumberDictionary> dictionary, uint32_t key, |
- Handle<Object> value, PropertyDetails details, bool used_as_prototype) { |
- dictionary->UpdateMaxNumberKey(key, used_as_prototype); |
+ Handle<Object> value, PropertyDetails details, |
+ Handle<JSObject> dictionary_holder) { |
+ dictionary->UpdateMaxNumberKey(key, dictionary_holder); |
SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound); |
return Add(dictionary, key, value, details); |
} |
@@ -18316,8 +18305,8 @@ Handle<UnseededNumberDictionary> UnseededNumberDictionary::DeleteKey( |
Handle<SeededNumberDictionary> SeededNumberDictionary::AtNumberPut( |
Handle<SeededNumberDictionary> dictionary, uint32_t key, |
- Handle<Object> value, bool used_as_prototype) { |
- dictionary->UpdateMaxNumberKey(key, used_as_prototype); |
+ Handle<Object> value, Handle<JSObject> dictionary_holder) { |
+ dictionary->UpdateMaxNumberKey(key, dictionary_holder); |
return AtPut(dictionary, key, value); |
} |
@@ -18329,13 +18318,13 @@ Handle<UnseededNumberDictionary> UnseededNumberDictionary::AtNumberPut( |
return AtPut(dictionary, key, value); |
} |
- |
Handle<SeededNumberDictionary> SeededNumberDictionary::Set( |
Handle<SeededNumberDictionary> dictionary, uint32_t key, |
- Handle<Object> value, PropertyDetails details, bool used_as_prototype) { |
+ Handle<Object> value, PropertyDetails details, |
+ Handle<JSObject> dictionary_holder) { |
int entry = dictionary->FindEntry(key); |
if (entry == kNotFound) { |
- return AddNumberEntry(dictionary, key, value, details, used_as_prototype); |
+ return AddNumberEntry(dictionary, key, value, details, dictionary_holder); |
} |
// Preserve enumeration index. |
details = details.set_index(dictionary->DetailsAt(entry).dictionary_index()); |