| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index 6fd95030c538d2d5618eb680b1c0a8752b535e75..02b55c84897ce8b7c24404a297779a487adf20c9 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -523,6 +523,38 @@ MaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck(
|
| }
|
|
|
|
|
| +static void ReplaceExistingPropertyCell(Handle<GlobalObject> global, int entry,
|
| + Handle<Object> value) {
|
| + Isolate* isolate = global->GetIsolate();
|
| + Handle<PropertyCell> cell(
|
| + PropertyCell::cast(global->property_dictionary()->ValueAt(entry)));
|
| +
|
| + Handle<PropertyCell> new_cell = isolate->factory()->NewPropertyCell(value);
|
| + global->property_dictionary()->ValueAtPut(entry, *new_cell);
|
| +
|
| + Handle<Object> hole = isolate->factory()->the_hole_value();
|
| + if (*hole == cell->value()) {
|
| + PropertyCell::SetValueInferType(cell,
|
| + isolate->factory()->undefined_value());
|
| + } else {
|
| + PropertyCell::SetValueInferType(cell, hole);
|
| + }
|
| +}
|
| +
|
| +
|
| +void GlobalObject::InvalidatePropertyCell(Handle<GlobalObject> global,
|
| + Handle<Name> name) {
|
| + DCHECK(!global->HasFastProperties());
|
| + int entry = global->property_dictionary()->FindEntry(name);
|
| + if (entry != NameDictionary::kNotFound) {
|
| + PropertyCell* cell =
|
| + PropertyCell::cast(global->property_dictionary()->ValueAt(entry));
|
| + Handle<Object> value(cell->value(), global->GetIsolate());
|
| + ReplaceExistingPropertyCell(global, entry, value);
|
| + }
|
| +}
|
| +
|
| +
|
| void JSObject::SetNormalizedProperty(Handle<JSObject> object,
|
| Handle<Name> name,
|
| Handle<Object> value,
|
| @@ -565,7 +597,12 @@ void JSObject::SetNormalizedProperty(Handle<JSObject> object,
|
| if (object->IsGlobalObject()) {
|
| Handle<PropertyCell> cell(
|
| PropertyCell::cast(property_dictionary->ValueAt(entry)));
|
| - PropertyCell::SetValueInferType(cell, value);
|
| + if (details.type() != property_dictionary->DetailsAt(entry).type()) {
|
| + ReplaceExistingPropertyCell(Handle<GlobalObject>::cast(object), entry,
|
| + value);
|
| + } else {
|
| + PropertyCell::SetValueInferType(cell, value);
|
| + }
|
| // Please note we have to update the property details.
|
| property_dictionary->DetailsAtPut(entry, details);
|
| } else {
|
| @@ -1776,14 +1813,13 @@ void JSObject::AddSlowProperty(Handle<JSObject> object,
|
| // In case name is an orphaned property reuse the cell.
|
| int entry = dict->FindEntry(name);
|
| if (entry != NameDictionary::kNotFound) {
|
| - Handle<PropertyCell> cell(PropertyCell::cast(dict->ValueAt(entry)));
|
| - PropertyCell::SetValueInferType(cell, value);
|
| + ReplaceExistingPropertyCell(Handle<GlobalObject>::cast(object), entry,
|
| + value);
|
| // Assign an enumeration index to the property and update
|
| // SetNextEnumerationIndex.
|
| int index = dict->NextEnumerationIndex();
|
| PropertyDetails details(attributes, DATA, index);
|
| - dict->SetNextEnumerationIndex(index + 1);
|
| - dict->SetEntry(entry, name, cell, details);
|
| + dict->DetailsAtPut(entry, details);
|
| return;
|
| }
|
| value = isolate->factory()->NewPropertyCell(value);
|
| @@ -5312,9 +5348,8 @@ void JSObject::DeleteNormalizedProperty(Handle<JSObject> object,
|
| if (object->IsGlobalObject()) {
|
| PropertyDetails details = dictionary->DetailsAt(entry);
|
| DCHECK(details.IsConfigurable());
|
| - Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry)));
|
| - Handle<Object> value = isolate->factory()->the_hole_value();
|
| - PropertyCell::SetValueInferType(cell, value);
|
| + ReplaceExistingPropertyCell(Handle<GlobalObject>::cast(object), entry,
|
| + isolate->factory()->the_hole_value());
|
| dictionary->DetailsAtPut(entry, details.AsDeleted());
|
| return;
|
| }
|
| @@ -7432,12 +7467,7 @@ Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map,
|
| Isolate* isolate = name->GetIsolate();
|
|
|
| // Dictionary maps can always have additional data properties.
|
| - if (map->is_dictionary_map()) {
|
| - // For global objects, property cells are inlined. We need to change the
|
| - // map.
|
| - if (map->IsGlobalObjectMap()) return Copy(map, "GlobalAccessor");
|
| - return map;
|
| - }
|
| + if (map->is_dictionary_map()) return map;
|
|
|
| // Migrate to the newest map before transitioning to the new property.
|
| map = Update(map);
|
| @@ -15311,32 +15341,6 @@ Handle<Object> ExternalFloat64Array::SetValue(
|
| }
|
|
|
|
|
| -void GlobalObject::InvalidatePropertyCell(Handle<GlobalObject> global,
|
| - Handle<Name> name) {
|
| - DCHECK(!global->HasFastProperties());
|
| - Isolate* isolate = global->GetIsolate();
|
| - int entry = global->property_dictionary()->FindEntry(name);
|
| - if (entry != NameDictionary::kNotFound) {
|
| - Handle<PropertyCell> cell(
|
| - PropertyCell::cast(global->property_dictionary()->ValueAt(entry)));
|
| -
|
| - Handle<Object> value(cell->value(), isolate);
|
| - Handle<PropertyCell> new_cell = isolate->factory()->NewPropertyCell(value);
|
| - global->property_dictionary()->ValueAtPut(entry, *new_cell);
|
| -
|
| - Handle<Object> hole = isolate->factory()->the_hole_value();
|
| - if (*hole != *value) {
|
| - PropertyCell::SetValueInferType(cell, hole);
|
| - } else {
|
| - // If property value was the hole, set it to any other value,
|
| - // to ensure that LoadNonexistent ICs execute a miss.
|
| - Handle<Object> undefined = isolate->factory()->undefined_value();
|
| - PropertyCell::SetValueInferType(cell, undefined);
|
| - }
|
| - }
|
| -}
|
| -
|
| -
|
| Handle<PropertyCell> GlobalObject::EnsurePropertyCell(
|
| Handle<GlobalObject> global, Handle<Name> name) {
|
| DCHECK(!global->HasFastProperties());
|
|
|