[runtime] Remove kIsEnumerable and move methods relying on it to BaseNameDictionary
Bug: Change-Id: Iab8fc855808b22a2786476ddc4568f3f474c73d8 Reviewed-on: https://chromium-review.googlesource.com/543079 Commit-Queue: Toon Verwaest <verwaest@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#46125}
This commit is contained in:
parent
626b5af7e1
commit
4a635150f1
@ -570,7 +570,7 @@ MaybeHandle<JSObject> ApiNatives::InstantiateRemoteObject(
|
||||
void ApiNatives::AddDataProperty(Isolate* isolate, Handle<TemplateInfo> info,
|
||||
Handle<Name> name, Handle<Object> value,
|
||||
PropertyAttributes attributes) {
|
||||
PropertyDetails details(kData, attributes, 0, PropertyCellType::kNoCell);
|
||||
PropertyDetails details(kData, attributes, PropertyCellType::kNoCell);
|
||||
auto details_handle = handle(details.AsSmi(), isolate);
|
||||
Handle<Object> data[] = {name, details_handle, value};
|
||||
AddPropertyToPropertyList(isolate, info, arraysize(data), data);
|
||||
@ -582,7 +582,7 @@ void ApiNatives::AddDataProperty(Isolate* isolate, Handle<TemplateInfo> info,
|
||||
PropertyAttributes attributes) {
|
||||
auto value = handle(Smi::FromInt(intrinsic), isolate);
|
||||
auto intrinsic_marker = isolate->factory()->true_value();
|
||||
PropertyDetails details(kData, attributes, 0, PropertyCellType::kNoCell);
|
||||
PropertyDetails details(kData, attributes, PropertyCellType::kNoCell);
|
||||
auto details_handle = handle(details.AsSmi(), isolate);
|
||||
Handle<Object> data[] = {name, intrinsic_marker, details_handle, value};
|
||||
AddPropertyToPropertyList(isolate, info, arraysize(data), data);
|
||||
@ -595,7 +595,7 @@ void ApiNatives::AddAccessorProperty(Isolate* isolate,
|
||||
Handle<FunctionTemplateInfo> getter,
|
||||
Handle<FunctionTemplateInfo> setter,
|
||||
PropertyAttributes attributes) {
|
||||
PropertyDetails details(kAccessor, attributes, 0, PropertyCellType::kNoCell);
|
||||
PropertyDetails details(kAccessor, attributes, PropertyCellType::kNoCell);
|
||||
auto details_handle = handle(details.AsSmi(), isolate);
|
||||
Handle<Object> data[] = {name, details_handle, getter, setter};
|
||||
AddPropertyToPropertyList(isolate, info, arraysize(data), data);
|
||||
|
@ -5004,7 +5004,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
|
||||
DCHECK(!to->HasFastProperties());
|
||||
// Add to dictionary.
|
||||
Handle<Object> value(descs->GetValue(i), isolate());
|
||||
PropertyDetails d(kAccessor, details.attributes(), i + 1,
|
||||
PropertyDetails d(kAccessor, details.attributes(),
|
||||
PropertyCellType::kMutable);
|
||||
JSObject::SetNormalizedProperty(to, key, value, d);
|
||||
}
|
||||
|
@ -5147,11 +5147,11 @@ void CodeStubAssembler::InsertEntry<NameDictionary>(Node* dictionary,
|
||||
StoreValueByKeyIndex<NameDictionary>(dictionary, index, value);
|
||||
|
||||
// Prepare details of the new property.
|
||||
const int kInitialIndex = 0;
|
||||
PropertyDetails d(kData, NONE, kInitialIndex, PropertyCellType::kNoCell);
|
||||
PropertyDetails d(kData, NONE, PropertyCellType::kNoCell);
|
||||
enum_index =
|
||||
SmiShl(enum_index, PropertyDetails::DictionaryStorageField::kShift);
|
||||
STATIC_ASSERT(kInitialIndex == 0);
|
||||
// We OR over the actual index below, so we expect the initial value to be 0.
|
||||
DCHECK_EQ(0, d.dictionary_index());
|
||||
VARIABLE(var_details, MachineRepresentation::kTaggedSigned,
|
||||
SmiOr(SmiConstant(d.AsSmi()), enum_index));
|
||||
|
||||
@ -5197,21 +5197,17 @@ void CodeStubAssembler::Add(Node* dictionary, Node* key, Node* value,
|
||||
CSA_ASSERT(this, SmiAbove(capacity, new_nof));
|
||||
Node* half_of_free_elements = SmiShr(SmiSub(capacity, new_nof), 1);
|
||||
GotoIf(SmiAbove(deleted, half_of_free_elements), bailout);
|
||||
Node* enum_index = nullptr;
|
||||
if (Dictionary::kIsEnumerable) {
|
||||
enum_index = GetNextEnumerationIndex<Dictionary>(dictionary);
|
||||
Node* new_enum_index = SmiAdd(enum_index, SmiConstant(1));
|
||||
Node* max_enum_index =
|
||||
SmiConstant(PropertyDetails::DictionaryStorageField::kMax);
|
||||
GotoIf(SmiAbove(new_enum_index, max_enum_index), bailout);
|
||||
|
||||
// No more bailouts after this point.
|
||||
// Operations from here on can have side effects.
|
||||
Node* enum_index = GetNextEnumerationIndex<Dictionary>(dictionary);
|
||||
Node* new_enum_index = SmiAdd(enum_index, SmiConstant(1));
|
||||
Node* max_enum_index =
|
||||
SmiConstant(PropertyDetails::DictionaryStorageField::kMax);
|
||||
GotoIf(SmiAbove(new_enum_index, max_enum_index), bailout);
|
||||
|
||||
SetNextEnumerationIndex<Dictionary>(dictionary, new_enum_index);
|
||||
} else {
|
||||
USE(enum_index);
|
||||
}
|
||||
// No more bailouts after this point.
|
||||
// Operations from here on can have side effects.
|
||||
|
||||
SetNextEnumerationIndex<Dictionary>(dictionary, new_enum_index);
|
||||
SetNumberOfElements<Dictionary>(dictionary, new_nof);
|
||||
|
||||
VARIABLE(var_key_index, MachineType::PointerRepresentation());
|
||||
|
@ -1303,11 +1303,11 @@ class ElementsAccessorBase : public ElementsAccessor {
|
||||
|
||||
static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
|
||||
uint32_t entry) {
|
||||
return PropertyDetails(kData, NONE, 0, PropertyCellType::kNoCell);
|
||||
return PropertyDetails(kData, NONE, PropertyCellType::kNoCell);
|
||||
}
|
||||
|
||||
static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) {
|
||||
return PropertyDetails(kData, NONE, 0, PropertyCellType::kNoCell);
|
||||
return PropertyDetails(kData, NONE, PropertyCellType::kNoCell);
|
||||
}
|
||||
|
||||
PropertyDetails GetDetails(JSObject* holder, uint32_t entry) final {
|
||||
@ -1467,15 +1467,16 @@ class DictionaryElementsAccessor
|
||||
if (attributes != NONE) object->RequireSlowElements(dictionary);
|
||||
dictionary->ValueAtPut(entry, *value);
|
||||
PropertyDetails details = dictionary->DetailsAt(entry);
|
||||
details = PropertyDetails(kData, attributes, details.dictionary_index(),
|
||||
PropertyCellType::kNoCell);
|
||||
details = PropertyDetails(kData, attributes, PropertyCellType::kNoCell,
|
||||
details.dictionary_index());
|
||||
|
||||
dictionary->DetailsAtPut(entry, details);
|
||||
}
|
||||
|
||||
static void AddImpl(Handle<JSObject> object, uint32_t index,
|
||||
Handle<Object> value, PropertyAttributes attributes,
|
||||
uint32_t new_capacity) {
|
||||
PropertyDetails details(kData, attributes, 0, PropertyCellType::kNoCell);
|
||||
PropertyDetails details(kData, attributes, PropertyCellType::kNoCell);
|
||||
Handle<SeededNumberDictionary> dictionary =
|
||||
object->HasFastElements() || object->HasFastStringWrapperElements()
|
||||
? JSObject::NormalizeElements(object)
|
||||
@ -2790,12 +2791,12 @@ class TypedElementsAccessor
|
||||
}
|
||||
|
||||
static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) {
|
||||
return PropertyDetails(kData, DONT_DELETE, 0, PropertyCellType::kNoCell);
|
||||
return PropertyDetails(kData, DONT_DELETE, PropertyCellType::kNoCell);
|
||||
}
|
||||
|
||||
static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
|
||||
uint32_t entry) {
|
||||
return PropertyDetails(kData, DONT_DELETE, 0, PropertyCellType::kNoCell);
|
||||
return PropertyDetails(kData, DONT_DELETE, PropertyCellType::kNoCell);
|
||||
}
|
||||
|
||||
static bool HasElementImpl(Isolate* isolate, JSObject* holder, uint32_t index,
|
||||
@ -3519,7 +3520,7 @@ class SloppyArgumentsElementsAccessor
|
||||
SloppyArgumentsElements::cast(holder->elements());
|
||||
uint32_t length = elements->parameter_map_length();
|
||||
if (entry < length) {
|
||||
return PropertyDetails(kData, NONE, 0, PropertyCellType::kNoCell);
|
||||
return PropertyDetails(kData, NONE, PropertyCellType::kNoCell);
|
||||
}
|
||||
FixedArray* arguments = elements->arguments();
|
||||
return ArgumentsAccessor::GetDetailsImpl(arguments, entry - length);
|
||||
@ -3730,7 +3731,7 @@ class SlowSloppyArgumentsElementsAccessor
|
||||
old_arguments->IsSeededNumberDictionary()
|
||||
? Handle<SeededNumberDictionary>::cast(old_arguments)
|
||||
: JSObject::NormalizeElements(object);
|
||||
PropertyDetails details(kData, attributes, 0, PropertyCellType::kNoCell);
|
||||
PropertyDetails details(kData, attributes, PropertyCellType::kNoCell);
|
||||
Handle<SeededNumberDictionary> new_dictionary =
|
||||
SeededNumberDictionary::Add(dictionary, index, value, details);
|
||||
if (attributes != NONE) object->RequireSlowElements(*new_dictionary);
|
||||
@ -3762,7 +3763,7 @@ class SlowSloppyArgumentsElementsAccessor
|
||||
value = isolate->factory()->NewAliasedArgumentsEntry(context_entry);
|
||||
}
|
||||
|
||||
PropertyDetails details(kData, attributes, 0, PropertyCellType::kNoCell);
|
||||
PropertyDetails details(kData, attributes, PropertyCellType::kNoCell);
|
||||
Handle<SeededNumberDictionary> arguments(
|
||||
SeededNumberDictionary::cast(elements->arguments()), isolate);
|
||||
arguments = SeededNumberDictionary::Add(arguments, entry, value, details);
|
||||
@ -3964,7 +3965,7 @@ class StringWrapperElementsAccessor
|
||||
if (entry < length) {
|
||||
PropertyAttributes attributes =
|
||||
static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
|
||||
return PropertyDetails(kData, attributes, 0, PropertyCellType::kNoCell);
|
||||
return PropertyDetails(kData, attributes, PropertyCellType::kNoCell);
|
||||
}
|
||||
return BackingStoreAccessor::GetDetailsImpl(holder, entry - length);
|
||||
}
|
||||
|
@ -1845,7 +1845,7 @@ Handle<JSGlobalObject> Factory::NewJSGlobalObject(
|
||||
PropertyDetails details = descs->GetDetails(i);
|
||||
// Only accessors are expected.
|
||||
DCHECK_EQ(kAccessor, details.kind());
|
||||
PropertyDetails d(kAccessor, details.attributes(), i + 1,
|
||||
PropertyDetails d(kAccessor, details.attributes(),
|
||||
PropertyCellType::kMutable);
|
||||
Handle<Name> name(descs->GetKey(i));
|
||||
Handle<PropertyCell> cell = NewPropertyCell();
|
||||
|
@ -289,7 +289,7 @@ void LookupIterator::ReconfigureDataProperty(Handle<Object> value,
|
||||
}
|
||||
|
||||
if (!IsElement() && !holder->HasFastProperties()) {
|
||||
PropertyDetails details(kData, attributes, 0, PropertyCellType::kMutable);
|
||||
PropertyDetails details(kData, attributes, PropertyCellType::kMutable);
|
||||
if (holder->IsJSGlobalObject()) {
|
||||
Handle<GlobalDictionary> dictionary(holder->global_dictionary());
|
||||
|
||||
@ -357,8 +357,8 @@ void LookupIterator::PrepareTransitionToDataProperty(
|
||||
// SetNextEnumerationIndex.
|
||||
int index = dictionary->NextEnumerationIndex();
|
||||
dictionary->SetNextEnumerationIndex(index + 1);
|
||||
property_details_ = PropertyDetails(kData, attributes, index,
|
||||
PropertyCellType::kUninitialized);
|
||||
property_details_ = PropertyDetails(
|
||||
kData, attributes, PropertyCellType::kUninitialized, index);
|
||||
PropertyCellType new_type =
|
||||
PropertyCell::UpdatedType(cell, value, property_details_);
|
||||
property_details_ = property_details_.set_cell_type(new_type);
|
||||
@ -368,7 +368,7 @@ void LookupIterator::PrepareTransitionToDataProperty(
|
||||
} else {
|
||||
// Don't set enumeration index (it will be set during value store).
|
||||
property_details_ =
|
||||
PropertyDetails(kData, attributes, 0, PropertyCellType::kNoCell);
|
||||
PropertyDetails(kData, attributes, PropertyCellType::kNoCell);
|
||||
transition_ = map;
|
||||
}
|
||||
return;
|
||||
@ -382,7 +382,7 @@ void LookupIterator::PrepareTransitionToDataProperty(
|
||||
if (transition->is_dictionary_map()) {
|
||||
// Don't set enumeration index (it will be set during value store).
|
||||
property_details_ =
|
||||
PropertyDetails(kData, attributes, 0, PropertyCellType::kNoCell);
|
||||
PropertyDetails(kData, attributes, PropertyCellType::kNoCell);
|
||||
} else {
|
||||
property_details_ = transition->GetLastDescriptorDetails();
|
||||
has_property_ = true;
|
||||
@ -530,7 +530,7 @@ void LookupIterator::TransitionToAccessorPair(Handle<Object> pair,
|
||||
Handle<JSObject> receiver = GetStoreTarget();
|
||||
holder_ = receiver;
|
||||
|
||||
PropertyDetails details(kAccessor, attributes, 0, PropertyCellType::kMutable);
|
||||
PropertyDetails details(kAccessor, attributes, PropertyCellType::kMutable);
|
||||
|
||||
if (IsElement()) {
|
||||
// TODO(verwaest): Move code into the element accessor.
|
||||
|
114
src/objects.cc
114
src/objects.cc
@ -3735,7 +3735,7 @@ void MigrateFastToSlow(Handle<JSObject> object, Handle<Map> new_map,
|
||||
value = handle(descs->GetValue(i), isolate);
|
||||
}
|
||||
DCHECK(!value.is_null());
|
||||
PropertyDetails d(details.kind(), details.attributes(), i + 1,
|
||||
PropertyDetails d(details.kind(), details.attributes(),
|
||||
PropertyCellType::kNoCell);
|
||||
dictionary = NameDictionary::Add(dictionary, key, value, d);
|
||||
}
|
||||
@ -7014,7 +7014,7 @@ Maybe<bool> JSProxy::SetPrivateProperty(Isolate* isolate, Handle<JSProxy> proxy,
|
||||
}
|
||||
|
||||
Handle<NameDictionary> dict(proxy->property_dictionary());
|
||||
PropertyDetails details(kData, DONT_ENUM, 0, PropertyCellType::kNoCell);
|
||||
PropertyDetails details(kData, DONT_ENUM, PropertyCellType::kNoCell);
|
||||
Handle<NameDictionary> result =
|
||||
NameDictionary::Add(dict, private_name, value, details);
|
||||
if (!dict.is_identical_to(result)) proxy->set_properties(*result);
|
||||
@ -16170,11 +16170,6 @@ template class EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
|
||||
template class Dictionary<UnseededNumberDictionary,
|
||||
UnseededNumberDictionaryShape>;
|
||||
|
||||
template Handle<SeededNumberDictionary>
|
||||
Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape>::New(
|
||||
Isolate*, int at_least_space_for, PretenureFlag pretenure,
|
||||
MinimumCapacity capacity_option);
|
||||
|
||||
template Handle<SeededNumberDictionary>
|
||||
Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape>::NewEmpty(
|
||||
Isolate*, PretenureFlag pretenure);
|
||||
@ -16183,22 +16178,17 @@ template Handle<UnseededNumberDictionary>
|
||||
Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape>::NewEmpty(
|
||||
Isolate*, PretenureFlag pretenure);
|
||||
|
||||
template Handle<UnseededNumberDictionary>
|
||||
Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape>::New(
|
||||
Isolate*, int at_least_space_for, PretenureFlag pretenure,
|
||||
MinimumCapacity capacity_option);
|
||||
|
||||
template Handle<NameDictionary>
|
||||
Dictionary<NameDictionary, NameDictionaryShape>::New(
|
||||
Isolate*, int n, PretenureFlag pretenure, MinimumCapacity capacity_option);
|
||||
BaseNameDictionary<NameDictionary, NameDictionaryShape>::New(
|
||||
Isolate*, int n, MinimumCapacity capacity_option, PretenureFlag pretenure);
|
||||
|
||||
template Handle<NameDictionary>
|
||||
Dictionary<NameDictionary, NameDictionaryShape>::NewEmpty(
|
||||
Isolate*, PretenureFlag pretenure);
|
||||
|
||||
template Handle<GlobalDictionary>
|
||||
Dictionary<GlobalDictionary, GlobalDictionaryShape>::New(
|
||||
Isolate*, int n, PretenureFlag pretenure, MinimumCapacity capacity_option);
|
||||
BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>::New(
|
||||
Isolate*, int n, MinimumCapacity capacity_option, PretenureFlag pretenure);
|
||||
|
||||
template Handle<SeededNumberDictionary>
|
||||
Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape>::AtPut(
|
||||
@ -16229,6 +16219,10 @@ template Handle<UnseededNumberDictionary>
|
||||
Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape>::
|
||||
DeleteEntry(Handle<UnseededNumberDictionary>, int);
|
||||
|
||||
template Handle<UnseededNumberDictionary>
|
||||
HashTable<UnseededNumberDictionary, UnseededNumberDictionaryShape>::New(
|
||||
Isolate*, int, MinimumCapacity, PretenureFlag);
|
||||
|
||||
template Handle<NameDictionary>
|
||||
HashTable<NameDictionary, NameDictionaryShape>::New(Isolate*, int,
|
||||
MinimumCapacity,
|
||||
@ -16267,19 +16261,11 @@ Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape>::Add(
|
||||
Handle<UnseededNumberDictionary>, uint32_t, Handle<Object>, PropertyDetails,
|
||||
int*);
|
||||
|
||||
template Handle<SeededNumberDictionary>
|
||||
Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape>::EnsureCapacity(
|
||||
Handle<SeededNumberDictionary>, int);
|
||||
|
||||
template Handle<UnseededNumberDictionary>
|
||||
Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape>::
|
||||
EnsureCapacity(Handle<UnseededNumberDictionary>, int);
|
||||
|
||||
template void Dictionary<
|
||||
NameDictionary, NameDictionaryShape>::SetRequiresCopyOnCapacityChange();
|
||||
|
||||
template Handle<NameDictionary>
|
||||
Dictionary<NameDictionary, NameDictionaryShape>::EnsureCapacity(
|
||||
BaseNameDictionary<NameDictionary, NameDictionaryShape>::EnsureCapacity(
|
||||
Handle<NameDictionary>, int);
|
||||
|
||||
template int Dictionary<GlobalDictionary,
|
||||
@ -16756,12 +16742,12 @@ Handle<PropertyCell> JSGlobalObject::EnsureEmptyPropertyCell(
|
||||
if (original_cell_type == PropertyCellType::kInvalidated) {
|
||||
cell = PropertyCell::InvalidateEntry(dictionary, entry);
|
||||
}
|
||||
PropertyDetails details(kData, NONE, 0, cell_type);
|
||||
PropertyDetails details(kData, NONE, cell_type);
|
||||
cell->set_property_details(details);
|
||||
return cell;
|
||||
}
|
||||
cell = isolate->factory()->NewPropertyCell();
|
||||
PropertyDetails details(kData, NONE, 0, cell_type);
|
||||
PropertyDetails details(kData, NONE, cell_type);
|
||||
dictionary =
|
||||
GlobalDictionary::Add(dictionary, name, cell, details, entry_out);
|
||||
// {*entry_out} is initialized inside GlobalDictionary::Add().
|
||||
@ -17468,30 +17454,23 @@ void CompilationCacheTable::Remove(Object* value) {
|
||||
}
|
||||
|
||||
template <typename Derived, typename Shape>
|
||||
Handle<Derived> Dictionary<Derived, Shape>::New(
|
||||
Isolate* isolate, int at_least_space_for, PretenureFlag pretenure,
|
||||
MinimumCapacity capacity_option) {
|
||||
DCHECK(0 <= at_least_space_for);
|
||||
Handle<Derived> dict = DerivedHashTable::New(isolate, at_least_space_for,
|
||||
capacity_option, pretenure);
|
||||
|
||||
if (Shape::kIsEnumerable) {
|
||||
// Initialize the next enumeration index.
|
||||
dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
|
||||
}
|
||||
Handle<Derived> BaseNameDictionary<Derived, Shape>::New(
|
||||
Isolate* isolate, int at_least_space_for, MinimumCapacity capacity_option,
|
||||
PretenureFlag pretenure) {
|
||||
DCHECK_LE(0, at_least_space_for);
|
||||
Handle<Derived> dict = Dictionary<Derived, Shape>::New(
|
||||
isolate, at_least_space_for, capacity_option, pretenure);
|
||||
dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
|
||||
return dict;
|
||||
}
|
||||
|
||||
template <typename Derived, typename Shape>
|
||||
Handle<Derived> Dictionary<Derived, Shape>::NewEmpty(Isolate* isolate,
|
||||
PretenureFlag pretenure) {
|
||||
Handle<Derived> dict = DerivedHashTable::New(isolate, 1, pretenure);
|
||||
Handle<Derived> dict =
|
||||
Derived::New(isolate, 1, USE_CUSTOM_MINIMUM_CAPACITY, pretenure);
|
||||
// Attempt to add one element to the empty dictionary must cause reallocation.
|
||||
DCHECK(!dict->HasSufficientCapacityToAdd(1));
|
||||
if (Shape::kIsEnumerable) {
|
||||
// Initialize the next enumeration index.
|
||||
dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
|
||||
@ -17505,15 +17484,14 @@ void Dictionary<Derived, Shape>::SetRequiresCopyOnCapacityChange() {
|
||||
}
|
||||
|
||||
template <typename Derived, typename Shape>
|
||||
Handle<Derived> Dictionary<Derived, Shape>::EnsureCapacity(
|
||||
Handle<Derived> BaseNameDictionary<Derived, Shape>::EnsureCapacity(
|
||||
Handle<Derived> dictionary, int n) {
|
||||
// Check whether there are enough enumeration indices to add n elements.
|
||||
if (Shape::kIsEnumerable &&
|
||||
!PropertyDetails::IsValidIndex(dictionary->NextEnumerationIndex() + n)) {
|
||||
if (!PropertyDetails::IsValidIndex(dictionary->NextEnumerationIndex() + n)) {
|
||||
// If not, we generate new indices for the properties.
|
||||
int length = dictionary->NumberOfElements();
|
||||
|
||||
Handle<FixedArray> iteration_order = Derived::IterationIndices(dictionary);
|
||||
Handle<FixedArray> iteration_order = IterationIndices(dictionary);
|
||||
DCHECK_EQ(length, iteration_order->length());
|
||||
|
||||
// Iterate over the dictionary using the enumeration order and update
|
||||
@ -17534,7 +17512,7 @@ Handle<Derived> Dictionary<Derived, Shape>::EnsureCapacity(
|
||||
dictionary->SetNextEnumerationIndex(PropertyDetails::kInitialIndex +
|
||||
length);
|
||||
}
|
||||
return DerivedHashTable::EnsureCapacity(dictionary, n);
|
||||
return HashTable<Derived, Shape>::EnsureCapacity(dictionary, n);
|
||||
}
|
||||
|
||||
template <typename Derived, typename Shape>
|
||||
@ -17557,16 +17535,40 @@ Handle<Derived> Dictionary<Derived, Shape>::AtPut(Handle<Derived> dictionary,
|
||||
|
||||
// If the entry is present set the value;
|
||||
if (entry == Dictionary::kNotFound) {
|
||||
return Add(dictionary, key, value, details);
|
||||
return Derived::Add(dictionary, key, value, details);
|
||||
}
|
||||
|
||||
// We don't need to copy over the enumeration index.
|
||||
DCHECK(!Shape::kIsEnumerable);
|
||||
dictionary->ValueAtPut(entry, *value);
|
||||
if (Shape::kEntrySize == 3) dictionary->DetailsAtPut(entry, details);
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
template <typename Derived, typename Shape>
|
||||
Handle<Derived> BaseNameDictionary<Derived, Shape>::Add(
|
||||
Handle<Derived> dictionary, Key key, Handle<Object> value,
|
||||
PropertyDetails details, int* entry_out) {
|
||||
// Insert element at empty or deleted entry
|
||||
DCHECK_EQ(0, details.dictionary_index());
|
||||
// Assign an enumeration index to the property and update
|
||||
// SetNextEnumerationIndex.
|
||||
int index = dictionary->NextEnumerationIndex();
|
||||
details = details.set_index(index);
|
||||
dictionary->SetNextEnumerationIndex(index + 1);
|
||||
return Dictionary<Derived, Shape>::Add(dictionary, key, value, details,
|
||||
entry_out);
|
||||
}
|
||||
|
||||
template Handle<NameDictionary>
|
||||
BaseNameDictionary<NameDictionary, NameDictionaryShape>::Add(
|
||||
Handle<NameDictionary>, Handle<Name>, Handle<Object>, PropertyDetails,
|
||||
int*);
|
||||
|
||||
template Handle<GlobalDictionary>
|
||||
BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>::Add(
|
||||
Handle<GlobalDictionary>, Handle<Name>, Handle<Object>, PropertyDetails,
|
||||
int*);
|
||||
|
||||
template <typename Derived, typename Shape>
|
||||
Handle<Derived> Dictionary<Derived, Shape>::Add(Handle<Derived> dictionary,
|
||||
Key key, Handle<Object> value,
|
||||
@ -17577,20 +17579,12 @@ Handle<Derived> Dictionary<Derived, Shape>::Add(Handle<Derived> dictionary,
|
||||
// Valdate key is absent.
|
||||
SLOW_DCHECK((dictionary->FindEntry(key) == Dictionary::kNotFound));
|
||||
// Check whether the dictionary should be extended.
|
||||
dictionary = EnsureCapacity(dictionary, 1);
|
||||
dictionary = Derived::EnsureCapacity(dictionary, 1);
|
||||
|
||||
// Compute the key object.
|
||||
Handle<Object> k = Shape::AsHandle(isolate, key);
|
||||
|
||||
uint32_t entry = dictionary->FindInsertionEntry(hash);
|
||||
// Insert element at empty or deleted entry
|
||||
if (details.dictionary_index() == 0 && Shape::kIsEnumerable) {
|
||||
// Assign an enumeration index to the property and update
|
||||
// SetNextEnumerationIndex.
|
||||
int index = dictionary->NextEnumerationIndex();
|
||||
details = details.set_index(index);
|
||||
dictionary->SetNextEnumerationIndex(index + 1);
|
||||
}
|
||||
dictionary->SetEntry(entry, k, value, details);
|
||||
DCHECK(dictionary->KeyAt(entry)->IsNumber() ||
|
||||
dictionary->KeyAt(entry)->IsUniqueName());
|
||||
@ -19249,7 +19243,7 @@ Handle<PropertyCell> PropertyCell::PrepareForValue(
|
||||
index = dictionary->NextEnumerationIndex();
|
||||
dictionary->SetNextEnumerationIndex(index + 1);
|
||||
}
|
||||
DCHECK(index > 0);
|
||||
DCHECK_LT(0, index);
|
||||
details = details.set_index(index);
|
||||
|
||||
PropertyCellType new_type = UpdatedType(cell, value, original_details);
|
||||
|
@ -62,20 +62,8 @@ class Dictionary : public HashTable<Derived, Shape> {
|
||||
return DerivedHashTable::Shrink(dictionary);
|
||||
}
|
||||
|
||||
int NextEnumerationIndex() { UNREACHABLE(); }
|
||||
void SetNextEnumerationIndex(int index) { UNREACHABLE(); }
|
||||
static Handle<FixedArray> IterationIndices(Handle<Derived> dictionary) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
int NumberOfEnumerableProperties();
|
||||
|
||||
// Creates a new dictionary.
|
||||
MUST_USE_RESULT static Handle<Derived> New(
|
||||
Isolate* isolate, int at_least_space_for,
|
||||
PretenureFlag pretenure = NOT_TENURED,
|
||||
MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY);
|
||||
|
||||
// Creates an dictionary with minimal possible capacity.
|
||||
MUST_USE_RESULT static Handle<Derived> NewEmpty(
|
||||
Isolate* isolate, PretenureFlag pretenure = NOT_TENURED);
|
||||
@ -83,9 +71,6 @@ class Dictionary : public HashTable<Derived, Shape> {
|
||||
// Ensures that a new dictionary is created when the capacity is checked.
|
||||
void SetRequiresCopyOnCapacityChange();
|
||||
|
||||
// Ensure enough space for n additional elements.
|
||||
static Handle<Derived> EnsureCapacity(Handle<Derived> obj, int n);
|
||||
|
||||
#ifdef OBJECT_PRINT
|
||||
// For our gdb macros, we should perhaps change these in the future.
|
||||
void Print();
|
||||
@ -105,8 +90,6 @@ class Dictionary : public HashTable<Derived, Shape> {
|
||||
PropertyDetails details,
|
||||
int* entry_out = nullptr);
|
||||
|
||||
static const bool kIsEnumerable = Shape::kIsEnumerable;
|
||||
|
||||
protected:
|
||||
// Generic at put operation.
|
||||
MUST_USE_RESULT static Handle<Derived> AtPut(Handle<Derived> dictionary,
|
||||
@ -153,12 +136,13 @@ class NameDictionaryShape : public BaseDictionaryShape<Handle<Name>> {
|
||||
static const int kEntrySize = 3;
|
||||
static const int kEntryValueIndex = 1;
|
||||
static const int kEntryDetailsIndex = 2;
|
||||
static const bool kIsEnumerable = true;
|
||||
static const bool kNeedsHoleCheck = false;
|
||||
};
|
||||
|
||||
template <typename Derived, typename Shape>
|
||||
class BaseNameDictionary : public Dictionary<Derived, Shape> {
|
||||
typedef typename Shape::Key Key;
|
||||
|
||||
public:
|
||||
static const int kNextEnumerationIndexIndex =
|
||||
HashTableBase::kPrefixStartIndex;
|
||||
@ -174,6 +158,12 @@ class BaseNameDictionary : public Dictionary<Derived, Shape> {
|
||||
return Smi::cast(this->get(kNextEnumerationIndexIndex))->value();
|
||||
}
|
||||
|
||||
// Creates a new dictionary.
|
||||
MUST_USE_RESULT static Handle<Derived> New(
|
||||
Isolate* isolate, int at_least_space_for,
|
||||
MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY,
|
||||
PretenureFlag pretenure = NOT_TENURED);
|
||||
|
||||
// Collect the keys into the given KeyAccumulator, in ascending chronological
|
||||
// order of property creation.
|
||||
static void CollectKeysTo(Handle<Derived> dictionary, KeyAccumulator* keys);
|
||||
@ -185,6 +175,14 @@ class BaseNameDictionary : public Dictionary<Derived, Shape> {
|
||||
static void CopyEnumKeysTo(Handle<Derived> dictionary,
|
||||
Handle<FixedArray> storage, KeyCollectionMode mode,
|
||||
KeyAccumulator* accumulator);
|
||||
|
||||
// Ensure enough space for n additional elements.
|
||||
static Handle<Derived> EnsureCapacity(Handle<Derived> dictionary, int n);
|
||||
|
||||
MUST_USE_RESULT static Handle<Derived> Add(Handle<Derived> dictionary,
|
||||
Key key, Handle<Object> value,
|
||||
PropertyDetails details,
|
||||
int* entry_out = nullptr);
|
||||
};
|
||||
|
||||
class NameDictionary
|
||||
@ -227,7 +225,6 @@ 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);
|
||||
static const bool kIsEnumerable = false;
|
||||
};
|
||||
|
||||
class SeededNumberDictionaryShape : public NumberDictionaryShape {
|
||||
|
@ -194,6 +194,10 @@ class HashTable : public HashTableBase {
|
||||
return (entry * kEntrySize) + kElementsStartIndex;
|
||||
}
|
||||
|
||||
// Ensure enough space for n additional elements.
|
||||
MUST_USE_RESULT static Handle<Derived> EnsureCapacity(
|
||||
Handle<Derived> table, int n, PretenureFlag pretenure = NOT_TENURED);
|
||||
|
||||
protected:
|
||||
friend class ObjectHashTable;
|
||||
|
||||
@ -207,10 +211,6 @@ class HashTable : public HashTableBase {
|
||||
// Attempt to shrink hash table after removal of key.
|
||||
MUST_USE_RESULT static Handle<Derived> Shrink(Handle<Derived> table);
|
||||
|
||||
// Ensure enough space for n additional elements.
|
||||
MUST_USE_RESULT static Handle<Derived> EnsureCapacity(
|
||||
Handle<Derived> table, int n, PretenureFlag pretenure = NOT_TENURED);
|
||||
|
||||
// Returns true if this table has sufficient capacity for adding n elements.
|
||||
bool HasSufficientCapacityToAdd(int number_of_additional_elements);
|
||||
|
||||
|
@ -231,11 +231,11 @@ enum class PropertyCellConstantType {
|
||||
class PropertyDetails BASE_EMBEDDED {
|
||||
public:
|
||||
// Property details for dictionary mode properties/elements.
|
||||
PropertyDetails(PropertyKind kind, PropertyAttributes attributes, int index,
|
||||
PropertyCellType cell_type) {
|
||||
PropertyDetails(PropertyKind kind, PropertyAttributes attributes,
|
||||
PropertyCellType cell_type, int dictionary_index = 0) {
|
||||
value_ = KindField::encode(kind) | LocationField::encode(kField) |
|
||||
AttributesField::encode(attributes) |
|
||||
DictionaryStorageField::encode(index) |
|
||||
DictionaryStorageField::encode(dictionary_index) |
|
||||
PropertyCellTypeField::encode(cell_type);
|
||||
}
|
||||
|
||||
@ -252,7 +252,7 @@ class PropertyDetails BASE_EMBEDDED {
|
||||
|
||||
static PropertyDetails Empty(
|
||||
PropertyCellType cell_type = PropertyCellType::kNoCell) {
|
||||
return PropertyDetails(kData, NONE, 0, cell_type);
|
||||
return PropertyDetails(kData, NONE, cell_type);
|
||||
}
|
||||
|
||||
int pointer() const { return DescriptorPointer::decode(value_); }
|
||||
|
@ -306,10 +306,8 @@ RUNTIME_FUNCTION(Runtime_AddDictionaryProperty) {
|
||||
DCHECK(name->IsUniqueName());
|
||||
|
||||
Handle<NameDictionary> dictionary(receiver->property_dictionary(), isolate);
|
||||
int entry;
|
||||
PropertyDetails property_details(kData, NONE, 0, PropertyCellType::kNoCell);
|
||||
dictionary =
|
||||
NameDictionary::Add(dictionary, name, value, property_details, &entry);
|
||||
PropertyDetails property_details(kData, NONE, PropertyCellType::kNoCell);
|
||||
dictionary = NameDictionary::Add(dictionary, name, value, property_details);
|
||||
receiver->set_properties(*dictionary);
|
||||
return *value;
|
||||
}
|
||||
|
@ -302,7 +302,8 @@ TEST(SetRequiresCopyOnCapacityChange) {
|
||||
LocalContext context;
|
||||
v8::HandleScope scope(context->GetIsolate());
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
Handle<NameDictionary> dict = NameDictionary::New(isolate, 0, TENURED);
|
||||
Handle<NameDictionary> dict =
|
||||
NameDictionary::New(isolate, 0, USE_DEFAULT_MINIMUM_CAPACITY, TENURED);
|
||||
dict->SetRequiresCopyOnCapacityChange();
|
||||
Handle<Name> key = isolate->factory()->InternalizeString(
|
||||
v8::Utils::OpenHandle(*v8_str("key")));
|
||||
|
Loading…
Reference in New Issue
Block a user