Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(543)

Unified Diff: src/objects.h

Issue 289503002: ES6 Map/Set iterators/forEach improvements (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: git rebase to fix merge conflict Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/collection.js ('k') | src/objects.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index d642e1e7da88b4f57bf49f79b485031f771a1ef3..910c25200ee3ec808f632a107078702138ea5d76 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -4153,16 +4153,27 @@ class ObjectHashTable: public HashTable<ObjectHashTable,
// [0]: bucket count
// [1]: element count
// [2]: deleted element count
-// [3]: live iterators (doubly-linked list)
-// [4..(NumberOfBuckets() - 1)]: "hash table", where each item is an offset
-// into the data table (see below) where the
-// first item in this bucket is stored.
-// [4 + NumberOfBuckets()..length]: "data table", an array of length
+// [3..(3 + NumberOfBuckets() - 1)]: "hash table", where each item is an
+// offset into the data table (see below) where the
+// first item in this bucket is stored.
+// [3 + NumberOfBuckets()..length]: "data table", an array of length
// Capacity() * kEntrySize, where the first entrysize
// items are handled by the derived class and the
// item at kChainOffset is another entry into the
// data table indicating the next entry in this hash
// bucket.
+//
+// When we transition the table to a new version we obsolete it and reuse parts
+// of the memory to store information how to transition an iterator to the new
+// table:
+//
+// Memory layout for obsolete table:
+// [0]: bucket count
+// [1]: Next newer table
+// [2]: Number of removed holes or -1 when the table was cleared.
+// [3..(3 + NumberOfRemovedHoles() - 1)]: The indexes of the removed holes.
+// [3 + NumberOfRemovedHoles()..length]: Not used
+//
template<class Derived, class Iterator, int entrysize>
class OrderedHashTable: public FixedArray {
public:
@@ -4199,10 +4210,6 @@ class OrderedHashTable: public FixedArray {
return Smi::cast(get(kNumberOfBucketsIndex))->value();
}
- Object* iterators() { return get(kIteratorsIndex); }
-
- void set_iterators(Object* value) { set(kIteratorsIndex, value); }
-
// Returns the index into the data table where the new entry
// should be placed. The table is assumed to have enough space
// for a new entry.
@@ -4219,6 +4226,20 @@ class OrderedHashTable: public FixedArray {
Object* KeyAt(int entry) { return get(EntryToIndex(entry)); }
+ bool IsObsolete() {
+ return !get(kNextTableIndex)->IsSmi();
+ }
+
+ // The next newer table. This is only valid if the table is obsolete.
+ Derived* NextTable() {
+ return Derived::cast(get(kNextTableIndex));
+ }
+
+ // When the table is obsolete we store the indexes of the removed holes.
+ int RemovedIndexAt(int index) {
+ return Smi::cast(get(kRemovedHolesIndex + index))->value();
+ }
+
static const int kNotFound = -1;
static const int kMinCapacity = 4;
@@ -4255,11 +4276,21 @@ class OrderedHashTable: public FixedArray {
return Smi::cast(get(kHashTableStartIndex + bucket))->value();
}
+ void SetNextTable(Derived* next_table) {
+ set(kNextTableIndex, next_table);
+ }
+
+ void SetRemovedIndexAt(int index, int removed_index) {
+ return set(kRemovedHolesIndex + index, Smi::FromInt(removed_index));
+ }
+
static const int kNumberOfBucketsIndex = 0;
static const int kNumberOfElementsIndex = kNumberOfBucketsIndex + 1;
static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1;
- static const int kIteratorsIndex = kNumberOfDeletedElementsIndex + 1;
- static const int kHashTableStartIndex = kIteratorsIndex + 1;
+ static const int kHashTableStartIndex = kNumberOfDeletedElementsIndex + 1;
+
+ static const int kNextTableIndex = kNumberOfElementsIndex;
+ static const int kRemovedHolesIndex = kHashTableStartIndex;
static const int kEntrySize = entrysize + 1;
static const int kChainOffset = entrysize;
@@ -9956,17 +9987,15 @@ class JSMap: public JSObject {
// OrderedHashTableIterator is an iterator that iterates over the keys and
// values of an OrderedHashTable.
//
-// The hash table has a reference to the iterator and the iterators themselves
-// have references to the [next_iterator] and [previous_iterator], thus creating
-// a double linked list.
+// The iterator has a reference to the underlying OrderedHashTable data,
+// [table], as well as the current [index] the iterator is at.
//
-// When the hash table changes the iterators are called to update their [index]
-// and [count]. The hash table calls [EntryRemoved], [TableCompacted] as well
-// as [TableCleared].
+// When the OrderedHashTable is rehashed it adds a reference from the old table
+// to the new table as well as storing enough data about the changes so that the
+// iterator [index] can be adjusted accordingly.
//
-// When an iterator is done it closes itself. It removes itself from the double
-// linked list and it sets its [table] to undefined, no longer keeping the
-// [table] alive.
+// When the [Next] result from the iterator is requested, the iterator checks if
+// there is a newer table that it needs to transition to.
template<class Derived, class TableType>
class OrderedHashTableIterator: public JSObject {
public:
@@ -9976,29 +10005,17 @@ class OrderedHashTableIterator: public JSObject {
// [index]: The index into the data table.
DECL_ACCESSORS(index, Smi)
- // [count]: The logical index into the data table, ignoring the holes.
- DECL_ACCESSORS(count, Smi)
-
// [kind]: The kind of iteration this is. One of the [Kind] enum values.
DECL_ACCESSORS(kind, Smi)
- // [next_iterator]: Used as a double linked list for the live iterators.
- DECL_ACCESSORS(next_iterator, Object)
-
- // [previous_iterator]: Used as a double linked list for the live iterators.
- DECL_ACCESSORS(previous_iterator, Object)
-
#ifdef OBJECT_PRINT
void OrderedHashTableIteratorPrint(FILE* out);
#endif
static const int kTableOffset = JSObject::kHeaderSize;
static const int kIndexOffset = kTableOffset + kPointerSize;
- static const int kCountOffset = kIndexOffset + kPointerSize;
- static const int kKindOffset = kCountOffset + kPointerSize;
- static const int kNextIteratorOffset = kKindOffset + kPointerSize;
- static const int kPreviousIteratorOffset = kNextIteratorOffset + kPointerSize;
- static const int kSize = kPreviousIteratorOffset + kPointerSize;
+ static const int kKindOffset = kIndexOffset + kPointerSize;
+ static const int kSize = kKindOffset + kPointerSize;
enum Kind {
kKindKeys = 1,
@@ -10006,25 +10023,6 @@ class OrderedHashTableIterator: public JSObject {
kKindEntries = 3
};
- // Called by the underlying [table] when an entry is removed.
- void EntryRemoved(int index);
-
- // Called by the underlying [table] when it is compacted/rehashed.
- void TableCompacted() {
- // All holes have been removed so index is now same as count.
- set_index(count());
- }
-
- // Called by the underlying [table] when it is cleared.
- void TableCleared() {
- set_index(Smi::FromInt(0));
- set_count(Smi::FromInt(0));
- }
-
- // Removes the iterator from the double linked list and removes its reference
- // back to the [table].
- void Close();
-
// Returns an iterator result object: {value: any, done: boolean} and moves
// the index to the next valid entry. Closes the iterator if moving past the
// end.
@@ -10035,16 +10033,9 @@ class OrderedHashTableIterator: public JSObject {
Handle<Map> map, Handle<TableType> table, int kind);
private:
- // Ensures [index] is not pointing to a hole.
- void Seek();
-
- // Moves [index] to next valid entry. Closes the iterator if moving past the
- // end.
- void MoveNext();
-
- bool Closed() {
- return table()->IsUndefined();
- }
+ // Transitions the iterator to the non obsolote backing store. This is a NOP
+ // if the [table] is not obsolete.
+ void Transition();
DISALLOW_IMPLICIT_CONSTRUCTORS(OrderedHashTableIterator);
};
@@ -10066,7 +10057,8 @@ class JSSetIterator: public OrderedHashTableIterator<JSSetIterator,
static inline JSSetIterator* cast(Object* obj);
static Handle<Object> ValueForKind(
- Handle<JSSetIterator> iterator, int entry_index);
+ Handle<JSSetIterator> iterator,
+ int entry_index);
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSSetIterator);
@@ -10089,7 +10081,8 @@ class JSMapIterator: public OrderedHashTableIterator<JSMapIterator,
static inline JSMapIterator* cast(Object* obj);
static Handle<Object> ValueForKind(
- Handle<JSMapIterator> iterator, int entry_index);
+ Handle<JSMapIterator> iterator,
+ int entry_index);
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSMapIterator);
« no previous file with comments | « src/collection.js ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698