Commit 2e2eb6a0 authored by adamk@chromium.org's avatar adamk@chromium.org

Split Put into Put and Remove

No longer treat the hole as a removal. This removes one branch in
Put and cleans up the API.

BUG=None
LOG=Y
R=adamk@chromium.org, mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/309663005

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21616 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 509a1a40
...@@ -5214,7 +5214,8 @@ void JSObject::DeleteHiddenProperty(Handle<JSObject> object, Handle<Name> key) { ...@@ -5214,7 +5214,8 @@ void JSObject::DeleteHiddenProperty(Handle<JSObject> object, Handle<Name> key) {
if (inline_value->IsUndefined() || inline_value->IsSmi()) return; if (inline_value->IsUndefined() || inline_value->IsSmi()) return;
Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value));
ObjectHashTable::Put(hashtable, key, isolate->factory()->the_hole_value()); bool was_present = false;
ObjectHashTable::Remove(hashtable, key, &was_present);
} }
...@@ -16039,6 +16040,7 @@ Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table, ...@@ -16039,6 +16040,7 @@ Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
Handle<Object> key, Handle<Object> key,
Handle<Object> value) { Handle<Object> value) {
ASSERT(table->IsKey(*key)); ASSERT(table->IsKey(*key));
ASSERT(!value->IsTheHole());
Isolate* isolate = table->GetIsolate(); Isolate* isolate = table->GetIsolate();
...@@ -16047,13 +16049,6 @@ Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table, ...@@ -16047,13 +16049,6 @@ Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
int entry = table->FindEntry(key); int entry = table->FindEntry(key);
// Check whether to perform removal operation.
if (value->IsTheHole()) {
if (entry == kNotFound) return table;
table->RemoveEntry(entry);
return Shrink(table, key);
}
// Key is already in table, just overwrite value. // Key is already in table, just overwrite value.
if (entry != kNotFound) { if (entry != kNotFound) {
table->set(EntryToIndex(entry) + 1, *value); table->set(EntryToIndex(entry) + 1, *value);
...@@ -16069,6 +16064,29 @@ Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table, ...@@ -16069,6 +16064,29 @@ Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
} }
Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table,
Handle<Object> key,
bool* was_present) {
ASSERT(table->IsKey(*key));
Object* hash = key->GetHash();
if (hash->IsUndefined()) {
*was_present = false;
return table;
}
int entry = table->FindEntry(key);
if (entry == kNotFound) {
*was_present = false;
return table;
}
*was_present = true;
table->RemoveEntry(entry);
return Shrink(table, key);
}
void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) { void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) {
set(EntryToIndex(entry), key); set(EntryToIndex(entry), key);
set(EntryToIndex(entry) + 1, value); set(EntryToIndex(entry) + 1, value);
...@@ -16200,6 +16218,20 @@ Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Clear( ...@@ -16200,6 +16218,20 @@ Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Clear(
} }
template<class Derived, class Iterator, int entrysize>
Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Remove(
Handle<Derived> table, Handle<Object> key, bool* was_present) {
int entry = table->FindEntry(key);
if (entry == kNotFound) {
*was_present = false;
return table;
}
*was_present = true;
table->RemoveEntry(entry);
return Shrink(table);
}
template<class Derived, class Iterator, int entrysize> template<class Derived, class Iterator, int entrysize>
Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash( Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash(
Handle<Derived> table, int new_capacity) { Handle<Derived> table, int new_capacity) {
...@@ -16309,6 +16341,10 @@ template Handle<OrderedHashSet> ...@@ -16309,6 +16341,10 @@ template Handle<OrderedHashSet>
OrderedHashTable<OrderedHashSet, JSSetIterator, 1>::Clear( OrderedHashTable<OrderedHashSet, JSSetIterator, 1>::Clear(
Handle<OrderedHashSet> table); Handle<OrderedHashSet> table);
template Handle<OrderedHashSet>
OrderedHashTable<OrderedHashSet, JSSetIterator, 1>::Remove(
Handle<OrderedHashSet> table, Handle<Object> key, bool* was_present);
template int template int
OrderedHashTable<OrderedHashSet, JSSetIterator, 1>::FindEntry( OrderedHashTable<OrderedHashSet, JSSetIterator, 1>::FindEntry(
Handle<Object> key); Handle<Object> key);
...@@ -16336,6 +16372,10 @@ template Handle<OrderedHashMap> ...@@ -16336,6 +16372,10 @@ template Handle<OrderedHashMap>
OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::Clear( OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::Clear(
Handle<OrderedHashMap> table); Handle<OrderedHashMap> table);
template Handle<OrderedHashMap>
OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::Remove(
Handle<OrderedHashMap> table, Handle<Object> key, bool* was_present);
template int template int
OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::FindEntry( OrderedHashTable<OrderedHashMap, JSMapIterator, 2>::FindEntry(
Handle<Object> key); Handle<Object> key);
...@@ -16365,20 +16405,6 @@ Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table, ...@@ -16365,20 +16405,6 @@ Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table,
} }
Handle<OrderedHashSet> OrderedHashSet::Remove(Handle<OrderedHashSet> table,
Handle<Object> key,
bool* was_present) {
int entry = table->FindEntry(key);
if (entry == kNotFound) {
*was_present = false;
return table;
}
*was_present = true;
table->RemoveEntry(entry);
return Shrink(table);
}
Object* OrderedHashMap::Lookup(Handle<Object> key) { Object* OrderedHashMap::Lookup(Handle<Object> key) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
int entry = FindEntry(key); int entry = FindEntry(key);
...@@ -16390,13 +16416,9 @@ Object* OrderedHashMap::Lookup(Handle<Object> key) { ...@@ -16390,13 +16416,9 @@ Object* OrderedHashMap::Lookup(Handle<Object> key) {
Handle<OrderedHashMap> OrderedHashMap::Put(Handle<OrderedHashMap> table, Handle<OrderedHashMap> OrderedHashMap::Put(Handle<OrderedHashMap> table,
Handle<Object> key, Handle<Object> key,
Handle<Object> value) { Handle<Object> value) {
int entry = table->FindEntry(key); ASSERT(!key->IsTheHole());
if (value->IsTheHole()) { int entry = table->FindEntry(key);
if (entry == kNotFound) return table;
table->RemoveEntry(entry);
return Shrink(table);
}
if (entry != kNotFound) { if (entry != kNotFound) {
table->set(table->EntryToIndex(entry) + kValueOffset, *value); table->set(table->EntryToIndex(entry) + kValueOffset, *value);
......
...@@ -4133,12 +4133,16 @@ class ObjectHashTable: public HashTable<ObjectHashTable, ...@@ -4133,12 +4133,16 @@ class ObjectHashTable: public HashTable<ObjectHashTable,
// returned in case the key is not present. // returned in case the key is not present.
Object* Lookup(Handle<Object> key); Object* Lookup(Handle<Object> key);
// Adds (or overwrites) the value associated with the given key. Mapping a // Adds (or overwrites) the value associated with the given key.
// key to the hole value causes removal of the whole entry.
static Handle<ObjectHashTable> Put(Handle<ObjectHashTable> table, static Handle<ObjectHashTable> Put(Handle<ObjectHashTable> table,
Handle<Object> key, Handle<Object> key,
Handle<Object> value); Handle<Object> value);
// Returns an ObjectHashTable (possibly |table|) where |key| has been removed.
static Handle<ObjectHashTable> Remove(Handle<ObjectHashTable> table,
Handle<Object> key,
bool* was_present);
private: private:
friend class MarkCompactCollector; friend class MarkCompactCollector;
...@@ -4203,10 +4207,15 @@ class OrderedHashTable: public FixedArray { ...@@ -4203,10 +4207,15 @@ class OrderedHashTable: public FixedArray {
// if possible. // if possible.
static Handle<Derived> Shrink(Handle<Derived> table); static Handle<Derived> Shrink(Handle<Derived> table);
// Returns a new empty OrderedHashTable and updates all the iterators to // Returns a new empty OrderedHashTable and records the clearing so that
// point to the new table. // exisiting iterators can be updated.
static Handle<Derived> Clear(Handle<Derived> table); static Handle<Derived> Clear(Handle<Derived> table);
// Returns an OrderedHashTable (possibly |table|) where |key| has been
// removed.
static Handle<Derived> Remove(Handle<Derived> table, Handle<Object> key,
bool* was_present);
// Returns kNotFound if the key isn't present. // Returns kNotFound if the key isn't present.
int FindEntry(Handle<Object> key); int FindEntry(Handle<Object> key);
...@@ -4330,8 +4339,6 @@ class OrderedHashSet: public OrderedHashTable< ...@@ -4330,8 +4339,6 @@ class OrderedHashSet: public OrderedHashTable<
bool Contains(Handle<Object> key); bool Contains(Handle<Object> key);
static Handle<OrderedHashSet> Add( static Handle<OrderedHashSet> Add(
Handle<OrderedHashSet> table, Handle<Object> key); Handle<OrderedHashSet> table, Handle<Object> key);
static Handle<OrderedHashSet> Remove(
Handle<OrderedHashSet> table, Handle<Object> key, bool* was_present);
}; };
......
...@@ -1646,11 +1646,11 @@ RUNTIME_FUNCTION(Runtime_MapDelete) { ...@@ -1646,11 +1646,11 @@ RUNTIME_FUNCTION(Runtime_MapDelete) {
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0); CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table())); Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
Handle<Object> lookup(table->Lookup(key), isolate); bool was_present = false;
Handle<OrderedHashMap> new_table = Handle<OrderedHashMap> new_table =
OrderedHashMap::Put(table, key, isolate->factory()->the_hole_value()); OrderedHashMap::Remove(table, key, &was_present);
holder->set_table(*new_table); holder->set_table(*new_table);
return isolate->heap()->ToBoolean(!lookup->IsTheHole()); return isolate->heap()->ToBoolean(was_present);
} }
...@@ -1767,11 +1767,11 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) { ...@@ -1767,11 +1767,11 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) {
Handle<ObjectHashTable> table(ObjectHashTable::cast( Handle<ObjectHashTable> table(ObjectHashTable::cast(
weak_collection->table())); weak_collection->table()));
RUNTIME_ASSERT(table->IsKey(*key)); RUNTIME_ASSERT(table->IsKey(*key));
Handle<Object> lookup(table->Lookup(key), isolate); bool was_present = false;
Handle<ObjectHashTable> new_table = Handle<ObjectHashTable> new_table =
ObjectHashTable::Put(table, key, isolate->factory()->the_hole_value()); ObjectHashTable::Remove(table, key, &was_present);
weak_collection->set_table(*new_table); weak_collection->set_table(*new_table);
return isolate->heap()->ToBoolean(!lookup->IsTheHole()); return isolate->heap()->ToBoolean(was_present);
} }
......
...@@ -51,6 +51,7 @@ static void TestHashMap(Handle<HashMap> table) { ...@@ -51,6 +51,7 @@ static void TestHashMap(Handle<HashMap> table) {
table = HashMap::Put(table, a, b); table = HashMap::Put(table, a, b);
CHECK_EQ(table->NumberOfElements(), 1); CHECK_EQ(table->NumberOfElements(), 1);
CHECK_EQ(table->Lookup(a), *b); CHECK_EQ(table->Lookup(a), *b);
// When the key does not exist in the map, Lookup returns the hole.
CHECK_EQ(table->Lookup(b), CcTest::heap()->the_hole_value()); CHECK_EQ(table->Lookup(b), CcTest::heap()->the_hole_value());
// Keys still have to be valid after objects were moved. // Keys still have to be valid after objects were moved.
...@@ -64,8 +65,10 @@ static void TestHashMap(Handle<HashMap> table) { ...@@ -64,8 +65,10 @@ static void TestHashMap(Handle<HashMap> table) {
CHECK_EQ(table->NumberOfElements(), 1); CHECK_EQ(table->NumberOfElements(), 1);
CHECK_NE(table->Lookup(a), *b); CHECK_NE(table->Lookup(a), *b);
// Keys mapped to the hole should be removed permanently. // Keys that have been removed are mapped to the hole.
table = HashMap::Put(table, a, factory->the_hole_value()); bool was_present = false;
table = HashMap::Remove(table, a, &was_present);
CHECK(was_present);
CHECK_EQ(table->NumberOfElements(), 0); CHECK_EQ(table->NumberOfElements(), 0);
CHECK_EQ(table->Lookup(a), CcTest::heap()->the_hole_value()); CHECK_EQ(table->Lookup(a), CcTest::heap()->the_hole_value());
......
...@@ -123,8 +123,9 @@ TEST(Map) { ...@@ -123,8 +123,9 @@ TEST(Map) {
ordered_map = OrderedHashMap::Put(ordered_map, obj, val); ordered_map = OrderedHashMap::Put(ordered_map, obj, val);
CHECK_EQ(1, ordered_map->NumberOfElements()); CHECK_EQ(1, ordered_map->NumberOfElements());
CHECK(ordered_map->Lookup(obj)->SameValue(*val)); CHECK(ordered_map->Lookup(obj)->SameValue(*val));
ordered_map = OrderedHashMap::Put( bool was_present = false;
ordered_map, obj, factory->the_hole_value()); ordered_map = OrderedHashMap::Remove(ordered_map, obj, &was_present);
CHECK(was_present);
CHECK_EQ(0, ordered_map->NumberOfElements()); CHECK_EQ(0, ordered_map->NumberOfElements());
CHECK(ordered_map->Lookup(obj)->IsTheHole()); CHECK(ordered_map->Lookup(obj)->IsTheHole());
...@@ -157,14 +158,14 @@ TEST(Map) { ...@@ -157,14 +158,14 @@ TEST(Map) {
CHECK_EQ(4, ordered_map->NumberOfBuckets()); CHECK_EQ(4, ordered_map->NumberOfBuckets());
// Test shrinking // Test shrinking
ordered_map = OrderedHashMap::Put( ordered_map = OrderedHashMap::Remove(ordered_map, obj, &was_present);
ordered_map, obj, factory->the_hole_value()); CHECK(was_present);
ordered_map = OrderedHashMap::Put( ordered_map = OrderedHashMap::Remove(ordered_map, obj1, &was_present);
ordered_map, obj1, factory->the_hole_value()); CHECK(was_present);
ordered_map = OrderedHashMap::Put( ordered_map = OrderedHashMap::Remove(ordered_map, obj2, &was_present);
ordered_map, obj2, factory->the_hole_value()); CHECK(was_present);
ordered_map = OrderedHashMap::Put( ordered_map = OrderedHashMap::Remove(ordered_map, obj3, &was_present);
ordered_map, obj3, factory->the_hole_value()); CHECK(was_present);
CHECK_EQ(1, ordered_map->NumberOfElements()); CHECK_EQ(1, ordered_map->NumberOfElements());
CHECK_EQ(2, ordered_map->NumberOfBuckets()); CHECK_EQ(2, ordered_map->NumberOfBuckets());
} }
......
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