Commit cdfc65ab authored by Sathya Gunasekaran's avatar Sathya Gunasekaran

[dict] Specialize FindEntry for name dictionary

in SmallOrderedHashTable

Bug: v8:6443, v8:7569
Change-Id: I14572b1acc30df45d0554ee7e8e129da85791529
Reviewed-on: https://chromium-review.googlesource.com/c/1329698Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57439}
parent d0749b78
......@@ -689,6 +689,42 @@ MaybeHandle<Derived> SmallOrderedHashTable<Derived>::Grow(
return Rehash(isolate, table, new_capacity);
}
template <class Derived>
int SmallOrderedHashTable<Derived>::FindEntry(Isolate* isolate, Object* key) {
DisallowHeapAllocation no_gc;
Object* hash = key->GetHash();
if (hash->IsUndefined(isolate)) return kNotFound;
int entry = HashToFirstEntry(Smi::ToInt(hash));
// Walk the chain in the bucket to find the key.
while (entry != kNotFound) {
Object* candidate_key = KeyAt(entry);
if (candidate_key->SameValueZero(key)) return entry;
entry = GetNextEntry(entry);
}
return kNotFound;
}
template <>
int SmallOrderedHashTable<SmallOrderedNameDictionary>::FindEntry(
Isolate* isolate, Object* key) {
DisallowHeapAllocation no_gc;
DCHECK(key->IsUniqueName());
Name* raw_key = Name::cast(key);
int entry = HashToFirstEntry(raw_key->Hash());
// Walk the chain in the bucket to find the key.
while (entry != kNotFound) {
Object* candidate_key = KeyAt(entry);
if (candidate_key == key) return entry;
entry = GetNextEntry(entry);
}
return kNotFound;
}
template bool SmallOrderedHashTable<SmallOrderedHashSet>::HasKey(
Isolate* isolate, Handle<Object> key);
template Handle<SmallOrderedHashSet>
......
......@@ -301,6 +301,8 @@ class SmallOrderedHashTable : public HeapObject {
static Handle<Derived> Rehash(Isolate* isolate, Handle<Derived> table,
int new_capacity);
int FindEntry(Isolate* isolate, Object* key);
// Iterates only fields in the DataTable.
class BodyDescriptor;
......@@ -453,22 +455,6 @@ class SmallOrderedHashTable : public HeapObject {
setByte(kNumberOfDeletedElementsOffset, 0, num);
}
int FindEntry(Isolate* isolate, Object* key) {
DisallowHeapAllocation no_gc;
Object* hash = key->GetHash();
if (hash->IsUndefined(isolate)) return kNotFound;
int entry = HashToFirstEntry(Smi::ToInt(hash));
// Walk the chain in the bucket to find the key.
while (entry != kNotFound) {
Object* candidate_key = KeyAt(entry);
if (candidate_key->SameValueZero(key)) return entry;
entry = GetNextEntry(entry);
}
return kNotFound;
}
static const Offset kNumberOfElementsOffset = kHeaderSize;
static const Offset kNumberOfDeletedElementsOffset =
kNumberOfElementsOffset + kOneByteSize;
......
......@@ -1502,6 +1502,50 @@ TEST(SmallOrderedNameDictionaryInsertion) {
CHECK(dict->HasKey(isolate, key2));
}
TEST(SmallOrderedNameDictionaryFindEntry) {
LocalContext context;
Isolate* isolate = GetIsolateFrom(&context);
Factory* factory = isolate->factory();
HandleScope scope(isolate);
Handle<SmallOrderedNameDictionary> dict =
factory->NewSmallOrderedNameDictionary();
Verify(isolate, dict);
CHECK_EQ(2, dict->NumberOfBuckets());
CHECK_EQ(0, dict->NumberOfElements());
Handle<String> key1 = isolate->factory()->InternalizeUtf8String("foo");
Handle<String> value = isolate->factory()->InternalizeUtf8String("foo");
CHECK(!dict->HasKey(isolate, key1));
PropertyDetails details = PropertyDetails::Empty();
dict = SmallOrderedNameDictionary::Add(isolate, dict, key1, value, details)
.ToHandleChecked();
Verify(isolate, dict);
CHECK_EQ(2, dict->NumberOfBuckets());
CHECK_EQ(1, dict->NumberOfElements());
CHECK(dict->HasKey(isolate, key1));
int entry = dict->FindEntry(isolate, *key1);
CHECK_NE(entry, OrderedNameDictionary::kNotFound);
Handle<Symbol> key2 = factory->NewSymbol();
CHECK(!dict->HasKey(isolate, key2));
dict = SmallOrderedNameDictionary::Add(isolate, dict, key2, value, details)
.ToHandleChecked();
Verify(isolate, dict);
CHECK_EQ(2, dict->NumberOfBuckets());
CHECK_EQ(2, dict->NumberOfElements());
CHECK(dict->HasKey(isolate, key1));
CHECK(dict->HasKey(isolate, key2));
entry = dict->FindEntry(isolate, *key1);
CHECK_NE(entry, OrderedNameDictionary::kNotFound);
entry = dict->FindEntry(isolate, *key2);
CHECK_NE(entry, OrderedNameDictionary::kNotFound);
}
} // namespace test_orderedhashtable
} // namespace internal
} // 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