Chromium Code Reviews| Index: src/objects.cc |
| diff --git a/src/objects.cc b/src/objects.cc |
| index f9a52e59c7455d2986ade2ac70296c2dd5db5034..1a835bd42703b70c4342f4dce7f4dd8874f97f44 100644 |
| --- a/src/objects.cc |
| +++ b/src/objects.cc |
| @@ -16214,7 +16214,6 @@ Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Allocate( |
| table->SetNumberOfBuckets(num_buckets); |
| table->SetNumberOfElements(0); |
| table->SetNumberOfDeletedElements(0); |
| - table->set_iterators(isolate->heap()->undefined_value()); |
| return table; |
| } |
| @@ -16222,6 +16221,8 @@ Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Allocate( |
| template<class Derived, class Iterator, int entrysize> |
| Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::EnsureGrowable( |
| Handle<Derived> table) { |
| + ASSERT(!table->IsObsolete()); |
| + |
| int nof = table->NumberOfElements(); |
| int nod = table->NumberOfDeletedElements(); |
| int capacity = table->Capacity(); |
| @@ -16236,9 +16237,11 @@ Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::EnsureGrowable( |
| template<class Derived, class Iterator, int entrysize> |
| Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Shrink( |
| Handle<Derived> table) { |
| + ASSERT(!table->IsObsolete()); |
| + |
| int nof = table->NumberOfElements(); |
| int capacity = table->Capacity(); |
| - if (nof > (capacity >> 2)) return table; |
| + if (nof >= (capacity >> 2)) return table; |
|
arv (Not doing code reviews)
2014/05/14 20:36:36
Since kMinCapacity is 4 we end up with nof=1 not b
|
| return Rehash(table, capacity / 2); |
| } |
| @@ -16246,21 +16249,15 @@ Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Shrink( |
| template<class Derived, class Iterator, int entrysize> |
| Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Clear( |
| Handle<Derived> table) { |
| + ASSERT(!table->IsObsolete()); |
| + |
| Handle<Derived> new_table = |
| Allocate(table->GetIsolate(), |
| kMinCapacity, |
| table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED); |
| - new_table->set_iterators(table->iterators()); |
| - table->set_iterators(table->GetHeap()->undefined_value()); |
| - |
| - DisallowHeapAllocation no_allocation; |
| - for (Object* object = new_table->iterators(); |
| - !object->IsUndefined(); |
| - object = Iterator::cast(object)->next_iterator()) { |
| - Iterator::cast(object)->TableCleared(); |
| - Iterator::cast(object)->set_table(*new_table); |
| - } |
| + table->SetNextTable(*new_table); |
| + table->SetNumberOfDeletedElements(-1); |
| return new_table; |
| } |
| @@ -16269,6 +16266,8 @@ Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Clear( |
| template<class Derived, class Iterator, int entrysize> |
| Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash( |
| Handle<Derived> table, int new_capacity) { |
| + ASSERT(!table->IsObsolete()); |
| + |
| Handle<Derived> new_table = |
| Allocate(table->GetIsolate(), |
| new_capacity, |
| @@ -16277,9 +16276,15 @@ Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash( |
| int nod = table->NumberOfDeletedElements(); |
| int new_buckets = new_table->NumberOfBuckets(); |
| int new_entry = 0; |
| + int removed_holes_index = 0; |
| + |
| for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) { |
| Object* key = table->KeyAt(old_entry); |
| - if (key->IsTheHole()) continue; |
| + if (key->IsTheHole()) { |
| + table->SetRemovedIndexAt(removed_holes_index++, old_entry); |
| + continue; |
| + } |
| + |
| Object* hash = key->GetHash(); |
| int bucket = Smi::cast(hash)->value() & (new_buckets - 1); |
| Object* chain_entry = new_table->get(kHashTableStartIndex + bucket); |
| @@ -16293,18 +16298,11 @@ Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash( |
| new_table->set(new_index + kChainOffset, chain_entry); |
| ++new_entry; |
| } |
| - new_table->SetNumberOfElements(nof); |
| - new_table->set_iterators(table->iterators()); |
| - table->set_iterators(table->GetHeap()->undefined_value()); |
| + ASSERT_EQ(nod, removed_holes_index); |
| - DisallowHeapAllocation no_allocation; |
| - for (Object* object = new_table->iterators(); |
| - !object->IsUndefined(); |
| - object = Iterator::cast(object)->next_iterator()) { |
| - Iterator::cast(object)->TableCompacted(); |
| - Iterator::cast(object)->set_table(*new_table); |
| - } |
| + new_table->SetNumberOfElements(nof); |
| + table->SetNextTable(*new_table); |
| return new_table; |
| } |
| @@ -16313,6 +16311,8 @@ Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash( |
| template<class Derived, class Iterator, int entrysize> |
| int OrderedHashTable<Derived, Iterator, entrysize>::FindEntry( |
| Handle<Object> key) { |
| + ASSERT(!IsObsolete()); |
| + |
| DisallowHeapAllocation no_gc; |
| ASSERT(!key->IsTheHole()); |
| Object* hash = key->GetHash(); |
| @@ -16330,6 +16330,8 @@ int OrderedHashTable<Derived, Iterator, entrysize>::FindEntry( |
| template<class Derived, class Iterator, int entrysize> |
| int OrderedHashTable<Derived, Iterator, entrysize>::AddEntry(int hash) { |
| + ASSERT(!IsObsolete()); |
| + |
| int entry = UsedCapacity(); |
| int bucket = HashToBucket(hash); |
| int index = EntryToIndex(entry); |
| @@ -16343,19 +16345,14 @@ int OrderedHashTable<Derived, Iterator, entrysize>::AddEntry(int hash) { |
| template<class Derived, class Iterator, int entrysize> |
| void OrderedHashTable<Derived, Iterator, entrysize>::RemoveEntry(int entry) { |
| + ASSERT(!IsObsolete()); |
| + |
| int index = EntryToIndex(entry); |
| for (int i = 0; i < entrysize; ++i) { |
| set_the_hole(index + i); |
| } |
| SetNumberOfElements(NumberOfElements() - 1); |
| SetNumberOfDeletedElements(NumberOfDeletedElements() + 1); |
| - |
| - DisallowHeapAllocation no_allocation; |
| - for (Object* object = iterators(); |
| - !object->IsUndefined(); |
| - object = Iterator::cast(object)->next_iterator()) { |
| - Iterator::cast(object)->EntryRemoved(entry); |
| - } |
| } |
| @@ -16475,97 +16472,69 @@ Handle<OrderedHashMap> OrderedHashMap::Put(Handle<OrderedHashMap> table, |
| template<class Derived, class TableType> |
| -void OrderedHashTableIterator<Derived, TableType>::EntryRemoved(int index) { |
| - int i = this->index()->value(); |
| - if (index < i) { |
| - set_count(Smi::FromInt(count()->value() - 1)); |
| - } |
| - if (index == i) { |
| - Seek(); |
| - } |
| -} |
| - |
| +Handle<JSObject> OrderedHashTableIterator<Derived, TableType>::Next( |
| + Handle<Derived> iterator) { |
| + Isolate* isolate = iterator->GetIsolate(); |
| + Factory* factory = isolate->factory(); |
| -template<class Derived, class TableType> |
| -void OrderedHashTableIterator<Derived, TableType>::Close() { |
| - if (Closed()) return; |
| + Handle<Object> maybe_table(iterator->table(), isolate); |
| + if (!maybe_table->IsUndefined()) { |
| + iterator->Transition(); |
| - DisallowHeapAllocation no_allocation; |
| + Handle<TableType> table(TableType::cast(iterator->table()), isolate); |
| + int index = Smi::cast(iterator->index())->value(); |
| + int used_capacity = table->UsedCapacity(); |
| - Object* undefined = GetHeap()->undefined_value(); |
| - TableType* table = TableType::cast(this->table()); |
| - Object* previous = previous_iterator(); |
| - Object* next = next_iterator(); |
| + while (index < used_capacity && table->KeyAt(index)->IsTheHole()) { |
| + index++; |
| + } |
| - if (previous == undefined) { |
| - ASSERT_EQ(table->iterators(), this); |
| - table->set_iterators(next); |
| - } else { |
| - ASSERT_EQ(Derived::cast(previous)->next_iterator(), this); |
| - Derived::cast(previous)->set_next_iterator(next); |
| - } |
| + if (index < used_capacity) { |
| + int entry_index = table->EntryToIndex(index); |
| + Handle<Object> value = |
| + Derived::ValueForKind(iterator, entry_index); |
| + iterator->set_index(Smi::FromInt(index + 1)); |
| + return factory->NewIteratorResultObject(value, false); |
| + } |
| - if (!next->IsUndefined()) { |
| - ASSERT_EQ(Derived::cast(next)->previous_iterator(), this); |
| - Derived::cast(next)->set_previous_iterator(previous); |
| + iterator->set_table(iterator->GetHeap()->undefined_value()); |
| } |
| - set_previous_iterator(undefined); |
| - set_next_iterator(undefined); |
| - set_table(undefined); |
| -} |
| - |
| - |
| -template<class Derived, class TableType> |
| -void OrderedHashTableIterator<Derived, TableType>::Seek() { |
| - ASSERT(!Closed()); |
| - |
| - DisallowHeapAllocation no_allocation; |
| - |
| - int index = this->index()->value(); |
| - |
| - TableType* table = TableType::cast(this->table()); |
| - int used_capacity = table->UsedCapacity(); |
| - |
| - while (index < used_capacity && table->KeyAt(index)->IsTheHole()) { |
| - index++; |
| - } |
| - set_index(Smi::FromInt(index)); |
| + return factory->NewIteratorResultObject(factory->undefined_value(), true); |
| } |
| template<class Derived, class TableType> |
| -void OrderedHashTableIterator<Derived, TableType>::MoveNext() { |
| - ASSERT(!Closed()); |
| - |
| - set_index(Smi::FromInt(index()->value() + 1)); |
| - set_count(Smi::FromInt(count()->value() + 1)); |
| - Seek(); |
| -} |
| - |
| +void OrderedHashTableIterator<Derived, TableType>::Transition() { |
| + Isolate* isolate = GetIsolate(); |
| + Handle<TableType> table(TableType::cast(this->table()), isolate); |
| + if (!table->IsObsolete()) return; |
| -template<class Derived, class TableType> |
| -Handle<JSObject> OrderedHashTableIterator<Derived, TableType>::Next( |
| - Handle<Derived> iterator) { |
| - Isolate* isolate = iterator->GetIsolate(); |
| - Factory* factory = isolate->factory(); |
| + int index = Smi::cast(this->index())->value(); |
| + while (table->IsObsolete()) { |
| + Handle<TableType> next_table(table->NextTable(), isolate); |
| - Handle<Object> object(iterator->table(), isolate); |
| + if (index > 0) { |
| + int nod = table->NumberOfDeletedElements(); |
| - if (!object->IsUndefined()) { |
| - Handle<TableType> table = Handle<TableType>::cast(object); |
| - int index = iterator->index()->value(); |
| - if (index < table->UsedCapacity()) { |
| - int entry_index = table->EntryToIndex(index); |
| - iterator->MoveNext(); |
| - Handle<Object> value = Derived::ValueForKind(iterator, entry_index); |
| - return factory->NewIteratorResultObject(value, false); |
| - } else { |
| - iterator->Close(); |
| + // When we clear the table we set the number of deleted elements to -1. |
| + if (nod == -1) { |
| + index = 0; |
| + } else { |
| + int old_index = index; |
| + for (int i = 0; i < nod; ++i) { |
| + int removed_index = table->RemovedIndexAt(i); |
| + if (removed_index >= old_index) break; |
|
arv (Not doing code reviews)
2014/05/14 20:36:36
This was wrong before. We need to compare with the
|
| + --index; |
| + } |
| + } |
| } |
| + |
| + table = next_table; |
| } |
| - return factory->NewIteratorResultObject(factory->undefined_value(), true); |
| + set_table(*table); |
| + set_index(Smi::FromInt(index)); |
| } |
| @@ -16576,60 +16545,37 @@ Handle<Derived> OrderedHashTableIterator<Derived, TableType>::CreateInternal( |
| int kind) { |
| Isolate* isolate = table->GetIsolate(); |
| - Handle<Object> undefined = isolate->factory()->undefined_value(); |
| - |
| Handle<Derived> new_iterator = Handle<Derived>::cast( |
| isolate->factory()->NewJSObjectFromMap(map)); |
| - new_iterator->set_previous_iterator(*undefined); |
| new_iterator->set_table(*table); |
| new_iterator->set_index(Smi::FromInt(0)); |
| - new_iterator->set_count(Smi::FromInt(0)); |
| new_iterator->set_kind(Smi::FromInt(kind)); |
| - |
| - Handle<Object> old_iterator(table->iterators(), isolate); |
| - if (!old_iterator->IsUndefined()) { |
| - Handle<Derived>::cast(old_iterator)->set_previous_iterator(*new_iterator); |
| - new_iterator->set_next_iterator(*old_iterator); |
| - } else { |
| - new_iterator->set_next_iterator(*undefined); |
| - } |
| - |
| - table->set_iterators(*new_iterator); |
| - |
| return new_iterator; |
| } |
| -template void |
| -OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::EntryRemoved( |
| - int index); |
| - |
| -template void |
| -OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::Close(); |
| - |
| template Handle<JSObject> |
| OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::Next( |
| Handle<JSSetIterator> iterator); |
| +template void |
| +OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::Transition(); |
| + |
| template Handle<JSSetIterator> |
| OrderedHashTableIterator<JSSetIterator, OrderedHashSet>::CreateInternal( |
| - Handle<Map> map, Handle<OrderedHashSet> table, int kind); |
| - |
| + Handle<Map> map, Handle<OrderedHashSet> table, int kind); |
| -template void |
| -OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::EntryRemoved( |
| - int index); |
| - |
| -template void |
| -OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::Close(); |
| template Handle<JSObject> |
| OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::Next( |
| Handle<JSMapIterator> iterator); |
| +template void |
| +OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::Transition(); |
| + |
| template Handle<JSMapIterator> |
| OrderedHashTableIterator<JSMapIterator, OrderedHashMap>::CreateInternal( |
| - Handle<Map> map, Handle<OrderedHashMap> table, int kind); |
| + Handle<Map> map, Handle<OrderedHashMap> table, int kind); |
| Handle<Object> JSSetIterator::ValueForKind( |