Enum DictionaryEntryType removed.
Dictionary customization should be implemented in respective shape class. Review URL: https://codereview.chromium.org/1160813009 Cr-Commit-Position: refs/heads/master@{#28738}
This commit is contained in:
parent
144be2c461
commit
aa470e0af0
@ -7210,6 +7210,13 @@ Handle<FixedArray> NameDictionary::DoGenerateNewEnumerationIndices(
|
||||
}
|
||||
|
||||
|
||||
template <typename Dictionary>
|
||||
bool GlobalDictionaryShape::IsDeleted(Dictionary* dict, int entry) {
|
||||
DCHECK(dict->ValueAt(entry)->IsPropertyCell());
|
||||
return PropertyCell::cast(dict->ValueAt(entry))->value()->IsTheHole();
|
||||
}
|
||||
|
||||
|
||||
bool ObjectHashTableShape::IsMatch(Handle<Object> key, Object* other) {
|
||||
return key->SameValue(other);
|
||||
}
|
||||
|
100
src/objects.cc
100
src/objects.cc
@ -6384,21 +6384,21 @@ Handle<FixedArray> JSObject::GetEnumPropertyKeys(Handle<JSObject> object,
|
||||
return storage;
|
||||
} else if (object->IsGlobalObject()) {
|
||||
Handle<GlobalDictionary> dictionary(object->global_dictionary());
|
||||
int length = dictionary->NumberOfEnumElements(*object);
|
||||
int length = dictionary->NumberOfEnumElements();
|
||||
if (length == 0) {
|
||||
return Handle<FixedArray>(isolate->heap()->empty_fixed_array());
|
||||
}
|
||||
Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length);
|
||||
dictionary->CopyEnumKeysTo(*object, *storage);
|
||||
dictionary->CopyEnumKeysTo(*storage);
|
||||
return storage;
|
||||
} else {
|
||||
Handle<NameDictionary> dictionary(object->property_dictionary());
|
||||
int length = dictionary->NumberOfEnumElements(*object);
|
||||
int length = dictionary->NumberOfEnumElements();
|
||||
if (length == 0) {
|
||||
return Handle<FixedArray>(isolate->heap()->empty_fixed_array());
|
||||
}
|
||||
Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length);
|
||||
dictionary->CopyEnumKeysTo(*object, *storage);
|
||||
dictionary->CopyEnumKeysTo(*storage);
|
||||
return storage;
|
||||
}
|
||||
}
|
||||
@ -14063,7 +14063,8 @@ void Dictionary<Derived, Shape, Key>::Print(std::ostream& os) { // NOLINT
|
||||
} else {
|
||||
os << Brief(k);
|
||||
}
|
||||
os << ": " << Brief(ValueAt(i)) << " " << DetailsAt(i) << "\n";
|
||||
os << ": " << Brief(this->ValueAt(i)) << " " << this->DetailsAt(i)
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -14079,7 +14080,7 @@ void Dictionary<Derived, Shape, Key>::CopyValuesTo(FixedArray* elements) {
|
||||
for (int i = 0; i < capacity; i++) {
|
||||
Object* k = this->KeyAt(i);
|
||||
if (this->IsKey(k)) {
|
||||
elements->set(pos++, ValueAt(i), mode);
|
||||
elements->set(pos++, this->ValueAt(i), mode);
|
||||
}
|
||||
}
|
||||
DCHECK(pos == elements->length());
|
||||
@ -14254,10 +14255,9 @@ int JSObject::NumberOfOwnProperties(PropertyAttributes filter) {
|
||||
}
|
||||
return map->NumberOfDescribedProperties(OWN_DESCRIPTORS, filter);
|
||||
} else if (IsGlobalObject()) {
|
||||
return global_dictionary()->NumberOfElementsFilterAttributes(this, filter);
|
||||
return global_dictionary()->NumberOfElementsFilterAttributes(filter);
|
||||
} else {
|
||||
return property_dictionary()->NumberOfElementsFilterAttributes(this,
|
||||
filter);
|
||||
return property_dictionary()->NumberOfElementsFilterAttributes(filter);
|
||||
}
|
||||
}
|
||||
|
||||
@ -14391,10 +14391,10 @@ void JSObject::GetOwnPropertyNames(
|
||||
}
|
||||
}
|
||||
} else if (IsGlobalObject()) {
|
||||
global_dictionary()->CopyKeysTo(this, storage, index, filter,
|
||||
global_dictionary()->CopyKeysTo(storage, index, filter,
|
||||
GlobalDictionary::UNSORTED);
|
||||
} else {
|
||||
property_dictionary()->CopyKeysTo(this, storage, index, filter,
|
||||
property_dictionary()->CopyKeysTo(storage, index, filter,
|
||||
NameDictionary::UNSORTED);
|
||||
}
|
||||
}
|
||||
@ -14478,13 +14478,10 @@ int JSObject::GetOwnElementKeys(FixedArray* storage,
|
||||
|
||||
case DICTIONARY_ELEMENTS: {
|
||||
if (storage != NULL) {
|
||||
element_dictionary()->CopyKeysTo<DictionaryEntryType::kObjects>(
|
||||
storage, filter, SeededNumberDictionary::SORTED);
|
||||
element_dictionary()->CopyKeysTo(storage, filter,
|
||||
SeededNumberDictionary::SORTED);
|
||||
}
|
||||
counter +=
|
||||
element_dictionary()
|
||||
->NumberOfElementsFilterAttributes<DictionaryEntryType::kObjects>(
|
||||
filter);
|
||||
counter += element_dictionary()->NumberOfElementsFilterAttributes(filter);
|
||||
break;
|
||||
}
|
||||
case SLOPPY_ARGUMENTS_ELEMENTS: {
|
||||
@ -14497,11 +14494,10 @@ int JSObject::GetOwnElementKeys(FixedArray* storage,
|
||||
SeededNumberDictionary* dictionary =
|
||||
SeededNumberDictionary::cast(arguments);
|
||||
if (storage != NULL) {
|
||||
dictionary->CopyKeysTo<DictionaryEntryType::kObjects>(
|
||||
storage, filter, SeededNumberDictionary::UNSORTED);
|
||||
dictionary->CopyKeysTo(storage, filter,
|
||||
SeededNumberDictionary::UNSORTED);
|
||||
}
|
||||
counter += dictionary->NumberOfElementsFilterAttributes<
|
||||
DictionaryEntryType::kObjects>(filter);
|
||||
counter += dictionary->NumberOfElementsFilterAttributes(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));
|
||||
@ -15166,13 +15162,8 @@ template Handle<NameDictionary>
|
||||
Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
|
||||
EnsureCapacity(Handle<NameDictionary>, int, Handle<Name>);
|
||||
|
||||
template bool
|
||||
Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape,
|
||||
uint32_t>::HasComplexElements<DictionaryEntryType::kCells>();
|
||||
|
||||
template bool
|
||||
Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape,
|
||||
uint32_t>::HasComplexElements<DictionaryEntryType::kObjects>();
|
||||
template bool Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape,
|
||||
uint32_t>::HasComplexElements();
|
||||
|
||||
template int HashTable<SeededNumberDictionary, SeededNumberDictionaryShape,
|
||||
uint32_t>::FindEntry(uint32_t);
|
||||
@ -16252,22 +16243,7 @@ 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:
|
||||
DCHECK(d->ValueAt(i)->IsPropertyCell());
|
||||
return PropertyCell::cast(d->ValueAt(i))->value()->IsTheHole();
|
||||
}
|
||||
UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template <typename Derived, typename Shape, typename Key>
|
||||
template <DictionaryEntryType type>
|
||||
int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes(
|
||||
PropertyAttributes filter) {
|
||||
int capacity = this->Capacity();
|
||||
@ -16275,8 +16251,8 @@ int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes(
|
||||
for (int i = 0; i < capacity; i++) {
|
||||
Object* k = this->KeyAt(i);
|
||||
if (this->IsKey(k) && !FilterKey(k, filter)) {
|
||||
if (IsDeleted<type>(this, i)) continue;
|
||||
PropertyDetails details = DetailsAt(i);
|
||||
if (this->IsDeleted(i)) continue;
|
||||
PropertyDetails details = this->DetailsAt(i);
|
||||
PropertyAttributes attr = details.attributes();
|
||||
if ((attr & filter) == 0) result++;
|
||||
}
|
||||
@ -16286,14 +16262,13 @@ int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes(
|
||||
|
||||
|
||||
template <typename Derived, typename Shape, typename Key>
|
||||
template <DictionaryEntryType type>
|
||||
bool Dictionary<Derived, Shape, Key>::HasComplexElements() {
|
||||
int capacity = this->Capacity();
|
||||
for (int i = 0; i < capacity; i++) {
|
||||
Object* k = this->KeyAt(i);
|
||||
if (this->IsKey(k) && !FilterKey(k, NONE)) {
|
||||
if (IsDeleted<type>(this, i)) continue;
|
||||
PropertyDetails details = DetailsAt(i);
|
||||
if (this->IsDeleted(i)) continue;
|
||||
PropertyDetails details = this->DetailsAt(i);
|
||||
if (details.type() == ACCESSOR_CONSTANT) return true;
|
||||
PropertyAttributes attr = details.attributes();
|
||||
if (attr & (READ_ONLY | DONT_DELETE | DONT_ENUM)) return true;
|
||||
@ -16304,18 +16279,17 @@ 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<type>(filter));
|
||||
DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter));
|
||||
int capacity = this->Capacity();
|
||||
int index = 0;
|
||||
for (int i = 0; i < capacity; i++) {
|
||||
Object* k = this->KeyAt(i);
|
||||
if (this->IsKey(k) && !FilterKey(k, filter)) {
|
||||
if (IsDeleted<type>(this, i)) continue;
|
||||
PropertyDetails details = DetailsAt(i);
|
||||
if (this->IsDeleted(i)) continue;
|
||||
PropertyDetails details = this->DetailsAt(i);
|
||||
PropertyAttributes attr = details.attributes();
|
||||
if ((attr & filter) == 0) storage->set(index++, k);
|
||||
}
|
||||
@ -16340,7 +16314,6 @@ struct EnumIndexComparator {
|
||||
|
||||
|
||||
template <typename Derived, typename Shape, typename Key>
|
||||
template <DictionaryEntryType type>
|
||||
void Dictionary<Derived, Shape, Key>::CopyEnumKeysTo(FixedArray* storage) {
|
||||
int length = storage->length();
|
||||
int capacity = this->Capacity();
|
||||
@ -16348,12 +16321,12 @@ void Dictionary<Derived, Shape, Key>::CopyEnumKeysTo(FixedArray* storage) {
|
||||
for (int i = 0; i < capacity; i++) {
|
||||
Object* k = this->KeyAt(i);
|
||||
if (this->IsKey(k) && !k->IsSymbol()) {
|
||||
PropertyDetails details = DetailsAt(i);
|
||||
if (details.IsDontEnum() || IsDeleted<type>(this, i)) continue;
|
||||
storage->set(properties, Smi::FromInt(i));
|
||||
properties++;
|
||||
if (properties == length) break;
|
||||
}
|
||||
PropertyDetails details = this->DetailsAt(i);
|
||||
if (details.IsDontEnum() || this->IsDeleted(i)) continue;
|
||||
storage->set(properties, Smi::FromInt(i));
|
||||
properties++;
|
||||
if (properties == length) break;
|
||||
}
|
||||
}
|
||||
CHECK_EQ(length, properties);
|
||||
EnumIndexComparator<Derived> cmp(static_cast<Derived*>(this));
|
||||
@ -16367,17 +16340,16 @@ void Dictionary<Derived, Shape, Key>::CopyEnumKeysTo(FixedArray* storage) {
|
||||
|
||||
|
||||
template <typename Derived, typename Shape, typename Key>
|
||||
template <DictionaryEntryType type>
|
||||
void Dictionary<Derived, Shape, Key>::CopyKeysTo(
|
||||
FixedArray* storage, int index, PropertyAttributes filter,
|
||||
typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) {
|
||||
DCHECK(storage->length() >= NumberOfElementsFilterAttributes<type>(filter));
|
||||
DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter));
|
||||
int capacity = this->Capacity();
|
||||
for (int i = 0; i < capacity; i++) {
|
||||
Object* k = this->KeyAt(i);
|
||||
if (this->IsKey(k) && !FilterKey(k, filter)) {
|
||||
if (IsDeleted<type>(this, i)) continue;
|
||||
PropertyDetails details = DetailsAt(i);
|
||||
if (this->IsDeleted(i)) continue;
|
||||
PropertyDetails details = this->DetailsAt(i);
|
||||
PropertyAttributes attr = details.attributes();
|
||||
if ((attr & filter) == 0) storage->set(index++, k);
|
||||
}
|
||||
@ -16396,7 +16368,7 @@ Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) {
|
||||
for (int i = 0; i < capacity; i++) {
|
||||
Object* k = this->KeyAt(i);
|
||||
if (this->IsKey(k)) {
|
||||
Object* e = ValueAt(i);
|
||||
Object* e = this->ValueAt(i);
|
||||
// TODO(dcarney): this should be templatized.
|
||||
if (e->IsPropertyCell()) {
|
||||
e = PropertyCell::cast(e)->value();
|
||||
|
@ -3598,9 +3598,6 @@ class StringTable: public HashTable<StringTable,
|
||||
};
|
||||
|
||||
|
||||
enum class DictionaryEntryType { kObjects, kCells };
|
||||
|
||||
|
||||
template <typename Derived, typename Shape, typename Key>
|
||||
class Dictionary: public HashTable<Derived, Shape, Key> {
|
||||
typedef HashTable<Derived, Shape, Key> DerivedHashTable;
|
||||
@ -3628,6 +3625,11 @@ class Dictionary: public HashTable<Derived, Shape, Key> {
|
||||
this->set(Derived::EntryToIndex(entry) + 2, value.AsSmi());
|
||||
}
|
||||
|
||||
// Returns true if property at given entry is deleted.
|
||||
bool IsDeleted(int entry) {
|
||||
return Shape::IsDeleted(static_cast<Derived*>(this), entry);
|
||||
}
|
||||
|
||||
// Delete a property from the dictionary.
|
||||
static Handle<Object> DeleteProperty(Handle<Derived> dictionary, int entry);
|
||||
|
||||
@ -3644,87 +3646,30 @@ class Dictionary: public HashTable<Derived, Shape, Key> {
|
||||
|
||||
// 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.
|
||||
template <DictionaryEntryType type>
|
||||
int NumberOfEnumElements() {
|
||||
return NumberOfElementsFilterAttributes<type>(
|
||||
return NumberOfElementsFilterAttributes(
|
||||
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.
|
||||
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.
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
// Accessors for next enumeration index.
|
||||
void SetNextEnumerationIndex(int index) {
|
||||
@ -3806,7 +3751,17 @@ class NameDictionaryBase : public Dictionary<Derived, Shape, Handle<Name> > {
|
||||
};
|
||||
|
||||
|
||||
class NameDictionaryShape : public BaseShape<Handle<Name> > {
|
||||
template <typename Key>
|
||||
class BaseDictionaryShape : public BaseShape<Key> {
|
||||
public:
|
||||
template <typename Dictionary>
|
||||
static bool IsDeleted(Dictionary* dict, int entry) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class NameDictionaryShape : public BaseDictionaryShape<Handle<Name> > {
|
||||
public:
|
||||
static inline bool IsMatch(Handle<Name> key, Object* other);
|
||||
static inline uint32_t Hash(Handle<Name> key);
|
||||
@ -3834,6 +3789,9 @@ class NameDictionary
|
||||
class GlobalDictionaryShape : public NameDictionaryShape {
|
||||
public:
|
||||
static const int kEntrySize = 3; // Overrides NameDictionaryShape::kEntrySize
|
||||
|
||||
template <typename Dictionary>
|
||||
static bool IsDeleted(Dictionary* dict, int entry);
|
||||
};
|
||||
|
||||
|
||||
@ -3844,7 +3802,7 @@ class GlobalDictionary
|
||||
};
|
||||
|
||||
|
||||
class NumberDictionaryShape : public BaseShape<uint32_t> {
|
||||
class NumberDictionaryShape : public BaseDictionaryShape<uint32_t> {
|
||||
public:
|
||||
static inline bool IsMatch(uint32_t key, Object* other);
|
||||
static inline Handle<Object> AsHandle(Isolate* isolate, uint32_t key);
|
||||
|
@ -1293,8 +1293,7 @@ RUNTIME_FUNCTION(Runtime_HasComplexElements) {
|
||||
return isolate->heap()->true_value();
|
||||
}
|
||||
if (!current->HasDictionaryElements()) continue;
|
||||
if (current->element_dictionary()
|
||||
->HasComplexElements<DictionaryEntryType::kObjects>()) {
|
||||
if (current->element_dictionary()->HasComplexElements()) {
|
||||
return isolate->heap()->true_value();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user