Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 886d26a22d0d5bfd4b0ea752612d23387ba6d419..76be0a6495e39c0fb56fbef6180565220ec9e00b 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -554,28 +554,29 @@ void JSObject::SetNormalizedProperty(Handle<JSObject> object, |
} |
PropertyDetails original_details = property_dictionary->DetailsAt(entry); |
- int enumeration_index; |
+ int enumeration_index = original_details.dictionary_index(); |
+ |
+ if (!object->IsGlobalObject()) { |
+ DCHECK(enumeration_index > 0); |
+ details = PropertyDetails(details.attributes(), details.type(), |
+ enumeration_index); |
+ property_dictionary->SetEntry(entry, name, value, details); |
+ return; |
+ } |
+ |
+ Handle<PropertyCell> cell( |
+ PropertyCell::cast(property_dictionary->ValueAt(entry))); |
// Preserve the enumeration index unless the property was deleted. |
- if (original_details.IsDeleted()) { |
+ if (cell->value()->IsTheHole()) { |
enumeration_index = property_dictionary->NextEnumerationIndex(); |
property_dictionary->SetNextEnumerationIndex(enumeration_index + 1); |
- } else { |
- enumeration_index = original_details.dictionary_index(); |
- DCHECK(enumeration_index > 0); |
} |
- |
+ DCHECK(enumeration_index > 0); |
details = PropertyDetails( |
details.attributes(), details.type(), enumeration_index); |
- |
- if (object->IsGlobalObject()) { |
- Handle<PropertyCell> cell( |
- PropertyCell::cast(property_dictionary->ValueAt(entry))); |
- PropertyCell::SetValueInferType(cell, value); |
- // Please note we have to update the property details. |
- property_dictionary->DetailsAtPut(entry, details); |
- } else { |
- property_dictionary->SetEntry(entry, name, value, details); |
- } |
+ PropertyCell::SetValueInferType(cell, value); |
+ // Please note we have to update the property details. |
+ property_dictionary->DetailsAtPut(entry, details); |
} |
@@ -5353,12 +5354,10 @@ void JSObject::DeleteNormalizedProperty(Handle<JSObject> object, |
// If we have a global object set the cell to the hole. |
if (object->IsGlobalObject()) { |
- PropertyDetails details = dictionary->DetailsAt(entry); |
- DCHECK(details.IsConfigurable()); |
+ DCHECK(dictionary->DetailsAt(entry).IsConfigurable()); |
Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); |
Handle<Object> value = isolate->factory()->the_hole_value(); |
PropertyCell::SetValueInferType(cell, value); |
- dictionary->DetailsAtPut(entry, details.AsDeleted()); |
return; |
} |
@@ -6295,12 +6294,12 @@ static Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object, |
return storage; |
} else { |
Handle<NameDictionary> dictionary(object->property_dictionary()); |
- int length = dictionary->NumberOfEnumElements(); |
+ 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(*storage); |
+ dictionary->CopyEnumKeysTo(*object, *storage); |
return storage; |
} |
} |
@@ -13946,7 +13945,7 @@ int JSObject::NumberOfOwnProperties(PropertyAttributes filter) { |
} |
return map->NumberOfDescribedProperties(OWN_DESCRIPTORS, filter); |
} |
- return property_dictionary()->NumberOfElementsFilterAttributes(filter); |
+ return property_dictionary()->NumberOfElementsFilterAttributes(this, filter); |
} |
@@ -14079,9 +14078,7 @@ void JSObject::GetOwnPropertyNames( |
} |
} |
} else { |
- property_dictionary()->CopyKeysTo(storage, |
- index, |
- filter, |
+ property_dictionary()->CopyKeysTo(this, storage, index, filter, |
NameDictionary::UNSORTED); |
} |
} |
@@ -14165,11 +14162,13 @@ int JSObject::GetOwnElementKeys(FixedArray* storage, |
case DICTIONARY_ELEMENTS: { |
if (storage != NULL) { |
- element_dictionary()->CopyKeysTo(storage, |
- filter, |
- SeededNumberDictionary::SORTED); |
+ element_dictionary()->CopyKeysTo<DictionaryEntryType::kObjects>( |
+ storage, filter, SeededNumberDictionary::SORTED); |
} |
- counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); |
+ counter += |
+ element_dictionary() |
+ ->NumberOfElementsFilterAttributes<DictionaryEntryType::kObjects>( |
+ filter); |
break; |
} |
case SLOPPY_ARGUMENTS_ELEMENTS: { |
@@ -14182,10 +14181,11 @@ int JSObject::GetOwnElementKeys(FixedArray* storage, |
SeededNumberDictionary* dictionary = |
SeededNumberDictionary::cast(arguments); |
if (storage != NULL) { |
- dictionary->CopyKeysTo( |
+ dictionary->CopyKeysTo<DictionaryEntryType::kObjects>( |
storage, filter, SeededNumberDictionary::UNSORTED); |
} |
- counter += dictionary->NumberOfElementsFilterAttributes(filter); |
+ counter += dictionary->NumberOfElementsFilterAttributes< |
+ DictionaryEntryType::kObjects>(filter); |
for (int i = 0; i < mapped_length; ++i) { |
if (!parameter_map->get(i + 2)->IsTheHole()) { |
if (storage != NULL) storage->set(counter, Smi::FromInt(i)); |
@@ -14776,15 +14776,6 @@ template Object* |
Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >:: |
SlowReverseLookup(Object* value); |
-template void |
-Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
- CopyKeysTo( |
- FixedArray*, |
- PropertyAttributes, |
- Dictionary<SeededNumberDictionary, |
- SeededNumberDictionaryShape, |
- uint32_t>::SortMode); |
- |
template Handle<Object> |
Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::DeleteProperty( |
Handle<NameDictionary>, int); |
@@ -14805,18 +14796,6 @@ template Handle<SeededNumberDictionary> |
HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
Shrink(Handle<SeededNumberDictionary>, uint32_t); |
-template void Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >:: |
- CopyKeysTo( |
- FixedArray*, |
- int, |
- PropertyAttributes, |
- Dictionary< |
- NameDictionary, NameDictionaryShape, Handle<Name> >::SortMode); |
- |
-template int |
-Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >:: |
- NumberOfElementsFilterAttributes(PropertyAttributes); |
- |
template Handle<NameDictionary> |
Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::Add( |
Handle<NameDictionary>, Handle<Name>, Handle<Object>, PropertyDetails); |
@@ -14829,10 +14808,6 @@ template Handle<FixedArray> Dictionary< |
NameDictionary, NameDictionaryShape, |
Handle<Name> >::GenerateNewEnumerationIndices(Handle<NameDictionary>); |
-template int |
-Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
- NumberOfElementsFilterAttributes(PropertyAttributes); |
- |
template Handle<SeededNumberDictionary> |
Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
Add(Handle<SeededNumberDictionary>, |
@@ -14859,16 +14834,13 @@ template Handle<NameDictionary> |
Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >:: |
EnsureCapacity(Handle<NameDictionary>, int, Handle<Name>); |
-template |
-int Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
- NumberOfEnumElements(); |
- |
-template |
-int Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >:: |
- NumberOfEnumElements(); |
+template bool |
+Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, |
+ uint32_t>::HasComplexElements<DictionaryEntryType::kCells>(); |
-template bool Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, |
- uint32_t>::HasComplexElements(); |
+template bool |
+Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, |
+ uint32_t>::HasComplexElements<DictionaryEntryType::kObjects>(); |
template int HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, |
uint32_t>::FindEntry(uint32_t); |
@@ -15330,7 +15302,6 @@ Handle<PropertyCell> GlobalObject::EnsurePropertyCell( |
Isolate* isolate = global->GetIsolate(); |
Handle<PropertyCell> cell = isolate->factory()->NewPropertyCellWithHole(); |
PropertyDetails details(NONE, DATA, 0); |
- details = details.AsDeleted(); |
Handle<NameDictionary> dictionary = NameDictionary::Add( |
handle(global->property_dictionary()), name, cell, details); |
global->set_properties(*dictionary); |
@@ -15839,9 +15810,7 @@ void Dictionary<Derived, Shape, Key>::AddEntry( |
uint32_t entry = dictionary->FindInsertionEntry(hash); |
// Insert element at empty or deleted entry |
- if (!details.IsDeleted() && |
- details.dictionary_index() == 0 && |
- Shape::kIsEnumerable) { |
+ if (details.dictionary_index() == 0 && Shape::kIsEnumerable) { |
// Assign an enumeration index to the property and update |
// SetNextEnumerationIndex. |
int index = dictionary->NextEnumerationIndex(); |
@@ -15945,8 +15914,21 @@ Handle<UnseededNumberDictionary> UnseededNumberDictionary::Set( |
} |
+template <DictionaryEntryType type, typename D> |
+static inline bool IsDeleted(D d, int i) { |
+ switch (type) { |
+ case DictionaryEntryType::kObjects: |
+ return false; |
+ case DictionaryEntryType::kCells: |
+ return PropertyCell::cast(d->ValueAt(i))->value()->IsTheHole(); |
+ } |
+ UNREACHABLE(); |
+ return false; |
+} |
-template<typename Derived, typename Shape, typename Key> |
+ |
+template <typename Derived, typename Shape, typename Key> |
+template <DictionaryEntryType type> |
int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes( |
PropertyAttributes filter) { |
int capacity = DerivedHashTable::Capacity(); |
@@ -15954,8 +15936,8 @@ int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes( |
for (int i = 0; i < capacity; i++) { |
Object* k = DerivedHashTable::KeyAt(i); |
if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) { |
+ if (IsDeleted<type>(this, i)) continue; |
PropertyDetails details = DetailsAt(i); |
- if (details.IsDeleted()) continue; |
PropertyAttributes attr = details.attributes(); |
if ((attr & filter) == 0) result++; |
} |
@@ -15964,21 +15946,15 @@ int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes( |
} |
-template<typename Derived, typename Shape, typename Key> |
-int Dictionary<Derived, Shape, Key>::NumberOfEnumElements() { |
- return NumberOfElementsFilterAttributes( |
- static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC)); |
-} |
- |
- |
template <typename Derived, typename Shape, typename Key> |
+template <DictionaryEntryType type> |
bool Dictionary<Derived, Shape, Key>::HasComplexElements() { |
int capacity = DerivedHashTable::Capacity(); |
for (int i = 0; i < capacity; i++) { |
Object* k = DerivedHashTable::KeyAt(i); |
if (DerivedHashTable::IsKey(k) && !FilterKey(k, NONE)) { |
+ if (IsDeleted<type>(this, i)) continue; |
PropertyDetails details = DetailsAt(i); |
- if (details.IsDeleted()) continue; |
if (details.type() == ACCESSOR_CONSTANT) return true; |
PropertyAttributes attr = details.attributes(); |
if (attr & (READ_ONLY | DONT_DELETE | DONT_ENUM)) return true; |
@@ -15989,17 +15965,18 @@ bool Dictionary<Derived, Shape, Key>::HasComplexElements() { |
template <typename Derived, typename Shape, typename Key> |
+template <DictionaryEntryType type> |
void Dictionary<Derived, Shape, Key>::CopyKeysTo( |
FixedArray* storage, PropertyAttributes filter, |
typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { |
- DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter)); |
+ DCHECK(storage->length() >= NumberOfElementsFilterAttributes<type>(filter)); |
int capacity = DerivedHashTable::Capacity(); |
int index = 0; |
for (int i = 0; i < capacity; i++) { |
Object* k = DerivedHashTable::KeyAt(i); |
if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) { |
+ if (IsDeleted<type>(this, i)) continue; |
PropertyDetails details = DetailsAt(i); |
- if (details.IsDeleted()) continue; |
PropertyAttributes attr = details.attributes(); |
if ((attr & filter) == 0) storage->set(index++, k); |
} |
@@ -16022,6 +15999,7 @@ struct EnumIndexComparator { |
}; |
+template <DictionaryEntryType type> |
void NameDictionary::CopyEnumKeysTo(FixedArray* storage) { |
int length = storage->length(); |
int capacity = Capacity(); |
@@ -16030,7 +16008,7 @@ void NameDictionary::CopyEnumKeysTo(FixedArray* storage) { |
Object* k = KeyAt(i); |
if (IsKey(k) && !k->IsSymbol()) { |
PropertyDetails details = DetailsAt(i); |
- if (details.IsDeleted() || details.IsDontEnum()) continue; |
+ if (details.IsDontEnum() || IsDeleted<type>(this, i)) continue; |
storage->set(properties, Smi::FromInt(i)); |
properties++; |
if (properties == length) break; |
@@ -16047,19 +16025,18 @@ void NameDictionary::CopyEnumKeysTo(FixedArray* storage) { |
} |
-template<typename Derived, typename Shape, typename Key> |
+template <typename Derived, typename Shape, typename Key> |
+template <DictionaryEntryType type> |
void Dictionary<Derived, Shape, Key>::CopyKeysTo( |
- FixedArray* storage, |
- int index, |
- PropertyAttributes filter, |
+ FixedArray* storage, int index, PropertyAttributes filter, |
typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { |
- DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter)); |
+ DCHECK(storage->length() >= NumberOfElementsFilterAttributes<type>(filter)); |
int capacity = DerivedHashTable::Capacity(); |
for (int i = 0; i < capacity; i++) { |
Object* k = DerivedHashTable::KeyAt(i); |
if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) { |
+ if (IsDeleted<type>(this, i)) continue; |
PropertyDetails details = DetailsAt(i); |
- if (details.IsDeleted()) continue; |
PropertyAttributes attr = details.attributes(); |
if ((attr & filter) == 0) storage->set(index++, k); |
} |
@@ -16079,6 +16056,7 @@ Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { |
Object* k = DerivedHashTable::KeyAt(i); |
if (Dictionary::IsKey(k)) { |
Object* e = ValueAt(i); |
+ // TODO(dcarney): this should be templatized. |
if (e->IsPropertyCell()) { |
e = PropertyCell::cast(e)->value(); |
} |