Update Dictionary classes to use InternalIndex

for "entries", i.e. indices into the backing store (as opposed to
"public indices" going into the hash function).
This improves consistency and compiler-enforced type safety; no change
in behavior is intended.

Change-Id: I25e57e3ddcf18a406e2dfbd66786b6980c4e9615
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1852768
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64317}
This commit is contained in:
Jakob Kummerow 2019-10-16 14:24:54 +02:00 committed by Commit Bot
parent 38301e7bb9
commit 0b9f10532a
44 changed files with 398 additions and 413 deletions

View File

@ -300,8 +300,8 @@ MaybeHandle<JSObject> ProbeInstantiationsCache(
(serial_number <= TemplateInfo::kSlowTemplateInstantiationsCacheSize)) { (serial_number <= TemplateInfo::kSlowTemplateInstantiationsCacheSize)) {
SimpleNumberDictionary slow_cache = SimpleNumberDictionary slow_cache =
native_context->slow_template_instantiations_cache(); native_context->slow_template_instantiations_cache();
int entry = slow_cache.FindEntry(isolate, serial_number); InternalIndex entry = slow_cache.FindEntry(isolate, serial_number);
if (entry != SimpleNumberDictionary::kNotFound) { if (entry.is_found()) {
return handle(JSObject::cast(slow_cache.ValueAt(entry)), isolate); return handle(JSObject::cast(slow_cache.ValueAt(entry)), isolate);
} }
} }
@ -348,8 +348,8 @@ void UncacheTemplateInstantiation(Isolate* isolate,
TemplateInfo::kSlowTemplateInstantiationsCacheSize)) { TemplateInfo::kSlowTemplateInstantiationsCacheSize)) {
Handle<SimpleNumberDictionary> cache = Handle<SimpleNumberDictionary> cache =
handle(native_context->slow_template_instantiations_cache(), isolate); handle(native_context->slow_template_instantiations_cache(), isolate);
int entry = cache->FindEntry(isolate, serial_number); InternalIndex entry = cache->FindEntry(isolate, serial_number);
DCHECK_NE(SimpleNumberDictionary::kNotFound, entry); DCHECK(entry.is_found());
cache = SimpleNumberDictionary::DeleteEntry(isolate, cache, entry); cache = SimpleNumberDictionary::DeleteEntry(isolate, cache, entry);
native_context->set_slow_template_instantiations_cache(*cache); native_context->set_slow_template_instantiations_cache(*cache);
} }

View File

@ -6442,8 +6442,8 @@ Local<v8::Object> v8::Object::New(Isolate* isolate,
} else { } else {
// Internalize the {name} first. // Internalize the {name} first.
name = i_isolate->factory()->InternalizeName(name); name = i_isolate->factory()->InternalizeName(name);
int const entry = properties->FindEntry(i_isolate, name); i::InternalIndex const entry = properties->FindEntry(i_isolate, name);
if (entry == i::NameDictionary::kNotFound) { if (entry.is_not_found()) {
// Add the {name}/{value} pair as a new entry. // Add the {name}/{value} pair as a new entry.
properties = i::NameDictionary::Add(i_isolate, properties, name, value, properties = i::NameDictionary::Add(i_isolate, properties, name, value,
i::PropertyDetails::Empty()); i::PropertyDetails::Empty());

View File

@ -853,9 +853,8 @@ uint32_t EstimateElementCount(Isolate* isolate, Handle<JSArray> array) {
} }
case DICTIONARY_ELEMENTS: { case DICTIONARY_ELEMENTS: {
NumberDictionary dictionary = NumberDictionary::cast(array->elements()); NumberDictionary dictionary = NumberDictionary::cast(array->elements());
int capacity = dictionary.Capacity();
ReadOnlyRoots roots(isolate); ReadOnlyRoots roots(isolate);
for (int i = 0; i < capacity; i++) { for (InternalIndex i : dictionary.IterateEntries()) {
Object key = dictionary.KeyAt(i); Object key = dictionary.KeyAt(i);
if (dictionary.IsKey(roots, key)) { if (dictionary.IsKey(roots, key)) {
element_count++; element_count++;
@ -930,7 +929,7 @@ void CollectElementIndices(Isolate* isolate, Handle<JSObject> object,
uint32_t capacity = dict.Capacity(); uint32_t capacity = dict.Capacity();
ReadOnlyRoots roots(isolate); ReadOnlyRoots roots(isolate);
FOR_WITH_HANDLE_SCOPE(isolate, uint32_t, j = 0, j, j < capacity, j++, { FOR_WITH_HANDLE_SCOPE(isolate, uint32_t, j = 0, j, j < capacity, j++, {
Object k = dict.KeyAt(j); Object k = dict.KeyAt(InternalIndex(j));
if (!dict.IsKey(roots, k)) continue; if (!dict.IsKey(roots, k)) continue;
DCHECK(k.IsNumber()); DCHECK(k.IsNumber());
uint32_t index = static_cast<uint32_t>(k.Number()); uint32_t index = static_cast<uint32_t>(k.Number());

View File

@ -1350,7 +1350,7 @@ Reduction JSCreateLowering::ReduceJSCreateObject(Node* node) {
int capacity = int capacity =
NameDictionary::ComputeCapacity(NameDictionary::kInitialCapacity); NameDictionary::ComputeCapacity(NameDictionary::kInitialCapacity);
DCHECK(base::bits::IsPowerOfTwo(capacity)); DCHECK(base::bits::IsPowerOfTwo(capacity));
int length = NameDictionary::EntryToIndex(capacity); int length = NameDictionary::EntryToIndex(InternalIndex(capacity));
int size = NameDictionary::SizeFor(length); int size = NameDictionary::SizeFor(length);
AllocationBuilder a(jsgraph(), effect, control); AllocationBuilder a(jsgraph(), effect, control);

View File

@ -1986,8 +1986,7 @@ void MapData::SerializeOwnDescriptors(JSHeapBroker* broker) {
TraceScope tracer(broker, this, "MapData::SerializeOwnDescriptors"); TraceScope tracer(broker, this, "MapData::SerializeOwnDescriptors");
Handle<Map> map = Handle<Map>::cast(object()); Handle<Map> map = Handle<Map>::cast(object());
int const number_of_own = map->NumberOfOwnDescriptors(); for (InternalIndex i : map->IterateOwnDescriptors()) {
for (InternalIndex i : InternalIndex::Range(number_of_own)) {
SerializeOwnDescriptor(broker, i); SerializeOwnDescriptor(broker, i);
} }
} }

View File

@ -477,8 +477,7 @@ bool JSObject::PrintProperties(std::ostream& os) { // NOLINT
if (HasFastProperties()) { if (HasFastProperties()) {
DescriptorArray descs = map().instance_descriptors(); DescriptorArray descs = map().instance_descriptors();
int nof_inobject_properties = map().GetInObjectProperties(); int nof_inobject_properties = map().GetInObjectProperties();
for (InternalIndex i : for (InternalIndex i : map().IterateOwnDescriptors()) {
InternalIndex::Range(map().NumberOfOwnDescriptors())) {
os << "\n "; os << "\n ";
descs.GetKey(i).NamePrint(os); descs.GetKey(i).NamePrint(os);
os << ": "; os << ": ";
@ -926,9 +925,9 @@ void PrintHashTableWithHeader(std::ostream& os, T table, const char* type) {
os << "\n - capacity: " << table.Capacity(); os << "\n - capacity: " << table.Capacity();
os << "\n - elements: {"; os << "\n - elements: {";
for (int i = 0; i < table.Capacity(); i++) { for (InternalIndex i : table.IterateEntries()) {
os << '\n' os << '\n'
<< std::setw(12) << i << ": " << Brief(table.KeyAt(i)) << " -> " << std::setw(12) << i.as_int() << ": " << Brief(table.KeyAt(i)) << " -> "
<< Brief(table.ValueAt(i)); << Brief(table.ValueAt(i));
} }
os << "\n }\n"; os << "\n }\n";

View File

@ -543,8 +543,8 @@ class StackFrameCacheHelper : public AllStatic {
return MaybeHandle<StackTraceFrame>(); return MaybeHandle<StackTraceFrame>();
const auto cache = Handle<SimpleNumberDictionary>::cast(maybe_cache); const auto cache = Handle<SimpleNumberDictionary>::cast(maybe_cache);
const int entry = cache->FindEntry(isolate, code_offset); const InternalIndex entry = cache->FindEntry(isolate, code_offset);
if (entry != NumberDictionary::kNotFound) { if (entry.is_found()) {
return handle(StackTraceFrame::cast(cache->ValueAt(entry)), isolate); return handle(StackTraceFrame::cast(cache->ValueAt(entry)), isolate);
} }
return MaybeHandle<StackTraceFrame>(); return MaybeHandle<StackTraceFrame>();
@ -3865,9 +3865,9 @@ Handle<Symbol> Isolate::SymbolFor(RootIndex dictionary_index,
Handle<String> key = factory()->InternalizeString(name); Handle<String> key = factory()->InternalizeString(name);
Handle<NameDictionary> dictionary = Handle<NameDictionary> dictionary =
Handle<NameDictionary>::cast(root_handle(dictionary_index)); Handle<NameDictionary>::cast(root_handle(dictionary_index));
int entry = dictionary->FindEntry(this, key); InternalIndex entry = dictionary->FindEntry(this, key);
Handle<Symbol> symbol; Handle<Symbol> symbol;
if (entry == NameDictionary::kNotFound) { if (entry.is_not_found()) {
symbol = symbol =
private_symbol ? factory()->NewPrivateSymbol() : factory()->NewSymbol(); private_symbol ? factory()->NewPrivateSymbol() : factory()->NewSymbol();
symbol->set_name(*key); symbol->set_name(*key);

View File

@ -479,7 +479,7 @@ class ConcurrentMarkingVisitor final
if (!ShouldVisit(table)) return 0; if (!ShouldVisit(table)) return 0;
weak_objects_->ephemeron_hash_tables.Push(task_id_, table); weak_objects_->ephemeron_hash_tables.Push(task_id_, table);
for (int i = 0; i < table.Capacity(); i++) { for (InternalIndex i : table.IterateEntries()) {
ObjectSlot key_slot = ObjectSlot key_slot =
table.RawFieldOfElementAt(EphemeronHashTable::EntryToIndex(i)); table.RawFieldOfElementAt(EphemeronHashTable::EntryToIndex(i));
HeapObject key = HeapObject::cast(table.KeyAt(i)); HeapObject key = HeapObject::cast(table.KeyAt(i));

View File

@ -2770,7 +2770,7 @@ Handle<JSGlobalObject> Factory::NewJSGlobalObject(
// The global object might be created from an object template with accessors. // The global object might be created from an object template with accessors.
// Fill these accessors into the dictionary. // Fill these accessors into the dictionary.
Handle<DescriptorArray> descs(map->instance_descriptors(), isolate()); Handle<DescriptorArray> descs(map->instance_descriptors(), isolate());
for (InternalIndex i : InternalIndex::Range(map->NumberOfOwnDescriptors())) { for (InternalIndex i : map->IterateOwnDescriptors()) {
PropertyDetails details = descs->GetDetails(i); PropertyDetails details = descs->GetDetails(i);
// Only accessors are expected. // Only accessors are expected.
DCHECK_EQ(kAccessor, details.kind()); DCHECK_EQ(kAccessor, details.kind());

View File

@ -4086,8 +4086,8 @@ class OldToNewSlotVerifyingVisitor : public SlotVerifyingVisitor {
CHECK(it != ephemeron_remembered_set_->end()); CHECK(it != ephemeron_remembered_set_->end());
int slot_index = int slot_index =
EphemeronHashTable::SlotToIndex(table.address(), key.address()); EphemeronHashTable::SlotToIndex(table.address(), key.address());
int entry = EphemeronHashTable::IndexToEntry(slot_index); InternalIndex entry = EphemeronHashTable::IndexToEntry(slot_index);
CHECK(it->second.find(entry) != it->second.end()); CHECK(it->second.find(entry.as_int()) != it->second.end());
} }
} }
} }
@ -6184,10 +6184,10 @@ void Heap::GenerationalBarrierSlow(HeapObject object, Address slot,
void Heap::RecordEphemeronKeyWrite(EphemeronHashTable table, Address slot) { void Heap::RecordEphemeronKeyWrite(EphemeronHashTable table, Address slot) {
DCHECK(ObjectInYoungGeneration(HeapObjectSlot(slot).ToHeapObject())); DCHECK(ObjectInYoungGeneration(HeapObjectSlot(slot).ToHeapObject()));
int slot_index = EphemeronHashTable::SlotToIndex(table.address(), slot); int slot_index = EphemeronHashTable::SlotToIndex(table.address(), slot);
int entry = EphemeronHashTable::IndexToEntry(slot_index); InternalIndex entry = EphemeronHashTable::IndexToEntry(slot_index);
auto it = auto it =
ephemeron_remembered_set_.insert({table, std::unordered_set<int>()}); ephemeron_remembered_set_.insert({table, std::unordered_set<int>()});
it.first->second.insert(entry); it.first->second.insert(entry.as_int());
} }
void Heap::EphemeronKeyWriteBarrierFromCode(Address raw_object, void Heap::EphemeronKeyWriteBarrierFromCode(Address raw_object,

View File

@ -167,7 +167,7 @@ int MarkingVisitor<fixed_array_mode, retaining_path_mode, MarkingState>::
VisitEphemeronHashTable(Map map, EphemeronHashTable table) { VisitEphemeronHashTable(Map map, EphemeronHashTable table) {
collector_->AddEphemeronHashTable(table); collector_->AddEphemeronHashTable(table);
for (int i = 0; i < table.Capacity(); i++) { for (InternalIndex i : table.IterateEntries()) {
ObjectSlot key_slot = ObjectSlot key_slot =
table.RawFieldOfElementAt(EphemeronHashTable::EntryToIndex(i)); table.RawFieldOfElementAt(EphemeronHashTable::EntryToIndex(i));
HeapObject key = HeapObject::cast(table.KeyAt(i)); HeapObject key = HeapObject::cast(table.KeyAt(i));

View File

@ -2297,7 +2297,7 @@ void MarkCompactCollector::ClearWeakCollections() {
EphemeronHashTable table; EphemeronHashTable table;
while (weak_objects_.ephemeron_hash_tables.Pop(kMainThread, &table)) { while (weak_objects_.ephemeron_hash_tables.Pop(kMainThread, &table)) {
for (int i = 0; i < table.Capacity(); i++) { for (InternalIndex i : table.IterateEntries()) {
HeapObject key = HeapObject::cast(table.KeyAt(i)); HeapObject key = HeapObject::cast(table.KeyAt(i));
#ifdef VERIFY_HEAP #ifdef VERIFY_HEAP
Object value = table.ValueAt(i); Object value = table.ValueAt(i);
@ -3654,8 +3654,8 @@ class EphemeronTableUpdatingItem : public UpdatingItem {
DCHECK(table.Object::IsEphemeronHashTable()); DCHECK(table.Object::IsEphemeronHashTable());
for (auto iti = indices.begin(); iti != indices.end();) { for (auto iti = indices.begin(); iti != indices.end();) {
// EphemeronHashTable keys must be heap objects. // EphemeronHashTable keys must be heap objects.
HeapObjectSlot key_slot( HeapObjectSlot key_slot(table.RawFieldOfElementAt(
table.RawFieldOfElementAt(EphemeronHashTable::EntryToIndex(*iti))); EphemeronHashTable::EntryToIndex(InternalIndex(*iti))));
HeapObject key = key_slot.ToHeapObject(); HeapObject key = key_slot.ToHeapObject();
MapWord map_word = key.map_word(); MapWord map_word = key.map_word();
if (map_word.IsForwardingAddress()) { if (map_word.IsForwardingAddress()) {

View File

@ -482,7 +482,7 @@ int ScavengeVisitor::VisitEphemeronHashTable(Map map,
// later. This allows to only iterate the tables' values, which are treated // later. This allows to only iterate the tables' values, which are treated
// as strong independetly of whether the key is live. // as strong independetly of whether the key is live.
scavenger_->AddEphemeronHashTable(table); scavenger_->AddEphemeronHashTable(table);
for (int i = 0; i < table.Capacity(); i++) { for (InternalIndex i : table.IterateEntries()) {
ObjectSlot value_slot = ObjectSlot value_slot =
table.RawFieldOfElementAt(EphemeronHashTable::EntryToValueIndex(i)); table.RawFieldOfElementAt(EphemeronHashTable::EntryToValueIndex(i));
VisitPointer(table, value_slot); VisitPointer(table, value_slot);

View File

@ -535,7 +535,7 @@ void ScavengerCollector::ProcessWeakReferences(
void ScavengerCollector::ClearYoungEphemerons( void ScavengerCollector::ClearYoungEphemerons(
EphemeronTableList* ephemeron_table_list) { EphemeronTableList* ephemeron_table_list) {
ephemeron_table_list->Iterate([this](EphemeronHashTable table) { ephemeron_table_list->Iterate([this](EphemeronHashTable table) {
for (int i = 0; i < table.Capacity(); i++) { for (InternalIndex i : table.IterateEntries()) {
// Keys in EphemeronHashTables must be heap objects. // Keys in EphemeronHashTables must be heap objects.
HeapObjectSlot key_slot( HeapObjectSlot key_slot(
table.RawFieldOfElementAt(EphemeronHashTable::EntryToIndex(i))); table.RawFieldOfElementAt(EphemeronHashTable::EntryToIndex(i)));
@ -560,11 +560,11 @@ void ScavengerCollector::ClearOldEphemerons() {
auto& indices = it->second; auto& indices = it->second;
for (auto iti = indices.begin(); iti != indices.end();) { for (auto iti = indices.begin(); iti != indices.end();) {
// Keys in EphemeronHashTables must be heap objects. // Keys in EphemeronHashTables must be heap objects.
HeapObjectSlot key_slot( HeapObjectSlot key_slot(table.RawFieldOfElementAt(
table.RawFieldOfElementAt(EphemeronHashTable::EntryToIndex(*iti))); EphemeronHashTable::EntryToIndex(InternalIndex(*iti))));
HeapObject key = key_slot.ToHeapObject(); HeapObject key = key_slot.ToHeapObject();
if (IsUnscavengedHeapObject(heap_, key)) { if (IsUnscavengedHeapObject(heap_, key)) {
table.RemoveEntry(*iti); table.RemoveEntry(InternalIndex(*iti));
iti = indices.erase(iti); iti = indices.erase(iti);
} else { } else {
HeapObject forwarded = ForwardingAddress(key); HeapObject forwarded = ForwardingAddress(key);

View File

@ -772,10 +772,10 @@ Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) {
Handle<ObjectHashTable> exports( Handle<ObjectHashTable> exports(
Handle<JSModuleNamespace>::cast(holder)->module().exports(), Handle<JSModuleNamespace>::cast(holder)->module().exports(),
isolate()); isolate());
int entry = exports->FindEntry(roots, lookup->name(), InternalIndex entry = exports->FindEntry(
Smi::ToInt(lookup->name()->GetHash())); roots, lookup->name(), Smi::ToInt(lookup->name()->GetHash()));
// We found the accessor, so the entry must exist. // We found the accessor, so the entry must exist.
DCHECK_NE(entry, ObjectHashTable::kNotFound); DCHECK(entry.is_found());
int index = ObjectHashTable::EntryToValueIndex(entry); int index = ObjectHashTable::EntryToValueIndex(entry);
return LoadHandler::LoadModuleExport(isolate(), index); return LoadHandler::LoadModuleExport(isolate(), index);
} }

View File

@ -5345,7 +5345,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
Handle<FixedArray> indices = Handle<FixedArray> indices =
GlobalDictionary::IterationIndices(isolate(), properties); GlobalDictionary::IterationIndices(isolate(), properties);
for (int i = 0; i < indices->length(); i++) { for (int i = 0; i < indices->length(); i++) {
int index = Smi::ToInt(indices->get(i)); InternalIndex index(Smi::ToInt(indices->get(i)));
Handle<PropertyCell> cell(properties->CellAt(index), isolate()); Handle<PropertyCell> cell(properties->CellAt(index), isolate());
Handle<Name> key(cell->name(), isolate()); Handle<Name> key(cell->name(), isolate());
// If the property is already there we skip it. // If the property is already there we skip it.
@ -5365,7 +5365,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
NameDictionary::IterationIndices(isolate(), properties); NameDictionary::IterationIndices(isolate(), properties);
ReadOnlyRoots roots(isolate()); ReadOnlyRoots roots(isolate());
for (int i = 0; i < key_indices->length(); i++) { for (int i = 0; i < key_indices->length(); i++) {
int key_index = Smi::ToInt(key_indices->get(i)); InternalIndex key_index(Smi::ToInt(key_indices->get(i)));
Object raw_key = properties->KeyAt(key_index); Object raw_key = properties->KeyAt(key_index);
DCHECK(properties->IsKey(roots, raw_key)); DCHECK(properties->IsKey(roots, raw_key));
DCHECK(raw_key.IsName()); DCHECK(raw_key.IsName());

View File

@ -70,14 +70,15 @@ void NumberDictionary::set_requires_slow_elements() {
} }
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
void Dictionary<Derived, Shape>::ClearEntry(Isolate* isolate, int entry) { void Dictionary<Derived, Shape>::ClearEntry(Isolate* isolate,
InternalIndex entry) {
Object the_hole = this->GetReadOnlyRoots().the_hole_value(); Object the_hole = this->GetReadOnlyRoots().the_hole_value();
PropertyDetails details = PropertyDetails::Empty(); PropertyDetails details = PropertyDetails::Empty();
Derived::cast(*this).SetEntry(isolate, entry, the_hole, the_hole, details); Derived::cast(*this).SetEntry(isolate, entry, the_hole, the_hole, details);
} }
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
void Dictionary<Derived, Shape>::SetEntry(Isolate* isolate, int entry, void Dictionary<Derived, Shape>::SetEntry(Isolate* isolate, InternalIndex entry,
Object key, Object value, Object key, Object value,
PropertyDetails details) { PropertyDetails details) {
DCHECK(Dictionary::kEntrySize == 2 || Dictionary::kEntrySize == 3); DCHECK(Dictionary::kEntrySize == 2 || Dictionary::kEntrySize == 3);
@ -98,12 +99,12 @@ RootIndex GlobalDictionaryShape::GetMapRootIndex() {
return RootIndex::kGlobalDictionaryMap; return RootIndex::kGlobalDictionaryMap;
} }
Name NameDictionary::NameAt(int entry) { Name NameDictionary::NameAt(InternalIndex entry) {
Isolate* isolate = GetIsolateForPtrCompr(*this); Isolate* isolate = GetIsolateForPtrCompr(*this);
return NameAt(isolate, entry); return NameAt(isolate, entry);
} }
Name NameDictionary::NameAt(Isolate* isolate, int entry) { Name NameDictionary::NameAt(Isolate* isolate, InternalIndex entry) {
return Name::cast(KeyAt(isolate, entry)); return Name::cast(KeyAt(isolate, entry));
} }
@ -111,12 +112,12 @@ RootIndex NameDictionaryShape::GetMapRootIndex() {
return RootIndex::kNameDictionaryMap; return RootIndex::kNameDictionaryMap;
} }
PropertyCell GlobalDictionary::CellAt(int entry) { PropertyCell GlobalDictionary::CellAt(InternalIndex entry) {
Isolate* isolate = GetIsolateForPtrCompr(*this); Isolate* isolate = GetIsolateForPtrCompr(*this);
return CellAt(isolate, entry); return CellAt(isolate, entry);
} }
PropertyCell GlobalDictionary::CellAt(Isolate* isolate, int entry) { PropertyCell GlobalDictionary::CellAt(Isolate* isolate, InternalIndex entry) {
DCHECK(KeyAt(isolate, entry).IsPropertyCell(isolate)); DCHECK(KeyAt(isolate, entry).IsPropertyCell(isolate));
return PropertyCell::cast(KeyAt(isolate, entry)); return PropertyCell::cast(KeyAt(isolate, entry));
} }
@ -130,32 +131,33 @@ bool GlobalDictionaryShape::IsKey(ReadOnlyRoots roots, Object k) {
return IsLive(roots, k) && !PropertyCell::cast(k).value().IsTheHole(roots); return IsLive(roots, k) && !PropertyCell::cast(k).value().IsTheHole(roots);
} }
Name GlobalDictionary::NameAt(int entry) { Name GlobalDictionary::NameAt(InternalIndex entry) {
Isolate* isolate = GetIsolateForPtrCompr(*this); Isolate* isolate = GetIsolateForPtrCompr(*this);
return NameAt(isolate, entry); return NameAt(isolate, entry);
} }
Name GlobalDictionary::NameAt(Isolate* isolate, int entry) { Name GlobalDictionary::NameAt(Isolate* isolate, InternalIndex entry) {
return CellAt(isolate, entry).name(isolate); return CellAt(isolate, entry).name(isolate);
} }
Object GlobalDictionary::ValueAt(int entry) { Object GlobalDictionary::ValueAt(InternalIndex entry) {
Isolate* isolate = GetIsolateForPtrCompr(*this); Isolate* isolate = GetIsolateForPtrCompr(*this);
return ValueAt(isolate, entry); return ValueAt(isolate, entry);
} }
Object GlobalDictionary::ValueAt(Isolate* isolate, int entry) { Object GlobalDictionary::ValueAt(Isolate* isolate, InternalIndex entry) {
return CellAt(isolate, entry).value(isolate); return CellAt(isolate, entry).value(isolate);
} }
void GlobalDictionary::SetEntry(Isolate* isolate, int entry, Object key, void GlobalDictionary::SetEntry(Isolate* isolate, InternalIndex entry,
Object value, PropertyDetails details) { Object key, Object value,
PropertyDetails details) {
DCHECK_EQ(key, PropertyCell::cast(value).name()); DCHECK_EQ(key, PropertyCell::cast(value).name());
set(EntryToIndex(entry) + kEntryKeyIndex, value); set(EntryToIndex(entry) + kEntryKeyIndex, value);
DetailsAtPut(isolate, entry, details); DetailsAtPut(isolate, entry, details);
} }
void GlobalDictionary::ValueAtPut(int entry, Object value) { void GlobalDictionary::ValueAtPut(InternalIndex entry, Object value) {
set(EntryToIndex(entry), value); set(EntryToIndex(entry), value);
} }
@ -219,15 +221,17 @@ Handle<Object> NameDictionaryShape::AsHandle(Isolate* isolate,
} }
template <typename Dictionary> template <typename Dictionary>
PropertyDetails GlobalDictionaryShape::DetailsAt(Dictionary dict, int entry) { PropertyDetails GlobalDictionaryShape::DetailsAt(Dictionary dict,
DCHECK_LE(0, entry); // Not found is -1, which is not caught by get(). InternalIndex entry) {
DCHECK(entry.is_found());
return dict.CellAt(entry).property_details(); return dict.CellAt(entry).property_details();
} }
template <typename Dictionary> template <typename Dictionary>
void GlobalDictionaryShape::DetailsAtPut(Isolate* isolate, Dictionary dict, void GlobalDictionaryShape::DetailsAtPut(Isolate* isolate, Dictionary dict,
int entry, PropertyDetails value) { InternalIndex entry,
DCHECK_LE(0, entry); // Not found is -1, which is not caught by get(). PropertyDetails value) {
DCHECK(entry.is_found());
PropertyCell cell = dict.CellAt(entry); PropertyCell cell = dict.CellAt(entry);
if (cell.property_details().IsReadOnly() != value.IsReadOnly()) { if (cell.property_details().IsReadOnly() != value.IsReadOnly()) {
cell.dependent_code().DeoptimizeDependentCodeGroup( cell.dependent_code().DeoptimizeDependentCodeGroup(

View File

@ -31,32 +31,35 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) Dictionary
public: public:
using Key = typename Shape::Key; using Key = typename Shape::Key;
// Returns the value at entry. // Returns the value at entry.
Object ValueAt(int entry) { Object ValueAt(InternalIndex entry) {
Isolate* isolate = GetIsolateForPtrCompr(*this); Isolate* isolate = GetIsolateForPtrCompr(*this);
return ValueAt(isolate, entry); return ValueAt(isolate, entry);
} }
Object ValueAt(Isolate* isolate, int entry) { Object ValueAt(Isolate* isolate, InternalIndex entry) {
return this->get(isolate, DerivedHashTable::EntryToIndex(entry) + 1); return this->get(isolate, DerivedHashTable::EntryToIndex(entry) +
Derived::kEntryValueIndex);
} }
// Set the value for entry. // Set the value for entry.
void ValueAtPut(int entry, Object value) { void ValueAtPut(InternalIndex entry, Object value) {
this->set(DerivedHashTable::EntryToIndex(entry) + 1, value); this->set(DerivedHashTable::EntryToIndex(entry) + Derived::kEntryValueIndex,
value);
} }
// Returns the property details for the property at entry. // Returns the property details for the property at entry.
PropertyDetails DetailsAt(int entry) { PropertyDetails DetailsAt(InternalIndex entry) {
return Shape::DetailsAt(Derived::cast(*this), entry); return Shape::DetailsAt(Derived::cast(*this), entry);
} }
// Set the details for entry. // Set the details for entry.
void DetailsAtPut(Isolate* isolate, int entry, PropertyDetails value) { void DetailsAtPut(Isolate* isolate, InternalIndex entry,
PropertyDetails value) {
Shape::DetailsAtPut(isolate, Derived::cast(*this), entry, value); Shape::DetailsAtPut(isolate, Derived::cast(*this), entry, value);
} }
// Delete a property from the dictionary. // Delete a property from the dictionary.
V8_WARN_UNUSED_RESULT static Handle<Derived> DeleteEntry( V8_WARN_UNUSED_RESULT static Handle<Derived> DeleteEntry(
Isolate* isolate, Handle<Derived> dictionary, int entry); Isolate* isolate, Handle<Derived> dictionary, InternalIndex entry);
// Attempt to shrink the dictionary after deletion of key. // Attempt to shrink the dictionary after deletion of key.
V8_WARN_UNUSED_RESULT static inline Handle<Derived> Shrink( V8_WARN_UNUSED_RESULT static inline Handle<Derived> Shrink(
@ -76,13 +79,14 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) Dictionary
Object SlowReverseLookup(Object value); Object SlowReverseLookup(Object value);
// Sets the entry to (key, value) pair. // Sets the entry to (key, value) pair.
inline void ClearEntry(Isolate* isolate, int entry); inline void ClearEntry(Isolate* isolate, InternalIndex entry);
inline void SetEntry(Isolate* isolate, int entry, Object key, Object value, inline void SetEntry(Isolate* isolate, InternalIndex entry, Object key,
PropertyDetails details); Object value, PropertyDetails details);
V8_WARN_UNUSED_RESULT static Handle<Derived> Add( V8_WARN_UNUSED_RESULT static Handle<Derived> Add(
Isolate* isolate, Handle<Derived> dictionary, Key key, Isolate* isolate, Handle<Derived> dictionary, Key key,
Handle<Object> value, PropertyDetails details, int* entry_out = nullptr); Handle<Object> value, PropertyDetails details,
InternalIndex* entry_out = nullptr);
protected: protected:
// Generic at put operation. // Generic at put operation.
@ -100,16 +104,17 @@ class BaseDictionaryShape : public BaseShape<Key> {
public: public:
static const bool kHasDetails = true; static const bool kHasDetails = true;
template <typename Dictionary> template <typename Dictionary>
static inline PropertyDetails DetailsAt(Dictionary dict, int entry) { static inline PropertyDetails DetailsAt(Dictionary dict,
InternalIndex entry) {
STATIC_ASSERT(Dictionary::kEntrySize == 3); STATIC_ASSERT(Dictionary::kEntrySize == 3);
DCHECK_GE(entry, 0); // Not found is -1, which is not caught by get(). DCHECK(entry.is_found());
return PropertyDetails(Smi::cast(dict.get(Dictionary::EntryToIndex(entry) + return PropertyDetails(Smi::cast(dict.get(Dictionary::EntryToIndex(entry) +
Dictionary::kEntryDetailsIndex))); Dictionary::kEntryDetailsIndex)));
} }
template <typename Dictionary> template <typename Dictionary>
static inline void DetailsAtPut(Isolate* isolate, Dictionary dict, int entry, static inline void DetailsAtPut(Isolate* isolate, Dictionary dict,
PropertyDetails value) { InternalIndex entry, PropertyDetails value) {
STATIC_ASSERT(Dictionary::kEntrySize == 3); STATIC_ASSERT(Dictionary::kEntrySize == 3);
dict.set(Dictionary::EntryToIndex(entry) + Dictionary::kEntryDetailsIndex, dict.set(Dictionary::EntryToIndex(entry) + Dictionary::kEntryDetailsIndex,
value.AsSmi()); value.AsSmi());
@ -190,11 +195,13 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) BaseNameDictionary
V8_WARN_UNUSED_RESULT static Handle<Derived> AddNoUpdateNextEnumerationIndex( V8_WARN_UNUSED_RESULT static Handle<Derived> AddNoUpdateNextEnumerationIndex(
Isolate* isolate, Handle<Derived> dictionary, Key key, Isolate* isolate, Handle<Derived> dictionary, Key key,
Handle<Object> value, PropertyDetails details, int* entry_out = nullptr); Handle<Object> value, PropertyDetails details,
InternalIndex* entry_out = nullptr);
V8_WARN_UNUSED_RESULT static Handle<Derived> Add( V8_WARN_UNUSED_RESULT static Handle<Derived> Add(
Isolate* isolate, Handle<Derived> dictionary, Key key, Isolate* isolate, Handle<Derived> dictionary, Key key,
Handle<Object> value, PropertyDetails details, int* entry_out = nullptr); Handle<Object> value, PropertyDetails details,
InternalIndex* entry_out = nullptr);
OBJECT_CONSTRUCTORS(BaseNameDictionary, Dictionary<Derived, Shape>); OBJECT_CONSTRUCTORS(BaseNameDictionary, Dictionary<Derived, Shape>);
}; };
@ -209,11 +216,12 @@ class V8_EXPORT_PRIVATE NameDictionary
public: public:
DECL_CAST(NameDictionary) DECL_CAST(NameDictionary)
static const int kEntryValueIndex = 1;
static const int kEntryDetailsIndex = 2; static const int kEntryDetailsIndex = 2;
static const int kInitialCapacity = 2; static const int kInitialCapacity = 2;
inline Name NameAt(int entry); inline Name NameAt(InternalIndex entry);
inline Name NameAt(Isolate* isolate, int entry); inline Name NameAt(Isolate* isolate, InternalIndex entry);
inline void set_hash(int hash); inline void set_hash(int hash);
inline int hash() const; inline int hash() const;
@ -230,11 +238,11 @@ class GlobalDictionaryShape : public NameDictionaryShape {
static const int kEntrySize = 1; // Overrides NameDictionaryShape::kEntrySize static const int kEntrySize = 1; // Overrides NameDictionaryShape::kEntrySize
template <typename Dictionary> template <typename Dictionary>
static inline PropertyDetails DetailsAt(Dictionary dict, int entry); static inline PropertyDetails DetailsAt(Dictionary dict, InternalIndex entry);
template <typename Dictionary> template <typename Dictionary>
static inline void DetailsAtPut(Isolate* isolate, Dictionary dict, int entry, static inline void DetailsAtPut(Isolate* isolate, Dictionary dict,
PropertyDetails value); InternalIndex entry, PropertyDetails value);
static inline Object Unwrap(Object key); static inline Object Unwrap(Object key);
static inline bool IsKey(ReadOnlyRoots roots, Object k); static inline bool IsKey(ReadOnlyRoots roots, Object k);
@ -252,15 +260,15 @@ class V8_EXPORT_PRIVATE GlobalDictionary
public: public:
DECL_CAST(GlobalDictionary) DECL_CAST(GlobalDictionary)
inline Object ValueAt(int entry); inline Object ValueAt(InternalIndex entry);
inline Object ValueAt(Isolate* isolate, int entry); inline Object ValueAt(Isolate* isolate, InternalIndex entry);
inline PropertyCell CellAt(int entry); inline PropertyCell CellAt(InternalIndex entry);
inline PropertyCell CellAt(Isolate* isolate, int entry); inline PropertyCell CellAt(Isolate* isolate, InternalIndex entry);
inline void SetEntry(Isolate* isolate, int entry, Object key, Object value, inline void SetEntry(Isolate* isolate, InternalIndex entry, Object key,
PropertyDetails details); Object value, PropertyDetails details);
inline Name NameAt(int entry); inline Name NameAt(InternalIndex entry);
inline Name NameAt(Isolate* isolate, int entry); inline Name NameAt(Isolate* isolate, InternalIndex entry);
inline void ValueAtPut(int entry, Object value); inline void ValueAtPut(InternalIndex entry, Object value);
OBJECT_CONSTRUCTORS( OBJECT_CONSTRUCTORS(
GlobalDictionary, GlobalDictionary,
@ -291,13 +299,14 @@ class SimpleNumberDictionaryShape : public NumberDictionaryBaseShape {
static const int kEntrySize = 2; static const int kEntrySize = 2;
template <typename Dictionary> template <typename Dictionary>
static inline PropertyDetails DetailsAt(Dictionary dict, int entry) { static inline PropertyDetails DetailsAt(Dictionary dict,
InternalIndex entry) {
UNREACHABLE(); UNREACHABLE();
} }
template <typename Dictionary> template <typename Dictionary>
static inline void DetailsAtPut(Isolate* isolate, Dictionary dict, int entry, static inline void DetailsAtPut(Isolate* isolate, Dictionary dict,
PropertyDetails value) { InternalIndex entry, PropertyDetails value) {
UNREACHABLE(); UNREACHABLE();
} }

View File

@ -228,8 +228,8 @@ void CopyDictionaryToObjectElements(Isolate* isolate, FixedArrayBase from_base,
} }
WriteBarrierMode write_barrier_mode = GetWriteBarrierMode(to_kind); WriteBarrierMode write_barrier_mode = GetWriteBarrierMode(to_kind);
for (int i = 0; i < copy_size; i++) { for (int i = 0; i < copy_size; i++) {
int entry = from.FindEntry(isolate, i + from_start); InternalIndex entry = from.FindEntry(isolate, i + from_start);
if (entry != NumberDictionary::kNotFound) { if (entry.is_found()) {
Object value = from.ValueAt(entry); Object value = from.ValueAt(entry);
DCHECK(!value.IsTheHole(isolate)); DCHECK(!value.IsTheHole(isolate));
to.set(i + to_start, value, write_barrier_mode); to.set(i + to_start, value, write_barrier_mode);
@ -432,8 +432,8 @@ void CopyDictionaryToDoubleElements(Isolate* isolate, FixedArrayBase from_base,
copy_size = to_length - to_start; copy_size = to_length - to_start;
} }
for (int i = 0; i < copy_size; i++) { for (int i = 0; i < copy_size; i++) {
int entry = from.FindEntry(isolate, i + from_start); InternalIndex entry = from.FindEntry(isolate, i + from_start);
if (entry != NumberDictionary::kNotFound) { if (entry.is_found()) {
to.set(i + to_start, from.ValueAt(entry).Number()); to.set(i + to_start, from.ValueAt(entry).Number());
} else { } else {
to.set_the_hole(i + to_start); to.set_the_hole(i + to_start);
@ -1364,7 +1364,6 @@ class DictionaryElementsAccessor
Handle<FixedArrayBase> backing_store) { Handle<FixedArrayBase> backing_store) {
Handle<NumberDictionary> dict = Handle<NumberDictionary> dict =
Handle<NumberDictionary>::cast(backing_store); Handle<NumberDictionary>::cast(backing_store);
int capacity = dict->Capacity();
uint32_t old_length = 0; uint32_t old_length = 0;
CHECK(array->length().ToArrayLength(&old_length)); CHECK(array->length().ToArrayLength(&old_length));
{ {
@ -1374,7 +1373,7 @@ class DictionaryElementsAccessor
if (dict->requires_slow_elements()) { if (dict->requires_slow_elements()) {
// Find last non-deletable element in range of elements to be // Find last non-deletable element in range of elements to be
// deleted and adjust range accordingly. // deleted and adjust range accordingly.
for (int entry = 0; entry < capacity; entry++) { for (InternalIndex entry : dict->IterateEntries()) {
Object index = dict->KeyAt(entry); Object index = dict->KeyAt(entry);
if (dict->IsKey(roots, index)) { if (dict->IsKey(roots, index)) {
uint32_t number = static_cast<uint32_t>(index.Number()); uint32_t number = static_cast<uint32_t>(index.Number());
@ -1392,7 +1391,7 @@ class DictionaryElementsAccessor
} else { } else {
// Remove elements that should be deleted. // Remove elements that should be deleted.
int removed_entries = 0; int removed_entries = 0;
for (int entry = 0; entry < capacity; entry++) { for (InternalIndex entry : dict->IterateEntries()) {
Object index = dict->KeyAt(entry); Object index = dict->KeyAt(entry);
if (dict->IsKey(roots, index)) { if (dict->IsKey(roots, index)) {
uint32_t number = static_cast<uint32_t>(index.Number()); uint32_t number = static_cast<uint32_t>(index.Number());
@ -1425,8 +1424,7 @@ class DictionaryElementsAccessor
static void DeleteImpl(Handle<JSObject> obj, InternalIndex entry) { static void DeleteImpl(Handle<JSObject> obj, InternalIndex entry) {
Handle<NumberDictionary> dict(NumberDictionary::cast(obj->elements()), Handle<NumberDictionary> dict(NumberDictionary::cast(obj->elements()),
obj->GetIsolate()); obj->GetIsolate());
dict = dict = NumberDictionary::DeleteEntry(obj->GetIsolate(), dict, entry);
NumberDictionary::DeleteEntry(obj->GetIsolate(), dict, entry.as_int());
obj->set_elements(*dict); obj->set_elements(*dict);
} }
@ -1434,9 +1432,8 @@ class DictionaryElementsAccessor
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
NumberDictionary dict = NumberDictionary::cast(backing_store); NumberDictionary dict = NumberDictionary::cast(backing_store);
if (!dict.requires_slow_elements()) return false; if (!dict.requires_slow_elements()) return false;
int capacity = dict.Capacity();
ReadOnlyRoots roots = holder.GetReadOnlyRoots(); ReadOnlyRoots roots = holder.GetReadOnlyRoots();
for (int i = 0; i < capacity; i++) { for (InternalIndex i : dict.IterateEntries()) {
Object key = dict.KeyAt(i); Object key = dict.KeyAt(i);
if (!dict.IsKey(roots, key)) continue; if (!dict.IsKey(roots, key)) continue;
PropertyDetails details = dict.DetailsAt(i); PropertyDetails details = dict.DetailsAt(i);
@ -1447,7 +1444,7 @@ class DictionaryElementsAccessor
static Object GetRaw(FixedArrayBase store, InternalIndex entry) { static Object GetRaw(FixedArrayBase store, InternalIndex entry) {
NumberDictionary backing_store = NumberDictionary::cast(store); NumberDictionary backing_store = NumberDictionary::cast(store);
return backing_store.ValueAt(entry.as_int()); return backing_store.ValueAt(entry);
} }
static Handle<Object> GetImpl(Isolate* isolate, FixedArrayBase backing_store, static Handle<Object> GetImpl(Isolate* isolate, FixedArrayBase backing_store,
@ -1462,7 +1459,7 @@ class DictionaryElementsAccessor
static inline void SetImpl(FixedArrayBase backing_store, InternalIndex entry, static inline void SetImpl(FixedArrayBase backing_store, InternalIndex entry,
Object value) { Object value) {
NumberDictionary::cast(backing_store).ValueAtPut(entry.as_int(), value); NumberDictionary::cast(backing_store).ValueAtPut(entry, value);
} }
static void ReconfigureImpl(Handle<JSObject> object, static void ReconfigureImpl(Handle<JSObject> object,
@ -1471,12 +1468,12 @@ class DictionaryElementsAccessor
PropertyAttributes attributes) { PropertyAttributes attributes) {
NumberDictionary dictionary = NumberDictionary::cast(*store); NumberDictionary dictionary = NumberDictionary::cast(*store);
if (attributes != NONE) object->RequireSlowElements(dictionary); if (attributes != NONE) object->RequireSlowElements(dictionary);
dictionary.ValueAtPut(entry.as_int(), *value); dictionary.ValueAtPut(entry, *value);
PropertyDetails details = dictionary.DetailsAt(entry.as_int()); PropertyDetails details = dictionary.DetailsAt(entry);
details = PropertyDetails(kData, attributes, PropertyCellType::kNoCell, details = PropertyDetails(kData, attributes, PropertyCellType::kNoCell,
details.dictionary_index()); details.dictionary_index());
dictionary.DetailsAtPut(object->GetIsolate(), entry.as_int(), details); dictionary.DetailsAtPut(object->GetIsolate(), entry, details);
} }
static void AddImpl(Handle<JSObject> object, uint32_t index, static void AddImpl(Handle<JSObject> object, uint32_t index,
@ -1500,7 +1497,7 @@ class DictionaryElementsAccessor
InternalIndex entry) { InternalIndex entry) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
NumberDictionary dict = NumberDictionary::cast(store); NumberDictionary dict = NumberDictionary::cast(store);
Object index = dict.KeyAt(entry.as_int()); Object index = dict.KeyAt(entry);
return !index.IsTheHole(isolate); return !index.IsTheHole(isolate);
} }
@ -1509,7 +1506,7 @@ class DictionaryElementsAccessor
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
NumberDictionary dict = NumberDictionary::cast(store); NumberDictionary dict = NumberDictionary::cast(store);
uint32_t result = 0; uint32_t result = 0;
CHECK(dict.KeyAt(entry.as_int()).ToArrayIndex(&result)); CHECK(dict.KeyAt(entry).ToArrayIndex(&result));
return result; return result;
} }
@ -1519,16 +1516,15 @@ class DictionaryElementsAccessor
PropertyFilter filter) { PropertyFilter filter) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
NumberDictionary dictionary = NumberDictionary::cast(store); NumberDictionary dictionary = NumberDictionary::cast(store);
int entry = dictionary.FindEntry(isolate, index); InternalIndex entry = dictionary.FindEntry(isolate, index);
if (entry == NumberDictionary::kNotFound) { if (entry.is_not_found()) return entry;
return InternalIndex::NotFound();
}
if (filter != ALL_PROPERTIES) { if (filter != ALL_PROPERTIES) {
PropertyDetails details = dictionary.DetailsAt(entry); PropertyDetails details = dictionary.DetailsAt(entry);
PropertyAttributes attr = details.attributes(); PropertyAttributes attr = details.attributes();
if ((attr & filter) != 0) return InternalIndex::NotFound(); if ((attr & filter) != 0) return InternalIndex::NotFound();
} }
return InternalIndex(entry); return entry;
} }
static PropertyDetails GetDetailsImpl(JSObject holder, InternalIndex entry) { static PropertyDetails GetDetailsImpl(JSObject holder, InternalIndex entry) {
@ -1537,11 +1533,12 @@ class DictionaryElementsAccessor
static PropertyDetails GetDetailsImpl(FixedArrayBase backing_store, static PropertyDetails GetDetailsImpl(FixedArrayBase backing_store,
InternalIndex entry) { InternalIndex entry) {
return NumberDictionary::cast(backing_store).DetailsAt(entry.as_int()); return NumberDictionary::cast(backing_store).DetailsAt(entry);
} }
static uint32_t FilterKey(Handle<NumberDictionary> dictionary, int entry, static uint32_t FilterKey(Handle<NumberDictionary> dictionary,
Object raw_key, PropertyFilter filter) { InternalIndex entry, Object raw_key,
PropertyFilter filter) {
DCHECK(raw_key.IsNumber()); DCHECK(raw_key.IsNumber());
DCHECK_LE(raw_key.Number(), kMaxUInt32); DCHECK_LE(raw_key.Number(), kMaxUInt32);
PropertyDetails details = dictionary->DetailsAt(entry); PropertyDetails details = dictionary->DetailsAt(entry);
@ -1552,7 +1549,8 @@ class DictionaryElementsAccessor
static uint32_t GetKeyForEntryImpl(Isolate* isolate, static uint32_t GetKeyForEntryImpl(Isolate* isolate,
Handle<NumberDictionary> dictionary, Handle<NumberDictionary> dictionary,
int entry, PropertyFilter filter) { InternalIndex entry,
PropertyFilter filter) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
Object raw_key = dictionary->KeyAt(entry); Object raw_key = dictionary->KeyAt(entry);
if (!dictionary->IsKey(ReadOnlyRoots(isolate), raw_key)) return kMaxUInt32; if (!dictionary->IsKey(ReadOnlyRoots(isolate), raw_key)) return kMaxUInt32;
@ -1566,13 +1564,12 @@ class DictionaryElementsAccessor
Isolate* isolate = keys->isolate(); Isolate* isolate = keys->isolate();
Handle<NumberDictionary> dictionary = Handle<NumberDictionary> dictionary =
Handle<NumberDictionary>::cast(backing_store); Handle<NumberDictionary>::cast(backing_store);
int capacity = dictionary->Capacity();
Handle<FixedArray> elements = isolate->factory()->NewFixedArray( Handle<FixedArray> elements = isolate->factory()->NewFixedArray(
GetMaxNumberOfEntries(*object, *backing_store)); GetMaxNumberOfEntries(*object, *backing_store));
int insertion_index = 0; int insertion_index = 0;
PropertyFilter filter = keys->filter(); PropertyFilter filter = keys->filter();
ReadOnlyRoots roots(isolate); ReadOnlyRoots roots(isolate);
for (int i = 0; i < capacity; i++) { for (InternalIndex i : dictionary->IterateEntries()) {
Object raw_key = dictionary->KeyAt(i); Object raw_key = dictionary->KeyAt(i);
if (!dictionary->IsKey(roots, raw_key)) continue; if (!dictionary->IsKey(roots, raw_key)) continue;
uint32_t key = FilterKey(dictionary, i, raw_key, filter); uint32_t key = FilterKey(dictionary, i, raw_key, filter);
@ -1600,8 +1597,7 @@ class DictionaryElementsAccessor
Handle<NumberDictionary> dictionary = Handle<NumberDictionary> dictionary =
Handle<NumberDictionary>::cast(backing_store); Handle<NumberDictionary>::cast(backing_store);
uint32_t capacity = dictionary->Capacity(); for (InternalIndex i : dictionary->IterateEntries()) {
for (uint32_t i = 0; i < capacity; i++) {
uint32_t key = GetKeyForEntryImpl(isolate, dictionary, i, filter); uint32_t key = GetKeyForEntryImpl(isolate, dictionary, i, filter);
if (key == kMaxUInt32) continue; if (key == kMaxUInt32) continue;
Handle<Object> index = isolate->factory()->NewNumberFromUint(key); Handle<Object> index = isolate->factory()->NewNumberFromUint(key);
@ -1618,9 +1614,8 @@ class DictionaryElementsAccessor
Isolate* isolate = accumulator->isolate(); Isolate* isolate = accumulator->isolate();
Handle<NumberDictionary> dictionary( Handle<NumberDictionary> dictionary(
NumberDictionary::cast(receiver->elements()), isolate); NumberDictionary::cast(receiver->elements()), isolate);
int capacity = dictionary->Capacity();
ReadOnlyRoots roots(isolate); ReadOnlyRoots roots(isolate);
for (int i = 0; i < capacity; i++) { for (InternalIndex i : dictionary->IterateEntries()) {
Object k = dictionary->KeyAt(i); Object k = dictionary->KeyAt(i);
if (!dictionary->IsKey(roots, k)) continue; if (!dictionary->IsKey(roots, k)) continue;
Object value = dictionary->ValueAt(i); Object value = dictionary->ValueAt(i);
@ -1637,14 +1632,13 @@ class DictionaryElementsAccessor
uint32_t length, Maybe<bool>* result) { uint32_t length, Maybe<bool>* result) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
NumberDictionary dictionary = NumberDictionary::cast(receiver->elements()); NumberDictionary dictionary = NumberDictionary::cast(receiver->elements());
int capacity = dictionary.Capacity();
Object the_hole = ReadOnlyRoots(isolate).the_hole_value(); Object the_hole = ReadOnlyRoots(isolate).the_hole_value();
Object undefined = ReadOnlyRoots(isolate).undefined_value(); Object undefined = ReadOnlyRoots(isolate).undefined_value();
// Scan for accessor properties. If accessors are present, then elements // Scan for accessor properties. If accessors are present, then elements
// must be accessed in order via the slow path. // must be accessed in order via the slow path.
bool found = false; bool found = false;
for (int i = 0; i < capacity; ++i) { for (InternalIndex i : dictionary.IterateEntries()) {
Object k = dictionary.KeyAt(i); Object k = dictionary.KeyAt(i);
if (k == the_hole) continue; if (k == the_hole) continue;
if (k == undefined) continue; if (k == undefined) continue;
@ -1690,14 +1684,13 @@ class DictionaryElementsAccessor
// observable // observable
for (uint32_t k = start_from; k < length; ++k) { for (uint32_t k = start_from; k < length; ++k) {
DCHECK_EQ(receiver->GetElementsKind(), original_elements_kind); DCHECK_EQ(receiver->GetElementsKind(), original_elements_kind);
int entry = dictionary->FindEntry(isolate, k); InternalIndex entry = dictionary->FindEntry(isolate, k);
if (entry == NumberDictionary::kNotFound) { if (entry.is_not_found()) {
if (search_for_hole) return Just(true); if (search_for_hole) return Just(true);
continue; continue;
} }
PropertyDetails details = PropertyDetails details = GetDetailsImpl(*dictionary, entry);
GetDetailsImpl(*dictionary, InternalIndex(entry));
switch (details.kind()) { switch (details.kind()) {
case kData: { case kData: {
Object element_k = dictionary->ValueAt(entry); Object element_k = dictionary->ValueAt(entry);
@ -1763,8 +1756,8 @@ class DictionaryElementsAccessor
// observable. // observable.
for (uint32_t k = start_from; k < length; ++k) { for (uint32_t k = start_from; k < length; ++k) {
DCHECK_EQ(receiver->GetElementsKind(), original_elements_kind); DCHECK_EQ(receiver->GetElementsKind(), original_elements_kind);
int entry = dictionary->FindEntry(isolate, k); InternalIndex entry = dictionary->FindEntry(isolate, k);
if (entry == NumberDictionary::kNotFound) continue; if (entry.is_not_found()) continue;
PropertyDetails details = PropertyDetails details =
GetDetailsImpl(*dictionary, InternalIndex(entry)); GetDetailsImpl(*dictionary, InternalIndex(entry));
@ -1821,10 +1814,9 @@ class DictionaryElementsAccessor
ReadOnlyRoots roots = holder.GetReadOnlyRoots(); ReadOnlyRoots roots = holder.GetReadOnlyRoots();
NumberDictionary dictionary = NumberDictionary::cast(holder.elements()); NumberDictionary dictionary = NumberDictionary::cast(holder.elements());
// Validate the requires_slow_elements and max_number_key values. // Validate the requires_slow_elements and max_number_key values.
int capacity = dictionary.Capacity();
bool requires_slow_elements = false; bool requires_slow_elements = false;
int max_key = 0; int max_key = 0;
for (int i = 0; i < capacity; ++i) { for (InternalIndex i : dictionary.IterateEntries()) {
Object k; Object k;
if (!dictionary.ToKey(roots, i, &k)) continue; if (!dictionary.ToKey(roots, i, &k)) continue;
DCHECK_LE(0.0, k.Number()); DCHECK_LE(0.0, k.Number());
@ -4288,8 +4280,8 @@ class SlowSloppyArgumentsElementsAccessor
Handle<NumberDictionary> dict(NumberDictionary::cast(elements->arguments()), Handle<NumberDictionary> dict(NumberDictionary::cast(elements->arguments()),
isolate); isolate);
uint32_t length = elements->parameter_map_length(); uint32_t length = elements->parameter_map_length();
dict = NumberDictionary::DeleteEntry(isolate, dict, dict =
entry.as_uint32() - length); NumberDictionary::DeleteEntry(isolate, dict, entry.adjust_down(length));
elements->set_arguments(*dict); elements->set_arguments(*dict);
} }
static void AddImpl(Handle<JSObject> object, uint32_t index, static void AddImpl(Handle<JSObject> object, uint32_t index,
@ -4391,9 +4383,9 @@ class FastSloppyArgumentsElementsAccessor
uint32_t length = elements->parameter_map_length(); uint32_t length = elements->parameter_map_length();
if (entry->as_uint32() >= length) { if (entry->as_uint32() >= length) {
*entry = *entry =
InternalIndex(dictionary->FindEntry(object->GetIsolate(), dictionary
entry->as_uint32() - length) + ->FindEntry(object->GetIsolate(), entry->as_uint32() - length)
length); .adjust_up(length);
} }
return dictionary; return dictionary;
} }

View File

@ -1278,8 +1278,8 @@ void FeedbackNexus::Collect(Handle<String> type, int position) {
Handle<ArrayList> position_specific_types; Handle<ArrayList> position_specific_types;
int entry = types->FindEntry(isolate, position); InternalIndex entry = types->FindEntry(isolate, position);
if (entry == SimpleNumberDictionary::kNotFound) { if (entry.is_not_found()) {
position_specific_types = ArrayList::New(isolate, 1); position_specific_types = ArrayList::New(isolate, 1);
types = SimpleNumberDictionary::Set( types = SimpleNumberDictionary::Set(
isolate, types, position, isolate, types, position,
@ -1341,10 +1341,9 @@ std::vector<Handle<String>> FeedbackNexus::GetTypesForSourcePositions(
SimpleNumberDictionary::cast(feedback->GetHeapObjectAssumeStrong()), SimpleNumberDictionary::cast(feedback->GetHeapObjectAssumeStrong()),
isolate); isolate);
int entry = types->FindEntry(isolate, position); InternalIndex entry = types->FindEntry(isolate, position);
if (entry == SimpleNumberDictionary::kNotFound) { if (entry.is_not_found()) return types_for_position;
return types_for_position;
}
DCHECK(types->ValueAt(entry).IsArrayList()); DCHECK(types->ValueAt(entry).IsArrayList());
Handle<ArrayList> position_specific_types = Handle<ArrayList> position_specific_types =
Handle<ArrayList>(ArrayList::cast(types->ValueAt(entry)), isolate); Handle<ArrayList>(ArrayList::cast(types->ValueAt(entry)), isolate);

View File

@ -85,6 +85,10 @@ int HashTableBase::Capacity() const {
return TaggedField<Smi>::load(*this, offset).value(); return TaggedField<Smi>::load(*this, offset).value();
} }
InternalIndex::Range HashTableBase::IterateEntries() const {
return InternalIndex::Range(Capacity());
}
void HashTableBase::ElementAdded() { void HashTableBase::ElementAdded() {
SetNumberOfElements(NumberOfElements() + 1); SetNumberOfElements(NumberOfElements() + 1);
} }
@ -127,16 +131,16 @@ RootIndex EphemeronHashTableShape::GetMapRootIndex() {
} }
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
int HashTable<Derived, Shape>::FindEntry(Isolate* isolate, Key key) { InternalIndex HashTable<Derived, Shape>::FindEntry(Isolate* isolate, Key key) {
return FindEntry(ReadOnlyRoots(isolate), key, Shape::Hash(isolate, key)); return FindEntry(ReadOnlyRoots(isolate), key, Shape::Hash(isolate, key));
} }
// Find entry for key otherwise return kNotFound. // Find entry for key otherwise return kNotFound.
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
int HashTable<Derived, Shape>::FindEntry(ReadOnlyRoots roots, Key key, InternalIndex HashTable<Derived, Shape>::FindEntry(ReadOnlyRoots roots, Key key,
int32_t hash) { int32_t hash) {
uint32_t capacity = Capacity(); uint32_t capacity = Capacity();
uint32_t entry = FirstProbe(hash, capacity); InternalIndex entry = FirstProbe(hash, capacity);
uint32_t count = 1; uint32_t count = 1;
// EnsureCapacity will guarantee the hash table is never full. // EnsureCapacity will guarantee the hash table is never full.
Object undefined = roots.undefined_value(); Object undefined = roots.undefined_value();
@ -152,7 +156,7 @@ int HashTable<Derived, Shape>::FindEntry(ReadOnlyRoots roots, Key key,
} }
entry = NextProbe(entry, count++, capacity); entry = NextProbe(entry, count++, capacity);
} }
return kNotFound; return InternalIndex::NotFound();
} }
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
@ -161,7 +165,7 @@ bool HashTable<Derived, Shape>::IsKey(ReadOnlyRoots roots, Object k) {
} }
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
bool HashTable<Derived, Shape>::ToKey(ReadOnlyRoots roots, int entry, bool HashTable<Derived, Shape>::ToKey(ReadOnlyRoots roots, InternalIndex entry,
Object* out_k) { Object* out_k) {
Object k = KeyAt(entry); Object k = KeyAt(entry);
if (!IsKey(roots, k)) return false; if (!IsKey(roots, k)) return false;
@ -170,7 +174,7 @@ bool HashTable<Derived, Shape>::ToKey(ReadOnlyRoots roots, int entry,
} }
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
bool HashTable<Derived, Shape>::ToKey(Isolate* isolate, int entry, bool HashTable<Derived, Shape>::ToKey(Isolate* isolate, InternalIndex entry,
Object* out_k) { Object* out_k) {
Object k = KeyAt(isolate, entry); Object k = KeyAt(isolate, entry);
if (!IsKey(GetReadOnlyRoots(isolate), k)) return false; if (!IsKey(GetReadOnlyRoots(isolate), k)) return false;
@ -202,13 +206,13 @@ bool BaseShape<KeyT>::IsLive(ReadOnlyRoots roots, Object k) {
} }
bool ObjectHashSet::Has(Isolate* isolate, Handle<Object> key, int32_t hash) { bool ObjectHashSet::Has(Isolate* isolate, Handle<Object> key, int32_t hash) {
return FindEntry(ReadOnlyRoots(isolate), key, hash) != kNotFound; return FindEntry(ReadOnlyRoots(isolate), key, hash).is_found();
} }
bool ObjectHashSet::Has(Isolate* isolate, Handle<Object> key) { bool ObjectHashSet::Has(Isolate* isolate, Handle<Object> key) {
Object hash = key->GetHash(); Object hash = key->GetHash();
if (!hash.IsSmi()) return false; if (!hash.IsSmi()) return false;
return FindEntry(ReadOnlyRoots(isolate), key, Smi::ToInt(hash)) != kNotFound; return FindEntry(ReadOnlyRoots(isolate), key, Smi::ToInt(hash)).is_found();
} }
bool ObjectHashTableShape::IsMatch(Handle<Object> key, Object other) { bool ObjectHashTableShape::IsMatch(Handle<Object> key, Object other) {

View File

@ -77,6 +77,8 @@ class V8_EXPORT_PRIVATE HashTableBase : public NON_EXPORTED_BASE(FixedArray) {
// Returns the capacity of the hash table. // Returns the capacity of the hash table.
inline int Capacity() const; inline int Capacity() const;
inline InternalIndex::Range IterateEntries() const;
// ElementAdded should be called whenever an element is added to a // ElementAdded should be called whenever an element is added to a
// hash table. // hash table.
inline void ElementAdded(); inline void ElementAdded();
@ -90,19 +92,11 @@ class V8_EXPORT_PRIVATE HashTableBase : public NON_EXPORTED_BASE(FixedArray) {
// number of elements. May be more than HashTable::kMaxCapacity. // number of elements. May be more than HashTable::kMaxCapacity.
static inline int ComputeCapacity(int at_least_space_for); static inline int ComputeCapacity(int at_least_space_for);
// Compute the probe offset (quadratic probing).
V8_INLINE static uint32_t GetProbeOffset(uint32_t n) {
return (n + n * n) >> 1;
}
static const int kNumberOfElementsIndex = 0; static const int kNumberOfElementsIndex = 0;
static const int kNumberOfDeletedElementsIndex = 1; static const int kNumberOfDeletedElementsIndex = 1;
static const int kCapacityIndex = 2; static const int kCapacityIndex = 2;
static const int kPrefixStartIndex = 3; static const int kPrefixStartIndex = 3;
// Constant used for denoting a absent entry.
static const int kNotFound = -1;
// Minimum capacity for newly created hash tables. // Minimum capacity for newly created hash tables.
static const int kMinCapacity = 4; static const int kMinCapacity = 4;
@ -114,18 +108,13 @@ class V8_EXPORT_PRIVATE HashTableBase : public NON_EXPORTED_BASE(FixedArray) {
inline void SetNumberOfDeletedElements(int nod); inline void SetNumberOfDeletedElements(int nod);
// Returns probe entry. // Returns probe entry.
static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) { inline static InternalIndex FirstProbe(uint32_t hash, uint32_t size) {
DCHECK(base::bits::IsPowerOfTwo(size)); return InternalIndex(hash & (size - 1));
return (hash + GetProbeOffset(number)) & (size - 1);
} }
inline static uint32_t FirstProbe(uint32_t hash, uint32_t size) { inline static InternalIndex NextProbe(InternalIndex last, uint32_t number,
return hash & (size - 1); uint32_t size) {
} return InternalIndex((last.as_uint32() + number) & (size - 1));
inline static uint32_t NextProbe(uint32_t last, uint32_t number,
uint32_t size) {
return (last + number) & (size - 1);
} }
OBJECT_CONSTRUCTORS(HashTableBase, FixedArray); OBJECT_CONSTRUCTORS(HashTableBase, FixedArray);
@ -149,8 +138,8 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) HashTable
void IterateElements(ObjectVisitor* visitor); void IterateElements(ObjectVisitor* visitor);
// Find entry for key otherwise return kNotFound. // Find entry for key otherwise return kNotFound.
inline int FindEntry(ReadOnlyRoots roots, Key key, int32_t hash); inline InternalIndex FindEntry(ReadOnlyRoots roots, Key key, int32_t hash);
inline int FindEntry(Isolate* isolate, Key key); inline InternalIndex FindEntry(Isolate* isolate, Key key);
// Rehashes the table in-place. // Rehashes the table in-place.
void Rehash(ReadOnlyRoots roots); void Rehash(ReadOnlyRoots roots);
@ -159,15 +148,15 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) HashTable
// as keys and can be used to indicate missing or deleted elements. // as keys and can be used to indicate missing or deleted elements.
static bool IsKey(ReadOnlyRoots roots, Object k); static bool IsKey(ReadOnlyRoots roots, Object k);
inline bool ToKey(ReadOnlyRoots roots, int entry, Object* out_k); inline bool ToKey(ReadOnlyRoots roots, InternalIndex entry, Object* out_k);
inline bool ToKey(Isolate* isolate, int entry, Object* out_k); inline bool ToKey(Isolate* isolate, InternalIndex entry, Object* out_k);
// Returns the key at entry. // Returns the key at entry.
Object KeyAt(int entry) { Object KeyAt(InternalIndex entry) {
Isolate* isolate = GetIsolateForPtrCompr(*this); Isolate* isolate = GetIsolateForPtrCompr(*this);
return KeyAt(isolate, entry); return KeyAt(isolate, entry);
} }
Object KeyAt(Isolate* isolate, int entry) { Object KeyAt(Isolate* isolate, InternalIndex entry) {
return get(isolate, EntryToIndex(entry) + kEntryKeyIndex); return get(isolate, EntryToIndex(entry) + kEntryKeyIndex);
} }
@ -189,13 +178,13 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) HashTable
static const int kMaxRegularCapacity = kMaxRegularHeapObjectSize / 32; static const int kMaxRegularCapacity = kMaxRegularHeapObjectSize / 32;
// Returns the index for an entry (of the key) // Returns the index for an entry (of the key)
static constexpr inline int EntryToIndex(int entry) { static constexpr inline int EntryToIndex(InternalIndex entry) {
return (entry * kEntrySize) + kElementsStartIndex; return (entry.as_int() * kEntrySize) + kElementsStartIndex;
} }
// Returns the index for an entry (of the key) // Returns the entry for an index (of the key)
static constexpr inline int IndexToEntry(int index) { static constexpr inline InternalIndex IndexToEntry(int index) {
return (index - kElementsStartIndex) / kEntrySize; return InternalIndex((index - kElementsStartIndex) / kEntrySize);
} }
// Returns the index for a slot address in the object. // Returns the index for a slot address in the object.
@ -219,7 +208,7 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) HashTable
// Find the entry at which to insert element with the given key that // Find the entry at which to insert element with the given key that
// has the given hash value. // has the given hash value.
uint32_t FindInsertionEntry(uint32_t hash); InternalIndex FindInsertionEntry(uint32_t hash);
// Attempt to shrink hash table after removal of key. // Attempt to shrink hash table after removal of key.
V8_WARN_UNUSED_RESULT static Handle<Derived> Shrink( V8_WARN_UNUSED_RESULT static Handle<Derived> Shrink(
@ -230,10 +219,12 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) HashTable
private: private:
// Ensure that kMaxRegularCapacity yields a non-large object dictionary. // Ensure that kMaxRegularCapacity yields a non-large object dictionary.
STATIC_ASSERT(EntryToIndex(kMaxRegularCapacity) < kMaxRegularLength); STATIC_ASSERT(EntryToIndex(InternalIndex(kMaxRegularCapacity)) <
kMaxRegularLength);
STATIC_ASSERT(v8::base::bits::IsPowerOfTwo(kMaxRegularCapacity)); STATIC_ASSERT(v8::base::bits::IsPowerOfTwo(kMaxRegularCapacity));
static const int kMaxRegularEntry = kMaxRegularCapacity / kEntrySize; static const int kMaxRegularEntry = kMaxRegularCapacity / kEntrySize;
static const int kMaxRegularIndex = EntryToIndex(kMaxRegularEntry); static const int kMaxRegularIndex =
EntryToIndex(InternalIndex(kMaxRegularEntry));
STATIC_ASSERT(OffsetOfElementAt(kMaxRegularIndex) < STATIC_ASSERT(OffsetOfElementAt(kMaxRegularIndex) <
kMaxRegularHeapObjectSize); kMaxRegularHeapObjectSize);
@ -250,10 +241,10 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) HashTable
// Returns _expected_ if one of entries given by the first _probe_ probes is // Returns _expected_ if one of entries given by the first _probe_ probes is
// equal to _expected_. Otherwise, returns the entry given by the probe // equal to _expected_. Otherwise, returns the entry given by the probe
// number _probe_. // number _probe_.
uint32_t EntryForProbe(ReadOnlyRoots roots, Object k, int probe, InternalIndex EntryForProbe(ReadOnlyRoots roots, Object k, int probe,
uint32_t expected); InternalIndex expected);
void Swap(uint32_t entry1, uint32_t entry2, WriteBarrierMode mode); void Swap(InternalIndex entry1, InternalIndex entry2, WriteBarrierMode mode);
// Rehashes this hash-table into the new table. // Rehashes this hash-table into the new table.
void Rehash(ReadOnlyRoots roots, Derived new_table); void Rehash(ReadOnlyRoots roots, Derived new_table);
@ -307,7 +298,7 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) ObjectHashTableBase
Object Lookup(ReadOnlyRoots roots, Handle<Object> key, int32_t hash); Object Lookup(ReadOnlyRoots roots, Handle<Object> key, int32_t hash);
// Returns the value at entry. // Returns the value at entry.
Object ValueAt(int entry); Object ValueAt(InternalIndex entry);
// Overwrite all keys and values with the hole value. // Overwrite all keys and values with the hole value.
static void FillEntriesWithHoles(Handle<Derived>); static void FillEntriesWithHoles(Handle<Derived>);
@ -327,14 +318,14 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) ObjectHashTableBase
int32_t hash); int32_t hash);
// Returns the index to the value of an entry. // Returns the index to the value of an entry.
static inline int EntryToValueIndex(int entry) { static inline int EntryToValueIndex(InternalIndex entry) {
return HashTable<Derived, Shape>::EntryToIndex(entry) + return HashTable<Derived, Shape>::EntryToIndex(entry) +
Shape::kEntryValueIndex; Shape::kEntryValueIndex;
} }
protected: protected:
void AddEntry(int entry, Object key, Object value); void AddEntry(InternalIndex entry, Object key, Object value);
void RemoveEntry(int entry); void RemoveEntry(InternalIndex entry);
OBJECT_CONSTRUCTORS(ObjectHashTableBase, HashTable<Derived, Shape>); OBJECT_CONSTRUCTORS(ObjectHashTableBase, HashTable<Derived, Shape>);
}; };

View File

@ -19,14 +19,14 @@ namespace internal {
// wrapper: get it via GetEntryForIndex, pass it on to consumers. // wrapper: get it via GetEntryForIndex, pass it on to consumers.
class InternalIndex { class InternalIndex {
public: public:
explicit InternalIndex(size_t raw) : entry_(raw) {} explicit constexpr InternalIndex(size_t raw) : entry_(raw) {}
static InternalIndex NotFound() { return InternalIndex(kNotFound); } static InternalIndex NotFound() { return InternalIndex(kNotFound); }
InternalIndex adjust_down(size_t subtract) { V8_WARN_UNUSED_RESULT InternalIndex adjust_down(size_t subtract) const {
DCHECK_GE(entry_, subtract); DCHECK_GE(entry_, subtract);
return InternalIndex(entry_ - subtract); return InternalIndex(entry_ - subtract);
} }
InternalIndex adjust_up(size_t add) { V8_WARN_UNUSED_RESULT InternalIndex adjust_up(size_t add) const {
DCHECK_LT(entry_, std::numeric_limits<size_t>::max() - add); DCHECK_LT(entry_, std::numeric_limits<size_t>::max() - add);
return InternalIndex(entry_ + add); return InternalIndex(entry_ + add);
} }
@ -39,8 +39,11 @@ class InternalIndex {
DCHECK_LE(entry_, std::numeric_limits<uint32_t>::max()); DCHECK_LE(entry_, std::numeric_limits<uint32_t>::max());
return static_cast<uint32_t>(entry_); return static_cast<uint32_t>(entry_);
} }
int as_int() const { constexpr int as_int() const {
DCHECK(entry_ >= 0 && entry_ <= std::numeric_limits<int>::max()); #if V8_CAN_HAVE_DCHECK_IN_CONSTEXPR
// TODO(clemensb): DCHECK_LE is not constexpr.
DCHECK(entry_ <= std::numeric_limits<int>::max());
#endif
return static_cast<int>(entry_); return static_cast<int>(entry_);
} }

View File

@ -705,15 +705,15 @@ Smi JSReceiver::GetOrCreateIdentityHash(Isolate* isolate) {
} }
void JSReceiver::DeleteNormalizedProperty(Handle<JSReceiver> object, void JSReceiver::DeleteNormalizedProperty(Handle<JSReceiver> object,
int entry) { InternalIndex entry) {
DCHECK(!object->HasFastProperties()); DCHECK(!object->HasFastProperties());
Isolate* isolate = object->GetIsolate(); Isolate* isolate = object->GetIsolate();
DCHECK(entry.is_found());
if (object->IsJSGlobalObject()) { if (object->IsJSGlobalObject()) {
// If we have a global object, invalidate the cell and swap in a new one. // If we have a global object, invalidate the cell and swap in a new one.
Handle<GlobalDictionary> dictionary( Handle<GlobalDictionary> dictionary(
JSGlobalObject::cast(*object).global_dictionary(), isolate); JSGlobalObject::cast(*object).global_dictionary(), isolate);
DCHECK_NE(GlobalDictionary::kNotFound, entry);
auto cell = PropertyCell::InvalidateEntry(isolate, dictionary, entry); auto cell = PropertyCell::InvalidateEntry(isolate, dictionary, entry);
cell->set_value(ReadOnlyRoots(isolate).the_hole_value()); cell->set_value(ReadOnlyRoots(isolate).the_hole_value());
@ -721,7 +721,6 @@ void JSReceiver::DeleteNormalizedProperty(Handle<JSReceiver> object,
PropertyDetails::Empty(PropertyCellType::kUninitialized)); PropertyDetails::Empty(PropertyCellType::kUninitialized));
} else { } else {
Handle<NameDictionary> dictionary(object->property_dictionary(), isolate); Handle<NameDictionary> dictionary(object->property_dictionary(), isolate);
DCHECK_NE(NameDictionary::kNotFound, entry);
dictionary = NameDictionary::DeleteEntry(isolate, dictionary, entry); dictionary = NameDictionary::DeleteEntry(isolate, dictionary, entry);
object->SetProperties(*dictionary); object->SetProperties(*dictionary);
@ -2332,9 +2331,10 @@ void JSObject::SetNormalizedProperty(Handle<JSObject> object, Handle<Name> name,
Handle<JSGlobalObject> global_obj = Handle<JSGlobalObject>::cast(object); Handle<JSGlobalObject> global_obj = Handle<JSGlobalObject>::cast(object);
Handle<GlobalDictionary> dictionary(global_obj->global_dictionary(), Handle<GlobalDictionary> dictionary(global_obj->global_dictionary(),
isolate); isolate);
int entry = dictionary->FindEntry(ReadOnlyRoots(isolate), name, hash); InternalIndex entry =
dictionary->FindEntry(ReadOnlyRoots(isolate), name, hash);
if (entry == GlobalDictionary::kNotFound) { if (entry.is_not_found()) {
DCHECK_IMPLIES(global_obj->map().is_prototype_map(), DCHECK_IMPLIES(global_obj->map().is_prototype_map(),
Map::IsPrototypeChainInvalidated(global_obj->map())); Map::IsPrototypeChainInvalidated(global_obj->map()));
auto cell = isolate->factory()->NewPropertyCell(name); auto cell = isolate->factory()->NewPropertyCell(name);
@ -2355,8 +2355,8 @@ void JSObject::SetNormalizedProperty(Handle<JSObject> object, Handle<Name> name,
} else { } else {
Handle<NameDictionary> dictionary(object->property_dictionary(), isolate); Handle<NameDictionary> dictionary(object->property_dictionary(), isolate);
int entry = dictionary->FindEntry(isolate, name); InternalIndex entry = dictionary->FindEntry(isolate, name);
if (entry == NameDictionary::kNotFound) { if (entry.is_not_found()) {
DCHECK_IMPLIES(object->map().is_prototype_map(), DCHECK_IMPLIES(object->map().is_prototype_map(),
Map::IsPrototypeChainInvalidated(object->map())); Map::IsPrototypeChainInvalidated(object->map()));
dictionary = dictionary =
@ -3331,7 +3331,7 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object,
// Compute the length of the instance descriptor. // Compute the length of the instance descriptor.
ReadOnlyRoots roots(isolate); ReadOnlyRoots roots(isolate);
for (int i = 0; i < instance_descriptor_length; i++) { for (int i = 0; i < instance_descriptor_length; i++) {
int index = Smi::ToInt(iteration_order->get(i)); InternalIndex index(Smi::ToInt(iteration_order->get(i)));
DCHECK(dictionary->IsKey(roots, dictionary->KeyAt(index))); DCHECK(dictionary->IsKey(roots, dictionary->KeyAt(index)));
PropertyKind kind = dictionary->DetailsAt(index).kind(); PropertyKind kind = dictionary->DetailsAt(index).kind();
@ -3391,7 +3391,7 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object,
// Fill in the instance descriptor and the fields. // Fill in the instance descriptor and the fields.
int current_offset = 0; int current_offset = 0;
for (int i = 0; i < instance_descriptor_length; i++) { for (int i = 0; i < instance_descriptor_length; i++) {
int index = Smi::ToInt(iteration_order->get(i)); InternalIndex index(Smi::ToInt(iteration_order->get(i)));
Name k = dictionary->NameAt(index); Name k = dictionary->NameAt(index);
// Dictionary keys are internalized upon insertion. // Dictionary keys are internalized upon insertion.
// TODO(jkummerow): Turn this into a DCHECK if it's not hit in the wild. // TODO(jkummerow): Turn this into a DCHECK if it's not hit in the wild.
@ -3611,8 +3611,7 @@ bool TestDictionaryPropertiesIntegrityLevel(Dictionary dict,
PropertyAttributes level) { PropertyAttributes level) {
DCHECK(level == SEALED || level == FROZEN); DCHECK(level == SEALED || level == FROZEN);
uint32_t capacity = dict.Capacity(); for (InternalIndex i : dict.IterateEntries()) {
for (uint32_t i = 0; i < capacity; i++) {
Object key; Object key;
if (!dict.ToKey(roots, i, &key)) continue; if (!dict.ToKey(roots, i, &key)) continue;
if (key.FilterKey(ALL_PROPERTIES)) continue; if (key.FilterKey(ALL_PROPERTIES)) continue;
@ -3773,8 +3772,7 @@ template <typename Dictionary>
void JSObject::ApplyAttributesToDictionary( void JSObject::ApplyAttributesToDictionary(
Isolate* isolate, ReadOnlyRoots roots, Handle<Dictionary> dictionary, Isolate* isolate, ReadOnlyRoots roots, Handle<Dictionary> dictionary,
const PropertyAttributes attributes) { const PropertyAttributes attributes) {
int capacity = dictionary->Capacity(); for (InternalIndex i : dictionary->IterateEntries()) {
for (int i = 0; i < capacity; i++) {
Object k; Object k;
if (!dictionary->ToKey(roots, i, &k)) continue; if (!dictionary->ToKey(roots, i, &k)) continue;
if (k.FilterKey(ALL_PROPERTIES)) continue; if (k.FilterKey(ALL_PROPERTIES)) continue;
@ -4615,7 +4613,7 @@ static ElementsKind BestFittingFastElementsKind(JSObject object) {
DCHECK(object.HasDictionaryElements()); DCHECK(object.HasDictionaryElements());
NumberDictionary dictionary = object.element_dictionary(); NumberDictionary dictionary = object.element_dictionary();
ElementsKind kind = HOLEY_SMI_ELEMENTS; ElementsKind kind = HOLEY_SMI_ELEMENTS;
for (int i = 0; i < dictionary.Capacity(); i++) { for (InternalIndex i : dictionary.IterateEntries()) {
Object key = dictionary.KeyAt(i); Object key = dictionary.KeyAt(i);
if (key.IsNumber()) { if (key.IsNumber()) {
Object value = dictionary.ValueAt(i); Object value = dictionary.ValueAt(i);
@ -5632,20 +5630,20 @@ void JSGlobalObject::InvalidatePropertyCell(Handle<JSGlobalObject> global,
DCHECK(!global->HasFastProperties()); DCHECK(!global->HasFastProperties());
auto dictionary = handle(global->global_dictionary(), global->GetIsolate()); auto dictionary = handle(global->global_dictionary(), global->GetIsolate());
int entry = dictionary->FindEntry(global->GetIsolate(), name); InternalIndex entry = dictionary->FindEntry(global->GetIsolate(), name);
if (entry == GlobalDictionary::kNotFound) return; if (entry.is_not_found()) return;
PropertyCell::InvalidateEntry(global->GetIsolate(), dictionary, entry); PropertyCell::InvalidateEntry(global->GetIsolate(), dictionary, entry);
} }
Handle<PropertyCell> JSGlobalObject::EnsureEmptyPropertyCell( Handle<PropertyCell> JSGlobalObject::EnsureEmptyPropertyCell(
Handle<JSGlobalObject> global, Handle<Name> name, Handle<JSGlobalObject> global, Handle<Name> name,
PropertyCellType cell_type, int* entry_out) { PropertyCellType cell_type, InternalIndex* entry_out) {
Isolate* isolate = global->GetIsolate(); Isolate* isolate = global->GetIsolate();
DCHECK(!global->HasFastProperties()); DCHECK(!global->HasFastProperties());
Handle<GlobalDictionary> dictionary(global->global_dictionary(), isolate); Handle<GlobalDictionary> dictionary(global->global_dictionary(), isolate);
int entry = dictionary->FindEntry(isolate, name); InternalIndex entry = dictionary->FindEntry(isolate, name);
Handle<PropertyCell> cell; Handle<PropertyCell> cell;
if (entry != GlobalDictionary::kNotFound) { if (entry.is_found()) {
if (entry_out) *entry_out = entry; if (entry_out) *entry_out = entry;
cell = handle(dictionary->CellAt(entry), isolate); cell = handle(dictionary->CellAt(entry), isolate);
PropertyCellType original_cell_type = cell->property_details().cell_type(); PropertyCellType original_cell_type = cell->property_details().cell_type();

View File

@ -68,7 +68,8 @@ class JSReceiver : public HeapObject {
inline void initialize_properties(Isolate* isolate); inline void initialize_properties(Isolate* isolate);
// Deletes an existing named property in a normalized object. // Deletes an existing named property in a normalized object.
static void DeleteNormalizedProperty(Handle<JSReceiver> object, int entry); static void DeleteNormalizedProperty(Handle<JSReceiver> object,
InternalIndex entry);
DECL_CAST(JSReceiver) DECL_CAST(JSReceiver)
DECL_VERIFIER(JSReceiver) DECL_VERIFIER(JSReceiver)
@ -1205,7 +1206,7 @@ class JSGlobalObject : public JSSpecialObject {
// Ensure that the global object has a cell for the given property name. // Ensure that the global object has a cell for the given property name.
static Handle<PropertyCell> EnsureEmptyPropertyCell( static Handle<PropertyCell> EnsureEmptyPropertyCell(
Handle<JSGlobalObject> global, Handle<Name> name, Handle<JSGlobalObject> global, Handle<Name> name,
PropertyCellType cell_type, int* entry_out = nullptr); PropertyCellType cell_type, InternalIndex* entry_out = nullptr);
DECL_CAST(JSGlobalObject) DECL_CAST(JSGlobalObject)

View File

@ -81,14 +81,16 @@ void AddToDescriptorArrayTemplate(
Handle<NameDictionary> DictionaryAddNoUpdateNextEnumerationIndex( Handle<NameDictionary> DictionaryAddNoUpdateNextEnumerationIndex(
Isolate* isolate, Handle<NameDictionary> dictionary, Handle<Name> name, Isolate* isolate, Handle<NameDictionary> dictionary, Handle<Name> name,
Handle<Object> value, PropertyDetails details, int* entry_out = nullptr) { Handle<Object> value, PropertyDetails details,
InternalIndex* entry_out = nullptr) {
return NameDictionary::AddNoUpdateNextEnumerationIndex( return NameDictionary::AddNoUpdateNextEnumerationIndex(
isolate, dictionary, name, value, details, entry_out); isolate, dictionary, name, value, details, entry_out);
} }
Handle<NumberDictionary> DictionaryAddNoUpdateNextEnumerationIndex( Handle<NumberDictionary> DictionaryAddNoUpdateNextEnumerationIndex(
Isolate* isolate, Handle<NumberDictionary> dictionary, uint32_t element, Isolate* isolate, Handle<NumberDictionary> dictionary, uint32_t element,
Handle<Object> value, PropertyDetails details, int* entry_out = nullptr) { Handle<Object> value, PropertyDetails details,
InternalIndex* entry_out = nullptr) {
// NumberDictionary does not maintain the enumeration order, so it's // NumberDictionary does not maintain the enumeration order, so it's
// a normal Add(). // a normal Add().
return NumberDictionary::Add(isolate, dictionary, element, value, details, return NumberDictionary::Add(isolate, dictionary, element, value, details,
@ -123,9 +125,9 @@ void AddToDictionaryTemplate(Isolate* isolate, Handle<Dictionary> dictionary,
Key key, int key_index, Key key, int key_index,
ClassBoilerplate::ValueKind value_kind, ClassBoilerplate::ValueKind value_kind,
Object value) { Object value) {
int entry = dictionary->FindEntry(isolate, key); InternalIndex entry = dictionary->FindEntry(isolate, key);
if (entry == kNotFound) { if (entry.is_not_found()) {
// Entry not found, add new one. // Entry not found, add new one.
const bool is_elements_dictionary = const bool is_elements_dictionary =
std::is_same<Dictionary, NumberDictionary>::value; std::is_same<Dictionary, NumberDictionary>::value;

View File

@ -40,8 +40,7 @@ LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
receiver_(receiver), receiver_(receiver),
initial_holder_(holder), initial_holder_(holder),
// kMaxUInt32 isn't a valid index. // kMaxUInt32 isn't a valid index.
index_(kMaxUInt32), index_(kMaxUInt32) {
number_(static_cast<uint32_t>(DescriptorArray::kNotFound)) {
#ifdef DEBUG #ifdef DEBUG
uint32_t index; // Assert that the name is not an array index. uint32_t index; // Assert that the name is not an array index.
DCHECK(!name->AsArrayIndex(&index)); DCHECK(!name->AsArrayIndex(&index));
@ -141,10 +140,10 @@ InternalIndex LookupIterator::descriptor_number() const {
DCHECK(!IsElement()); DCHECK(!IsElement());
DCHECK(has_property_); DCHECK(has_property_);
DCHECK(holder_->HasFastProperties(isolate_)); DCHECK(holder_->HasFastProperties(isolate_));
return InternalIndex(number_); return number_;
} }
int LookupIterator::dictionary_entry() const { InternalIndex LookupIterator::dictionary_entry() const {
DCHECK(!IsElement()); DCHECK(!IsElement());
DCHECK(has_property_); DCHECK(has_property_);
DCHECK(!holder_->HasFastProperties(isolate_)); DCHECK(!holder_->HasFastProperties(isolate_));

View File

@ -95,8 +95,7 @@ LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
transition_(transition_map), transition_(transition_map),
receiver_(receiver), receiver_(receiver),
initial_holder_(GetRoot(isolate, receiver)), initial_holder_(GetRoot(isolate, receiver)),
index_(kMaxUInt32), index_(kMaxUInt32) {
number_(static_cast<uint32_t>(DescriptorArray::kNotFound)) {
holder_ = initial_holder_; holder_ = initial_holder_;
} }
@ -164,7 +163,7 @@ template <bool is_element>
void LookupIterator::RestartInternal(InterceptorState interceptor_state) { void LookupIterator::RestartInternal(InterceptorState interceptor_state) {
interceptor_state_ = interceptor_state; interceptor_state_ = interceptor_state;
property_details_ = PropertyDetails::Empty(); property_details_ = PropertyDetails::Empty();
number_ = static_cast<uint32_t>(DescriptorArray::kNotFound); number_ = InternalIndex::NotFound();
Start<is_element>(); Start<is_element>();
} }
@ -534,7 +533,7 @@ void LookupIterator::ReconfigureDataProperty(Handle<Object> value,
DCHECK(attributes != NONE || !holder_obj->HasFastElements(isolate_)); DCHECK(attributes != NONE || !holder_obj->HasFastElements(isolate_));
Handle<FixedArrayBase> elements(holder_obj->elements(isolate_), isolate()); Handle<FixedArrayBase> elements(holder_obj->elements(isolate_), isolate());
holder_obj->GetElementsAccessor(isolate_)->Reconfigure( holder_obj->GetElementsAccessor(isolate_)->Reconfigure(
holder_obj, elements, InternalIndex(number_), value, attributes); holder_obj, elements, number_, value, attributes);
ReloadPropertyInformation<true>(); ReloadPropertyInformation<true>();
} else if (holder_obj->HasFastProperties(isolate_)) { } else if (holder_obj->HasFastProperties(isolate_)) {
Handle<Map> old_map(holder_obj->map(isolate_), isolate_); Handle<Map> old_map(holder_obj->map(isolate_), isolate_);
@ -624,9 +623,8 @@ void LookupIterator::PrepareTransitionToDataProperty(
if (map->IsJSGlobalObjectMap()) { if (map->IsJSGlobalObjectMap()) {
// Install a property cell. // Install a property cell.
Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(receiver); Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(receiver);
int entry;
Handle<PropertyCell> cell = JSGlobalObject::EnsureEmptyPropertyCell( Handle<PropertyCell> cell = JSGlobalObject::EnsureEmptyPropertyCell(
global, name(), PropertyCellType::kUninitialized, &entry); global, name(), PropertyCellType::kUninitialized, &number_);
Handle<GlobalDictionary> dictionary(global->global_dictionary(isolate_), Handle<GlobalDictionary> dictionary(global->global_dictionary(isolate_),
isolate_); isolate_);
DCHECK(cell->value(isolate_).IsTheHole(isolate_)); DCHECK(cell->value(isolate_).IsTheHole(isolate_));
@ -642,7 +640,6 @@ void LookupIterator::PrepareTransitionToDataProperty(
PropertyCell::UpdatedType(isolate(), cell, value, property_details_); PropertyCell::UpdatedType(isolate(), cell, value, property_details_);
property_details_ = property_details_.set_cell_type(new_type); property_details_ = property_details_.set_cell_type(new_type);
cell->set_property_details(property_details_); cell->set_property_details(property_details_);
number_ = entry;
has_property_ = true; has_property_ = true;
} else { } else {
// Don't set enumeration index (it will be set during value store). // Don't set enumeration index (it will be set during value store).
@ -699,24 +696,22 @@ void LookupIterator::ApplyTransitionToDataProperty(
} }
if (simple_transition) { if (simple_transition) {
number_ = transition->LastAdded().as_uint32(); number_ = transition->LastAdded();
property_details_ = transition->GetLastDescriptorDetails(isolate_); property_details_ = transition->GetLastDescriptorDetails(isolate_);
state_ = DATA; state_ = DATA;
} else if (receiver->map(isolate_).is_dictionary_map()) { } else if (receiver->map(isolate_).is_dictionary_map()) {
Handle<NameDictionary> dictionary(receiver->property_dictionary(isolate_), Handle<NameDictionary> dictionary(receiver->property_dictionary(isolate_),
isolate_); isolate_);
int entry;
if (receiver->map(isolate_).is_prototype_map() && if (receiver->map(isolate_).is_prototype_map() &&
receiver->IsJSObject(isolate_)) { receiver->IsJSObject(isolate_)) {
JSObject::InvalidatePrototypeChains(receiver->map(isolate_)); JSObject::InvalidatePrototypeChains(receiver->map(isolate_));
} }
dictionary = NameDictionary::Add(isolate(), dictionary, name(), dictionary = NameDictionary::Add(isolate(), dictionary, name(),
isolate_->factory()->uninitialized_value(), isolate_->factory()->uninitialized_value(),
property_details_, &entry); property_details_, &number_);
receiver->SetProperties(*dictionary); receiver->SetProperties(*dictionary);
// Reload details containing proper enumeration index value. // Reload details containing proper enumeration index value.
property_details_ = dictionary->DetailsAt(entry); property_details_ = dictionary->DetailsAt(number_);
number_ = entry;
has_property_ = true; has_property_ = true;
state_ = DATA; state_ = DATA;
@ -730,7 +725,7 @@ void LookupIterator::Delete() {
if (IsElement()) { if (IsElement()) {
Handle<JSObject> object = Handle<JSObject>::cast(holder); Handle<JSObject> object = Handle<JSObject>::cast(holder);
ElementsAccessor* accessor = object->GetElementsAccessor(isolate_); ElementsAccessor* accessor = object->GetElementsAccessor(isolate_);
accessor->Delete(object, InternalIndex(number_)); accessor->Delete(object, number_);
} else { } else {
DCHECK(!name()->IsPrivateName(isolate_)); DCHECK(!name()->IsPrivateName(isolate_));
bool is_prototype_map = holder->map(isolate_).is_prototype_map(); bool is_prototype_map = holder->map(isolate_).is_prototype_map();
@ -747,7 +742,7 @@ void LookupIterator::Delete() {
mode, 0, "DeletingProperty"); mode, 0, "DeletingProperty");
ReloadPropertyInformation<false>(); ReloadPropertyInformation<false>();
} }
JSReceiver::DeleteNormalizedProperty(holder, number_); JSReceiver::DeleteNormalizedProperty(holder, dictionary_entry());
if (holder->IsJSObject(isolate_)) { if (holder->IsJSObject(isolate_)) {
JSObject::ReoptimizeIfPrototype(Handle<JSObject>::cast(holder)); JSObject::ReoptimizeIfPrototype(Handle<JSObject>::cast(holder));
} }
@ -776,20 +771,18 @@ void LookupIterator::TransitionToAccessorProperty(
} else if (state_ == INTERCEPTOR) { } else if (state_ == INTERCEPTOR) {
LookupInRegularHolder<false>(*old_map, *holder_); LookupInRegularHolder<false>(*old_map, *holder_);
} }
// TODO(jkummerow): {IsFound()} should be enough once {number_} has type // The case of IsFound() && number_.is_not_found() can occur for
// {InternalIndex}. // interceptors.
InternalIndex descriptor = (IsFound() && number_ != kMaxUInt32) DCHECK_IMPLIES(!IsFound(), number_.is_not_found());
? InternalIndex(number_)
: InternalIndex::NotFound();
Handle<Map> new_map = Map::TransitionToAccessorProperty( Handle<Map> new_map = Map::TransitionToAccessorProperty(
isolate_, old_map, name_, descriptor, getter, setter, attributes); isolate_, old_map, name_, number_, getter, setter, attributes);
bool simple_transition = bool simple_transition =
new_map->GetBackPointer(isolate_) == receiver->map(isolate_); new_map->GetBackPointer(isolate_) == receiver->map(isolate_);
JSObject::MigrateToMap(isolate_, receiver, new_map); JSObject::MigrateToMap(isolate_, receiver, new_map);
if (simple_transition) { if (simple_transition) {
number_ = new_map->LastAdded().as_uint32(); number_ = new_map->LastAdded();
property_details_ = new_map->GetLastDescriptorDetails(isolate_); property_details_ = new_map->GetLastDescriptorDetails(isolate_);
state_ = ACCESSOR; state_ = ACCESSOR;
return; return;
@ -845,8 +838,8 @@ void LookupIterator::TransitionToAccessorPair(Handle<Object> pair,
if (receiver->HasSlowArgumentsElements(isolate_)) { if (receiver->HasSlowArgumentsElements(isolate_)) {
FixedArray parameter_map = FixedArray::cast(receiver->elements(isolate_)); FixedArray parameter_map = FixedArray::cast(receiver->elements(isolate_));
uint32_t length = parameter_map.length() - 2; uint32_t length = parameter_map.length() - 2;
if (number_ < length) { if (number_.is_found() && number_.as_uint32() < length) {
parameter_map.set(number_ + 2, parameter_map.set(number_.as_int() + 2,
ReadOnlyRoots(isolate_).the_hole_value()); ReadOnlyRoots(isolate_).the_hole_value());
} }
FixedArray::cast(receiver->elements(isolate_)).set(1, *dictionary); FixedArray::cast(receiver->elements(isolate_)).set(1, *dictionary);
@ -895,10 +888,11 @@ Handle<Object> LookupIterator::FetchValue() const {
if (IsElement()) { if (IsElement()) {
Handle<JSObject> holder = GetHolder<JSObject>(); Handle<JSObject> holder = GetHolder<JSObject>();
ElementsAccessor* accessor = holder->GetElementsAccessor(isolate_); ElementsAccessor* accessor = holder->GetElementsAccessor(isolate_);
return accessor->Get(holder, InternalIndex(number_)); return accessor->Get(holder, number_);
} else if (holder_->IsJSGlobalObject(isolate_)) { } else if (holder_->IsJSGlobalObject(isolate_)) {
Handle<JSGlobalObject> holder = GetHolder<JSGlobalObject>(); Handle<JSGlobalObject> holder = GetHolder<JSGlobalObject>();
result = holder->global_dictionary(isolate_).ValueAt(isolate_, number_); result = holder->global_dictionary(isolate_).ValueAt(isolate_,
dictionary_entry());
} else if (!holder_->HasFastProperties(isolate_)) { } else if (!holder_->HasFastProperties(isolate_)) {
result = holder_->property_dictionary(isolate_).ValueAt(isolate_, result = holder_->property_dictionary(isolate_).ValueAt(isolate_,
dictionary_entry()); dictionary_entry());
@ -1031,7 +1025,7 @@ void LookupIterator::WriteDataValue(Handle<Object> value,
if (IsElement()) { if (IsElement()) {
Handle<JSObject> object = Handle<JSObject>::cast(holder); Handle<JSObject> object = Handle<JSObject>::cast(holder);
ElementsAccessor* accessor = object->GetElementsAccessor(isolate_); ElementsAccessor* accessor = object->GetElementsAccessor(isolate_);
accessor->Set(object, InternalIndex(number_), *value); accessor->Set(object, number_, *value);
} else if (holder->HasFastProperties(isolate_)) { } else if (holder->HasFastProperties(isolate_)) {
if (property_details_.location() == kField) { if (property_details_.location() == kField) {
// Check that in case of VariableMode::kConst field the existing value is // Check that in case of VariableMode::kConst field the existing value is
@ -1129,9 +1123,8 @@ LookupIterator::State LookupIterator::LookupInSpecialHolder(
if (!is_element && map.IsJSGlobalObjectMap()) { if (!is_element && map.IsJSGlobalObjectMap()) {
GlobalDictionary dict = GlobalDictionary dict =
JSGlobalObject::cast(holder).global_dictionary(isolate_); JSGlobalObject::cast(holder).global_dictionary(isolate_);
int number = dict.FindEntry(isolate(), name_); number_ = dict.FindEntry(isolate(), name_);
if (number == GlobalDictionary::kNotFound) return NOT_FOUND; if (number_.is_not_found()) return NOT_FOUND;
number_ = static_cast<uint32_t>(number);
PropertyCell cell = dict.CellAt(isolate_, number_); PropertyCell cell = dict.CellAt(isolate_, number_);
if (cell.value(isolate_).IsTheHole(isolate_)) return NOT_FOUND; if (cell.value(isolate_).IsTheHole(isolate_)) return NOT_FOUND;
property_details_ = cell.property_details(); property_details_ = cell.property_details();
@ -1167,15 +1160,13 @@ LookupIterator::State LookupIterator::LookupInRegularHolder(
JSObject js_object = JSObject::cast(holder); JSObject js_object = JSObject::cast(holder);
ElementsAccessor* accessor = js_object.GetElementsAccessor(isolate_); ElementsAccessor* accessor = js_object.GetElementsAccessor(isolate_);
FixedArrayBase backing_store = js_object.elements(isolate_); FixedArrayBase backing_store = js_object.elements(isolate_);
// TODO(jkummerow): {number_} should have type InternalIndex. number_ =
InternalIndex entry =
accessor->GetEntryForIndex(isolate_, js_object, backing_store, index_); accessor->GetEntryForIndex(isolate_, js_object, backing_store, index_);
number_ = entry.is_found() ? entry.as_uint32() : kMaxUInt32; if (number_.is_not_found()) {
if (number_ == kMaxUInt32) {
return holder.IsJSTypedArray(isolate_) ? INTEGER_INDEXED_EXOTIC return holder.IsJSTypedArray(isolate_) ? INTEGER_INDEXED_EXOTIC
: NOT_FOUND; : NOT_FOUND;
} }
property_details_ = accessor->GetDetails(js_object, InternalIndex(number_)); property_details_ = accessor->GetDetails(js_object, number_);
if (map.has_frozen_elements()) { if (map.has_frozen_elements()) {
property_details_ = property_details_.CopyAddAttributes(FROZEN); property_details_ = property_details_.CopyAddAttributes(FROZEN);
} else if (map.has_sealed_elements()) { } else if (map.has_sealed_elements()) {
@ -1183,16 +1174,14 @@ LookupIterator::State LookupIterator::LookupInRegularHolder(
} }
} else if (!map.is_dictionary_map()) { } else if (!map.is_dictionary_map()) {
DescriptorArray descriptors = map.instance_descriptors(isolate_); DescriptorArray descriptors = map.instance_descriptors(isolate_);
InternalIndex number = descriptors.SearchWithCache(isolate_, *name_, map); number_ = descriptors.SearchWithCache(isolate_, *name_, map);
if (number.is_not_found()) return NotFound(holder); if (number_.is_not_found()) return NotFound(holder);
number_ = number.as_uint32(); property_details_ = descriptors.GetDetails(number_);
property_details_ = descriptors.GetDetails(InternalIndex(number_));
} else { } else {
DCHECK_IMPLIES(holder.IsJSProxy(isolate_), name()->IsPrivate(isolate_)); DCHECK_IMPLIES(holder.IsJSProxy(isolate_), name()->IsPrivate(isolate_));
NameDictionary dict = holder.property_dictionary(isolate_); NameDictionary dict = holder.property_dictionary(isolate_);
int number = dict.FindEntry(isolate(), name_); number_ = dict.FindEntry(isolate(), name_);
if (number == NameDictionary::kNotFound) return NotFound(holder); if (number_.is_not_found()) return NotFound(holder);
number_ = static_cast<uint32_t>(number);
property_details_ = dict.DetailsAt(number_); property_details_ = dict.DetailsAt(number_);
} }
has_property_ = true; has_property_ = true;

View File

@ -69,8 +69,7 @@ class V8_EXPORT_PRIVATE LookupIterator final {
isolate_(isolate), isolate_(isolate),
receiver_(receiver), receiver_(receiver),
initial_holder_(holder), initial_holder_(holder),
index_(index), index_(index) {
number_(static_cast<uint32_t>(DescriptorArray::kNotFound)) {
// kMaxUInt32 isn't a valid index. // kMaxUInt32 isn't a valid index.
DCHECK_NE(kMaxUInt32, index_); DCHECK_NE(kMaxUInt32, index_);
Start<true>(); Start<true>();
@ -242,7 +241,7 @@ class V8_EXPORT_PRIVATE LookupIterator final {
return (configuration_ & kInterceptor) != 0; return (configuration_ & kInterceptor) != 0;
} }
inline InternalIndex descriptor_number() const; inline InternalIndex descriptor_number() const;
inline int dictionary_entry() const; inline InternalIndex dictionary_entry() const;
static inline Configuration ComputeConfiguration(Isolate* isolate, static inline Configuration ComputeConfiguration(Isolate* isolate,
Configuration configuration, Configuration configuration,
@ -270,7 +269,7 @@ class V8_EXPORT_PRIVATE LookupIterator final {
Handle<JSReceiver> holder_; Handle<JSReceiver> holder_;
const Handle<JSReceiver> initial_holder_; const Handle<JSReceiver> initial_holder_;
const uint32_t index_; const uint32_t index_;
uint32_t number_; InternalIndex number_ = InternalIndex::NotFound();
}; };
} // namespace internal } // namespace internal

View File

@ -303,7 +303,7 @@ Handle<JSModuleNamespace> Module::GetModuleNamespace(Isolate* isolate,
Handle<ObjectHashTable> exports(module->exports(), isolate); Handle<ObjectHashTable> exports(module->exports(), isolate);
ZoneVector<Handle<String>> names(&zone); ZoneVector<Handle<String>> names(&zone);
names.reserve(exports->NumberOfElements()); names.reserve(exports->NumberOfElements());
for (int i = 0, n = exports->Capacity(); i < n; ++i) { for (InternalIndex i : exports->IterateEntries()) {
Object key; Object key;
if (!exports->ToKey(roots, i, &key)) continue; if (!exports->ToKey(roots, i, &key)) continue;
names.push_back(handle(String::cast(key), isolate)); names.push_back(handle(String::cast(key), isolate));

View File

@ -1106,11 +1106,10 @@ class EphemeronHashTable::BodyDescriptor final : public BodyDescriptorBase {
EphemeronHashTable::kElementsStartIndex * kTaggedSize; EphemeronHashTable::kElementsStartIndex * kTaggedSize;
IteratePointers(obj, EphemeronHashTable::kHeaderSize, entries_start, v); IteratePointers(obj, EphemeronHashTable::kHeaderSize, entries_start, v);
EphemeronHashTable table = EphemeronHashTable::unchecked_cast(obj); EphemeronHashTable table = EphemeronHashTable::unchecked_cast(obj);
int entries = table.Capacity(); for (InternalIndex i : table.IterateEntries()) {
for (int i = 0; i < entries; ++i) {
const int key_index = EphemeronHashTable::EntryToIndex(i); const int key_index = EphemeronHashTable::EntryToIndex(i);
const int value_index = EphemeronHashTable::EntryToValueIndex(i); const int value_index = EphemeronHashTable::EntryToValueIndex(i);
IterateEphemeron(obj, i, OffsetOfElementAt(key_index), IterateEphemeron(obj, i.as_int(), OffsetOfElementAt(key_index),
OffsetOfElementAt(value_index), v); OffsetOfElementAt(value_index), v);
} }
} }

View File

@ -5678,8 +5678,7 @@ void Dictionary<Derived, Shape>::Print(std::ostream& os) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
ReadOnlyRoots roots = this->GetReadOnlyRoots(); ReadOnlyRoots roots = this->GetReadOnlyRoots();
Derived dictionary = Derived::cast(*this); Derived dictionary = Derived::cast(*this);
int capacity = dictionary.Capacity(); for (InternalIndex i : dictionary.IterateEntries()) {
for (int i = 0; i < capacity; i++) {
Object k = dictionary.KeyAt(i); Object k = dictionary.KeyAt(i);
if (!dictionary.ToKey(roots, i, &k)) continue; if (!dictionary.ToKey(roots, i, &k)) continue;
os << "\n "; os << "\n ";
@ -6442,7 +6441,7 @@ template <typename Derived, typename Shape>
Handle<Derived> HashTable<Derived, Shape>::NewInternal( Handle<Derived> HashTable<Derived, Shape>::NewInternal(
Isolate* isolate, int capacity, AllocationType allocation) { Isolate* isolate, int capacity, AllocationType allocation) {
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
int length = EntryToIndex(capacity); int length = EntryToIndex(InternalIndex(capacity));
RootIndex map_root_index = Shape::GetMapRootIndex(); RootIndex map_root_index = Shape::GetMapRootIndex();
Handle<FixedArray> array = Handle<FixedArray> array =
factory->NewFixedArrayWithMap(map_root_index, length, allocation); factory->NewFixedArrayWithMap(map_root_index, length, allocation);
@ -6467,8 +6466,7 @@ void HashTable<Derived, Shape>::Rehash(ReadOnlyRoots roots, Derived new_table) {
} }
// Rehash the elements. // Rehash the elements.
int capacity = this->Capacity(); for (InternalIndex i : this->IterateEntries()) {
for (int i = 0; i < capacity; i++) {
uint32_t from_index = EntryToIndex(i); uint32_t from_index = EntryToIndex(i);
Object k = this->get(from_index); Object k = this->get(from_index);
if (!Shape::IsLive(roots, k)) continue; if (!Shape::IsLive(roots, k)) continue;
@ -6484,12 +6482,12 @@ void HashTable<Derived, Shape>::Rehash(ReadOnlyRoots roots, Derived new_table) {
} }
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
uint32_t HashTable<Derived, Shape>::EntryForProbe(ReadOnlyRoots roots, Object k, InternalIndex HashTable<Derived, Shape>::EntryForProbe(ReadOnlyRoots roots,
int probe, Object k, int probe,
uint32_t expected) { InternalIndex expected) {
uint32_t hash = Shape::HashForObject(roots, k); uint32_t hash = Shape::HashForObject(roots, k);
uint32_t capacity = this->Capacity(); uint32_t capacity = this->Capacity();
uint32_t entry = FirstProbe(hash, capacity); InternalIndex entry = FirstProbe(hash, capacity);
for (int i = 1; i < probe; i++) { for (int i = 1; i < probe; i++) {
if (entry == expected) return expected; if (entry == expected) return expected;
entry = NextProbe(entry, i, capacity); entry = NextProbe(entry, i, capacity);
@ -6498,7 +6496,7 @@ uint32_t HashTable<Derived, Shape>::EntryForProbe(ReadOnlyRoots roots, Object k,
} }
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
void HashTable<Derived, Shape>::Swap(uint32_t entry1, uint32_t entry2, void HashTable<Derived, Shape>::Swap(InternalIndex entry1, InternalIndex entry2,
WriteBarrierMode mode) { WriteBarrierMode mode) {
int index1 = EntryToIndex(entry1); int index1 = EntryToIndex(entry1);
int index2 = EntryToIndex(entry2); int index2 = EntryToIndex(entry2);
@ -6527,22 +6525,30 @@ void HashTable<Derived, Shape>::Rehash(ReadOnlyRoots roots) {
// All elements at entries given by one of the first _probe_ probes // All elements at entries given by one of the first _probe_ probes
// are placed correctly. Other elements might need to be moved. // are placed correctly. Other elements might need to be moved.
done = true; done = true;
for (uint32_t current = 0; current < capacity; current++) { for (InternalIndex current(0); current.raw_value() < capacity;
/* {current} is advanced manually below, when appropriate.*/) {
Object current_key = KeyAt(current); Object current_key = KeyAt(current);
if (!Shape::IsLive(roots, current_key)) continue; if (!Shape::IsLive(roots, current_key)) {
uint32_t target = EntryForProbe(roots, current_key, probe, current); ++current; // Advance to next entry.
if (current == target) continue; continue;
}
InternalIndex target = EntryForProbe(roots, current_key, probe, current);
if (current == target) {
++current; // Advance to next entry.
continue;
}
Object target_key = KeyAt(target); Object target_key = KeyAt(target);
if (!Shape::IsLive(roots, target_key) || if (!Shape::IsLive(roots, target_key) ||
EntryForProbe(roots, target_key, probe, target) != target) { EntryForProbe(roots, target_key, probe, target) != target) {
// Put the current element into the correct position. // Put the current element into the correct position.
Swap(current, target, mode); Swap(current, target, mode);
// The other element will be processed on the next iteration. // The other element will be processed on the next iteration,
current--; // so don't advance {current} here!
} else { } else {
// The place for the current element is occupied. Leave the element // The place for the current element is occupied. Leave the element
// for the next probe. // for the next probe.
done = false; done = false;
++current; // Advance to next entry.
} }
} }
} }
@ -6550,7 +6556,7 @@ void HashTable<Derived, Shape>::Rehash(ReadOnlyRoots roots) {
Object the_hole = roots.the_hole_value(); Object the_hole = roots.the_hole_value();
HeapObject undefined = roots.undefined_value(); HeapObject undefined = roots.undefined_value();
Derived* self = static_cast<Derived*>(this); Derived* self = static_cast<Derived*>(this);
for (uint32_t current = 0; current < capacity; current++) { for (InternalIndex current : InternalIndex::Range(capacity)) {
if (KeyAt(current) == the_hole) { if (KeyAt(current) == the_hole) {
self->set_key(EntryToIndex(current) + kEntryKeyIndex, undefined, self->set_key(EntryToIndex(current) + kEntryKeyIndex, undefined,
SKIP_WRITE_BARRIER); SKIP_WRITE_BARRIER);
@ -6630,9 +6636,9 @@ Handle<Derived> HashTable<Derived, Shape>::Shrink(Isolate* isolate,
} }
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
uint32_t HashTable<Derived, Shape>::FindInsertionEntry(uint32_t hash) { InternalIndex HashTable<Derived, Shape>::FindInsertionEntry(uint32_t hash) {
uint32_t capacity = Capacity(); uint32_t capacity = Capacity();
uint32_t entry = FirstProbe(hash, capacity); InternalIndex entry = FirstProbe(hash, capacity);
uint32_t count = 1; uint32_t count = 1;
// EnsureCapacity will guarantee the hash table is never full. // EnsureCapacity will guarantee the hash table is never full.
ReadOnlyRoots roots = GetReadOnlyRoots(); ReadOnlyRoots roots = GetReadOnlyRoots();
@ -6690,10 +6696,10 @@ Handle<String> StringTable::LookupString(Isolate* isolate,
template <typename StringTableKey> template <typename StringTableKey>
Handle<String> StringTable::LookupKey(Isolate* isolate, StringTableKey* key) { Handle<String> StringTable::LookupKey(Isolate* isolate, StringTableKey* key) {
Handle<StringTable> table = isolate->factory()->string_table(); Handle<StringTable> table = isolate->factory()->string_table();
int entry = table->FindEntry(isolate, key); InternalIndex entry = table->FindEntry(isolate, key);
// String already in table. // String already in table.
if (entry != kNotFound) { if (entry.is_found()) {
return handle(String::cast(table->KeyAt(entry)), isolate); return handle(String::cast(table->KeyAt(entry)), isolate);
} }
@ -6724,10 +6730,10 @@ Handle<String> StringTable::AddKeyNoResize(Isolate* isolate,
// InvalidStringLength error. // InvalidStringLength error.
CHECK(!string.is_null()); CHECK(!string.is_null());
DCHECK(string->HasHashCode()); DCHECK(string->HasHashCode());
DCHECK_EQ(table->FindEntry(isolate, key), kNotFound); DCHECK(table->FindEntry(isolate, key).is_not_found());
// Add the new string and return it along with the string table. // Add the new string and return it along with the string table.
int entry = table->FindInsertionEntry(key->hash()); InternalIndex entry = table->FindInsertionEntry(key->hash());
table->set(EntryToIndex(entry), *string); table->set(EntryToIndex(entry), *string);
table->ElementAdded(); table->ElementAdded();
@ -6783,8 +6789,9 @@ Address LookupString(Isolate* isolate, String string, String source,
return Smi::FromInt(ResultSentinel::kUnsupported).ptr(); return Smi::FromInt(ResultSentinel::kUnsupported).ptr();
} }
int entry = table.FindEntry(ReadOnlyRoots(isolate), &key, key.hash()); InternalIndex entry =
if (entry == kNotFound) { table.FindEntry(ReadOnlyRoots(isolate), &key, key.hash());
if (entry.is_not_found()) {
// A string that's not an array index, and not in the string table, // A string that's not an array index, and not in the string table,
// cannot have been used as a property name before. // cannot have been used as a property name before.
return Smi::FromInt(ResultSentinel::kNotFound).ptr(); return Smi::FromInt(ResultSentinel::kNotFound).ptr();
@ -6842,7 +6849,7 @@ Handle<StringSet> StringSet::Add(Isolate* isolate, Handle<StringSet> stringset,
if (!stringset->Has(isolate, name)) { if (!stringset->Has(isolate, name)) {
stringset = EnsureCapacity(isolate, stringset, 1); stringset = EnsureCapacity(isolate, stringset, 1);
uint32_t hash = ShapeT::Hash(isolate, *name); uint32_t hash = ShapeT::Hash(isolate, *name);
int entry = stringset->FindInsertionEntry(hash); InternalIndex entry = stringset->FindInsertionEntry(hash);
stringset->set(EntryToIndex(entry), *name); stringset->set(EntryToIndex(entry), *name);
stringset->ElementAdded(); stringset->ElementAdded();
} }
@ -6850,7 +6857,7 @@ Handle<StringSet> StringSet::Add(Isolate* isolate, Handle<StringSet> stringset,
} }
bool StringSet::Has(Isolate* isolate, Handle<String> name) { bool StringSet::Has(Isolate* isolate, Handle<String> name) {
return FindEntry(isolate, *name) != kNotFound; return FindEntry(isolate, *name).is_found();
} }
Handle<ObjectHashSet> ObjectHashSet::Add(Isolate* isolate, Handle<ObjectHashSet> ObjectHashSet::Add(Isolate* isolate,
@ -6859,7 +6866,7 @@ Handle<ObjectHashSet> ObjectHashSet::Add(Isolate* isolate,
int32_t hash = key->GetOrCreateHash(isolate).value(); int32_t hash = key->GetOrCreateHash(isolate).value();
if (!set->Has(isolate, key, hash)) { if (!set->Has(isolate, key, hash)) {
set = EnsureCapacity(isolate, set, 1); set = EnsureCapacity(isolate, set, 1);
int entry = set->FindInsertionEntry(hash); InternalIndex entry = set->FindInsertionEntry(hash);
set->set(EntryToIndex(entry), *key); set->set(EntryToIndex(entry), *key);
set->ElementAdded(); set->ElementAdded();
} }
@ -6996,8 +7003,8 @@ MaybeHandle<SharedFunctionInfo> CompilationCacheTable::LookupScript(
Isolate* isolate = native_context->GetIsolate(); Isolate* isolate = native_context->GetIsolate();
src = String::Flatten(isolate, src); src = String::Flatten(isolate, src);
StringSharedKey key(src, shared, language_mode, kNoSourcePosition); StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
int entry = table->FindEntry(isolate, &key); InternalIndex entry = table->FindEntry(isolate, &key);
if (entry == kNotFound) return MaybeHandle<SharedFunctionInfo>(); if (entry.is_not_found()) return MaybeHandle<SharedFunctionInfo>();
int index = EntryToIndex(entry); int index = EntryToIndex(entry);
if (!table->get(index).IsFixedArray()) { if (!table->get(index).IsFixedArray()) {
return MaybeHandle<SharedFunctionInfo>(); return MaybeHandle<SharedFunctionInfo>();
@ -7017,14 +7024,14 @@ InfoCellPair CompilationCacheTable::LookupEval(
Isolate* isolate = native_context->GetIsolate(); Isolate* isolate = native_context->GetIsolate();
src = String::Flatten(isolate, src); src = String::Flatten(isolate, src);
StringSharedKey key(src, outer_info, language_mode, position); StringSharedKey key(src, outer_info, language_mode, position);
int entry = table->FindEntry(isolate, &key); InternalIndex entry = table->FindEntry(isolate, &key);
if (entry == kNotFound) return empty_result; if (entry.is_not_found()) return empty_result;
int index = EntryToIndex(entry); int index = EntryToIndex(entry);
if (!table->get(index).IsFixedArray()) return empty_result; if (!table->get(index).IsFixedArray()) return empty_result;
Object obj = table->get(EntryToIndex(entry) + 1); Object obj = table->get(index + 1);
if (obj.IsSharedFunctionInfo()) { if (obj.IsSharedFunctionInfo()) {
FeedbackCell feedback_cell = FeedbackCell feedback_cell =
SearchLiteralsMap(*table, EntryToIndex(entry) + 2, *native_context); SearchLiteralsMap(*table, index + 2, *native_context);
return InfoCellPair(SharedFunctionInfo::cast(obj), feedback_cell); return InfoCellPair(SharedFunctionInfo::cast(obj), feedback_cell);
} }
return empty_result; return empty_result;
@ -7035,8 +7042,8 @@ Handle<Object> CompilationCacheTable::LookupRegExp(Handle<String> src,
Isolate* isolate = GetIsolate(); Isolate* isolate = GetIsolate();
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
RegExpKey key(src, flags); RegExpKey key(src, flags);
int entry = FindEntry(isolate, &key); InternalIndex entry = FindEntry(isolate, &key);
if (entry == kNotFound) return isolate->factory()->undefined_value(); if (entry.is_not_found()) return isolate->factory()->undefined_value();
return Handle<Object>(get(EntryToIndex(entry) + 1), isolate); return Handle<Object>(get(EntryToIndex(entry) + 1), isolate);
} }
@ -7055,7 +7062,7 @@ Handle<CompilationCacheTable> CompilationCacheTable::PutScript(
StringSharedKey key(src, shared, language_mode, kNoSourcePosition); StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
Handle<Object> k = key.AsHandle(isolate); Handle<Object> k = key.AsHandle(isolate);
cache = EnsureCapacity(isolate, cache, 1); cache = EnsureCapacity(isolate, cache, 1);
int entry = cache->FindInsertionEntry(key.Hash()); InternalIndex entry = cache->FindInsertionEntry(key.Hash());
cache->set(EntryToIndex(entry), *k); cache->set(EntryToIndex(entry), *k);
cache->set(EntryToIndex(entry) + 1, *value); cache->set(EntryToIndex(entry) + 1, *value);
cache->ElementAdded(); cache->ElementAdded();
@ -7072,8 +7079,8 @@ Handle<CompilationCacheTable> CompilationCacheTable::PutEval(
StringSharedKey key(src, outer_info, value->language_mode(), position); StringSharedKey key(src, outer_info, value->language_mode(), position);
{ {
Handle<Object> k = key.AsHandle(isolate); Handle<Object> k = key.AsHandle(isolate);
int entry = cache->FindEntry(isolate, &key); InternalIndex entry = cache->FindEntry(isolate, &key);
if (entry != kNotFound) { if (entry.is_found()) {
cache->set(EntryToIndex(entry), *k); cache->set(EntryToIndex(entry), *k);
cache->set(EntryToIndex(entry) + 1, *value); cache->set(EntryToIndex(entry) + 1, *value);
// AddToFeedbackCellsMap may allocate a new sub-array to live in the // AddToFeedbackCellsMap may allocate a new sub-array to live in the
@ -7087,7 +7094,7 @@ Handle<CompilationCacheTable> CompilationCacheTable::PutEval(
} }
cache = EnsureCapacity(isolate, cache, 1); cache = EnsureCapacity(isolate, cache, 1);
int entry = cache->FindInsertionEntry(key.Hash()); InternalIndex entry = cache->FindInsertionEntry(key.Hash());
Handle<Object> k = Handle<Object> k =
isolate->factory()->NewNumber(static_cast<double>(key.Hash())); isolate->factory()->NewNumber(static_cast<double>(key.Hash()));
cache->set(EntryToIndex(entry), *k); cache->set(EntryToIndex(entry), *k);
@ -7101,7 +7108,7 @@ Handle<CompilationCacheTable> CompilationCacheTable::PutRegExp(
JSRegExp::Flags flags, Handle<FixedArray> value) { JSRegExp::Flags flags, Handle<FixedArray> value) {
RegExpKey key(src, flags); RegExpKey key(src, flags);
cache = EnsureCapacity(isolate, cache, 1); cache = EnsureCapacity(isolate, cache, 1);
int entry = cache->FindInsertionEntry(key.Hash()); InternalIndex entry = cache->FindInsertionEntry(key.Hash());
// We store the value in the key slot, and compare the search key // We store the value in the key slot, and compare the search key
// to the stored value with a custon IsMatch function during lookups. // to the stored value with a custon IsMatch function during lookups.
cache->set(EntryToIndex(entry), *value); cache->set(EntryToIndex(entry), *value);
@ -7113,7 +7120,7 @@ Handle<CompilationCacheTable> CompilationCacheTable::PutRegExp(
void CompilationCacheTable::Age() { void CompilationCacheTable::Age() {
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
Object the_hole_value = GetReadOnlyRoots().the_hole_value(); Object the_hole_value = GetReadOnlyRoots().the_hole_value();
for (int entry = 0, size = Capacity(); entry < size; entry++) { for (InternalIndex entry : IterateEntries()) {
int entry_index = EntryToIndex(entry); int entry_index = EntryToIndex(entry);
int value_index = entry_index + 1; int value_index = entry_index + 1;
@ -7142,7 +7149,7 @@ void CompilationCacheTable::Age() {
void CompilationCacheTable::Remove(Object value) { void CompilationCacheTable::Remove(Object value) {
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
Object the_hole_value = GetReadOnlyRoots().the_hole_value(); Object the_hole_value = GetReadOnlyRoots().the_hole_value();
for (int entry = 0, size = Capacity(); entry < size; entry++) { for (InternalIndex entry : IterateEntries()) {
int entry_index = EntryToIndex(entry); int entry_index = EntryToIndex(entry);
int value_index = entry_index + 1; int value_index = entry_index + 1;
if (get(value_index) == value) { if (get(value_index) == value) {
@ -7180,7 +7187,7 @@ Handle<Derived> BaseNameDictionary<Derived, Shape>::EnsureCapacity(
// Iterate over the dictionary using the enumeration order and update // Iterate over the dictionary using the enumeration order and update
// the dictionary with new enumeration indices. // the dictionary with new enumeration indices.
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
int index = Smi::ToInt(iteration_order->get(i)); InternalIndex index(Smi::ToInt(iteration_order->get(i)));
DCHECK(dictionary->IsKey(dictionary->GetReadOnlyRoots(), DCHECK(dictionary->IsKey(dictionary->GetReadOnlyRoots(),
dictionary->KeyAt(index))); dictionary->KeyAt(index)));
@ -7200,7 +7207,7 @@ Handle<Derived> BaseNameDictionary<Derived, Shape>::EnsureCapacity(
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
Handle<Derived> Dictionary<Derived, Shape>::DeleteEntry( Handle<Derived> Dictionary<Derived, Shape>::DeleteEntry(
Isolate* isolate, Handle<Derived> dictionary, int entry) { Isolate* isolate, Handle<Derived> dictionary, InternalIndex entry) {
DCHECK(Shape::kEntrySize != 3 || DCHECK(Shape::kEntrySize != 3 ||
dictionary->DetailsAt(entry).IsConfigurable()); dictionary->DetailsAt(entry).IsConfigurable());
dictionary->ClearEntry(isolate, entry); dictionary->ClearEntry(isolate, entry);
@ -7213,10 +7220,10 @@ Handle<Derived> Dictionary<Derived, Shape>::AtPut(Isolate* isolate,
Handle<Derived> dictionary, Handle<Derived> dictionary,
Key key, Handle<Object> value, Key key, Handle<Object> value,
PropertyDetails details) { PropertyDetails details) {
int entry = dictionary->FindEntry(isolate, key); InternalIndex entry = dictionary->FindEntry(isolate, key);
// If the entry is present set the value; // If the entry is present set the value;
if (entry == Dictionary::kNotFound) { if (entry.is_not_found()) {
return Derived::Add(isolate, dictionary, key, value, details); return Derived::Add(isolate, dictionary, key, value, details);
} }
@ -7230,8 +7237,8 @@ template <typename Derived, typename Shape>
Handle<Derived> Handle<Derived>
BaseNameDictionary<Derived, Shape>::AddNoUpdateNextEnumerationIndex( BaseNameDictionary<Derived, Shape>::AddNoUpdateNextEnumerationIndex(
Isolate* isolate, Handle<Derived> dictionary, Key key, Handle<Object> value, Isolate* isolate, Handle<Derived> dictionary, Key key, Handle<Object> value,
PropertyDetails details, int* entry_out) { PropertyDetails details, InternalIndex* entry_out) {
// Insert element at empty or deleted entry // Insert element at empty or deleted entry.
return Dictionary<Derived, Shape>::Add(isolate, dictionary, key, value, return Dictionary<Derived, Shape>::Add(isolate, dictionary, key, value,
details, entry_out); details, entry_out);
} }
@ -7239,7 +7246,7 @@ BaseNameDictionary<Derived, Shape>::AddNoUpdateNextEnumerationIndex(
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
Handle<Derived> BaseNameDictionary<Derived, Shape>::Add( Handle<Derived> BaseNameDictionary<Derived, Shape>::Add(
Isolate* isolate, Handle<Derived> dictionary, Key key, Handle<Object> value, Isolate* isolate, Handle<Derived> dictionary, Key key, Handle<Object> value,
PropertyDetails details, int* entry_out) { PropertyDetails details, InternalIndex* entry_out) {
// Insert element at empty or deleted entry // Insert element at empty or deleted entry
DCHECK_EQ(0, details.dictionary_index()); DCHECK_EQ(0, details.dictionary_index());
// Assign an enumeration index to the property and update // Assign an enumeration index to the property and update
@ -7259,17 +7266,17 @@ Handle<Derived> Dictionary<Derived, Shape>::Add(Isolate* isolate,
Handle<Derived> dictionary, Handle<Derived> dictionary,
Key key, Handle<Object> value, Key key, Handle<Object> value,
PropertyDetails details, PropertyDetails details,
int* entry_out) { InternalIndex* entry_out) {
uint32_t hash = Shape::Hash(isolate, key); uint32_t hash = Shape::Hash(isolate, key);
// Valdate key is absent. // Validate that the key is absent.
SLOW_DCHECK((dictionary->FindEntry(isolate, key) == Dictionary::kNotFound)); SLOW_DCHECK(dictionary->FindEntry(isolate, key).is_not_found());
// Check whether the dictionary should be extended. // Check whether the dictionary should be extended.
dictionary = Derived::EnsureCapacity(isolate, dictionary, 1); dictionary = Derived::EnsureCapacity(isolate, dictionary, 1);
// Compute the key object. // Compute the key object.
Handle<Object> k = Shape::AsHandle(isolate, key); Handle<Object> k = Shape::AsHandle(isolate, key);
uint32_t entry = dictionary->FindInsertionEntry(hash); InternalIndex entry = dictionary->FindInsertionEntry(hash);
dictionary->SetEntry(isolate, entry, *k, *value, details); dictionary->SetEntry(isolate, entry, *k, *value, details);
DCHECK(dictionary->KeyAt(entry).IsNumber() || DCHECK(dictionary->KeyAt(entry).IsNumber() ||
Shape::Unwrap(dictionary->KeyAt(entry)).IsUniqueName()); Shape::Unwrap(dictionary->KeyAt(entry)).IsUniqueName());
@ -7324,10 +7331,9 @@ Handle<NumberDictionary> NumberDictionary::Set(
void NumberDictionary::CopyValuesTo(FixedArray elements) { void NumberDictionary::CopyValuesTo(FixedArray elements) {
ReadOnlyRoots roots = GetReadOnlyRoots(); ReadOnlyRoots roots = GetReadOnlyRoots();
int pos = 0; int pos = 0;
int capacity = this->Capacity();
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
WriteBarrierMode mode = elements.GetWriteBarrierMode(no_gc); WriteBarrierMode mode = elements.GetWriteBarrierMode(no_gc);
for (int i = 0; i < capacity; i++) { for (InternalIndex i : this->IterateEntries()) {
Object k; Object k;
if (this->ToKey(roots, i, &k)) { if (this->ToKey(roots, i, &k)) {
elements.set(pos++, this->ValueAt(i), mode); elements.set(pos++, this->ValueAt(i), mode);
@ -7339,9 +7345,8 @@ void NumberDictionary::CopyValuesTo(FixedArray elements) {
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
int Dictionary<Derived, Shape>::NumberOfEnumerableProperties() { int Dictionary<Derived, Shape>::NumberOfEnumerableProperties() {
ReadOnlyRoots roots = this->GetReadOnlyRoots(); ReadOnlyRoots roots = this->GetReadOnlyRoots();
int capacity = this->Capacity();
int result = 0; int result = 0;
for (int i = 0; i < capacity; i++) { for (InternalIndex i : this->IterateEntries()) {
Object k; Object k;
if (!this->ToKey(roots, i, &k)) continue; if (!this->ToKey(roots, i, &k)) continue;
if (k.FilterKey(ENUMERABLE_STRINGS)) continue; if (k.FilterKey(ENUMERABLE_STRINGS)) continue;
@ -7356,8 +7361,10 @@ template <typename Dictionary>
struct EnumIndexComparator { struct EnumIndexComparator {
explicit EnumIndexComparator(Dictionary dict) : dict(dict) {} explicit EnumIndexComparator(Dictionary dict) : dict(dict) {}
bool operator()(Tagged_t a, Tagged_t b) { bool operator()(Tagged_t a, Tagged_t b) {
PropertyDetails da(dict.DetailsAt(Smi(static_cast<Address>(a)).value())); PropertyDetails da(
PropertyDetails db(dict.DetailsAt(Smi(static_cast<Address>(b)).value())); dict.DetailsAt(InternalIndex(Smi(static_cast<Address>(a)).value())));
PropertyDetails db(
dict.DetailsAt(InternalIndex(Smi(static_cast<Address>(b)).value())));
return da.dictionary_index() < db.dictionary_index(); return da.dictionary_index() < db.dictionary_index();
} }
Dictionary dict; Dictionary dict;
@ -7369,10 +7376,9 @@ void BaseNameDictionary<Derived, Shape>::CopyEnumKeysTo(
KeyCollectionMode mode, KeyAccumulator* accumulator) { KeyCollectionMode mode, KeyAccumulator* accumulator) {
DCHECK_IMPLIES(mode != KeyCollectionMode::kOwnOnly, accumulator != nullptr); DCHECK_IMPLIES(mode != KeyCollectionMode::kOwnOnly, accumulator != nullptr);
int length = storage->length(); int length = storage->length();
int capacity = dictionary->Capacity();
int properties = 0; int properties = 0;
ReadOnlyRoots roots(isolate); ReadOnlyRoots roots(isolate);
for (int i = 0; i < capacity; i++) { for (InternalIndex i : dictionary->IterateEntries()) {
Object key; Object key;
if (!dictionary->ToKey(roots, i, &key)) continue; if (!dictionary->ToKey(roots, i, &key)) continue;
bool is_shadowing_key = false; bool is_shadowing_key = false;
@ -7389,7 +7395,7 @@ void BaseNameDictionary<Derived, Shape>::CopyEnumKeysTo(
accumulator->AddShadowingKey(key); accumulator->AddShadowingKey(key);
continue; continue;
} else { } else {
storage->set(properties, Smi::FromInt(i)); storage->set(properties, Smi::FromInt(i.as_int()));
} }
properties++; properties++;
if (mode == KeyCollectionMode::kOwnOnly && properties == length) break; if (mode == KeyCollectionMode::kOwnOnly && properties == length) break;
@ -7405,7 +7411,7 @@ void BaseNameDictionary<Derived, Shape>::CopyEnumKeysTo(
AtomicSlot start(storage->GetFirstElementAddress()); AtomicSlot start(storage->GetFirstElementAddress());
std::sort(start, start + length, cmp); std::sort(start, start + length, cmp);
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
int index = Smi::ToInt(raw_storage.get(i)); InternalIndex index(Smi::ToInt(raw_storage.get(i)));
raw_storage.set(i, raw_dictionary.NameAt(index)); raw_storage.set(i, raw_dictionary.NameAt(index));
} }
} }
@ -7413,7 +7419,6 @@ void BaseNameDictionary<Derived, Shape>::CopyEnumKeysTo(
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
Handle<FixedArray> BaseNameDictionary<Derived, Shape>::IterationIndices( Handle<FixedArray> BaseNameDictionary<Derived, Shape>::IterationIndices(
Isolate* isolate, Handle<Derived> dictionary) { Isolate* isolate, Handle<Derived> dictionary) {
int capacity = dictionary->Capacity();
int length = dictionary->NumberOfElements(); int length = dictionary->NumberOfElements();
Handle<FixedArray> array = isolate->factory()->NewFixedArray(length); Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
ReadOnlyRoots roots(isolate); ReadOnlyRoots roots(isolate);
@ -7421,10 +7426,10 @@ Handle<FixedArray> BaseNameDictionary<Derived, Shape>::IterationIndices(
{ {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
Derived raw_dictionary = *dictionary; Derived raw_dictionary = *dictionary;
for (int i = 0; i < capacity; i++) { for (InternalIndex i : dictionary->IterateEntries()) {
Object k; Object k;
if (!raw_dictionary.ToKey(roots, i, &k)) continue; if (!raw_dictionary.ToKey(roots, i, &k)) continue;
array->set(array_size++, Smi::FromInt(i)); array->set(array_size++, Smi::FromInt(i.as_int()));
} }
DCHECK_EQ(array_size, length); DCHECK_EQ(array_size, length);
@ -7443,7 +7448,7 @@ ExceptionStatus BaseNameDictionary<Derived, Shape>::CollectKeysTo(
Handle<Derived> dictionary, KeyAccumulator* keys) { Handle<Derived> dictionary, KeyAccumulator* keys) {
Isolate* isolate = keys->isolate(); Isolate* isolate = keys->isolate();
ReadOnlyRoots roots(isolate); ReadOnlyRoots roots(isolate);
int capacity = dictionary->Capacity(); // TODO(jkummerow): Consider using a std::unique_ptr<InternalIndex[]> instead.
Handle<FixedArray> array = Handle<FixedArray> array =
isolate->factory()->NewFixedArray(dictionary->NumberOfElements()); isolate->factory()->NewFixedArray(dictionary->NumberOfElements());
int array_size = 0; int array_size = 0;
@ -7451,7 +7456,7 @@ ExceptionStatus BaseNameDictionary<Derived, Shape>::CollectKeysTo(
{ {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
Derived raw_dictionary = *dictionary; Derived raw_dictionary = *dictionary;
for (int i = 0; i < capacity; i++) { for (InternalIndex i : dictionary->IterateEntries()) {
Object k; Object k;
if (!raw_dictionary.ToKey(roots, i, &k)) continue; if (!raw_dictionary.ToKey(roots, i, &k)) continue;
if (k.FilterKey(filter)) continue; if (k.FilterKey(filter)) continue;
@ -7466,7 +7471,7 @@ ExceptionStatus BaseNameDictionary<Derived, Shape>::CollectKeysTo(
if (!accessors.IsAccessorInfo()) continue; if (!accessors.IsAccessorInfo()) continue;
if (!AccessorInfo::cast(accessors).all_can_read()) continue; if (!AccessorInfo::cast(accessors).all_can_read()) continue;
} }
array->set(array_size++, Smi::FromInt(i)); array->set(array_size++, Smi::FromInt(i.as_int()));
} }
EnumIndexComparator<Derived> cmp(raw_dictionary); EnumIndexComparator<Derived> cmp(raw_dictionary);
@ -7478,7 +7483,7 @@ ExceptionStatus BaseNameDictionary<Derived, Shape>::CollectKeysTo(
bool has_seen_symbol = false; bool has_seen_symbol = false;
for (int i = 0; i < array_size; i++) { for (int i = 0; i < array_size; i++) {
int index = Smi::ToInt(array->get(i)); InternalIndex index(Smi::ToInt(array->get(i)));
Object key = dictionary->NameAt(index); Object key = dictionary->NameAt(index);
if (key.IsSymbol()) { if (key.IsSymbol()) {
has_seen_symbol = true; has_seen_symbol = true;
@ -7489,7 +7494,7 @@ ExceptionStatus BaseNameDictionary<Derived, Shape>::CollectKeysTo(
} }
if (has_seen_symbol) { if (has_seen_symbol) {
for (int i = 0; i < array_size; i++) { for (int i = 0; i < array_size; i++) {
int index = Smi::ToInt(array->get(i)); InternalIndex index(Smi::ToInt(array->get(i)));
Object key = dictionary->NameAt(index); Object key = dictionary->NameAt(index);
if (!key.IsSymbol()) continue; if (!key.IsSymbol()) continue;
ExceptionStatus status = keys->AddKey(key, DO_NOT_CONVERT); ExceptionStatus status = keys->AddKey(key, DO_NOT_CONVERT);
@ -7504,8 +7509,7 @@ template <typename Derived, typename Shape>
Object Dictionary<Derived, Shape>::SlowReverseLookup(Object value) { Object Dictionary<Derived, Shape>::SlowReverseLookup(Object value) {
Derived dictionary = Derived::cast(*this); Derived dictionary = Derived::cast(*this);
ReadOnlyRoots roots = dictionary.GetReadOnlyRoots(); ReadOnlyRoots roots = dictionary.GetReadOnlyRoots();
int capacity = dictionary.Capacity(); for (InternalIndex i : dictionary.IterateEntries()) {
for (int i = 0; i < capacity; i++) {
Object k; Object k;
if (!dictionary.ToKey(roots, i, &k)) continue; if (!dictionary.ToKey(roots, i, &k)) continue;
Object e = dictionary.ValueAt(i); Object e = dictionary.ValueAt(i);
@ -7518,7 +7522,7 @@ template <typename Derived, typename Shape>
void ObjectHashTableBase<Derived, Shape>::FillEntriesWithHoles( void ObjectHashTableBase<Derived, Shape>::FillEntriesWithHoles(
Handle<Derived> table) { Handle<Derived> table) {
int length = table->length(); int length = table->length();
for (int i = Derived::EntryToIndex(0); i < length; i++) { for (int i = Derived::EntryToIndex(InternalIndex(0)); i < length; i++) {
table->set_the_hole(i); table->set_the_hole(i);
} }
} }
@ -7530,8 +7534,8 @@ Object ObjectHashTableBase<Derived, Shape>::Lookup(ReadOnlyRoots roots,
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
DCHECK(this->IsKey(roots, *key)); DCHECK(this->IsKey(roots, *key));
int entry = this->FindEntry(roots, key, hash); InternalIndex entry = this->FindEntry(roots, key, hash);
if (entry == kNotFound) return roots.the_hole_value(); if (entry.is_not_found()) return roots.the_hole_value();
return this->get(Derived::EntryToIndex(entry) + 1); return this->get(Derived::EntryToIndex(entry) + 1);
} }
@ -7557,7 +7561,7 @@ Object ObjectHashTableBase<Derived, Shape>::Lookup(Handle<Object> key,
} }
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
Object ObjectHashTableBase<Derived, Shape>::ValueAt(int entry) { Object ObjectHashTableBase<Derived, Shape>::ValueAt(InternalIndex entry) {
return this->get(EntryToValueIndex(entry)); return this->get(EntryToValueIndex(entry));
} }
@ -7586,10 +7590,10 @@ Handle<Derived> ObjectHashTableBase<Derived, Shape>::Put(Isolate* isolate,
DCHECK(table->IsKey(roots, *key)); DCHECK(table->IsKey(roots, *key));
DCHECK(!value->IsTheHole(roots)); DCHECK(!value->IsTheHole(roots));
int entry = table->FindEntry(roots, key, hash); InternalIndex entry = table->FindEntry(roots, key, hash);
// Key is already in table, just overwrite value. // Key is already in table, just overwrite value.
if (entry != kNotFound) { if (entry.is_found()) {
table->set(Derived::EntryToValueIndex(entry), *value); table->set(Derived::EntryToValueIndex(entry), *value);
return table; return table;
} }
@ -7641,8 +7645,8 @@ Handle<Derived> ObjectHashTableBase<Derived, Shape>::Remove(
ReadOnlyRoots roots = table->GetReadOnlyRoots(); ReadOnlyRoots roots = table->GetReadOnlyRoots();
DCHECK(table->IsKey(roots, *key)); DCHECK(table->IsKey(roots, *key));
int entry = table->FindEntry(roots, key, hash); InternalIndex entry = table->FindEntry(roots, key, hash);
if (entry == kNotFound) { if (entry.is_not_found()) {
*was_present = false; *was_present = false;
return table; return table;
} }
@ -7653,8 +7657,8 @@ Handle<Derived> ObjectHashTableBase<Derived, Shape>::Remove(
} }
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
void ObjectHashTableBase<Derived, Shape>::AddEntry(int entry, Object key, void ObjectHashTableBase<Derived, Shape>::AddEntry(InternalIndex entry,
Object value) { Object key, Object value) {
Derived* self = static_cast<Derived*>(this); Derived* self = static_cast<Derived*>(this);
self->set_key(Derived::EntryToIndex(entry), key); self->set_key(Derived::EntryToIndex(entry), key);
self->set(Derived::EntryToValueIndex(entry), value); self->set(Derived::EntryToValueIndex(entry), value);
@ -7662,7 +7666,7 @@ void ObjectHashTableBase<Derived, Shape>::AddEntry(int entry, Object key,
} }
template <typename Derived, typename Shape> template <typename Derived, typename Shape>
void ObjectHashTableBase<Derived, Shape>::RemoveEntry(int entry) { void ObjectHashTableBase<Derived, Shape>::RemoveEntry(InternalIndex entry) {
this->set_the_hole(Derived::EntryToIndex(entry)); this->set_the_hole(Derived::EntryToIndex(entry));
this->set_the_hole(Derived::EntryToValueIndex(entry)); this->set_the_hole(Derived::EntryToValueIndex(entry));
this->ElementRemoved(); this->ElementRemoved();
@ -7754,7 +7758,7 @@ Handle<JSArray> JSWeakCollection::GetEntries(Handle<JSWeakCollection> holder,
for (int i = 0; for (int i = 0;
count / values_per_entry < max_entries && i < table->Capacity(); i++) { count / values_per_entry < max_entries && i < table->Capacity(); i++) {
Object key; Object key;
if (table->ToKey(roots, i, &key)) { if (table->ToKey(roots, InternalIndex(i), &key)) {
entries->set(count++, key); entries->set(count++, key);
if (values_per_entry > 1) { if (values_per_entry > 1) {
Object value = table->Lookup(handle(key, isolate)); Object value = table->Lookup(handle(key, isolate));
@ -7768,7 +7772,8 @@ Handle<JSArray> JSWeakCollection::GetEntries(Handle<JSWeakCollection> holder,
} }
Handle<PropertyCell> PropertyCell::InvalidateEntry( Handle<PropertyCell> PropertyCell::InvalidateEntry(
Isolate* isolate, Handle<GlobalDictionary> dictionary, int entry) { Isolate* isolate, Handle<GlobalDictionary> dictionary,
InternalIndex entry) {
// Swap with a copy. // Swap with a copy.
Handle<PropertyCell> cell(dictionary->CellAt(entry), isolate); Handle<PropertyCell> cell(dictionary->CellAt(entry), isolate);
Handle<Name> name(cell->name(), isolate); Handle<Name> name(cell->name(), isolate);
@ -7848,7 +7853,7 @@ PropertyCellType PropertyCell::UpdatedType(Isolate* isolate,
} }
Handle<PropertyCell> PropertyCell::PrepareForValue( Handle<PropertyCell> PropertyCell::PrepareForValue(
Isolate* isolate, Handle<GlobalDictionary> dictionary, int entry, Isolate* isolate, Handle<GlobalDictionary> dictionary, InternalIndex entry,
Handle<Object> value, PropertyDetails details) { Handle<Object> value, PropertyDetails details) {
DCHECK(!value->IsTheHole(isolate)); DCHECK(!value->IsTheHole(isolate));
Handle<PropertyCell> cell(dictionary->CellAt(entry), isolate); Handle<PropertyCell> cell(dictionary->CellAt(entry), isolate);

View File

@ -41,11 +41,12 @@ class PropertyCell : public HeapObject {
// As a result the old cell could be invalidated and/or dependent code could // As a result the old cell could be invalidated and/or dependent code could
// be deoptimized. Returns the prepared property cell. // be deoptimized. Returns the prepared property cell.
static Handle<PropertyCell> PrepareForValue( static Handle<PropertyCell> PrepareForValue(
Isolate* isolate, Handle<GlobalDictionary> dictionary, int entry, Isolate* isolate, Handle<GlobalDictionary> dictionary,
Handle<Object> value, PropertyDetails details); InternalIndex entry, Handle<Object> value, PropertyDetails details);
static Handle<PropertyCell> InvalidateEntry( static Handle<PropertyCell> InvalidateEntry(
Isolate* isolate, Handle<GlobalDictionary> dictionary, int entry); Isolate* isolate, Handle<GlobalDictionary> dictionary,
InternalIndex entry);
static void SetValueWithInvalidation(Isolate* isolate, const char* cell_name, static void SetValueWithInvalidation(Isolate* isolate, const char* cell_name,
Handle<PropertyCell> cell, Handle<PropertyCell> cell,

View File

@ -536,7 +536,7 @@ void SourceTextModule::FetchStarExports(Isolate* isolate,
// the name to undefined instead of a Cell. // the name to undefined instead of a Cell.
Handle<ObjectHashTable> requested_exports(requested_module->exports(), Handle<ObjectHashTable> requested_exports(requested_module->exports(),
isolate); isolate);
for (int i = 0, n = requested_exports->Capacity(); i < n; ++i) { for (InternalIndex i : requested_exports->IterateEntries()) {
Object key; Object key;
if (!requested_exports->ToKey(roots, i, &key)) continue; if (!requested_exports->ToKey(roots, i, &key)) continue;
Handle<String> name(String::cast(key), isolate); Handle<String> name(String::cast(key), isolate);

View File

@ -69,7 +69,7 @@ class StringTable : public HashTable<StringTable, StringTableShape> {
static Handle<String> LookupKey(Isolate* isolate, StringTableKey* key); static Handle<String> LookupKey(Isolate* isolate, StringTableKey* key);
static Handle<String> AddKeyNoResize(Isolate* isolate, StringTableKey* key); static Handle<String> AddKeyNoResize(Isolate* isolate, StringTableKey* key);
// Shink the StringTable if it's very empty (kMaxEmptyFactor) to avoid the // Shrink the StringTable if it's very empty (kMaxEmptyFactor) to avoid the
// performance overhead of re-allocating the StringTable over and over again. // performance overhead of re-allocating the StringTable over and over again.
static Handle<StringTable> CautiousShrink(Isolate* isolate, static Handle<StringTable> CautiousShrink(Isolate* isolate,
Handle<StringTable> table); Handle<StringTable> table);

View File

@ -1814,8 +1814,8 @@ MaybeHandle<JSArrayBuffer> ValueDeserializer::ReadTransferredJSArrayBuffer() {
!array_buffer_transfer_map_.ToHandle(&transfer_map)) { !array_buffer_transfer_map_.ToHandle(&transfer_map)) {
return MaybeHandle<JSArrayBuffer>(); return MaybeHandle<JSArrayBuffer>();
} }
int index = transfer_map->FindEntry(isolate_, transfer_id); InternalIndex index = transfer_map->FindEntry(isolate_, transfer_id);
if (index == SimpleNumberDictionary::kNotFound) { if (index.is_not_found()) {
return MaybeHandle<JSArrayBuffer>(); return MaybeHandle<JSArrayBuffer>();
} }
Handle<JSArrayBuffer> array_buffer( Handle<JSArrayBuffer> array_buffer(

View File

@ -930,7 +930,7 @@ void V8HeapExplorer::ExtractJSWeakCollectionReferences(HeapEntry* entry,
void V8HeapExplorer::ExtractEphemeronHashTableReferences( void V8HeapExplorer::ExtractEphemeronHashTableReferences(
HeapEntry* entry, EphemeronHashTable table) { HeapEntry* entry, EphemeronHashTable table) {
for (int i = 0, capacity = table.Capacity(); i < capacity; ++i) { for (InternalIndex i : table.IterateEntries()) {
int key_index = EphemeronHashTable::EntryToIndex(i) + int key_index = EphemeronHashTable::EntryToIndex(i) +
EphemeronHashTable::kEntryKeyIndex; EphemeronHashTable::kEntryKeyIndex;
int value_index = EphemeronHashTable::EntryToValueIndex(i); int value_index = EphemeronHashTable::EntryToValueIndex(i);
@ -1333,9 +1333,8 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject js_obj,
// We assume that global objects can only have slow properties. // We assume that global objects can only have slow properties.
GlobalDictionary dictionary = GlobalDictionary dictionary =
JSGlobalObject::cast(js_obj).global_dictionary(); JSGlobalObject::cast(js_obj).global_dictionary();
int length = dictionary.Capacity();
ReadOnlyRoots roots(isolate); ReadOnlyRoots roots(isolate);
for (int i = 0; i < length; ++i) { for (InternalIndex i : dictionary.IterateEntries()) {
if (!dictionary.IsKey(roots, dictionary.KeyAt(i))) continue; if (!dictionary.IsKey(roots, dictionary.KeyAt(i))) continue;
PropertyCell cell = dictionary.CellAt(i); PropertyCell cell = dictionary.CellAt(i);
Name name = cell.name(); Name name = cell.name();
@ -1345,9 +1344,8 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject js_obj,
} }
} else { } else {
NameDictionary dictionary = js_obj.property_dictionary(); NameDictionary dictionary = js_obj.property_dictionary();
int length = dictionary.Capacity();
ReadOnlyRoots roots(isolate); ReadOnlyRoots roots(isolate);
for (int i = 0; i < length; ++i) { for (InternalIndex i : dictionary.IterateEntries()) {
Object k = dictionary.KeyAt(i); Object k = dictionary.KeyAt(i);
if (!dictionary.IsKey(roots, k)) continue; if (!dictionary.IsKey(roots, k)) continue;
Object value = dictionary.ValueAt(i); Object value = dictionary.ValueAt(i);
@ -1388,8 +1386,7 @@ void V8HeapExplorer::ExtractElementReferences(JSObject js_obj,
} }
} else if (js_obj.HasDictionaryElements()) { } else if (js_obj.HasDictionaryElements()) {
NumberDictionary dictionary = js_obj.element_dictionary(); NumberDictionary dictionary = js_obj.element_dictionary();
int length = dictionary.Capacity(); for (InternalIndex i : dictionary.IterateEntries()) {
for (int i = 0; i < length; ++i) {
Object k = dictionary.KeyAt(i); Object k = dictionary.KeyAt(i);
if (!dictionary.IsKey(roots, k)) continue; if (!dictionary.IsKey(roots, k)) continue;
DCHECK(k.IsNumber()); DCHECK(k.IsNumber());

View File

@ -215,8 +215,7 @@ Handle<Dictionary> ShallowCopyDictionaryTemplate(
Handle<Dictionary>::cast(isolate->factory()->CopyFixedArrayWithMap( Handle<Dictionary>::cast(isolate->factory()->CopyFixedArrayWithMap(
dictionary_template, dictionary_map)); dictionary_template, dictionary_map));
// Clone all AccessorPairs in the dictionary. // Clone all AccessorPairs in the dictionary.
int capacity = dictionary->Capacity(); for (InternalIndex i : dictionary->IterateEntries()) {
for (int i = 0; i < capacity; i++) {
Object value = dictionary->ValueAt(i); Object value = dictionary->ValueAt(i);
if (value.IsAccessorPair()) { if (value.IsAccessorPair()) {
Handle<AccessorPair> pair(AccessorPair::cast(value), isolate); Handle<AccessorPair> pair(AccessorPair::cast(value), isolate);
@ -235,9 +234,8 @@ bool SubstituteValues(Isolate* isolate, Handle<Dictionary> dictionary,
Handle<Name> name_string = isolate->factory()->name_string(); Handle<Name> name_string = isolate->factory()->name_string();
// Replace all indices with proper methods. // Replace all indices with proper methods.
int capacity = dictionary->Capacity();
ReadOnlyRoots roots(isolate); ReadOnlyRoots roots(isolate);
for (int i = 0; i < capacity; i++) { for (InternalIndex i : dictionary->IterateEntries()) {
Object maybe_key = dictionary->KeyAt(i); Object maybe_key = dictionary->KeyAt(i);
if (!Dictionary::IsKey(roots, maybe_key)) continue; if (!Dictionary::IsKey(roots, maybe_key)) continue;
if (install_name_accessor && *install_name_accessor && if (install_name_accessor && *install_name_accessor &&

View File

@ -133,8 +133,7 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
} }
} else { } else {
Handle<NameDictionary> dict(copy->property_dictionary(isolate), isolate); Handle<NameDictionary> dict(copy->property_dictionary(isolate), isolate);
int capacity = dict->Capacity(); for (InternalIndex i : dict->IterateEntries()) {
for (int i = 0; i < capacity; i++) {
Object raw = dict->ValueAt(isolate, i); Object raw = dict->ValueAt(isolate, i);
if (!raw.IsJSObject(isolate)) continue; if (!raw.IsJSObject(isolate)) continue;
DCHECK(dict->KeyAt(isolate, i).IsName()); DCHECK(dict->KeyAt(isolate, i).IsName());
@ -183,8 +182,7 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
case DICTIONARY_ELEMENTS: { case DICTIONARY_ELEMENTS: {
Handle<NumberDictionary> element_dictionary( Handle<NumberDictionary> element_dictionary(
copy->element_dictionary(isolate), isolate); copy->element_dictionary(isolate), isolate);
int capacity = element_dictionary->Capacity(); for (InternalIndex i : element_dictionary->IterateEntries()) {
for (int i = 0; i < capacity; i++) {
Object raw = element_dictionary->ValueAt(isolate, i); Object raw = element_dictionary->ValueAt(isolate, i);
if (!raw.IsJSObject(isolate)) continue; if (!raw.IsJSObject(isolate)) continue;
Handle<JSObject> value(JSObject::cast(raw), isolate); Handle<JSObject> value(JSObject::cast(raw), isolate);

View File

@ -617,8 +617,8 @@ RUNTIME_FUNCTION(Runtime_GetProperty) {
// Attempt dictionary lookup. // Attempt dictionary lookup.
GlobalDictionary dictionary = GlobalDictionary dictionary =
JSGlobalObject::cast(*receiver).global_dictionary(); JSGlobalObject::cast(*receiver).global_dictionary();
int entry = dictionary.FindEntry(isolate, key); InternalIndex entry = dictionary.FindEntry(isolate, key);
if (entry != GlobalDictionary::kNotFound) { if (entry.is_found()) {
PropertyCell cell = dictionary.CellAt(entry); PropertyCell cell = dictionary.CellAt(entry);
if (cell.property_details().kind() == kData) { if (cell.property_details().kind() == kData) {
Object value = cell.value(); Object value = cell.value();
@ -629,8 +629,8 @@ RUNTIME_FUNCTION(Runtime_GetProperty) {
} else if (!receiver->HasFastProperties()) { } else if (!receiver->HasFastProperties()) {
// Attempt dictionary lookup. // Attempt dictionary lookup.
NameDictionary dictionary = receiver->property_dictionary(); NameDictionary dictionary = receiver->property_dictionary();
int entry = dictionary.FindEntry(isolate, key); InternalIndex entry = dictionary.FindEntry(isolate, key);
if ((entry != NameDictionary::kNotFound) && if ((entry.is_found()) &&
(dictionary.DetailsAt(entry).kind() == kData)) { (dictionary.DetailsAt(entry).kind() == kData)) {
return dictionary.ValueAt(entry); return dictionary.ValueAt(entry);
} }

View File

@ -191,8 +191,8 @@ namespace {
String ForwardStringIfExists(Isolate* isolate, StringTableInsertionKey* key) { String ForwardStringIfExists(Isolate* isolate, StringTableInsertionKey* key) {
StringTable table = isolate->heap()->string_table(); StringTable table = isolate->heap()->string_table();
int entry = table.FindEntry(isolate, key); InternalIndex entry = table.FindEntry(isolate, key);
if (entry == kNotFound) return String(); if (entry.is_not_found()) return String();
String canonical = String::cast(table.KeyAt(entry)); String canonical = String::cast(table.KeyAt(entry));
DCHECK_NE(canonical, key->string()); DCHECK_NE(canonical, key->string());

View File

@ -679,7 +679,8 @@ void TestEntryToIndex() {
entry = entry * 1.01 + 1) { entry = entry * 1.01 + 1) {
Handle<Object> result = Handle<Object> result =
ft.Call(handle(Smi::FromInt(entry), isolate)).ToHandleChecked(); ft.Call(handle(Smi::FromInt(entry), isolate)).ToHandleChecked();
CHECK_EQ(Dictionary::EntryToIndex(entry), Smi::ToInt(*result)); CHECK_EQ(Dictionary::EntryToIndex(InternalIndex(entry)),
Smi::ToInt(*result));
} }
} }
@ -759,10 +760,10 @@ void TestNameDictionaryLookup() {
} }
for (size_t i = 0; i < arraysize(keys); i++) { for (size_t i = 0; i < arraysize(keys); i++) {
int entry = dictionary->FindEntry(isolate, keys[i]); InternalIndex entry = dictionary->FindEntry(isolate, keys[i]);
int name_index = int name_index =
Dictionary::EntryToIndex(entry) + Dictionary::kEntryKeyIndex; Dictionary::EntryToIndex(entry) + Dictionary::kEntryKeyIndex;
CHECK_NE(Dictionary::kNotFound, entry); CHECK(entry.is_found());
Handle<Object> expected_name_index(Smi::FromInt(name_index), isolate); Handle<Object> expected_name_index(Smi::FromInt(name_index), isolate);
ft.CheckTrue(dictionary, keys[i], expect_found, expected_name_index); ft.CheckTrue(dictionary, keys[i], expect_found, expected_name_index);
@ -781,8 +782,8 @@ void TestNameDictionaryLookup() {
}; };
for (size_t i = 0; i < arraysize(non_existing_keys); i++) { for (size_t i = 0; i < arraysize(non_existing_keys); i++) {
int entry = dictionary->FindEntry(isolate, non_existing_keys[i]); InternalIndex entry = dictionary->FindEntry(isolate, non_existing_keys[i]);
CHECK_EQ(Dictionary::kNotFound, entry); CHECK(entry.is_not_found());
ft.CheckTrue(dictionary, non_existing_keys[i], expect_not_found); ft.CheckTrue(dictionary, non_existing_keys[i], expect_not_found);
} }
@ -851,8 +852,7 @@ TEST(NumberDictionaryLookup) {
for (int i = 0; i < kKeysCount; i++) { for (int i = 0; i < kKeysCount; i++) {
int random_key = rand_gen.NextInt(Smi::kMaxValue); int random_key = rand_gen.NextInt(Smi::kMaxValue);
keys[i] = static_cast<uint32_t>(random_key); keys[i] = static_cast<uint32_t>(random_key);
if (dictionary->FindEntry(isolate, keys[i]) != NumberDictionary::kNotFound) if (dictionary->FindEntry(isolate, keys[i]).is_found()) continue;
continue;
dictionary = NumberDictionary::Add(isolate, dictionary, keys[i], fake_value, dictionary = NumberDictionary::Add(isolate, dictionary, keys[i], fake_value,
fake_details); fake_details);
@ -860,19 +860,19 @@ TEST(NumberDictionaryLookup) {
// Now try querying existing keys. // Now try querying existing keys.
for (int i = 0; i < kKeysCount; i++) { for (int i = 0; i < kKeysCount; i++) {
int entry = dictionary->FindEntry(isolate, keys[i]); InternalIndex entry = dictionary->FindEntry(isolate, keys[i]);
CHECK_NE(NumberDictionary::kNotFound, entry); CHECK(entry.is_found());
Handle<Object> key(Smi::FromInt(keys[i]), isolate); Handle<Object> key(Smi::FromInt(keys[i]), isolate);
Handle<Object> expected_entry(Smi::FromInt(entry), isolate); Handle<Object> expected_entry(Smi::FromInt(entry.as_int()), isolate);
ft.CheckTrue(dictionary, key, expect_found, expected_entry); ft.CheckTrue(dictionary, key, expect_found, expected_entry);
} }
// Now try querying random keys which do not exist in the dictionary. // Now try querying random keys which do not exist in the dictionary.
for (int i = 0; i < kKeysCount;) { for (int i = 0; i < kKeysCount;) {
int random_key = rand_gen.NextInt(Smi::kMaxValue); int random_key = rand_gen.NextInt(Smi::kMaxValue);
int entry = dictionary->FindEntry(isolate, random_key); InternalIndex entry = dictionary->FindEntry(isolate, random_key);
if (entry != NumberDictionary::kNotFound) continue; if (entry.is_found()) continue;
i++; i++;
Handle<Object> key(Smi::FromInt(random_key), isolate); Handle<Object> key(Smi::FromInt(random_key), isolate);

View File

@ -84,7 +84,7 @@ static void TestHashMap(Handle<HashMap> table) {
Handle<JSObject> value = factory->NewJSArray(11); Handle<JSObject> value = factory->NewJSArray(11);
table = HashMap::Put(table, key, value); table = HashMap::Put(table, key, value);
CHECK_EQ(table->NumberOfElements(), i + 1); CHECK_EQ(table->NumberOfElements(), i + 1);
CHECK_NE(table->FindEntry(isolate, key), HashMap::kNotFound); CHECK(table->FindEntry(isolate, key).is_found());
CHECK_EQ(table->Lookup(key), *value); CHECK_EQ(table->Lookup(key), *value);
CHECK(key->GetIdentityHash().IsSmi()); CHECK(key->GetIdentityHash().IsSmi());
} }
@ -94,7 +94,7 @@ static void TestHashMap(Handle<HashMap> table) {
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
Handle<JSReceiver> key = factory->NewJSArray(7); Handle<JSReceiver> key = factory->NewJSArray(7);
CHECK(key->GetOrCreateIdentityHash(isolate).IsSmi()); CHECK(key->GetOrCreateIdentityHash(isolate).IsSmi());
CHECK_EQ(table->FindEntry(isolate, key), HashMap::kNotFound); CHECK(table->FindEntry(isolate, key).is_not_found());
CHECK_EQ(table->Lookup(key), roots.the_hole_value()); CHECK_EQ(table->Lookup(key), roots.the_hole_value());
CHECK(key->GetIdentityHash().IsSmi()); CHECK(key->GetIdentityHash().IsSmi());
} }
@ -189,9 +189,8 @@ TEST(HashSet) {
class ObjectHashTableTest: public ObjectHashTable { class ObjectHashTableTest: public ObjectHashTable {
public: public:
explicit ObjectHashTableTest(ObjectHashTable o) : ObjectHashTable(o) {} explicit ObjectHashTableTest(ObjectHashTable o) : ObjectHashTable(o) {}
ObjectHashTableTest* operator->() { return this; }
void insert(int entry, int key, int value) { void insert(InternalIndex entry, int key, int value) {
set(EntryToIndex(entry), Smi::FromInt(key)); set(EntryToIndex(entry), Smi::FromInt(key));
set(EntryToIndex(entry) + 1, Smi::FromInt(value)); set(EntryToIndex(entry) + 1, Smi::FromInt(value));
} }
@ -217,7 +216,7 @@ TEST(HashTableRehash) {
ObjectHashTableTest t(*table); ObjectHashTableTest t(*table);
int capacity = t.capacity(); int capacity = t.capacity();
for (int i = 0; i < capacity - 1; i++) { for (int i = 0; i < capacity - 1; i++) {
t.insert(i, i * i, i); t.insert(InternalIndex(i), i * i, i);
} }
t.Rehash(ReadOnlyRoots(isolate)); t.Rehash(ReadOnlyRoots(isolate));
for (int i = 0; i < capacity - 1; i++) { for (int i = 0; i < capacity - 1; i++) {
@ -230,7 +229,7 @@ TEST(HashTableRehash) {
ObjectHashTableTest t(*table); ObjectHashTableTest t(*table);
int capacity = t.capacity(); int capacity = t.capacity();
for (int i = 0; i < capacity / 2; i++) { for (int i = 0; i < capacity / 2; i++) {
t.insert(i, i * i, i); t.insert(InternalIndex(i), i * i, i);
} }
t.Rehash(ReadOnlyRoots(isolate)); t.Rehash(ReadOnlyRoots(isolate));
for (int i = 0; i < capacity / 2; i++) { for (int i = 0; i < capacity / 2; i++) {
@ -308,7 +307,8 @@ TEST(MaximumClonedShallowObjectProperties) {
// not in large-object space. // not in large-object space.
const int max_capacity = NameDictionary::ComputeCapacity( const int max_capacity = NameDictionary::ComputeCapacity(
ConstructorBuiltins::kMaximumClonedShallowObjectProperties); ConstructorBuiltins::kMaximumClonedShallowObjectProperties);
const int max_literal_entry = max_capacity / NameDictionary::kEntrySize; const InternalIndex max_literal_entry(max_capacity /
NameDictionary::kEntrySize);
const int max_literal_index = NameDictionary::EntryToIndex(max_literal_entry); const int max_literal_index = NameDictionary::EntryToIndex(max_literal_entry);
CHECK_LE(NameDictionary::OffsetOfElementAt(max_literal_index), CHECK_LE(NameDictionary::OffsetOfElementAt(max_literal_index),
kMaxRegularHeapObjectSize); kMaxRegularHeapObjectSize);

View File

@ -150,7 +150,7 @@ TEST(Shrinking) {
namespace { namespace {
bool EphemeronHashTableContainsKey(EphemeronHashTable table, HeapObject key) { bool EphemeronHashTableContainsKey(EphemeronHashTable table, HeapObject key) {
for (int i = 0; i < table.Capacity(); ++i) { for (InternalIndex i : table.IterateEntries()) {
if (table.KeyAt(i) == key) return true; if (table.KeyAt(i) == key) return true;
} }
return false; return false;