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

[dict-proto] make ordered hash tables use InternalIndex for indices

This changes the ordered hash data structures in ordered-hash-table.h to
use InternalIndex as the type used for indices, rather than int.

This makes the interface more similar to the (unordered) hash tables in
dictionary.h and hash-table.h

Bug: v8:7569

Change-Id: I2389b0c7d103eb7c33c5ed620b16eb198109b54c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2503949
Commit-Queue: Frank Emrich <emrich@google.com>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70873}
parent 8eaf1cde
......@@ -7011,10 +7011,11 @@ i::Handle<i::JSArray> MapAsArray(i::Isolate* isolate, i::Object table_obj,
i::DisallowHeapAllocation no_gc;
i::Oddball the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
for (int i = offset; i < capacity; ++i) {
i::Object key = table->KeyAt(i);
i::InternalIndex entry(i);
i::Object key = table->KeyAt(entry);
if (key == the_hole) continue;
if (collect_keys) result->set(result_index++, key);
if (collect_values) result->set(result_index++, table->ValueAt(i));
if (collect_values) result->set(result_index++, table->ValueAt(entry));
}
}
DCHECK_GE(max_length, result_index);
......@@ -7114,7 +7115,8 @@ i::Handle<i::JSArray> SetAsArray(i::Isolate* isolate, i::Object table_obj,
i::DisallowHeapAllocation no_gc;
i::Oddball the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
for (int i = offset; i < capacity; ++i) {
i::Object key = table->KeyAt(i);
i::InternalIndex entry(i);
i::Object key = table->KeyAt(entry);
if (key == the_hole) continue;
result->set(result_index++, key);
if (collect_key_values) result->set(result_index++, key);
......
......@@ -45,11 +45,15 @@ class InternalIndex {
return static_cast<int>(entry_);
}
bool operator==(const InternalIndex& other) { return entry_ == other.entry_; }
bool operator==(const InternalIndex& other) const {
return entry_ == other.entry_;
}
// Iteration support.
InternalIndex operator*() { return *this; }
bool operator!=(const InternalIndex& other) { return entry_ != other.entry_; }
bool operator!=(const InternalIndex& other) const {
return entry_ != other.entry_;
}
InternalIndex& operator++() {
entry_++;
return *this;
......
......@@ -49,7 +49,9 @@ CAST_ACCESSOR(JSMapIterator)
Object JSMapIterator::CurrentValue() {
OrderedHashMap table = OrderedHashMap::cast(this->table());
int index = Smi::ToInt(this->index());
Object value = table.ValueAt(index);
DCHECK_GE(index, 0);
InternalIndex entry(index);
Object value = table.ValueAt(entry);
DCHECK(!value.IsTheHole());
return value;
}
......
......@@ -97,38 +97,34 @@ Handle<Map> SmallOrderedHashSet::GetMap(ReadOnlyRoots roots) {
return roots.small_ordered_hash_set_map_handle();
}
inline Object OrderedHashMap::ValueAt(int entry) {
DCHECK_NE(entry, kNotFound);
DCHECK_LT(entry, UsedCapacity());
inline Object OrderedHashMap::ValueAt(InternalIndex entry) {
DCHECK_LT(entry.as_int(), UsedCapacity());
return get(EntryToIndex(entry) + kValueOffset);
}
inline Object OrderedNameDictionary::ValueAt(int entry) {
DCHECK_NE(entry, kNotFound);
DCHECK_LT(entry, UsedCapacity());
inline Object OrderedNameDictionary::ValueAt(InternalIndex entry) {
DCHECK_LT(entry.as_int(), UsedCapacity());
return get(EntryToIndex(entry) + kValueOffset);
}
// Set the value for entry.
inline void OrderedNameDictionary::ValueAtPut(int entry, Object value) {
DCHECK_NE(entry, kNotFound);
DCHECK_LT(entry, UsedCapacity());
inline void OrderedNameDictionary::ValueAtPut(InternalIndex entry,
Object value) {
DCHECK_LT(entry.as_int(), UsedCapacity());
this->set(EntryToIndex(entry) + kValueOffset, value);
}
// Returns the property details for the property at entry.
inline PropertyDetails OrderedNameDictionary::DetailsAt(int entry) {
DCHECK_NE(entry, kNotFound);
DCHECK_LT(entry, this->UsedCapacity());
inline PropertyDetails OrderedNameDictionary::DetailsAt(InternalIndex entry) {
DCHECK_LT(entry.as_int(), this->UsedCapacity());
// TODO(gsathya): Optimize the cast away.
return PropertyDetails(
Smi::cast(get(EntryToIndex(entry) + kPropertyDetailsOffset)));
}
inline void OrderedNameDictionary::DetailsAtPut(int entry,
inline void OrderedNameDictionary::DetailsAtPut(InternalIndex entry,
PropertyDetails value) {
DCHECK_NE(entry, kNotFound);
DCHECK_LT(entry, this->UsedCapacity());
DCHECK_LT(entry.as_int(), this->UsedCapacity());
// TODO(gsathya): Optimize the cast away.
this->set(EntryToIndex(entry) + kPropertyDetailsOffset, value.AsSmi());
}
......@@ -193,7 +189,9 @@ template <class Derived, class TableType>
Object OrderedHashTableIterator<Derived, TableType>::CurrentKey() {
TableType table = TableType::cast(this->table());
int index = Smi::ToInt(this->index());
Object key = table.KeyAt(index);
DCHECK_LE(0, index);
InternalIndex entry(index);
Object key = table.KeyAt(entry);
DCHECK(!key.IsTheHole());
return key;
}
......
This diff is collapsed.
......@@ -8,6 +8,7 @@
#include "src/base/export-template.h"
#include "src/common/globals.h"
#include "src/objects/fixed-array.h"
#include "src/objects/internal-index.h"
#include "src/objects/js-objects.h"
#include "src/objects/smi.h"
#include "src/roots/roots.h"
......@@ -82,7 +83,7 @@ class OrderedHashTable : public FixedArray {
// the key has been deleted. This does not shrink the table.
static bool Delete(Isolate* isolate, Derived table, Object key);
int FindEntry(Isolate* isolate, Object key);
InternalIndex FindEntry(Isolate* isolate, Object key);
int NumberOfElements() const {
return Smi::ToInt(get(NumberOfElementsIndex()));
......@@ -102,27 +103,13 @@ class OrderedHashTable : public FixedArray {
return Smi::ToInt(get(NumberOfBucketsIndex()));
}
// Returns an index into |this| for the given entry.
int EntryToIndex(int entry) {
return HashTableStartIndex() + NumberOfBuckets() + (entry * kEntrySize);
}
int HashToBucket(int hash) { return hash & (NumberOfBuckets() - 1); }
int HashToEntry(int hash) {
int bucket = HashToBucket(hash);
Object entry = this->get(HashTableStartIndex() + bucket);
return Smi::ToInt(entry);
}
int NextChainEntry(int entry) {
Object next_entry = get(EntryToIndex(entry) + kChainOffset);
return Smi::ToInt(next_entry);
InternalIndex::Range IterateEntries() {
return InternalIndex::Range(UsedCapacity());
}
// use KeyAt(i)->IsTheHole(isolate) to determine if this is a deleted entry.
Object KeyAt(int entry) {
DCHECK_LT(entry, this->UsedCapacity());
Object KeyAt(InternalIndex entry) {
DCHECK_LT(entry.as_int(), this->UsedCapacity());
return get(EntryToIndex(entry));
}
......@@ -212,6 +199,33 @@ class OrderedHashTable : public FixedArray {
static MaybeHandle<Derived> Rehash(Isolate* isolate, Handle<Derived> table,
int new_capacity);
int HashToEntryRaw(int hash) {
int bucket = HashToBucket(hash);
Object entry = this->get(HashTableStartIndex() + bucket);
int entry_int = Smi::ToInt(entry);
DCHECK(entry_int == kNotFound || entry_int >= 0);
return entry_int;
}
int NextChainEntryRaw(int entry) {
DCHECK_LT(entry, this->UsedCapacity());
Object next_entry = get(EntryToIndexRaw(entry) + kChainOffset);
int next_entry_int = Smi::ToInt(next_entry);
DCHECK(next_entry_int == kNotFound || next_entry_int >= 0);
return next_entry_int;
}
// Returns an index into |this| for the given entry.
int EntryToIndexRaw(int entry) {
return HashTableStartIndex() + NumberOfBuckets() + (entry * kEntrySize);
}
int EntryToIndex(InternalIndex entry) {
return EntryToIndexRaw(entry.as_int());
}
int HashToBucket(int hash) { return hash & (NumberOfBuckets() - 1); }
void SetNumberOfBuckets(int num) {
set(NumberOfBucketsIndex(), Smi::FromInt(num));
}
......@@ -298,7 +312,7 @@ class V8_EXPORT_PRIVATE OrderedHashMap
int new_capacity);
static MaybeHandle<OrderedHashMap> Rehash(Isolate* isolate,
Handle<OrderedHashMap> table);
Object ValueAt(int entry);
Object ValueAt(InternalIndex entry);
// This takes and returns raw Address values containing tagged Object
// pointers because it is called via ExternalReference.
......@@ -727,12 +741,14 @@ class V8_EXPORT_PRIVATE OrderedNameDictionary
Isolate* isolate, Handle<OrderedNameDictionary> table, Handle<Name> key,
Handle<Object> value, PropertyDetails details);
void SetEntry(int entry, Object key, Object value, PropertyDetails details);
void SetEntry(InternalIndex entry, Object key, Object value,
PropertyDetails details);
int FindEntry(Isolate* isolate, Object key);
InternalIndex FindEntry(Isolate* isolate, Object key);
static Handle<OrderedNameDictionary> DeleteEntry(
Isolate* isolate, Handle<OrderedNameDictionary> table, int entry);
Isolate* isolate, Handle<OrderedNameDictionary> table,
InternalIndex entry);
static MaybeHandle<OrderedNameDictionary> Allocate(
Isolate* isolate, int capacity,
......@@ -745,16 +761,16 @@ class V8_EXPORT_PRIVATE OrderedNameDictionary
Isolate* isolate, Handle<OrderedNameDictionary> table, int new_capacity);
// Returns the value for entry.
inline Object ValueAt(int entry);
inline Object ValueAt(InternalIndex entry);
// Set the value for entry.
inline void ValueAtPut(int entry, Object value);
inline void ValueAtPut(InternalIndex entry, Object value);
// Returns the property details for the property at entry.
inline PropertyDetails DetailsAt(int entry);
inline PropertyDetails DetailsAt(InternalIndex entry);
// Set the details for entry.
inline void DetailsAtPut(int entry, PropertyDetails value);
inline void DetailsAtPut(InternalIndex entry, PropertyDetails value);
inline void SetHash(int hash);
inline int Hash();
......
......@@ -792,13 +792,12 @@ Maybe<bool> ValueSerializer::WriteJSMap(Handle<JSMap> map) {
{
DisallowHeapAllocation no_gc;
Oddball the_hole = ReadOnlyRoots(isolate_).the_hole_value();
int capacity = table->UsedCapacity();
int result_index = 0;
for (int i = 0; i < capacity; i++) {
Object key = table->KeyAt(i);
for (InternalIndex entry : table->IterateEntries()) {
Object key = table->KeyAt(entry);
if (key == the_hole) continue;
entries->set(result_index++, key);
entries->set(result_index++, table->ValueAt(i));
entries->set(result_index++, table->ValueAt(entry));
}
DCHECK_EQ(result_index, length);
}
......@@ -823,10 +822,9 @@ Maybe<bool> ValueSerializer::WriteJSSet(Handle<JSSet> set) {
{
DisallowHeapAllocation no_gc;
Oddball the_hole = ReadOnlyRoots(isolate_).the_hole_value();
int capacity = table->UsedCapacity();
int result_index = 0;
for (int i = 0; i < capacity; i++) {
Object key = table->KeyAt(i);
for (InternalIndex entry : table->IterateEntries()) {
Object key = table->KeyAt(entry);
if (key == the_hole) continue;
entries->set(result_index++, key);
}
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment