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