Commit d5040c43 authored by Sathya Gunasekaran's avatar Sathya Gunasekaran Committed by Commit Bot

[collections] Add OrderedHashTable::Delete

Bug: v8:5717
Change-Id: Icc601c409ac79195991facf1cb2027aab6145ff8
Reviewed-on: https://chromium-review.googlesource.com/540659
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46066}
parent da607264
......@@ -18158,14 +18158,9 @@ Object* OrderedHashTable<Derived, entrysize>::HasKey(Isolate* isolate,
Object* key) {
DCHECK(table->IsOrderedHashTable());
DisallowHeapAllocation no_gc;
int entry = table->KeyToFirstEntry(isolate, key);
// Walk the chain in the bucket to find the key.
while (entry != kNotFound) {
Object* candidate_key = table->KeyAt(entry);
if (candidate_key->SameValueZero(key)) return isolate->heap()->true_value();
entry = table->NextChainEntry(entry);
}
return isolate->heap()->false_value();
int entry = table->FindEntry(isolate, key);
return entry == kNotFound ? isolate->heap()->false_value()
: isolate->heap()->true_value();
}
Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table,
......@@ -18267,20 +18262,35 @@ Handle<Derived> OrderedHashTable<Derived, entrysize>::Rehash(
return new_table;
}
template <class Derived, int entrysize>
bool OrderedHashTable<Derived, entrysize>::Delete(Isolate* isolate,
Derived* table, Object* key) {
DisallowHeapAllocation no_gc;
int entry = table->FindEntry(isolate, key);
if (entry == kNotFound) return false;
int nof = table->NumberOfElements();
int nod = table->NumberOfDeletedElements();
int index = table->EntryToIndex(entry);
Object* hole = isolate->heap()->the_hole_value();
for (int i = 0; i < entrysize; ++i) {
table->set(index + i, hole);
}
table->SetNumberOfElements(nof - 1);
table->SetNumberOfDeletedElements(nod + 1);
return true;
}
Object* OrderedHashMap::Get(Isolate* isolate, OrderedHashMap* table,
Object* key) {
DCHECK(table->IsOrderedHashMap());
DisallowHeapAllocation no_gc;
int entry = table->KeyToFirstEntry(isolate, key);
// Walk the chain in the bucket to find the key.
while (entry != kNotFound) {
Object* candidate_key = table->KeyAt(entry);
if (candidate_key->SameValueZero(key)) {
int entry = table->FindEntry(isolate, key);
if (entry == kNotFound) return isolate->heap()->undefined_value();
return table->ValueAt(entry);
}
entry = table->NextChainEntry(entry);
}
return isolate->heap()->undefined_value();
}
Handle<OrderedHashMap> OrderedHashMap::Add(Handle<OrderedHashMap> table,
......@@ -18332,6 +18342,10 @@ template Handle<OrderedHashSet> OrderedHashTable<OrderedHashSet, 1>::Clear(
template Object* OrderedHashTable<OrderedHashSet, 1>::HasKey(
Isolate* isolate, OrderedHashSet* table, Object* key);
template bool OrderedHashTable<OrderedHashSet, 1>::Delete(Isolate* isolate,
OrderedHashSet* table,
Object* key);
template Handle<OrderedHashMap> OrderedHashTable<OrderedHashMap, 2>::Allocate(
Isolate* isolate, int capacity, PretenureFlag pretenure);
......@@ -18347,6 +18361,10 @@ template Handle<OrderedHashMap> OrderedHashTable<OrderedHashMap, 2>::Clear(
template Object* OrderedHashTable<OrderedHashMap, 2>::HasKey(
Isolate* isolate, OrderedHashMap* table, Object* key);
template bool OrderedHashTable<OrderedHashMap, 2>::Delete(Isolate* isolate,
OrderedHashMap* table,
Object* key);
template <>
Handle<SmallOrderedHashSet>
SmallOrderedHashTable<SmallOrderedHashSet>::Allocate(Isolate* isolate,
......
......@@ -410,6 +410,10 @@ class OrderedHashTable : public FixedArray {
// existing iterators can be updated.
static Handle<Derived> Clear(Handle<Derived> table);
// Returns a true value if the OrderedHashTable contains the key and
// the key has been deleted. This does not shrink the table.
static bool Delete(Isolate* isolate, Derived* table, Object* key);
// Returns a true value if the OrderedHashTable contains the key
static Object* HasKey(Isolate* isolate, Derived* table, Object* key);
......@@ -457,6 +461,18 @@ class OrderedHashTable : public FixedArray {
return HashToEntry(Smi::cast(hash)->value());
}
int FindEntry(Isolate* isolate, Object* key) {
int entry = KeyToFirstEntry(isolate, key);
// Walk the chain in the bucket to find the key.
while (entry != kNotFound) {
Object* candidate_key = KeyAt(entry);
if (candidate_key->SameValueZero(key)) break;
entry = NextChainEntry(entry);
}
return entry;
}
int NextChainEntry(int entry) {
Object* next_entry = get(EntryToIndex(entry) + kChainOffset);
return Smi::cast(next_entry)->value();
......
......@@ -13,6 +13,19 @@ static Isolate* GetIsolateFrom(LocalContext* context) {
return reinterpret_cast<Isolate*>((*context)->GetIsolate());
}
void CopyHashCode(Isolate* isolate, Handle<JSReceiver> from,
Handle<JSReceiver> to) {
Handle<Name> hash_code_symbol = isolate->factory()->hash_code_symbol();
Handle<Smi> hash =
Handle<Smi>::cast(JSObject::GetDataProperty(from, hash_code_symbol));
LookupIterator it(to, hash_code_symbol, to, LookupIterator::OWN);
CHECK(to->AddDataProperty(
&it, hash, NONE, v8::internal::AccessCheckInfo::THROW_ON_ERROR,
v8::internal::AccessCheckInfo::CERTAINLY_NOT_STORE_FROM_KEYED)
.IsJust());
}
void Verify(Handle<SmallOrderedHashSet> set) {
#if VERIFY_HEAP
set->ObjectVerify();
......@@ -31,6 +44,12 @@ void Verify(Handle<OrderedHashMap> map) {
#endif
}
void Verify(Handle<OrderedHashSet> set) {
#if VERIFY_HEAP
set->ObjectVerify();
#endif
}
TEST(SmallOrderedHashSetInsertion) {
LocalContext context;
Isolate* isolate = GetIsolateFrom(&context);
......@@ -211,20 +230,8 @@ TEST(SmallOrderedHashSetDuplicateHashCode) {
CHECK_EQ(1, set->NumberOfElements());
CHECK(set->HasKey(isolate, key1));
Handle<Name> hash_code_symbol = isolate->factory()->hash_code_symbol();
Handle<Smi> hash =
Handle<Smi>::cast(JSObject::GetDataProperty(key1, hash_code_symbol));
Handle<JSObject> key2 = factory->NewJSObjectWithNullProto();
LookupIterator it(key2, hash_code_symbol, key2, LookupIterator::OWN);
CHECK(key2->AddDataProperty(
&it, hash, NONE, v8::internal::AccessCheckInfo::THROW_ON_ERROR,
v8::internal::AccessCheckInfo::CERTAINLY_NOT_STORE_FROM_KEYED)
.IsJust());
CHECK(!key1->SameValue(*key2));
Object* hash1 = key1->GetHash();
Object* hash2 = key2->GetHash();
CHECK_EQ(hash1, hash2);
CopyHashCode(isolate, key1, key2);
set = SmallOrderedHashSet::Add(set, key2);
Verify(set);
......@@ -612,16 +619,8 @@ TEST(OrderedHashMapDuplicateHashCode) {
CHECK_EQ(1, map->NumberOfElements());
CHECK_EQ(*true_val, OrderedHashMap::HasKey(isolate, *map, *key1));
Handle<Name> hash_code_symbol = isolate->factory()->hash_code_symbol();
Handle<Smi> hash =
Handle<Smi>::cast(JSObject::GetDataProperty(key1, hash_code_symbol));
Handle<JSObject> key2 = factory->NewJSObjectWithNullProto();
LookupIterator it(key2, hash_code_symbol, key2, LookupIterator::OWN);
CHECK(key2->AddDataProperty(
&it, hash, NONE, v8::internal::AccessCheckInfo::THROW_ON_ERROR,
v8::internal::AccessCheckInfo::CERTAINLY_NOT_STORE_FROM_KEYED)
.IsJust());
CopyHashCode(isolate, key1, key2);
map = OrderedHashMap::Add(map, key2, value);
Verify(map);
......@@ -630,3 +629,312 @@ TEST(OrderedHashMapDuplicateHashCode) {
CHECK_EQ(*true_val, OrderedHashMap::HasKey(isolate, *map, *key1));
CHECK_EQ(*true_val, OrderedHashMap::HasKey(isolate, *map, *key2));
}
TEST(OrderedHashMapDeletion) {
LocalContext context;
Isolate* isolate = GetIsolateFrom(&context);
Factory* factory = isolate->factory();
HandleScope scope(isolate);
Handle<Object> true_val = factory->true_value();
Handle<Object> false_val = factory->false_value();
Handle<Smi> value1(Smi::FromInt(1), isolate);
Handle<String> value = factory->NewStringFromAsciiChecked("bar");
Handle<OrderedHashMap> map = factory->NewOrderedHashMap();
Verify(map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(0, map->NumberOfElements());
CHECK_EQ(0, map->NumberOfDeletedElements());
// Delete from an empty hash table
Handle<Smi> key1(Smi::FromInt(1), isolate);
CHECK(!OrderedHashMap::Delete(isolate, *map, *key1));
Verify(map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(0, map->NumberOfElements());
CHECK_EQ(0, map->NumberOfDeletedElements());
CHECK_EQ(*false_val, OrderedHashMap::HasKey(isolate, *map, *key1));
map = OrderedHashMap::Add(map, key1, value1);
Verify(map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(1, map->NumberOfElements());
CHECK_EQ(0, map->NumberOfDeletedElements());
CHECK_EQ(*true_val, OrderedHashMap::HasKey(isolate, *map, *key1));
// Delete single existing key
CHECK(OrderedHashMap::Delete(isolate, *map, *key1));
Verify(map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(0, map->NumberOfElements());
CHECK_EQ(1, map->NumberOfDeletedElements());
CHECK_EQ(*false_val, OrderedHashMap::HasKey(isolate, *map, *key1));
map = OrderedHashMap::Add(map, key1, value1);
Verify(map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(1, map->NumberOfElements());
CHECK_EQ(1, map->NumberOfDeletedElements());
CHECK_EQ(*true_val, OrderedHashMap::HasKey(isolate, *map, *key1));
Handle<String> key2 = factory->NewStringFromAsciiChecked("foo");
CHECK_EQ(*false_val, OrderedHashMap::HasKey(isolate, *map, *key2));
map = OrderedHashMap::Add(map, key2, value);
Verify(map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(2, map->NumberOfElements());
CHECK_EQ(1, map->NumberOfDeletedElements());
CHECK_EQ(*true_val, OrderedHashMap::HasKey(isolate, *map, *key2));
Handle<Symbol> key3 = factory->NewSymbol();
CHECK_EQ(*false_val, OrderedHashMap::HasKey(isolate, *map, *key3));
map = OrderedHashMap::Add(map, key3, value);
Verify(map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(3, map->NumberOfElements());
CHECK_EQ(1, map->NumberOfDeletedElements());
CHECK_EQ(*true_val, OrderedHashMap::HasKey(isolate, *map, *key1));
CHECK_EQ(*true_val, OrderedHashMap::HasKey(isolate, *map, *key2));
CHECK_EQ(*true_val, OrderedHashMap::HasKey(isolate, *map, *key3));
// Delete multiple existing keys
CHECK(OrderedHashMap::Delete(isolate, *map, *key1));
Verify(map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(2, map->NumberOfElements());
CHECK_EQ(2, map->NumberOfDeletedElements());
CHECK_EQ(*false_val, OrderedHashMap::HasKey(isolate, *map, *key1));
CHECK_EQ(*true_val, OrderedHashMap::HasKey(isolate, *map, *key2));
CHECK_EQ(*true_val, OrderedHashMap::HasKey(isolate, *map, *key3));
CHECK(OrderedHashMap::Delete(isolate, *map, *key2));
Verify(map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(1, map->NumberOfElements());
CHECK_EQ(3, map->NumberOfDeletedElements());
CHECK_EQ(*false_val, OrderedHashMap::HasKey(isolate, *map, *key1));
CHECK_EQ(*false_val, OrderedHashMap::HasKey(isolate, *map, *key2));
CHECK_EQ(*true_val, OrderedHashMap::HasKey(isolate, *map, *key3));
CHECK(OrderedHashMap::Delete(isolate, *map, *key3));
Verify(map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(0, map->NumberOfElements());
CHECK_EQ(4, map->NumberOfDeletedElements());
CHECK_EQ(*false_val, OrderedHashMap::HasKey(isolate, *map, *key1));
CHECK_EQ(*false_val, OrderedHashMap::HasKey(isolate, *map, *key2));
CHECK_EQ(*false_val, OrderedHashMap::HasKey(isolate, *map, *key3));
// Delete non existant key from non new hash table
CHECK(!OrderedHashMap::Delete(isolate, *map, *key3));
Verify(map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(0, map->NumberOfElements());
CHECK_EQ(4, map->NumberOfDeletedElements());
CHECK_EQ(*false_val, OrderedHashMap::HasKey(isolate, *map, *key1));
CHECK_EQ(*false_val, OrderedHashMap::HasKey(isolate, *map, *key2));
CHECK_EQ(*false_val, OrderedHashMap::HasKey(isolate, *map, *key3));
// Delete non existant key from non empty hash table
map = OrderedHashMap::Shrink(map);
map = OrderedHashMap::Add(map, key1, value);
Verify(map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(1, map->NumberOfElements());
CHECK_EQ(0, map->NumberOfDeletedElements());
CHECK_EQ(*true_val, OrderedHashMap::HasKey(isolate, *map, *key1));
CHECK_EQ(*false_val, OrderedHashMap::HasKey(isolate, *map, *key2));
CHECK_EQ(*false_val, OrderedHashMap::HasKey(isolate, *map, *key3));
CHECK(!OrderedHashMap::Delete(isolate, *map, *key2));
Verify(map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(1, map->NumberOfElements());
CHECK_EQ(0, map->NumberOfDeletedElements());
CHECK_EQ(*true_val, OrderedHashMap::HasKey(isolate, *map, *key1));
CHECK_EQ(*false_val, OrderedHashMap::HasKey(isolate, *map, *key2));
CHECK_EQ(*false_val, OrderedHashMap::HasKey(isolate, *map, *key3));
}
TEST(OrderedHashMapDuplicateHashCodeDeletion) {
LocalContext context;
Isolate* isolate = GetIsolateFrom(&context);
Factory* factory = isolate->factory();
HandleScope scope(isolate);
Handle<OrderedHashMap> map = factory->NewOrderedHashMap();
Handle<JSObject> key1 = factory->NewJSObjectWithNullProto();
Handle<JSObject> value = factory->NewJSObjectWithNullProto();
Handle<Object> true_val = factory->true_value();
Handle<Object> false_val = factory->false_value();
map = OrderedHashMap::Add(map, key1, value);
Verify(map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(1, map->NumberOfElements());
CHECK_EQ(0, map->NumberOfDeletedElements());
CHECK_EQ(*true_val, OrderedHashMap::HasKey(isolate, *map, *key1));
Handle<JSObject> key2 = factory->NewJSObjectWithNullProto();
CopyHashCode(isolate, key1, key2);
// We shouldn't be able to delete the key!
CHECK(!OrderedHashMap::Delete(isolate, *map, *key2));
Verify(map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(1, map->NumberOfElements());
CHECK_EQ(0, map->NumberOfDeletedElements());
CHECK_EQ(*true_val, OrderedHashMap::HasKey(isolate, *map, *key1));
CHECK_EQ(*false_val, OrderedHashMap::HasKey(isolate, *map, *key2));
}
TEST(OrderedHashSetDeletion) {
LocalContext context;
Isolate* isolate = GetIsolateFrom(&context);
Factory* factory = isolate->factory();
HandleScope scope(isolate);
Handle<Object> true_val = factory->true_value();
Handle<Object> false_val = factory->false_value();
Handle<OrderedHashSet> set = factory->NewOrderedHashSet();
Verify(set);
CHECK_EQ(2, set->NumberOfBuckets());
CHECK_EQ(0, set->NumberOfElements());
CHECK_EQ(0, set->NumberOfDeletedElements());
// Delete from an empty hash table
Handle<Smi> key1(Smi::FromInt(1), isolate);
CHECK(!OrderedHashSet::Delete(isolate, *set, *key1));
Verify(set);
CHECK_EQ(2, set->NumberOfBuckets());
CHECK_EQ(0, set->NumberOfElements());
CHECK_EQ(0, set->NumberOfDeletedElements());
CHECK_EQ(*false_val, OrderedHashSet::HasKey(isolate, *set, *key1));
set = OrderedHashSet::Add(set, key1);
Verify(set);
CHECK_EQ(2, set->NumberOfBuckets());
CHECK_EQ(1, set->NumberOfElements());
CHECK_EQ(0, set->NumberOfDeletedElements());
CHECK_EQ(*true_val, OrderedHashSet::HasKey(isolate, *set, *key1));
// Delete single existing key
CHECK(OrderedHashSet::Delete(isolate, *set, *key1));
Verify(set);
CHECK_EQ(2, set->NumberOfBuckets());
CHECK_EQ(0, set->NumberOfElements());
CHECK_EQ(1, set->NumberOfDeletedElements());
CHECK_EQ(*false_val, OrderedHashSet::HasKey(isolate, *set, *key1));
set = OrderedHashSet::Add(set, key1);
Verify(set);
CHECK_EQ(2, set->NumberOfBuckets());
CHECK_EQ(1, set->NumberOfElements());
CHECK_EQ(1, set->NumberOfDeletedElements());
CHECK_EQ(*true_val, OrderedHashSet::HasKey(isolate, *set, *key1));
Handle<String> key2 = factory->NewStringFromAsciiChecked("foo");
CHECK_EQ(*false_val, OrderedHashSet::HasKey(isolate, *set, *key2));
set = OrderedHashSet::Add(set, key2);
Verify(set);
CHECK_EQ(2, set->NumberOfBuckets());
CHECK_EQ(2, set->NumberOfElements());
CHECK_EQ(1, set->NumberOfDeletedElements());
CHECK_EQ(*true_val, OrderedHashSet::HasKey(isolate, *set, *key2));
Handle<Symbol> key3 = factory->NewSymbol();
CHECK_EQ(*false_val, OrderedHashSet::HasKey(isolate, *set, *key3));
set = OrderedHashSet::Add(set, key3);
Verify(set);
CHECK_EQ(2, set->NumberOfBuckets());
CHECK_EQ(3, set->NumberOfElements());
CHECK_EQ(1, set->NumberOfDeletedElements());
CHECK_EQ(*true_val, OrderedHashSet::HasKey(isolate, *set, *key1));
CHECK_EQ(*true_val, OrderedHashSet::HasKey(isolate, *set, *key2));
CHECK_EQ(*true_val, OrderedHashSet::HasKey(isolate, *set, *key3));
// Delete multiple existing keys
CHECK(OrderedHashSet::Delete(isolate, *set, *key1));
Verify(set);
CHECK_EQ(2, set->NumberOfBuckets());
CHECK_EQ(2, set->NumberOfElements());
CHECK_EQ(2, set->NumberOfDeletedElements());
CHECK_EQ(*false_val, OrderedHashSet::HasKey(isolate, *set, *key1));
CHECK_EQ(*true_val, OrderedHashSet::HasKey(isolate, *set, *key2));
CHECK_EQ(*true_val, OrderedHashSet::HasKey(isolate, *set, *key3));
CHECK(OrderedHashSet::Delete(isolate, *set, *key2));
Verify(set);
CHECK_EQ(2, set->NumberOfBuckets());
CHECK_EQ(1, set->NumberOfElements());
CHECK_EQ(3, set->NumberOfDeletedElements());
CHECK_EQ(*false_val, OrderedHashSet::HasKey(isolate, *set, *key1));
CHECK_EQ(*false_val, OrderedHashSet::HasKey(isolate, *set, *key2));
CHECK_EQ(*true_val, OrderedHashSet::HasKey(isolate, *set, *key3));
CHECK(OrderedHashSet::Delete(isolate, *set, *key3));
Verify(set);
CHECK_EQ(2, set->NumberOfBuckets());
CHECK_EQ(0, set->NumberOfElements());
CHECK_EQ(4, set->NumberOfDeletedElements());
CHECK_EQ(*false_val, OrderedHashSet::HasKey(isolate, *set, *key1));
CHECK_EQ(*false_val, OrderedHashSet::HasKey(isolate, *set, *key2));
CHECK_EQ(*false_val, OrderedHashSet::HasKey(isolate, *set, *key3));
// Delete non existant key from non new hash table
CHECK(!OrderedHashSet::Delete(isolate, *set, *key3));
Verify(set);
CHECK_EQ(2, set->NumberOfBuckets());
CHECK_EQ(0, set->NumberOfElements());
CHECK_EQ(4, set->NumberOfDeletedElements());
CHECK_EQ(*false_val, OrderedHashSet::HasKey(isolate, *set, *key1));
CHECK_EQ(*false_val, OrderedHashSet::HasKey(isolate, *set, *key2));
CHECK_EQ(*false_val, OrderedHashSet::HasKey(isolate, *set, *key3));
// Delete non existant key from non empty hash table
set = OrderedHashSet::Shrink(set);
set = OrderedHashSet::Add(set, key1);
Verify(set);
CHECK_EQ(2, set->NumberOfBuckets());
CHECK_EQ(1, set->NumberOfElements());
CHECK_EQ(0, set->NumberOfDeletedElements());
CHECK_EQ(*true_val, OrderedHashSet::HasKey(isolate, *set, *key1));
CHECK_EQ(*false_val, OrderedHashSet::HasKey(isolate, *set, *key2));
CHECK_EQ(*false_val, OrderedHashSet::HasKey(isolate, *set, *key3));
CHECK(!OrderedHashSet::Delete(isolate, *set, *key2));
Verify(set);
CHECK_EQ(2, set->NumberOfBuckets());
CHECK_EQ(1, set->NumberOfElements());
CHECK_EQ(0, set->NumberOfDeletedElements());
CHECK_EQ(*true_val, OrderedHashSet::HasKey(isolate, *set, *key1));
CHECK_EQ(*false_val, OrderedHashSet::HasKey(isolate, *set, *key2));
CHECK_EQ(*false_val, OrderedHashSet::HasKey(isolate, *set, *key3));
}
TEST(OrderedHashSetDuplicateHashCodeDeletion) {
LocalContext context;
Isolate* isolate = GetIsolateFrom(&context);
Factory* factory = isolate->factory();
HandleScope scope(isolate);
Handle<OrderedHashSet> set = factory->NewOrderedHashSet();
Handle<JSObject> key1 = factory->NewJSObjectWithNullProto();
Handle<Object> true_val = factory->true_value();
Handle<Object> false_val = factory->false_value();
set = OrderedHashSet::Add(set, key1);
Verify(set);
CHECK_EQ(2, set->NumberOfBuckets());
CHECK_EQ(1, set->NumberOfElements());
CHECK_EQ(0, set->NumberOfDeletedElements());
CHECK_EQ(*true_val, OrderedHashSet::HasKey(isolate, *set, *key1));
Handle<JSObject> key2 = factory->NewJSObjectWithNullProto();
CopyHashCode(isolate, key1, key2);
// We shouldn't be able to delete the key!
CHECK(!OrderedHashSet::Delete(isolate, *set, *key2));
Verify(set);
CHECK_EQ(2, set->NumberOfBuckets());
CHECK_EQ(1, set->NumberOfElements());
CHECK_EQ(0, set->NumberOfDeletedElements());
CHECK_EQ(*true_val, OrderedHashSet::HasKey(isolate, *set, *key1));
CHECK_EQ(*false_val, OrderedHashSet::HasKey(isolate, *set, *key2));
}
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