Commit 635f938f authored by Sathya Gunasekaran's avatar Sathya Gunasekaran Committed by Commit Bot

[dict] Add facade around the two different kind of dicts

OrderedNameDictionarHandler is the external API to interface with the
OrderedNameDictionary variants. This abstracts away the need for the
user to know that there are two different backing stores.

Bug: v8:6443, v8:7569
Change-Id: Ief4f0904823988e629a01060b018b4cb0291542d
Reviewed-on: https://chromium-review.googlesource.com/c/1381758
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58369}
parent b534e00e
...@@ -828,6 +828,10 @@ OrderedHashTableHandler<SmallOrderedHashSet, OrderedHashSet>::Allocate( ...@@ -828,6 +828,10 @@ OrderedHashTableHandler<SmallOrderedHashSet, OrderedHashSet>::Allocate(
template Handle<HeapObject> template Handle<HeapObject>
OrderedHashTableHandler<SmallOrderedHashMap, OrderedHashMap>::Allocate( OrderedHashTableHandler<SmallOrderedHashMap, OrderedHashMap>::Allocate(
Isolate* isolate, int capacity); Isolate* isolate, int capacity);
template Handle<HeapObject>
OrderedHashTableHandler<SmallOrderedNameDictionary,
OrderedNameDictionary>::Allocate(Isolate* isolate,
int capacity);
template <class SmallTable, class LargeTable> template <class SmallTable, class LargeTable>
bool OrderedHashTableHandler<SmallTable, LargeTable>::Delete( bool OrderedHashTableHandler<SmallTable, LargeTable>::Delete(
...@@ -900,6 +904,29 @@ Handle<OrderedHashSet> OrderedHashSetHandler::AdjustRepresentation( ...@@ -900,6 +904,29 @@ Handle<OrderedHashSet> OrderedHashSetHandler::AdjustRepresentation(
return new_table; return new_table;
} }
Handle<OrderedNameDictionary>
OrderedNameDictionaryHandler::AdjustRepresentation(
Isolate* isolate, Handle<SmallOrderedNameDictionary> table) {
Handle<OrderedNameDictionary> new_table =
OrderedNameDictionary::Allocate(isolate, OrderedHashTableMinSize);
int nof = table->NumberOfElements();
int nod = table->NumberOfDeletedElements();
// TODO(gsathya): Optimize the lookup to not re calc offsets. Also,
// unhandlify this code as we preallocate the new backing store with
// the proper capacity.
for (int entry = 0; entry < (nof + nod); ++entry) {
Handle<Name> key(Name::cast(table->KeyAt(entry)), isolate);
if (key->IsTheHole(isolate)) continue;
Handle<Object> value(table->ValueAt(entry), isolate);
PropertyDetails details = table->DetailsAt(entry);
new_table =
OrderedNameDictionary::Add(isolate, new_table, key, value, details);
}
return new_table;
}
Handle<HeapObject> OrderedHashMapHandler::Add(Isolate* isolate, Handle<HeapObject> OrderedHashMapHandler::Add(Isolate* isolate,
Handle<HeapObject> table, Handle<HeapObject> table,
Handle<Object> key, Handle<Object> key,
...@@ -940,6 +967,105 @@ Handle<HeapObject> OrderedHashSetHandler::Add(Isolate* isolate, ...@@ -940,6 +967,105 @@ Handle<HeapObject> OrderedHashSetHandler::Add(Isolate* isolate,
return OrderedHashSet::Add(isolate, Handle<OrderedHashSet>::cast(table), key); return OrderedHashSet::Add(isolate, Handle<OrderedHashSet>::cast(table), key);
} }
Handle<HeapObject> OrderedNameDictionaryHandler::Add(Isolate* isolate,
Handle<HeapObject> table,
Handle<Name> key,
Handle<Object> value,
PropertyDetails details) {
if (table->IsSmallOrderedNameDictionary()) {
Handle<SmallOrderedNameDictionary> small_dict =
Handle<SmallOrderedNameDictionary>::cast(table);
MaybeHandle<SmallOrderedNameDictionary> new_dict =
SmallOrderedNameDictionary::Add(isolate, small_dict, key, value,
details);
if (!new_dict.is_null()) return new_dict.ToHandleChecked();
// We couldn't add to the small table, let's migrate to the
// big table.
table =
OrderedNameDictionaryHandler::AdjustRepresentation(isolate, small_dict);
}
DCHECK(table->IsOrderedNameDictionary());
return OrderedNameDictionary::Add(
isolate, Handle<OrderedNameDictionary>::cast(table), key, value, details);
}
int OrderedNameDictionaryHandler::FindEntry(Isolate* isolate, HeapObject* table,
Object* key) {
if (table->IsSmallOrderedNameDictionary()) {
int entry =
SmallOrderedNameDictionary::cast(table)->FindEntry(isolate, key);
return entry == SmallOrderedNameDictionary::kNotFound
? OrderedNameDictionaryHandler::kNotFound
: entry;
}
DCHECK(table->IsOrderedNameDictionary());
int entry = OrderedNameDictionary::cast(table)->FindEntry(isolate, key);
return entry == OrderedNameDictionary::kNotFound
? OrderedNameDictionaryHandler::kNotFound
: entry;
}
Object* OrderedNameDictionaryHandler::ValueAt(HeapObject* table, int entry) {
if (table->IsSmallOrderedNameDictionary()) {
return SmallOrderedNameDictionary::cast(table)->ValueAt(entry);
}
DCHECK(table->IsOrderedNameDictionary());
return OrderedNameDictionary::cast(table)->ValueAt(entry);
}
void OrderedNameDictionaryHandler::ValueAtPut(HeapObject* table, int entry,
Object* value) {
if (table->IsSmallOrderedNameDictionary()) {
return SmallOrderedNameDictionary::cast(table)->ValueAtPut(entry, value);
}
DCHECK(table->IsOrderedNameDictionary());
OrderedNameDictionary::cast(table)->ValueAtPut(entry, value);
}
PropertyDetails OrderedNameDictionaryHandler::DetailsAt(HeapObject* table,
int entry) {
if (table->IsSmallOrderedNameDictionary()) {
return SmallOrderedNameDictionary::cast(table)->DetailsAt(entry);
}
DCHECK(table->IsOrderedNameDictionary());
return OrderedNameDictionary::cast(table)->DetailsAt(entry);
}
void OrderedNameDictionaryHandler::DetailsAtPut(HeapObject* table, int entry,
PropertyDetails details) {
if (table->IsSmallOrderedNameDictionary()) {
return SmallOrderedNameDictionary::cast(table)->DetailsAtPut(entry,
details);
}
DCHECK(table->IsOrderedNameDictionary());
OrderedNameDictionary::cast(table)->DetailsAtPut(entry, details);
}
int OrderedNameDictionaryHandler::Hash(HeapObject* table) {
if (table->IsSmallOrderedNameDictionary()) {
return SmallOrderedNameDictionary::cast(table)->Hash();
}
DCHECK(table->IsOrderedNameDictionary());
return OrderedNameDictionary::cast(table)->Hash();
}
void OrderedNameDictionaryHandler::SetHash(HeapObject* table, int hash) {
if (table->IsSmallOrderedNameDictionary()) {
return SmallOrderedNameDictionary::cast(table)->SetHash(hash);
}
DCHECK(table->IsOrderedNameDictionary());
OrderedNameDictionary::cast(table)->SetHash(hash);
}
template <class Derived, class TableType> template <class Derived, class TableType>
void OrderedHashTableIterator<Derived, TableType>::Transition() { void OrderedHashTableIterator<Derived, TableType>::Transition() {
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
......
...@@ -561,6 +561,7 @@ class SmallOrderedHashTable : public HeapObjectPtr { ...@@ -561,6 +561,7 @@ class SmallOrderedHashTable : public HeapObjectPtr {
private: private:
friend class OrderedHashMapHandler; friend class OrderedHashMapHandler;
friend class OrderedHashSetHandler; friend class OrderedHashSetHandler;
friend class OrderedNameDictionaryHandler;
friend class CodeStubAssembler; friend class CodeStubAssembler;
OBJECT_CONSTRUCTORS(SmallOrderedHashTable, HeapObjectPtr) OBJECT_CONSTRUCTORS(SmallOrderedHashTable, HeapObjectPtr)
...@@ -700,6 +701,38 @@ class OrderedNameDictionary ...@@ -700,6 +701,38 @@ class OrderedNameDictionary
OrderedHashTable<OrderedNameDictionary, 3>) OrderedHashTable<OrderedNameDictionary, 3>)
}; };
class OrderedNameDictionaryHandler
: public OrderedHashTableHandler<SmallOrderedNameDictionary,
OrderedNameDictionary> {
public:
static Handle<HeapObject> Add(Isolate* isolate, Handle<HeapObject> table,
Handle<Name> key, Handle<Object> value,
PropertyDetails details);
static int FindEntry(Isolate* isolate, HeapObject* table, Object* key);
// Returns the value for entry.
static Object* ValueAt(HeapObject* table, int entry);
// Set the value for entry.
static void ValueAtPut(HeapObject* table, int entry, Object* value);
// Returns the property details for the property at entry.
static PropertyDetails DetailsAt(HeapObject* table, int entry);
// Set the details for entry.
static void DetailsAtPut(HeapObject* table, int entry, PropertyDetails value);
static void SetHash(HeapObject* table, int hash);
static int Hash(HeapObject* table);
static const int kNotFound = -1;
protected:
static Handle<OrderedNameDictionary> AdjustRepresentation(
Isolate* isolate, Handle<SmallOrderedNameDictionary> table);
};
class SmallOrderedNameDictionary class SmallOrderedNameDictionary
: public SmallOrderedHashTable<SmallOrderedNameDictionary> { : public SmallOrderedHashTable<SmallOrderedNameDictionary> {
public: public:
......
...@@ -1730,6 +1730,57 @@ TEST(OrderedNameDictionarySetAndMigrateHash) { ...@@ -1730,6 +1730,57 @@ TEST(OrderedNameDictionarySetAndMigrateHash) {
} }
} }
TEST(OrderedNameDictionaryHandlerInsertion) {
LocalContext context;
Isolate* isolate = GetIsolateFrom(&context);
HandleScope scope(isolate);
Handle<HeapObject> table = OrderedNameDictionaryHandler::Allocate(isolate, 4);
CHECK(table->IsSmallOrderedNameDictionary());
Verify(isolate, table);
// Add a new key.
Handle<String> value = isolate->factory()->InternalizeUtf8String("bar");
Handle<String> key = isolate->factory()->InternalizeUtf8String("foo");
PropertyDetails details = PropertyDetails::Empty();
table =
OrderedNameDictionaryHandler::Add(isolate, table, key, value, details);
DCHECK(key->IsUniqueName());
Verify(isolate, table);
CHECK(table->IsSmallOrderedNameDictionary());
CHECK_NE(OrderedNameDictionaryHandler::kNotFound,
OrderedNameDictionaryHandler::FindEntry(isolate, *table, *key));
char buf[10];
for (int i = 0; i < 1024; i++) {
CHECK_LT(0, snprintf(buf, sizeof(buf), "foo%d", i));
key = isolate->factory()->InternalizeUtf8String(buf);
table =
OrderedNameDictionaryHandler::Add(isolate, table, key, value, details);
DCHECK(key->IsUniqueName());
Verify(isolate, table);
for (int j = 0; j <= i; j++) {
CHECK_LT(0, snprintf(buf, sizeof(buf), "foo%d", j));
Handle<Name> key_j = isolate->factory()->InternalizeUtf8String(buf);
CHECK_NE(
OrderedNameDictionaryHandler::kNotFound,
OrderedNameDictionaryHandler::FindEntry(isolate, *table, *key_j));
}
for (int j = i + 1; j < 1024; j++) {
CHECK_LT(0, snprintf(buf, sizeof(buf), "foo%d", j));
Handle<Name> key_j = isolate->factory()->InternalizeUtf8String(buf);
CHECK_EQ(
OrderedNameDictionaryHandler::kNotFound,
OrderedNameDictionaryHandler::FindEntry(isolate, *table, *key_j));
}
}
CHECK(table->IsOrderedNameDictionary());
}
} // namespace test_orderedhashtable } // namespace test_orderedhashtable
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
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