Commit fc7ca518 authored by Frank Emrich's avatar Frank Emrich Committed by Commit Bot

[dict-proto] SwissNameDictionary rollout in runtime code, pt. 1

This CL is part of a series that makes SwissNameDictionary available
as a new property backing store. Currently, the flag
v8_dict_mode_prototypes allows selecting between NameDictionary and
OrderedNameDictionary as the backing store used for all dictionary
mode objects. This series of CLs changes this such that enabling the
flag causes SwissNameDictionary being used instead of
OrderedNameDictionary. The behavior for when the flag is not set
remains unchanged (= use NameDictionary).

This particular CL
a) moves two operations from ordered-hash-table.cc to
swiss-name-dictionary.cc (which were itself just copies of existing
functions, see the existing TODOs about cleaning this up).

b) adds a new getter for the SwissNameDictionary backing store,
called JSReceiver::property_dictionary_swiss.

c) contains a first wave of replacing usages of
OrderedNameDictionary with SwissNameDictionary.

Bug: v8:11388
Change-Id: Ie6b45571aee3646c0c0d3937b3c25f0f033810dd
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2732676Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Frank Emrich <emrich@google.com>
Cr-Commit-Position: refs/heads/master@{#73213}
parent d4f31caa
...@@ -1602,13 +1602,15 @@ Handle<JSObject> Factory::CopyJSObjectWithAllocationSite( ...@@ -1602,13 +1602,15 @@ Handle<JSObject> Factory::CopyJSObjectWithAllocationSite(
clone->set_raw_properties_or_hash(*prop); clone->set_raw_properties_or_hash(*prop);
} }
} else { } else {
Handle<FixedArray> properties = Handle<Object> copied_properties;
handle(V8_DICT_MODE_PROTOTYPES_BOOL if (V8_DICT_MODE_PROTOTYPES_BOOL) {
? FixedArray::cast(source->property_dictionary_ordered()) copied_properties = SwissNameDictionary::ShallowCopy(
: FixedArray::cast(source->property_dictionary()), isolate(), handle(source->property_dictionary_swiss(), isolate()));
isolate()); } else {
Handle<FixedArray> prop = CopyFixedArray(properties); copied_properties =
clone->set_raw_properties_or_hash(*prop); CopyFixedArray(handle(source->property_dictionary(), isolate()));
}
clone->set_raw_properties_or_hash(*copied_properties);
} }
return clone; return clone;
} }
...@@ -2190,8 +2192,7 @@ Handle<JSObject> Factory::NewSlowJSObjectFromMap( ...@@ -2190,8 +2192,7 @@ Handle<JSObject> Factory::NewSlowJSObjectFromMap(
DCHECK(map->is_dictionary_map()); DCHECK(map->is_dictionary_map());
Handle<HeapObject> object_properties; Handle<HeapObject> object_properties;
if (V8_DICT_MODE_PROTOTYPES_BOOL) { if (V8_DICT_MODE_PROTOTYPES_BOOL) {
object_properties = object_properties = NewSwissNameDictionary(capacity, allocation);
OrderedNameDictionary::Allocate(isolate(), capacity).ToHandleChecked();
} else { } else {
object_properties = NameDictionary::New(isolate(), capacity); object_properties = NameDictionary::New(isolate(), capacity);
} }
...@@ -2205,7 +2206,7 @@ Handle<JSObject> Factory::NewSlowJSObjectWithPropertiesAndElements( ...@@ -2205,7 +2206,7 @@ Handle<JSObject> Factory::NewSlowJSObjectWithPropertiesAndElements(
Handle<HeapObject> prototype, Handle<HeapObject> properties, Handle<HeapObject> prototype, Handle<HeapObject> properties,
Handle<FixedArrayBase> elements) { Handle<FixedArrayBase> elements) {
DCHECK_IMPLIES(V8_DICT_MODE_PROTOTYPES_BOOL, DCHECK_IMPLIES(V8_DICT_MODE_PROTOTYPES_BOOL,
properties->IsOrderedNameDictionary()); properties->IsSwissNameDictionary());
DCHECK_IMPLIES(!V8_DICT_MODE_PROTOTYPES_BOOL, properties->IsNameDictionary()); DCHECK_IMPLIES(!V8_DICT_MODE_PROTOTYPES_BOOL, properties->IsNameDictionary());
Handle<Map> object_map = isolate()->slow_object_with_object_prototype_map(); Handle<Map> object_map = isolate()->slow_object_with_object_prototype_map();
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
#include "src/objects/ordered-hash-table.h" #include "src/objects/ordered-hash-table.h"
#include "src/objects/property-cell.h" #include "src/objects/property-cell.h"
#include "src/objects/slots-inl.h" #include "src/objects/slots-inl.h"
#include "src/objects/swiss-name-dictionary-inl.h"
#include "src/objects/templates.h" #include "src/objects/templates.h"
#include "src/snapshot/snapshot.h" #include "src/snapshot/snapshot.h"
#include "src/wasm/wasm-js.h" #include "src/wasm/wasm-js.h"
...@@ -5202,10 +5203,10 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from, ...@@ -5202,10 +5203,10 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
} else if (V8_DICT_MODE_PROTOTYPES_BOOL) { } else if (V8_DICT_MODE_PROTOTYPES_BOOL) {
// Copy all keys and values in enumeration order. // Copy all keys and values in enumeration order.
Handle<OrderedNameDictionary> properties = Handle<OrderedNameDictionary>( Handle<SwissNameDictionary> properties = Handle<SwissNameDictionary>(
from->property_dictionary_ordered(), isolate()); from->property_dictionary_swiss(), isolate());
ReadOnlyRoots roots(isolate()); ReadOnlyRoots roots(isolate());
for (InternalIndex entry : properties->IterateEntries()) { for (InternalIndex entry : properties->IterateEntriesOrdered()) {
Object raw_key; Object raw_key;
if (!properties->ToKey(roots, entry, &raw_key)) continue; if (!properties->ToKey(roots, entry, &raw_key)) continue;
......
...@@ -75,6 +75,9 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) Dictionary ...@@ -75,6 +75,9 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) Dictionary
Handle<Object> value, PropertyDetails details, Handle<Object> value, PropertyDetails details,
InternalIndex* entry_out = nullptr); InternalIndex* entry_out = nullptr);
static Handle<Derived> ShallowCopy(Isolate* isolate,
Handle<Derived> dictionary);
protected: protected:
// Generic at put operation. // Generic at put operation.
V8_WARN_UNUSED_RESULT static Handle<Derived> AtPut(Isolate* isolate, V8_WARN_UNUSED_RESULT static Handle<Derived> AtPut(Isolate* isolate,
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "src/objects/shared-function-info.h" #include "src/objects/shared-function-info.h"
#include "src/objects/slots.h" #include "src/objects/slots.h"
#include "src/objects/smi-inl.h" #include "src/objects/smi-inl.h"
#include "src/objects/swiss-name-dictionary-inl.h"
// Has to be the last include (doesn't have include guards): // Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h" #include "src/objects/object-macros.h"
...@@ -605,7 +606,7 @@ void JSReceiver::initialize_properties(Isolate* isolate) { ...@@ -605,7 +606,7 @@ void JSReceiver::initialize_properties(Isolate* isolate) {
if (map(isolate).is_dictionary_map()) { if (map(isolate).is_dictionary_map()) {
if (V8_DICT_MODE_PROTOTYPES_BOOL) { if (V8_DICT_MODE_PROTOTYPES_BOOL) {
WRITE_FIELD(*this, kPropertiesOrHashOffset, WRITE_FIELD(*this, kPropertiesOrHashOffset,
roots.empty_ordered_property_dictionary()); roots.empty_swiss_property_dictionary());
} else { } else {
WRITE_FIELD(*this, kPropertiesOrHashOffset, WRITE_FIELD(*this, kPropertiesOrHashOffset,
roots.empty_property_dictionary()); roots.empty_property_dictionary());
...@@ -619,7 +620,7 @@ DEF_GETTER(JSReceiver, HasFastProperties, bool) { ...@@ -619,7 +620,7 @@ DEF_GETTER(JSReceiver, HasFastProperties, bool) {
DCHECK(raw_properties_or_hash(isolate).IsSmi() || DCHECK(raw_properties_or_hash(isolate).IsSmi() ||
((raw_properties_or_hash(isolate).IsGlobalDictionary(isolate) || ((raw_properties_or_hash(isolate).IsGlobalDictionary(isolate) ||
raw_properties_or_hash(isolate).IsNameDictionary(isolate) || raw_properties_or_hash(isolate).IsNameDictionary(isolate) ||
raw_properties_or_hash(isolate).IsOrderedNameDictionary(isolate)) == raw_properties_or_hash(isolate).IsSwissNameDictionary(isolate)) ==
map(isolate).is_dictionary_map())); map(isolate).is_dictionary_map()));
return !map(isolate).is_dictionary_map(); return !map(isolate).is_dictionary_map();
} }
...@@ -652,6 +653,20 @@ DEF_GETTER(JSReceiver, property_dictionary_ordered, OrderedNameDictionary) { ...@@ -652,6 +653,20 @@ DEF_GETTER(JSReceiver, property_dictionary_ordered, OrderedNameDictionary) {
return OrderedNameDictionary::cast(prop); return OrderedNameDictionary::cast(prop);
} }
DEF_GETTER(JSReceiver, property_dictionary_swiss, SwissNameDictionary) {
DCHECK(!IsJSGlobalObject(isolate));
DCHECK(!HasFastProperties(isolate));
DCHECK(V8_DICT_MODE_PROTOTYPES_BOOL);
// Can't use ReadOnlyRoots(isolate) as this isolate could be produced by
// i::GetIsolateForPtrCompr(HeapObject).
Object prop = raw_properties_or_hash(isolate);
if (prop.IsSmi()) {
return GetReadOnlyRoots(isolate).empty_swiss_property_dictionary();
}
return SwissNameDictionary::cast(prop);
}
// TODO(gsathya): Pass isolate directly to this function and access // TODO(gsathya): Pass isolate directly to this function and access
// the heap from this. // the heap from this.
DEF_GETTER(JSReceiver, property_array, PropertyArray) { DEF_GETTER(JSReceiver, property_array, PropertyArray) {
......
This diff is collapsed.
...@@ -50,7 +50,11 @@ class JSReceiver : public HeapObject { ...@@ -50,7 +50,11 @@ class JSReceiver : public HeapObject {
// Gets slow properties for non-global objects (if v8_dict_mode_prototypes is // Gets slow properties for non-global objects (if v8_dict_mode_prototypes is
// set). // set).
// TODO(v8:11388) Keeping both versions around while transition to
// SwissNameDictionary is in progress, will then delete
// property_dictionary_ordered.
DECL_GETTER(property_dictionary_ordered, OrderedNameDictionary) DECL_GETTER(property_dictionary_ordered, OrderedNameDictionary)
DECL_GETTER(property_dictionary_swiss, SwissNameDictionary)
// Sets the properties backing store and makes sure any existing hash is moved // Sets the properties backing store and makes sure any existing hash is moved
// to the new properties store. To clear out the properties store, pass in the // to the new properties store. To clear out the properties store, pass in the
......
...@@ -66,7 +66,7 @@ Handle<JSRegExpResultIndices> JSRegExpResultIndices::BuildIndices( ...@@ -66,7 +66,7 @@ Handle<JSRegExpResultIndices> JSRegExpResultIndices::BuildIndices(
int num_names = names->length() >> 1; int num_names = names->length() >> 1;
Handle<HeapObject> group_names; Handle<HeapObject> group_names;
if (V8_DICT_MODE_PROTOTYPES_BOOL) { if (V8_DICT_MODE_PROTOTYPES_BOOL) {
group_names = isolate->factory()->NewOrderedNameDictionary(num_names); group_names = isolate->factory()->NewSwissNameDictionary(num_names);
} else { } else {
group_names = isolate->factory()->NewNameDictionary(num_names); group_names = isolate->factory()->NewNameDictionary(num_names);
} }
...@@ -82,11 +82,9 @@ Handle<JSRegExpResultIndices> JSRegExpResultIndices::BuildIndices( ...@@ -82,11 +82,9 @@ Handle<JSRegExpResultIndices> JSRegExpResultIndices::BuildIndices(
capture_indices = Handle<JSArray>::cast(capture_indices); capture_indices = Handle<JSArray>::cast(capture_indices);
} }
if (V8_DICT_MODE_PROTOTYPES_BOOL) { if (V8_DICT_MODE_PROTOTYPES_BOOL) {
group_names = group_names = SwissNameDictionary::Add(
OrderedNameDictionary::Add( isolate, Handle<SwissNameDictionary>::cast(group_names), name,
isolate, Handle<OrderedNameDictionary>::cast(group_names), name, capture_indices, PropertyDetails::Empty());
capture_indices, PropertyDetails::Empty())
.ToHandleChecked();
} else { } else {
group_names = NameDictionary::Add( group_names = NameDictionary::Add(
isolate, Handle<NameDictionary>::cast(group_names), name, isolate, Handle<NameDictionary>::cast(group_names), name,
......
...@@ -830,7 +830,7 @@ void CommonCopyEnumKeysTo(Isolate* isolate, Handle<Dictionary> dictionary, ...@@ -830,7 +830,7 @@ void CommonCopyEnumKeysTo(Isolate* isolate, Handle<Dictionary> dictionary,
continue; continue;
} else { } else {
if (Dictionary::kIsOrderedDictionaryType) { if (Dictionary::kIsOrderedDictionaryType) {
storage->set(properties, dictionary->NameAt(i)); storage->set(properties, Name::cast(key));
} else { } else {
// If the dictionary does not store elements in enumeration order, // If the dictionary does not store elements in enumeration order,
// we need to sort it afterwards in CopyEnumKeysTo. To enable this we // we need to sort it afterwards in CopyEnumKeysTo. To enable this we
...@@ -875,11 +875,11 @@ void CopyEnumKeysTo(Isolate* isolate, Handle<Dictionary> dictionary, ...@@ -875,11 +875,11 @@ void CopyEnumKeysTo(Isolate* isolate, Handle<Dictionary> dictionary,
} }
template <> template <>
void CopyEnumKeysTo(Isolate* isolate, Handle<OrderedNameDictionary> dictionary, void CopyEnumKeysTo(Isolate* isolate, Handle<SwissNameDictionary> dictionary,
Handle<FixedArray> storage, KeyCollectionMode mode, Handle<FixedArray> storage, KeyCollectionMode mode,
KeyAccumulator* accumulator) { KeyAccumulator* accumulator) {
CommonCopyEnumKeysTo<OrderedNameDictionary>(isolate, dictionary, storage, CommonCopyEnumKeysTo<SwissNameDictionary>(isolate, dictionary, storage, mode,
mode, accumulator); accumulator);
// No need to sort, as CommonCopyEnumKeysTo on OrderedNameDictionary // No need to sort, as CommonCopyEnumKeysTo on OrderedNameDictionary
// adds entries to |storage| in the dict's insertion order // adds entries to |storage| in the dict's insertion order
...@@ -1006,7 +1006,7 @@ Maybe<bool> KeyAccumulator::CollectOwnPropertyNames(Handle<JSReceiver> receiver, ...@@ -1006,7 +1006,7 @@ Maybe<bool> KeyAccumulator::CollectOwnPropertyNames(Handle<JSReceiver> receiver,
JSGlobalObject::cast(*object).global_dictionary(kAcquireLoad)); JSGlobalObject::cast(*object).global_dictionary(kAcquireLoad));
} else if (V8_DICT_MODE_PROTOTYPES_BOOL) { } else if (V8_DICT_MODE_PROTOTYPES_BOOL) {
enum_keys = GetOwnEnumPropertyDictionaryKeys( enum_keys = GetOwnEnumPropertyDictionaryKeys(
isolate_, mode_, this, object, object->property_dictionary_ordered()); isolate_, mode_, this, object, object->property_dictionary_swiss());
} else { } else {
enum_keys = GetOwnEnumPropertyDictionaryKeys( enum_keys = GetOwnEnumPropertyDictionaryKeys(
isolate_, mode_, this, object, object->property_dictionary()); isolate_, mode_, this, object, object->property_dictionary());
...@@ -1045,7 +1045,7 @@ Maybe<bool> KeyAccumulator::CollectOwnPropertyNames(Handle<JSReceiver> receiver, ...@@ -1045,7 +1045,7 @@ Maybe<bool> KeyAccumulator::CollectOwnPropertyNames(Handle<JSReceiver> receiver,
this)); this));
} else if (V8_DICT_MODE_PROTOTYPES_BOOL) { } else if (V8_DICT_MODE_PROTOTYPES_BOOL) {
RETURN_NOTHING_IF_NOT_SUCCESSFUL(CollectKeysFromDictionary( RETURN_NOTHING_IF_NOT_SUCCESSFUL(CollectKeysFromDictionary(
handle(object->property_dictionary_ordered(), isolate_), this)); handle(object->property_dictionary_swiss(), isolate_), this));
} else { } else {
RETURN_NOTHING_IF_NOT_SUCCESSFUL(CollectKeysFromDictionary( RETURN_NOTHING_IF_NOT_SUCCESSFUL(CollectKeysFromDictionary(
handle(object->property_dictionary(), isolate_), this)); handle(object->property_dictionary(), isolate_), this));
...@@ -1070,7 +1070,7 @@ ExceptionStatus KeyAccumulator::CollectPrivateNames(Handle<JSReceiver> receiver, ...@@ -1070,7 +1070,7 @@ ExceptionStatus KeyAccumulator::CollectPrivateNames(Handle<JSReceiver> receiver,
this)); this));
} else if (V8_DICT_MODE_PROTOTYPES_BOOL) { } else if (V8_DICT_MODE_PROTOTYPES_BOOL) {
RETURN_FAILURE_IF_NOT_SUCCESSFUL(CollectKeysFromDictionary( RETURN_FAILURE_IF_NOT_SUCCESSFUL(CollectKeysFromDictionary(
handle(object->property_dictionary_ordered(), isolate_), this)); handle(object->property_dictionary_swiss(), isolate_), this));
} else { } else {
RETURN_FAILURE_IF_NOT_SUCCESSFUL(CollectKeysFromDictionary( RETURN_FAILURE_IF_NOT_SUCCESSFUL(CollectKeysFromDictionary(
handle(object->property_dictionary(), isolate_), this)); handle(object->property_dictionary(), isolate_), this));
...@@ -1156,7 +1156,7 @@ Handle<FixedArray> KeyAccumulator::GetOwnEnumPropertyKeys( ...@@ -1156,7 +1156,7 @@ Handle<FixedArray> KeyAccumulator::GetOwnEnumPropertyKeys(
} else if (V8_DICT_MODE_PROTOTYPES_BOOL) { } else if (V8_DICT_MODE_PROTOTYPES_BOOL) {
return GetOwnEnumPropertyDictionaryKeys( return GetOwnEnumPropertyDictionaryKeys(
isolate, KeyCollectionMode::kOwnOnly, nullptr, object, isolate, KeyCollectionMode::kOwnOnly, nullptr, object,
object->property_dictionary_ordered()); object->property_dictionary_swiss());
} else { } else {
return GetOwnEnumPropertyDictionaryKeys( return GetOwnEnumPropertyDictionaryKeys(
isolate, KeyCollectionMode::kOwnOnly, nullptr, object, isolate, KeyCollectionMode::kOwnOnly, nullptr, object,
...@@ -1189,7 +1189,7 @@ Maybe<bool> KeyAccumulator::CollectOwnJSProxyKeys(Handle<JSReceiver> receiver, ...@@ -1189,7 +1189,7 @@ Maybe<bool> KeyAccumulator::CollectOwnJSProxyKeys(Handle<JSReceiver> receiver,
if (filter_ == PRIVATE_NAMES_ONLY) { if (filter_ == PRIVATE_NAMES_ONLY) {
if (V8_DICT_MODE_PROTOTYPES_BOOL) { if (V8_DICT_MODE_PROTOTYPES_BOOL) {
RETURN_NOTHING_IF_NOT_SUCCESSFUL(CollectKeysFromDictionary( RETURN_NOTHING_IF_NOT_SUCCESSFUL(CollectKeysFromDictionary(
handle(proxy->property_dictionary_ordered(), isolate_), this)); handle(proxy->property_dictionary_swiss(), isolate_), this));
} else { } else {
RETURN_NOTHING_IF_NOT_SUCCESSFUL(CollectKeysFromDictionary( RETURN_NOTHING_IF_NOT_SUCCESSFUL(CollectKeysFromDictionary(
handle(proxy->property_dictionary(), isolate_), this)); handle(proxy->property_dictionary(), isolate_), this));
......
...@@ -572,6 +572,13 @@ template void ClassBoilerplate::AddToPropertiesTemplate( ...@@ -572,6 +572,13 @@ template void ClassBoilerplate::AddToPropertiesTemplate(
Isolate* isolate, Handle<OrderedNameDictionary> dictionary, Isolate* isolate, Handle<OrderedNameDictionary> dictionary,
Handle<Name> name, int key_index, ClassBoilerplate::ValueKind value_kind, Handle<Name> name, int key_index, ClassBoilerplate::ValueKind value_kind,
Smi value); Smi value);
template <>
void ClassBoilerplate::AddToPropertiesTemplate(
Isolate* isolate, Handle<SwissNameDictionary> dictionary, Handle<Name> name,
int key_index, ClassBoilerplate::ValueKind value_kind, Smi value) {
// TODO(v8:11388) Temporary dummy to make MSVC happy, removed in next CL.
UNREACHABLE();
}
template <typename LocalIsolate> template <typename LocalIsolate>
void ClassBoilerplate::AddToElementsTemplate( void ClassBoilerplate::AddToElementsTemplate(
......
...@@ -3561,11 +3561,10 @@ Maybe<bool> JSProxy::SetPrivateSymbol(Isolate* isolate, Handle<JSProxy> proxy, ...@@ -3561,11 +3561,10 @@ Maybe<bool> JSProxy::SetPrivateSymbol(Isolate* isolate, Handle<JSProxy> proxy,
PropertyDetails details(kData, DONT_ENUM, PropertyConstness::kMutable); PropertyDetails details(kData, DONT_ENUM, PropertyConstness::kMutable);
if (V8_DICT_MODE_PROTOTYPES_BOOL) { if (V8_DICT_MODE_PROTOTYPES_BOOL) {
Handle<OrderedNameDictionary> dict(proxy->property_dictionary_ordered(), Handle<SwissNameDictionary> dict(proxy->property_dictionary_swiss(),
isolate); isolate);
Handle<OrderedNameDictionary> result = Handle<SwissNameDictionary> result =
OrderedNameDictionary::Add(isolate, dict, private_name, value, details) SwissNameDictionary::Add(isolate, dict, private_name, value, details);
.ToHandleChecked();
if (!dict.is_identical_to(result)) proxy->SetProperties(*result); if (!dict.is_identical_to(result)) proxy->SetProperties(*result);
} else { } else {
Handle<NameDictionary> dict(proxy->property_dictionary(), isolate); Handle<NameDictionary> dict(proxy->property_dictionary(), isolate);
...@@ -5922,6 +5921,13 @@ Handle<Derived> Dictionary<Derived, Shape>::Add(LocalIsolate* isolate, ...@@ -5922,6 +5921,13 @@ Handle<Derived> Dictionary<Derived, Shape>::Add(LocalIsolate* isolate,
return dictionary; return dictionary;
} }
template <typename Derived, typename Shape>
Handle<Derived> Dictionary<Derived, Shape>::ShallowCopy(
Isolate* isolate, Handle<Derived> dictionary) {
return Handle<Derived>::cast(isolate->factory()->CopyFixedArrayWithMap(
dictionary, Derived::GetMap(ReadOnlyRoots(isolate))));
}
// static // static
Handle<SimpleNumberDictionary> SimpleNumberDictionary::Set( Handle<SimpleNumberDictionary> SimpleNumberDictionary::Set(
Isolate* isolate, Handle<SimpleNumberDictionary> dictionary, uint32_t key, Isolate* isolate, Handle<SimpleNumberDictionary> dictionary, uint32_t key,
......
...@@ -438,38 +438,6 @@ InternalIndex OrderedNameDictionary::FindEntry(LocalIsolate* isolate, ...@@ -438,38 +438,6 @@ InternalIndex OrderedNameDictionary::FindEntry(LocalIsolate* isolate,
return InternalIndex::NotFound(); return InternalIndex::NotFound();
} }
// TODO(emrich): This is almost an identical copy of
// Dictionary<..>::SlowReverseLookup.
// Consolidate both versions elsewhere (e.g., hash-table-utils)?
Object OrderedNameDictionary::SlowReverseLookup(Isolate* isolate,
Object value) {
ReadOnlyRoots roots(isolate);
for (InternalIndex i : IterateEntries()) {
Object k;
if (!ToKey(roots, i, &k)) continue;
Object e = this->ValueAt(i);
if (e == value) return k;
}
return roots.undefined_value();
}
// TODO(emrich): This is almost an identical copy of
// HashTable<..>::NumberOfEnumerableProperties.
// Consolidate both versions elsewhere (e.g., hash-table-utils)?
int OrderedNameDictionary::NumberOfEnumerableProperties() {
ReadOnlyRoots roots = this->GetReadOnlyRoots();
int result = 0;
for (InternalIndex i : this->IterateEntries()) {
Object k;
if (!this->ToKey(roots, i, &k)) continue;
if (k.FilterKey(ENUMERABLE_STRINGS)) continue;
PropertyDetails details = this->DetailsAt(i);
PropertyAttributes attr = details.attributes();
if ((attr & ONLY_ENUMERABLE) == 0) result++;
}
return result;
}
template <typename LocalIsolate> template <typename LocalIsolate>
MaybeHandle<OrderedNameDictionary> OrderedNameDictionary::Add( MaybeHandle<OrderedNameDictionary> OrderedNameDictionary::Add(
LocalIsolate* isolate, Handle<OrderedNameDictionary> table, LocalIsolate* isolate, Handle<OrderedNameDictionary> table,
......
...@@ -92,8 +92,6 @@ class OrderedHashTable : public FixedArray { ...@@ -92,8 +92,6 @@ class OrderedHashTable : public FixedArray {
InternalIndex FindEntry(Isolate* isolate, Object key); InternalIndex FindEntry(Isolate* isolate, Object key);
Object SlowReverseLookup(Isolate* isolate, Object value);
int NumberOfElements() const { int NumberOfElements() const {
return Smi::ToInt(get(NumberOfElementsIndex())); return Smi::ToInt(get(NumberOfElementsIndex()));
} }
...@@ -784,10 +782,6 @@ class V8_EXPORT_PRIVATE OrderedNameDictionary ...@@ -784,10 +782,6 @@ class V8_EXPORT_PRIVATE OrderedNameDictionary
return FindEntry(isolate, *key); return FindEntry(isolate, *key);
} }
int NumberOfEnumerableProperties();
Object SlowReverseLookup(Isolate* isolate, Object value);
static Handle<OrderedNameDictionary> DeleteEntry( static Handle<OrderedNameDictionary> DeleteEntry(
Isolate* isolate, Handle<OrderedNameDictionary> table, Isolate* isolate, Handle<OrderedNameDictionary> table,
InternalIndex entry); InternalIndex entry);
......
...@@ -107,8 +107,13 @@ bool SwissNameDictionary::EqualsForTesting(SwissNameDictionary other) { ...@@ -107,8 +107,13 @@ bool SwissNameDictionary::EqualsForTesting(SwissNameDictionary other) {
} }
// static // static
Handle<SwissNameDictionary> SwissNameDictionary::CopyForTesting( Handle<SwissNameDictionary> SwissNameDictionary::ShallowCopy(
Isolate* isolate, Handle<SwissNameDictionary> table) { Isolate* isolate, Handle<SwissNameDictionary> table) {
// TODO(v8:11388) Consider doing some cleanup during copying: For example, we
// could turn kDeleted into kEmpty in certain situations. But this would
// require tidying up the enumeration table in a similar fashion as would be
// required when trying to re-use deleted entries.
if (table->Capacity() == 0) { if (table->Capacity() == 0) {
return table; return table;
} }
...@@ -242,6 +247,37 @@ void SwissNameDictionary::Rehash(Isolate* isolate) { ...@@ -242,6 +247,37 @@ void SwissNameDictionary::Rehash(Isolate* isolate) {
} }
} }
// TODO(emrich,v8:11388): This is almost an identical copy of
// HashTable<..>::NumberOfEnumerableProperties. Consolidate both versions
// elsewhere (e.g., hash-table-utils)?
int SwissNameDictionary::NumberOfEnumerableProperties() {
ReadOnlyRoots roots = this->GetReadOnlyRoots();
int result = 0;
for (InternalIndex i : this->IterateEntries()) {
Object k;
if (!this->ToKey(roots, i, &k)) continue;
if (k.FilterKey(ENUMERABLE_STRINGS)) continue;
PropertyDetails details = this->DetailsAt(i);
PropertyAttributes attr = details.attributes();
if ((attr & ONLY_ENUMERABLE) == 0) result++;
}
return result;
}
// TODO(emrich, v8:11388): This is almost an identical copy of
// Dictionary<..>::SlowReverseLookup. Consolidate both versions elsewhere (e.g.,
// hash-table-utils)?
Object SwissNameDictionary::SlowReverseLookup(Isolate* isolate, Object value) {
ReadOnlyRoots roots(isolate);
for (InternalIndex i : IterateEntries()) {
Object k;
if (!ToKey(roots, i, &k)) continue;
Object e = this->ValueAt(i);
if (e == value) return k;
}
return roots.undefined_value();
}
// The largest value we ever have to store in the enumeration table is // The largest value we ever have to store in the enumeration table is
// Capacity() - 1. The largest value we ever have to store for the present or // Capacity() - 1. The largest value we ever have to store for the present or
// deleted element count is MaxUsableCapacity(Capacity()). All data in the // deleted element count is MaxUsableCapacity(Capacity()). All data in the
......
...@@ -112,18 +112,17 @@ class V8_EXPORT_PRIVATE SwissNameDictionary : public HeapObject { ...@@ -112,18 +112,17 @@ class V8_EXPORT_PRIVATE SwissNameDictionary : public HeapObject {
inline int Capacity(); inline int Capacity();
inline int UsedCapacity(); inline int UsedCapacity();
int NumberOfEnumerableProperties();
static Handle<SwissNameDictionary> ShallowCopy(
Isolate* isolate, Handle<SwissNameDictionary> table);
// Strict in the sense that it checks that all used/initialized memory in // Strict in the sense that it checks that all used/initialized memory in
// |this| and |other| is the same. The only exceptions are the meta table // |this| and |other| is the same. The only exceptions are the meta table
// pointer (which must differ between the two tables) and PropertyDetails of // pointer (which must differ between the two tables) and PropertyDetails of
// deleted entries (which reside in initialized memory, but are not compared). // deleted entries (which reside in initialized memory, but are not compared).
bool EqualsForTesting(SwissNameDictionary other); bool EqualsForTesting(SwissNameDictionary other);
// Copy operation for testing purposes. Guarantees that DebugEquals holds for
// the old table and its copy. In particular, no kind of tidying up is
// performed.
static Handle<SwissNameDictionary> CopyForTesting(
Isolate* isolate, Handle<SwissNameDictionary> table);
template <typename LocalIsolate> template <typename LocalIsolate>
void Initialize(LocalIsolate* isolate, ByteArray meta_table, int capacity); void Initialize(LocalIsolate* isolate, ByteArray meta_table, int capacity);
...@@ -136,6 +135,8 @@ class V8_EXPORT_PRIVATE SwissNameDictionary : public HeapObject { ...@@ -136,6 +135,8 @@ class V8_EXPORT_PRIVATE SwissNameDictionary : public HeapObject {
inline void SetHash(int hash); inline void SetHash(int hash);
inline int Hash(); inline int Hash();
Object SlowReverseLookup(Isolate* isolate, Object value);
class IndexIterator { class IndexIterator {
public: public:
inline IndexIterator(Handle<SwissNameDictionary> dict, int start); inline IndexIterator(Handle<SwissNameDictionary> dict, int start);
......
...@@ -1371,7 +1371,7 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject js_obj, ...@@ -1371,7 +1371,7 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject js_obj,
SetDataOrAccessorPropertyReference(details.kind(), entry, name, value); SetDataOrAccessorPropertyReference(details.kind(), entry, name, value);
} }
} else if (V8_DICT_MODE_PROTOTYPES_BOOL) { } else if (V8_DICT_MODE_PROTOTYPES_BOOL) {
OrderedNameDictionary dictionary = js_obj.property_dictionary_ordered(); SwissNameDictionary dictionary = js_obj.property_dictionary_swiss();
ReadOnlyRoots roots(isolate); ReadOnlyRoots roots(isolate);
for (InternalIndex i : dictionary.IterateEntries()) { for (InternalIndex i : dictionary.IterateEntries()) {
Object k = dictionary.KeyAt(i); Object k = dictionary.KeyAt(i);
......
...@@ -117,7 +117,7 @@ namespace { ...@@ -117,7 +117,7 @@ namespace {
template <typename Dictionary> template <typename Dictionary>
Handle<Name> KeyToName(Isolate* isolate, Handle<Object> key) { Handle<Name> KeyToName(Isolate* isolate, Handle<Object> key) {
STATIC_ASSERT((std::is_same<Dictionary, OrderedNameDictionary>::value || STATIC_ASSERT((std::is_same<Dictionary, SwissNameDictionary>::value ||
std::is_same<Dictionary, NameDictionary>::value)); std::is_same<Dictionary, NameDictionary>::value));
DCHECK(key->IsName()); DCHECK(key->IsName());
return Handle<Name>::cast(key); return Handle<Name>::cast(key);
...@@ -190,8 +190,7 @@ Handle<Dictionary> ShallowCopyDictionaryTemplate( ...@@ -190,8 +190,7 @@ Handle<Dictionary> ShallowCopyDictionaryTemplate(
Isolate* isolate, Handle<Dictionary> dictionary_template) { Isolate* isolate, Handle<Dictionary> dictionary_template) {
Handle<Map> dictionary_map(dictionary_template->map(), isolate); Handle<Map> dictionary_map(dictionary_template->map(), isolate);
Handle<Dictionary> dictionary = Handle<Dictionary> dictionary =
Handle<Dictionary>::cast(isolate->factory()->CopyFixedArrayWithMap( Dictionary::ShallowCopy(isolate, dictionary_template);
dictionary_template, dictionary_map));
// Clone all AccessorPairs in the dictionary. // Clone all AccessorPairs in the dictionary.
for (InternalIndex i : dictionary->IterateEntries()) { for (InternalIndex i : dictionary->IterateEntries()) {
Object value = dictionary->ValueAt(i); Object value = dictionary->ValueAt(i);
...@@ -530,8 +529,8 @@ bool InitClassPrototype(Isolate* isolate, ...@@ -530,8 +529,8 @@ bool InitClassPrototype(Isolate* isolate,
const bool install_name_accessor = false; const bool install_name_accessor = false;
if (V8_DICT_MODE_PROTOTYPES_BOOL) { if (V8_DICT_MODE_PROTOTYPES_BOOL) {
Handle<OrderedNameDictionary> properties_dictionary_template = Handle<SwissNameDictionary> properties_dictionary_template =
Handle<OrderedNameDictionary>::cast(properties_template); Handle<SwissNameDictionary>::cast(properties_template);
return AddDescriptorsByTemplate( return AddDescriptorsByTemplate(
isolate, map, properties_dictionary_template, isolate, map, properties_dictionary_template,
elements_dictionary_template, computed_properties, prototype, elements_dictionary_template, computed_properties, prototype,
...@@ -591,8 +590,8 @@ bool InitClassConstructor( ...@@ -591,8 +590,8 @@ bool InitClassConstructor(
const bool install_name_accessor = true; const bool install_name_accessor = true;
if (V8_DICT_MODE_PROTOTYPES_BOOL) { if (V8_DICT_MODE_PROTOTYPES_BOOL) {
Handle<OrderedNameDictionary> properties_dictionary_template = Handle<SwissNameDictionary> properties_dictionary_template =
Handle<OrderedNameDictionary>::cast(properties_template); Handle<SwissNameDictionary>::cast(properties_template);
return AddDescriptorsByTemplate( return AddDescriptorsByTemplate(
isolate, map, properties_dictionary_template, isolate, map, properties_dictionary_template,
......
...@@ -134,8 +134,8 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk( ...@@ -134,8 +134,8 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
} }
} else { } else {
if (V8_DICT_MODE_PROTOTYPES_BOOL) { if (V8_DICT_MODE_PROTOTYPES_BOOL) {
Handle<OrderedNameDictionary> dict( Handle<SwissNameDictionary> dict(
copy->property_dictionary_ordered(isolate), isolate); copy->property_dictionary_swiss(isolate), isolate);
for (InternalIndex i : dict->IterateEntries()) { for (InternalIndex i : dict->IterateEntries()) {
Object raw = dict->ValueAt(i); Object raw = dict->ValueAt(i);
if (!raw.IsJSObject(isolate)) continue; if (!raw.IsJSObject(isolate)) continue;
......
...@@ -402,11 +402,10 @@ RUNTIME_FUNCTION(Runtime_AddDictionaryProperty) { ...@@ -402,11 +402,10 @@ RUNTIME_FUNCTION(Runtime_AddDictionaryProperty) {
PropertyDetails property_details( PropertyDetails property_details(
kData, NONE, PropertyDetails::kConstIfDictConstnessTracking); kData, NONE, PropertyDetails::kConstIfDictConstnessTracking);
if (V8_DICT_MODE_PROTOTYPES_BOOL) { if (V8_DICT_MODE_PROTOTYPES_BOOL) {
Handle<OrderedNameDictionary> dictionary( Handle<SwissNameDictionary> dictionary(
receiver->property_dictionary_ordered(), isolate); receiver->property_dictionary_swiss(), isolate);
dictionary = OrderedNameDictionary::Add(isolate, dictionary, name, value, dictionary = SwissNameDictionary::Add(isolate, dictionary, name, value,
property_details) property_details);
.ToHandleChecked();
receiver->SetProperties(*dictionary); receiver->SetProperties(*dictionary);
} else { } else {
Handle<NameDictionary> dictionary(receiver->property_dictionary(), isolate); Handle<NameDictionary> dictionary(receiver->property_dictionary(), isolate);
...@@ -682,8 +681,7 @@ RUNTIME_FUNCTION(Runtime_GetProperty) { ...@@ -682,8 +681,7 @@ RUNTIME_FUNCTION(Runtime_GetProperty) {
} else if (!holder->HasFastProperties()) { } else if (!holder->HasFastProperties()) {
// Attempt dictionary lookup. // Attempt dictionary lookup.
if (V8_DICT_MODE_PROTOTYPES_BOOL) { if (V8_DICT_MODE_PROTOTYPES_BOOL) {
OrderedNameDictionary dictionary = SwissNameDictionary dictionary = holder->property_dictionary_swiss();
holder->property_dictionary_ordered();
InternalIndex entry = dictionary.FindEntry(isolate, *key); InternalIndex entry = dictionary.FindEntry(isolate, *key);
if (entry.is_found() && if (entry.is_found() &&
(dictionary.DetailsAt(entry).kind() == kData)) { (dictionary.DetailsAt(entry).kind() == kData)) {
...@@ -816,10 +814,10 @@ RUNTIME_FUNCTION(Runtime_ShrinkPropertyDictionary) { ...@@ -816,10 +814,10 @@ RUNTIME_FUNCTION(Runtime_ShrinkPropertyDictionary) {
DCHECK_EQ(1, args.length()); DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
if (V8_DICT_MODE_PROTOTYPES_BOOL) { if (V8_DICT_MODE_PROTOTYPES_BOOL) {
Handle<OrderedNameDictionary> dictionary( Handle<SwissNameDictionary> dictionary(
receiver->property_dictionary_ordered(), isolate); receiver->property_dictionary_swiss(), isolate);
Handle<OrderedNameDictionary> new_properties = Handle<SwissNameDictionary> new_properties =
OrderedNameDictionary::Shrink(isolate, dictionary); SwissNameDictionary::Shrink(isolate, dictionary);
receiver->SetProperties(*new_properties); receiver->SetProperties(*new_properties);
} else { } else {
Handle<NameDictionary> dictionary(receiver->property_dictionary(), isolate); Handle<NameDictionary> dictionary(receiver->property_dictionary(), isolate);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment