Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 679a3cb6956d3f7933c8ed680f0d96c859c43412..1a58efabd9b1c027b8a2c336fb172218ee8d0bcc 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -555,39 +555,44 @@ void JSObject::SetNormalizedProperty(Handle<JSObject> object, |
Handle<Object> value, |
PropertyDetails details) { |
DCHECK(!object->HasFastProperties()); |
- Handle<NameDictionary> property_dictionary(object->property_dictionary()); |
- |
if (!name->IsUniqueName()) { |
name = object->GetIsolate()->factory()->InternalizeString( |
Handle<String>::cast(name)); |
} |
- int entry = property_dictionary->FindEntry(name); |
- if (entry == NameDictionary::kNotFound) { |
- if (object->IsGlobalObject()) { |
+ if (object->IsGlobalObject()) { |
+ Handle<GlobalDictionary> property_dictionary(object->global_dictionary()); |
+ |
+ int entry = property_dictionary->FindEntry(name); |
+ if (entry == GlobalDictionary::kNotFound) { |
auto cell = object->GetIsolate()->factory()->NewPropertyCell(); |
cell->set_value(*value); |
auto cell_type = value->IsUndefined() ? PropertyCellType::kUndefined |
: 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); |
+ } else { |
+ PropertyCell::UpdateCell(property_dictionary, entry, value, details); |
} |
- property_dictionary = |
- NameDictionary::Add(property_dictionary, name, value, details); |
- object->set_properties(*property_dictionary); |
- return; |
- } |
+ } else { |
+ Handle<NameDictionary> property_dictionary(object->property_dictionary()); |
- if (object->IsGlobalObject()) { |
- PropertyCell::UpdateCell(property_dictionary, entry, value, details); |
- return; |
+ int entry = property_dictionary->FindEntry(name); |
+ if (entry == NameDictionary::kNotFound) { |
+ property_dictionary = |
+ NameDictionary::Add(property_dictionary, name, value, details); |
+ object->set_properties(*property_dictionary); |
+ } else { |
+ PropertyDetails original_details = property_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); |
+ } |
} |
- |
- PropertyDetails original_details = property_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); |
} |
@@ -1804,12 +1809,12 @@ void JSObject::AddSlowProperty(Handle<JSObject> object, |
PropertyAttributes attributes) { |
DCHECK(!object->HasFastProperties()); |
Isolate* isolate = object->GetIsolate(); |
- Handle<NameDictionary> dict(object->property_dictionary()); |
- PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); |
if (object->IsGlobalObject()) { |
+ 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 != NameDictionary::kNotFound) { |
+ if (entry != GlobalDictionary::kNotFound) { |
PropertyCell::UpdateCell(dict, entry, value, details); |
// TODO(dcarney): move this to UpdateCell. |
// Need to adjust the details. |
@@ -1817,18 +1822,26 @@ void JSObject::AddSlowProperty(Handle<JSObject> object, |
dict->SetNextEnumerationIndex(index + 1); |
details = dict->DetailsAt(entry).set_index(index); |
dict->DetailsAtPut(entry, details); |
- return; |
+ |
+ } else { |
+ auto cell = isolate->factory()->NewPropertyCell(); |
+ cell->set_value(*value); |
+ auto cell_type = value->IsUndefined() ? 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); |
} |
- auto cell = isolate->factory()->NewPropertyCell(); |
- cell->set_value(*value); |
- auto cell_type = value->IsUndefined() ? PropertyCellType::kUndefined |
- : PropertyCellType::kConstant; |
- details = details.set_cell_type(cell_type); |
- value = cell; |
+ } 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); |
} |
- Handle<NameDictionary> result = |
- NameDictionary::Add(dict, name, value, details); |
- if (*dict != *result) object->set_properties(*result); |
} |
@@ -5400,24 +5413,28 @@ void JSObject::DeleteNormalizedProperty(Handle<JSObject> object, |
Handle<Name> name) { |
DCHECK(!object->HasFastProperties()); |
Isolate* isolate = object->GetIsolate(); |
- Handle<NameDictionary> dictionary(object->property_dictionary()); |
- int entry = dictionary->FindEntry(name); |
- DCHECK_NE(NameDictionary::kNotFound, entry); |
- // If we have a global object, invalidate the cell and swap in a new one. |
if (object->IsGlobalObject()) { |
+ // If we have a global object, invalidate the cell and swap in a new one. |
+ Handle<GlobalDictionary> dictionary(object->global_dictionary()); |
+ int entry = dictionary->FindEntry(name); |
+ DCHECK_NE(GlobalDictionary::kNotFound, entry); |
+ |
auto cell = PropertyCell::InvalidateEntry(dictionary, entry); |
cell->set_value(isolate->heap()->the_hole_value()); |
// TODO(dcarney): InvalidateForDelete |
dictionary->DetailsAtPut(entry, dictionary->DetailsAt(entry).set_cell_type( |
PropertyCellType::kInvalidated)); |
- return; |
- } |
+ } else { |
+ Handle<NameDictionary> dictionary(object->property_dictionary()); |
+ int entry = dictionary->FindEntry(name); |
+ DCHECK_NE(NameDictionary::kNotFound, entry); |
- NameDictionary::DeleteProperty(dictionary, entry); |
- Handle<NameDictionary> new_properties = |
- NameDictionary::Shrink(dictionary, name); |
- object->set_properties(*new_properties); |
+ NameDictionary::DeleteProperty(dictionary, entry); |
+ Handle<NameDictionary> new_properties = |
+ NameDictionary::Shrink(dictionary, name); |
+ object->set_properties(*new_properties); |
+ } |
} |
@@ -5851,7 +5868,11 @@ MaybeHandle<Object> JSObject::PreventExtensionsWithTransition( |
JSObject::MigrateToMap(object, new_map); |
if (attrs != NONE) { |
- ApplyAttributesToDictionary(object->property_dictionary(), attrs); |
+ if (object->IsGlobalObject()) { |
+ ApplyAttributesToDictionary(object->global_dictionary(), attrs); |
+ } else { |
+ ApplyAttributesToDictionary(object->property_dictionary(), attrs); |
+ } |
} |
} |
@@ -6343,6 +6364,15 @@ Handle<FixedArray> JSObject::GetEnumPropertyKeys(Handle<JSObject> object, |
object->map()->SetEnumLength(own_property_count); |
} |
return storage; |
+ } else if (object->IsGlobalObject()) { |
+ Handle<GlobalDictionary> dictionary(object->global_dictionary()); |
+ int length = dictionary->NumberOfEnumElements(*object); |
+ if (length == 0) { |
+ return Handle<FixedArray>(isolate->heap()->empty_fixed_array()); |
+ } |
+ Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length); |
+ dictionary->CopyEnumKeysTo(*object, *storage); |
+ return storage; |
} else { |
Handle<NameDictionary> dictionary(object->property_dictionary()); |
int length = dictionary->NumberOfEnumElements(*object); |
@@ -6922,6 +6952,8 @@ Object* JSObject::SlowReverseLookup(Object* value) { |
} |
} |
return GetHeap()->undefined_value(); |
+ } else if (IsGlobalObject()) { |
+ return global_dictionary()->SlowReverseLookup(value); |
} else { |
return property_dictionary()->SlowReverseLookup(value); |
} |
@@ -14176,8 +14208,12 @@ int JSObject::NumberOfOwnProperties(PropertyAttributes filter) { |
if (result != kInvalidEnumCacheSentinel) return result; |
} |
return map->NumberOfDescribedProperties(OWN_DESCRIPTORS, filter); |
+ } else if (IsGlobalObject()) { |
+ return global_dictionary()->NumberOfElementsFilterAttributes(this, filter); |
+ } else { |
+ return property_dictionary()->NumberOfElementsFilterAttributes(this, |
+ filter); |
} |
- return property_dictionary()->NumberOfElementsFilterAttributes(this, filter); |
} |
@@ -14309,6 +14345,9 @@ void JSObject::GetOwnPropertyNames( |
storage->set(index++, descs->GetKey(i)); |
} |
} |
+ } else if (IsGlobalObject()) { |
+ global_dictionary()->CopyKeysTo(this, storage, index, filter, |
+ GlobalDictionary::UNSORTED); |
} else { |
property_dictionary()->CopyKeysTo(this, storage, index, filter, |
NameDictionary::UNSORTED); |
@@ -14976,6 +15015,9 @@ template class HashTable<WeakHashTable, WeakHashTableShape<2>, Handle<Object> >; |
template class Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >; |
+template class Dictionary<GlobalDictionary, GlobalDictionaryShape, |
+ Handle<Name> >; |
+ |
template class Dictionary<SeededNumberDictionary, |
SeededNumberDictionaryShape, |
uint32_t>; |
@@ -14996,6 +15038,10 @@ template Handle<NameDictionary> |
Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >:: |
New(Isolate*, int n, PretenureFlag pretenure); |
+template Handle<GlobalDictionary> |
+Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name> >::New( |
+ Isolate*, int n, PretenureFlag pretenure); |
+ |
template Handle<SeededNumberDictionary> |
Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
AtPut(Handle<SeededNumberDictionary>, uint32_t, Handle<Object>); |
@@ -15036,6 +15082,11 @@ template Handle<NameDictionary> |
Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::Add( |
Handle<NameDictionary>, Handle<Name>, Handle<Object>, PropertyDetails); |
+template Handle<GlobalDictionary> |
+ Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name> >::Add( |
+ Handle<GlobalDictionary>, Handle<Name>, Handle<Object>, |
+ PropertyDetails); |
+ |
template Handle<FixedArray> Dictionary< |
NameDictionary, NameDictionaryShape, |
Handle<Name> >::BuildIterationIndicesArray(Handle<NameDictionary>); |
@@ -15525,9 +15576,9 @@ Handle<Object> ExternalFloat64Array::SetValue( |
void GlobalObject::InvalidatePropertyCell(Handle<GlobalObject> global, |
Handle<Name> name) { |
DCHECK(!global->HasFastProperties()); |
- auto dictionary = handle(global->property_dictionary()); |
+ auto dictionary = handle(global->global_dictionary()); |
int entry = dictionary->FindEntry(name); |
- if (entry == NameDictionary::kNotFound) return; |
+ if (entry == GlobalDictionary::kNotFound) return; |
PropertyCell::InvalidateEntry(dictionary, entry); |
} |
@@ -15536,10 +15587,10 @@ void GlobalObject::InvalidatePropertyCell(Handle<GlobalObject> global, |
Handle<PropertyCell> GlobalObject::EnsurePropertyCell( |
Handle<GlobalObject> global, Handle<Name> name) { |
DCHECK(!global->HasFastProperties()); |
- auto dictionary = handle(global->property_dictionary()); |
+ auto dictionary = handle(global->global_dictionary()); |
int entry = dictionary->FindEntry(name); |
Handle<PropertyCell> cell; |
- if (entry != NameDictionary::kNotFound) { |
+ if (entry != GlobalDictionary::kNotFound) { |
// This call should be idempotent. |
DCHECK(dictionary->DetailsAt(entry).cell_type() == |
PropertyCellType::kUninitialized || |
@@ -15553,7 +15604,7 @@ Handle<PropertyCell> GlobalObject::EnsurePropertyCell( |
Isolate* isolate = global->GetIsolate(); |
cell = isolate->factory()->NewPropertyCell(); |
PropertyDetails details(NONE, DATA, 0, PropertyCellType::kUninitialized); |
- dictionary = NameDictionary::Add(dictionary, name, cell, details); |
+ dictionary = GlobalDictionary::Add(dictionary, name, cell, details); |
global->set_properties(*dictionary); |
return cell; |
} |
@@ -17227,7 +17278,7 @@ Handle<JSArrayBuffer> JSTypedArray::GetBuffer() { |
Handle<PropertyCell> PropertyCell::InvalidateEntry( |
- Handle<NameDictionary> dictionary, int entry) { |
+ Handle<GlobalDictionary> dictionary, int entry) { |
Isolate* isolate = dictionary->GetIsolate(); |
// Swap with a copy. |
DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); |
@@ -17310,7 +17361,7 @@ PropertyCellType PropertyCell::UpdatedType(Handle<PropertyCell> cell, |
} |
-void PropertyCell::UpdateCell(Handle<NameDictionary> dictionary, int entry, |
+void PropertyCell::UpdateCell(Handle<GlobalDictionary> dictionary, int entry, |
Handle<Object> value, PropertyDetails details) { |
DCHECK(!value->IsTheHole()); |
DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); |