Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index b7928af19361db20e754f564a6dfe7f02c1dc49f..b114cc076a8b14ccd6254fc777f7d59cd9c64170 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -16220,7 +16220,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; |
} |
@@ -16228,6 +16227,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(); |
@@ -16242,9 +16243,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; |
return Rehash(table, capacity / 2); |
} |
@@ -16252,21 +16255,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; |
} |
@@ -16275,6 +16272,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, |
@@ -16283,9 +16282,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); |
@@ -16299,18 +16304,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; |
} |
@@ -16319,6 +16317,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(); |
@@ -16336,6 +16336,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); |
@@ -16349,19 +16351,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); |
- } |
} |
@@ -16481,97 +16478,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; |
+ --index; |
+ } |
+ } |
} |
+ |
+ table = next_table; |
} |
- return factory->NewIteratorResultObject(factory->undefined_value(), true); |
+ set_table(*table); |
+ set_index(Smi::FromInt(index)); |
} |
@@ -16582,60 +16551,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( |