| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index 2da837e8ab82022e55294f722d9d5d37f57c73ce..a934eeaab19b97fe26d0ef93ec6c8c1c43b6fe70 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -1606,9 +1606,9 @@ void JSObject::SetNormalizedProperty(Handle<JSObject> object,
|
| }
|
|
|
| if (object->IsJSGlobalObject()) {
|
| - Handle<GlobalDictionary> property_dictionary(object->global_dictionary());
|
| + Handle<GlobalDictionary> dictionary(object->global_dictionary());
|
|
|
| - int entry = property_dictionary->FindEntry(name);
|
| + int entry = dictionary->FindEntry(name);
|
| if (entry == GlobalDictionary::kNotFound) {
|
| Isolate* isolate = object->GetIsolate();
|
| auto cell = isolate->factory()->NewPropertyCell();
|
| @@ -1618,26 +1618,26 @@ void JSObject::SetNormalizedProperty(Handle<JSObject> object,
|
| : PropertyCellType::kConstant;
|
| details = details.set_cell_type(cell_type);
|
| value = cell;
|
| - property_dictionary =
|
| - GlobalDictionary::Add(property_dictionary, name, value, details);
|
| - object->set_properties(*property_dictionary);
|
| + dictionary = GlobalDictionary::Add(dictionary, name, value, details);
|
| + object->set_properties(*dictionary);
|
| } else {
|
| - PropertyCell::UpdateCell(property_dictionary, entry, value, details);
|
| + Handle<PropertyCell> cell =
|
| + PropertyCell::PrepareForValue(dictionary, entry, value, details);
|
| + cell->set_value(*value);
|
| }
|
| } else {
|
| - Handle<NameDictionary> property_dictionary(object->property_dictionary());
|
| + Handle<NameDictionary> dictionary(object->property_dictionary());
|
|
|
| - int entry = property_dictionary->FindEntry(name);
|
| + int entry = dictionary->FindEntry(name);
|
| if (entry == NameDictionary::kNotFound) {
|
| - property_dictionary =
|
| - NameDictionary::Add(property_dictionary, name, value, details);
|
| - object->set_properties(*property_dictionary);
|
| + dictionary = NameDictionary::Add(dictionary, name, value, details);
|
| + object->set_properties(*dictionary);
|
| } else {
|
| - PropertyDetails original_details = property_dictionary->DetailsAt(entry);
|
| + PropertyDetails original_details = dictionary->DetailsAt(entry);
|
| int enumeration_index = original_details.dictionary_index();
|
| DCHECK(enumeration_index > 0);
|
| details = details.set_index(enumeration_index);
|
| - property_dictionary->SetEntry(entry, name, value, details);
|
| + dictionary->SetEntry(entry, name, value, details);
|
| }
|
| }
|
| }
|
| @@ -2848,51 +2848,6 @@ MaybeHandle<Map> Map::CopyWithConstant(Handle<Map> map,
|
| return Map::CopyAddDescriptor(map, &new_constant_desc, flag);
|
| }
|
|
|
| -
|
| -void JSObject::AddSlowProperty(Handle<JSObject> object,
|
| - Handle<Name> name,
|
| - Handle<Object> value,
|
| - PropertyAttributes attributes) {
|
| - DCHECK(!object->HasFastProperties());
|
| - Isolate* isolate = object->GetIsolate();
|
| - if (object->IsJSGlobalObject()) {
|
| - Handle<GlobalDictionary> dict(object->global_dictionary());
|
| - PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
|
| - int entry = dict->FindEntry(name);
|
| - // If there's a cell there, just invalidate and set the property.
|
| - if (entry != GlobalDictionary::kNotFound) {
|
| - PropertyCell::UpdateCell(dict, entry, value, details);
|
| - // TODO(ishell): move this to UpdateCell.
|
| - // Need to adjust the details.
|
| - int index = dict->NextEnumerationIndex();
|
| - dict->SetNextEnumerationIndex(index + 1);
|
| - PropertyCell* cell = PropertyCell::cast(dict->ValueAt(entry));
|
| - details = cell->property_details().set_index(index);
|
| - cell->set_property_details(details);
|
| -
|
| - } else {
|
| - auto cell = isolate->factory()->NewPropertyCell();
|
| - cell->set_value(*value);
|
| - auto cell_type = value->IsUndefined(isolate)
|
| - ? PropertyCellType::kUndefined
|
| - : PropertyCellType::kConstant;
|
| - details = details.set_cell_type(cell_type);
|
| - value = cell;
|
| -
|
| - Handle<GlobalDictionary> result =
|
| - GlobalDictionary::Add(dict, name, value, details);
|
| - if (*dict != *result) object->set_properties(*result);
|
| - }
|
| - } else {
|
| - Handle<NameDictionary> dict(object->property_dictionary());
|
| - PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
|
| - Handle<NameDictionary> result =
|
| - NameDictionary::Add(dict, name, value, details);
|
| - if (*dict != *result) object->set_properties(*result);
|
| - }
|
| -}
|
| -
|
| -
|
| const char* Representation::Mnemonic() const {
|
| switch (kind_) {
|
| case kNone: return "v";
|
| @@ -4743,14 +4698,8 @@ Maybe<bool> Object::AddDataProperty(LookupIterator* it, Handle<Object> value,
|
| DCHECK_EQ(LookupIterator::TRANSITION, it->state());
|
| it->ApplyTransitionToDataProperty(receiver);
|
|
|
| - // TODO(verwaest): Encapsulate dictionary handling better.
|
| - if (receiver->map()->is_dictionary_map()) {
|
| - // TODO(dcarney): just populate TransitionPropertyCell here?
|
| - JSObject::AddSlowProperty(receiver, it->name(), value, attributes);
|
| - } else {
|
| - // Write the property value.
|
| - it->WriteDataValue(value);
|
| - }
|
| + // Write the property value.
|
| + it->WriteDataValue(value);
|
|
|
| #if VERIFY_HEAP
|
| if (FLAG_verify_heap) {
|
| @@ -6087,9 +6036,8 @@ void JSReceiver::DeleteNormalizedProperty(Handle<JSReceiver> object,
|
|
|
| auto cell = PropertyCell::InvalidateEntry(dictionary, entry);
|
| cell->set_value(isolate->heap()->the_hole_value());
|
| - // TODO(ishell): InvalidateForDelete
|
| cell->set_property_details(
|
| - cell->property_details().set_cell_type(PropertyCellType::kInvalidated));
|
| + PropertyDetails::Empty(PropertyCellType::kUninitialized));
|
| } else {
|
| Handle<NameDictionary> dictionary(object->property_dictionary());
|
| DCHECK_NE(NameDictionary::kNotFound, entry);
|
| @@ -16467,13 +16415,14 @@ template Handle<UnseededNumberDictionary>
|
| uint32_t>::Shrink(Handle<UnseededNumberDictionary>, uint32_t);
|
|
|
| template Handle<NameDictionary>
|
| -Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::Add(
|
| - Handle<NameDictionary>, Handle<Name>, Handle<Object>, PropertyDetails);
|
| +Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>::Add(
|
| + Handle<NameDictionary>, Handle<Name>, Handle<Object>, PropertyDetails,
|
| + int*);
|
|
|
| template Handle<GlobalDictionary>
|
| - Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name> >::Add(
|
| - Handle<GlobalDictionary>, Handle<Name>, Handle<Object>,
|
| - PropertyDetails);
|
| +Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>::Add(
|
| + Handle<GlobalDictionary>, Handle<Name>, Handle<Object>, PropertyDetails,
|
| + int*);
|
|
|
| template Handle<FixedArray> Dictionary<
|
| NameDictionary, NameDictionaryShape,
|
| @@ -16484,18 +16433,14 @@ template Handle<FixedArray> Dictionary<
|
| Handle<Name> >::GenerateNewEnumerationIndices(Handle<NameDictionary>);
|
|
|
| template Handle<SeededNumberDictionary>
|
| -Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
|
| - Add(Handle<SeededNumberDictionary>,
|
| - uint32_t,
|
| - Handle<Object>,
|
| - PropertyDetails);
|
| +Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::Add(
|
| + Handle<SeededNumberDictionary>, uint32_t, Handle<Object>, PropertyDetails,
|
| + int*);
|
|
|
| template Handle<UnseededNumberDictionary>
|
| -Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>::
|
| - Add(Handle<UnseededNumberDictionary>,
|
| - uint32_t,
|
| - Handle<Object>,
|
| - PropertyDetails);
|
| +Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape,
|
| + uint32_t>::Add(Handle<UnseededNumberDictionary>, uint32_t,
|
| + Handle<Object>, PropertyDetails, int*);
|
|
|
| template Handle<SeededNumberDictionary>
|
| Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
|
| @@ -16818,29 +16763,35 @@ void JSGlobalObject::InvalidatePropertyCell(Handle<JSGlobalObject> global,
|
| PropertyCell::InvalidateEntry(dictionary, entry);
|
| }
|
|
|
| -
|
| -// TODO(ishell): rename to EnsureEmptyPropertyCell or something.
|
| -Handle<PropertyCell> JSGlobalObject::EnsurePropertyCell(
|
| - Handle<JSGlobalObject> global, Handle<Name> name) {
|
| +Handle<PropertyCell> JSGlobalObject::EnsureEmptyPropertyCell(
|
| + Handle<JSGlobalObject> global, Handle<Name> name,
|
| + PropertyCellType cell_type, int* entry_out) {
|
| Isolate* isolate = global->GetIsolate();
|
| DCHECK(!global->HasFastProperties());
|
| - auto dictionary = handle(global->global_dictionary(), isolate);
|
| + Handle<GlobalDictionary> dictionary(global->global_dictionary(), isolate);
|
| int entry = dictionary->FindEntry(name);
|
| Handle<PropertyCell> cell;
|
| if (entry != GlobalDictionary::kNotFound) {
|
| + if (entry_out) *entry_out = entry;
|
| // This call should be idempotent.
|
| DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
|
| cell = handle(PropertyCell::cast(dictionary->ValueAt(entry)));
|
| - DCHECK(cell->property_details().cell_type() ==
|
| - PropertyCellType::kUninitialized ||
|
| - cell->property_details().cell_type() ==
|
| - PropertyCellType::kInvalidated);
|
| + PropertyCellType original_cell_type = cell->property_details().cell_type();
|
| + DCHECK(original_cell_type == PropertyCellType::kInvalidated ||
|
| + original_cell_type == PropertyCellType::kUninitialized);
|
| DCHECK(cell->value()->IsTheHole(isolate));
|
| + if (original_cell_type == PropertyCellType::kInvalidated) {
|
| + cell = PropertyCell::InvalidateEntry(dictionary, entry);
|
| + }
|
| + PropertyDetails details(NONE, DATA, 0, cell_type);
|
| + cell->set_property_details(details);
|
| return cell;
|
| }
|
| cell = isolate->factory()->NewPropertyCell();
|
| - PropertyDetails details(NONE, DATA, 0, PropertyCellType::kUninitialized);
|
| - dictionary = GlobalDictionary::Add(dictionary, name, cell, details);
|
| + PropertyDetails details(NONE, DATA, 0, cell_type);
|
| + dictionary =
|
| + GlobalDictionary::Add(dictionary, name, cell, details, entry_out);
|
| + // {*entry_out} is initialized inside GlobalDictionary::Add().
|
| global->set_properties(*dictionary);
|
| return cell;
|
| }
|
| @@ -17339,31 +17290,28 @@ Handle<Derived> Dictionary<Derived, Shape, Key>::AtPut(
|
| return dictionary;
|
| }
|
|
|
| -
|
| -template<typename Derived, typename Shape, typename Key>
|
| -Handle<Derived> Dictionary<Derived, Shape, Key>::Add(
|
| - Handle<Derived> dictionary,
|
| - Key key,
|
| - Handle<Object> value,
|
| - PropertyDetails details) {
|
| +template <typename Derived, typename Shape, typename Key>
|
| +Handle<Derived> Dictionary<Derived, Shape, Key>::Add(Handle<Derived> dictionary,
|
| + Key key,
|
| + Handle<Object> value,
|
| + PropertyDetails details,
|
| + int* entry_out) {
|
| // Valdate key is absent.
|
| SLOW_DCHECK((dictionary->FindEntry(key) == Dictionary::kNotFound));
|
| // Check whether the dictionary should be extended.
|
| dictionary = EnsureCapacity(dictionary, 1, key);
|
|
|
| - AddEntry(dictionary, key, value, details, dictionary->Hash(key));
|
| + int entry = AddEntry(dictionary, key, value, details, dictionary->Hash(key));
|
| + if (entry_out) *entry_out = entry;
|
| return dictionary;
|
| }
|
|
|
| -
|
| -// Add a key, value pair to the dictionary.
|
| -template<typename Derived, typename Shape, typename Key>
|
| -void Dictionary<Derived, Shape, Key>::AddEntry(
|
| - Handle<Derived> dictionary,
|
| - Key key,
|
| - Handle<Object> value,
|
| - PropertyDetails details,
|
| - uint32_t hash) {
|
| +// Add a key, value pair to the dictionary. Returns entry value.
|
| +template <typename Derived, typename Shape, typename Key>
|
| +int Dictionary<Derived, Shape, Key>::AddEntry(Handle<Derived> dictionary,
|
| + Key key, Handle<Object> value,
|
| + PropertyDetails details,
|
| + uint32_t hash) {
|
| // Compute the key object.
|
| Handle<Object> k = Shape::AsHandle(dictionary->GetIsolate(), key);
|
|
|
| @@ -17380,6 +17328,7 @@ void Dictionary<Derived, Shape, Key>::AddEntry(
|
| DCHECK((dictionary->KeyAt(entry)->IsNumber() ||
|
| dictionary->KeyAt(entry)->IsName()));
|
| dictionary->ElementAdded();
|
| + return entry;
|
| }
|
|
|
| bool SeededNumberDictionary::HasComplexElements() {
|
| @@ -18770,13 +18719,13 @@ Handle<PropertyCell> PropertyCell::InvalidateEntry(
|
| // Swap with a copy.
|
| DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
|
| Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry)));
|
| - auto new_cell = isolate->factory()->NewPropertyCell();
|
| + Handle<PropertyCell> new_cell = isolate->factory()->NewPropertyCell();
|
| new_cell->set_value(cell->value());
|
| dictionary->ValueAtPut(entry, *new_cell);
|
| bool is_the_hole = cell->value()->IsTheHole(isolate);
|
| // Cell is officially mutable henceforth.
|
| PropertyDetails details = cell->property_details();
|
| - details = details.set_cell_type(is_the_hole ? PropertyCellType::kInvalidated
|
| + details = details.set_cell_type(is_the_hole ? PropertyCellType::kUninitialized
|
| : PropertyCellType::kMutable);
|
| new_cell->set_property_details(details);
|
| // Old cell is ready for invalidation.
|
| @@ -18850,9 +18799,9 @@ PropertyCellType PropertyCell::UpdatedType(Handle<PropertyCell> cell,
|
| return PropertyCellType::kMutable;
|
| }
|
|
|
| -
|
| -void PropertyCell::UpdateCell(Handle<GlobalDictionary> dictionary, int entry,
|
| - Handle<Object> value, PropertyDetails details) {
|
| +Handle<PropertyCell> PropertyCell::PrepareForValue(
|
| + Handle<GlobalDictionary> dictionary, int entry, Handle<Object> value,
|
| + PropertyDetails details) {
|
| Isolate* isolate = dictionary->GetIsolate();
|
| DCHECK(!value->IsTheHole(isolate));
|
| DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
|
| @@ -18868,8 +18817,6 @@ void PropertyCell::UpdateCell(Handle<GlobalDictionary> dictionary, int entry,
|
| if (cell->value()->IsTheHole(isolate)) {
|
| index = dictionary->NextEnumerationIndex();
|
| dictionary->SetNextEnumerationIndex(index + 1);
|
| - // Negative lookup cells must be invalidated.
|
| - invalidate = true;
|
| }
|
| DCHECK(index > 0);
|
| details = details.set_index(index);
|
| @@ -18877,10 +18824,9 @@ void PropertyCell::UpdateCell(Handle<GlobalDictionary> dictionary, int entry,
|
| PropertyCellType new_type = UpdatedType(cell, value, original_details);
|
| if (invalidate) cell = PropertyCell::InvalidateEntry(dictionary, entry);
|
|
|
| - // Install new property details and cell value.
|
| + // Install new property details.
|
| details = details.set_cell_type(new_type);
|
| cell->set_property_details(details);
|
| - cell->set_value(*value);
|
|
|
| // Deopt when transitioning from a constant type.
|
| if (!invalidate && (old_type != new_type ||
|
| @@ -18888,6 +18834,7 @@ void PropertyCell::UpdateCell(Handle<GlobalDictionary> dictionary, int entry,
|
| cell->dependent_code()->DeoptimizeDependentCodeGroup(
|
| isolate, DependentCode::kPropertyCellChangedGroup);
|
| }
|
| + return cell;
|
| }
|
|
|
|
|
|
|