}
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);
}
// 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;
}
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;
}
}
}
return map->NumberOfDescribedProperties(OWN_DESCRIPTORS, filter);
}
- return property_dictionary()->NumberOfElementsFilterAttributes(filter);
+ return property_dictionary()->NumberOfElementsFilterAttributes(this, filter);
}
}
}
} else {
- property_dictionary()->CopyKeysTo(storage,
- index,
- filter,
+ property_dictionary()->CopyKeysTo(this, storage, index, filter,
NameDictionary::UNSORTED);
}
}
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: {
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));
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);
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);
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>,
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);
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);
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();
}
+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();
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++;
}
}
-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;
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);
}
};
+template <DictionaryEntryType type>
void NameDictionary::CopyEnumKeysTo(FixedArray* storage) {
int length = storage->length();
int capacity = Capacity();
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;
}
-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);
}
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();
}
};
+enum class DictionaryEntryType { kObjects, kCells };
+
+
template <typename Derived, typename Shape, typename Key>
class Dictionary: public HashTable<Derived, Shape, Key> {
protected:
this->set(DerivedHashTable::EntryToIndex(entry) + 2, value.AsSmi());
}
- // Sorting support
- void CopyValuesTo(FixedArray* elements);
-
// Delete a property from the dictionary.
static Handle<Object> DeleteProperty(Handle<Derived> dictionary, int entry);
return DerivedHashTable::Shrink(dictionary, key);
}
+ // Sorting support
+ // TODO(dcarney): templatize or move to SeededNumberDictionary
+ void CopyValuesTo(FixedArray* elements);
+
// Returns the number of elements in the dictionary filtering out properties
// with the specified attributes.
+ template <DictionaryEntryType type>
int NumberOfElementsFilterAttributes(PropertyAttributes filter);
+ int NumberOfElementsFilterAttributes(Object* holder,
+ PropertyAttributes filter) {
+ if (holder->IsGlobalObject()) {
+ return NumberOfElementsFilterAttributes<DictionaryEntryType::kCells>(
+ filter);
+ } else {
+ return NumberOfElementsFilterAttributes<DictionaryEntryType::kObjects>(
+ filter);
+ }
+ }
// Returns the number of enumerable elements in the dictionary.
- int NumberOfEnumElements();
+ template <DictionaryEntryType type>
+ int NumberOfEnumElements() {
+ return NumberOfElementsFilterAttributes<type>(
+ static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC));
+ }
+ int NumberOfEnumElements(Object* holder) {
+ if (holder->IsGlobalObject()) {
+ return NumberOfEnumElements<DictionaryEntryType::kCells>();
+ } else {
+ return NumberOfEnumElements<DictionaryEntryType::kObjects>();
+ }
+ }
// Returns true if the dictionary contains any elements that are non-writable,
// non-configurable, non-enumerable, or have getters/setters.
+ template <DictionaryEntryType type>
bool HasComplexElements();
+ bool HasComplexElements(Object* holder) {
+ if (holder->IsGlobalObject()) {
+ return HasComplexElements<DictionaryEntryType::kCells>();
+ } else {
+ return HasComplexElements<DictionaryEntryType::kObjects>();
+ }
+ }
enum SortMode { UNSORTED, SORTED };
+
// Copies keys to preallocated fixed array.
- void CopyKeysTo(FixedArray* storage,
- PropertyAttributes filter,
+ template <DictionaryEntryType type>
+ void CopyKeysTo(FixedArray* storage, PropertyAttributes filter,
SortMode sort_mode);
+ void CopyKeysTo(Object* holder, FixedArray* storage,
+ PropertyAttributes filter, SortMode sort_mode) {
+ if (holder->IsGlobalObject()) {
+ return CopyKeysTo<DictionaryEntryType::kCells>(storage, filter,
+ sort_mode);
+ } else {
+ return CopyKeysTo<DictionaryEntryType::kObjects>(storage, filter,
+ sort_mode);
+ }
+ }
+
// Fill in details for properties into storage.
- void CopyKeysTo(FixedArray* storage,
- int index,
- PropertyAttributes filter,
+ template <DictionaryEntryType type>
+ void CopyKeysTo(FixedArray* storage, int index, PropertyAttributes filter,
SortMode sort_mode);
+ void CopyKeysTo(Object* holder, FixedArray* storage, int index,
+ PropertyAttributes filter, SortMode sort_mode) {
+ if (holder->IsGlobalObject()) {
+ return CopyKeysTo<DictionaryEntryType::kCells>(storage, index, filter,
+ sort_mode);
+ } else {
+ return CopyKeysTo<DictionaryEntryType::kObjects>(storage, index, filter,
+ sort_mode);
+ }
+ }
// Accessors for next enumeration index.
void SetNextEnumerationIndex(int index) {
DECLARE_CAST(NameDictionary)
// Copies enumerable keys to preallocated fixed array.
+ template <DictionaryEntryType type>
void CopyEnumKeysTo(FixedArray* storage);
+ void CopyEnumKeysTo(Object* holder, FixedArray* storage) {
+ if (holder->IsGlobalObject()) {
+ return CopyEnumKeysTo<DictionaryEntryType::kCells>(storage);
+ } else {
+ return CopyEnumKeysTo<DictionaryEntryType::kObjects>(storage);
+ }
+ }
+
inline static Handle<FixedArray> DoGenerateNewEnumerationIndices(
Handle<NameDictionary> dictionary);