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

Side by Side 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: partial code review feedback update 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/collection.js ('k') | src/objects.cc » ('j') | src/objects.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_OBJECTS_H_ 5 #ifndef V8_OBJECTS_H_
6 #define V8_OBJECTS_H_ 6 #define V8_OBJECTS_H_
7 7
8 #include "allocation.h" 8 #include "allocation.h"
9 #include "assert-scope.h" 9 #include "assert-scope.h"
10 #include "builtins.h" 10 #include "builtins.h"
(...skipping 4135 matching lines...) Expand 10 before | Expand all | Expand 10 after
4146 // equality operator and Object::GetHash() for the hash function. 4146 // equality operator and Object::GetHash() for the hash function.
4147 // 4147 //
4148 // Based on the "Deterministic Hash Table" as described by Jason Orendorff at 4148 // Based on the "Deterministic Hash Table" as described by Jason Orendorff at
4149 // https://wiki.mozilla.org/User:Jorend/Deterministic_hash_tables 4149 // https://wiki.mozilla.org/User:Jorend/Deterministic_hash_tables
4150 // Originally attributed to Tyler Close. 4150 // Originally attributed to Tyler Close.
4151 // 4151 //
4152 // Memory layout: 4152 // Memory layout:
4153 // [0]: bucket count 4153 // [0]: bucket count
4154 // [1]: element count 4154 // [1]: element count
4155 // [2]: deleted element count 4155 // [2]: deleted element count
4156 // [3]: live iterators (doubly-linked list) 4156 // [3]: "next table". When the table is rehashed the old table points to the
4157 // [4..(NumberOfBuckets() - 1)]: "hash table", where each item is an offset 4157 // next newer table. The changes between the two tables are described by
4158 // [changes].
4159 // [4]: "changes". This contains the information needed to transition an
4160 // iterator to the next table.
4161 // [5..(NumberOfBuckets() - 1)]: "hash table", where each item is an offset
4158 // into the data table (see below) where the 4162 // into the data table (see below) where the
4159 // first item in this bucket is stored. 4163 // first item in this bucket is stored.
4160 // [4 + NumberOfBuckets()..length]: "data table", an array of length 4164 // [5 + NumberOfBuckets()..length]: "data table", an array of length
4161 // Capacity() * kEntrySize, where the first entrysize 4165 // Capacity() * kEntrySize, where the first entrysize
4162 // items are handled by the derived class and the 4166 // items are handled by the derived class and the
4163 // item at kChainOffset is another entry into the 4167 // item at kChainOffset is another entry into the
4164 // data table indicating the next entry in this hash 4168 // data table indicating the next entry in this hash
4165 // bucket. 4169 // bucket.
4166 template<class Derived, class Iterator, int entrysize> 4170 template<class Derived, class Iterator, int entrysize>
4167 class OrderedHashTable: public FixedArray { 4171 class OrderedHashTable: public FixedArray {
4168 public: 4172 public:
4169 // Returns an OrderedHashTable with a capacity of at least |capacity|. 4173 // Returns an OrderedHashTable with a capacity of at least |capacity|.
4170 static Handle<Derived> Allocate( 4174 static Handle<Derived> Allocate(
(...skipping 21 matching lines...) Expand all
4192 int NumberOfDeletedElements() { 4196 int NumberOfDeletedElements() {
4193 return Smi::cast(get(kNumberOfDeletedElementsIndex))->value(); 4197 return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
4194 } 4198 }
4195 4199
4196 int UsedCapacity() { return NumberOfElements() + NumberOfDeletedElements(); } 4200 int UsedCapacity() { return NumberOfElements() + NumberOfDeletedElements(); }
4197 4201
4198 int NumberOfBuckets() { 4202 int NumberOfBuckets() {
4199 return Smi::cast(get(kNumberOfBucketsIndex))->value(); 4203 return Smi::cast(get(kNumberOfBucketsIndex))->value();
4200 } 4204 }
4201 4205
4202 Object* iterators() { return get(kIteratorsIndex); } 4206 // The next newer table or |undefined| if no newer table exists.
4207 Object* next_table() {
4208 return get(kNextTableIndex);
4209 }
4203 4210
4204 void set_iterators(Object* value) { set(kIteratorsIndex, value); } 4211 // The changes describing how to transition an iterator to the [next_table].
4212 // This is an array of the removed holes during a Rehash. In case the table
4213 // was cleared, this stays as |undefined|.
4214 Object* changes() {
4215 return get(kChangesIndex);
4216 }
4205 4217
4206 // Returns the index into the data table where the new entry 4218 // Returns the index into the data table where the new entry
4207 // should be placed. The table is assumed to have enough space 4219 // should be placed. The table is assumed to have enough space
4208 // for a new entry. 4220 // for a new entry.
4209 int AddEntry(int hash); 4221 int AddEntry(int hash);
4210 4222
4211 // Removes the entry, and puts the_hole in entrysize pointers 4223 // Removes the entry, and puts the_hole in entrysize pointers
4212 // (leaving the hash table chain intact). 4224 // (leaving the hash table chain intact).
4213 void RemoveEntry(int entry); 4225 void RemoveEntry(int entry);
4214 4226
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
4248 4260
4249 int HashToBucket(int hash) { 4261 int HashToBucket(int hash) {
4250 return hash & (NumberOfBuckets() - 1); 4262 return hash & (NumberOfBuckets() - 1);
4251 } 4263 }
4252 4264
4253 int HashToEntry(int hash) { 4265 int HashToEntry(int hash) {
4254 int bucket = HashToBucket(hash); 4266 int bucket = HashToBucket(hash);
4255 return Smi::cast(get(kHashTableStartIndex + bucket))->value(); 4267 return Smi::cast(get(kHashTableStartIndex + bucket))->value();
4256 } 4268 }
4257 4269
4270 void set_next_table(Object* next_table) {
4271 set(kNextTableIndex, next_table);
4272 }
4273
4274 void set_changes(Object* changes) {
4275 set(kChangesIndex, changes);
4276 }
4277
4258 static const int kNumberOfBucketsIndex = 0; 4278 static const int kNumberOfBucketsIndex = 0;
4259 static const int kNumberOfElementsIndex = kNumberOfBucketsIndex + 1; 4279 static const int kNumberOfElementsIndex = kNumberOfBucketsIndex + 1;
4260 static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1; 4280 static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1;
4261 static const int kIteratorsIndex = kNumberOfDeletedElementsIndex + 1; 4281 static const int kNextTableIndex = kNumberOfDeletedElementsIndex + 1;
4262 static const int kHashTableStartIndex = kIteratorsIndex + 1; 4282 static const int kChangesIndex = kNextTableIndex + 1;
4283 static const int kHashTableStartIndex = kChangesIndex + 1;
4263 4284
4264 static const int kEntrySize = entrysize + 1; 4285 static const int kEntrySize = entrysize + 1;
4265 static const int kChainOffset = entrysize; 4286 static const int kChainOffset = entrysize;
4266 4287
4267 static const int kLoadFactor = 2; 4288 static const int kLoadFactor = 2;
4268 static const int kMaxCapacity = 4289 static const int kMaxCapacity =
4269 (FixedArray::kMaxLength - kHashTableStartIndex) 4290 (FixedArray::kMaxLength - kHashTableStartIndex)
4270 / (1 + (kEntrySize * kLoadFactor)); 4291 / (1 + (kEntrySize * kLoadFactor));
4271 }; 4292 };
4272 4293
(...skipping 5676 matching lines...) Expand 10 before | Expand all | Expand 10 after
9949 static const int kSize = kTableOffset + kPointerSize; 9970 static const int kSize = kTableOffset + kPointerSize;
9950 9971
9951 private: 9972 private:
9952 DISALLOW_IMPLICIT_CONSTRUCTORS(JSMap); 9973 DISALLOW_IMPLICIT_CONSTRUCTORS(JSMap);
9953 }; 9974 };
9954 9975
9955 9976
9956 // OrderedHashTableIterator is an iterator that iterates over the keys and 9977 // OrderedHashTableIterator is an iterator that iterates over the keys and
9957 // values of an OrderedHashTable. 9978 // values of an OrderedHashTable.
9958 // 9979 //
9959 // The hash table has a reference to the iterator and the iterators themselves 9980 // The iterator has a reference to the underlying OrderedHashTable data,
9960 // have references to the [next_iterator] and [previous_iterator], thus creating 9981 // [table], as well as the current [index] the iterator is at.
9961 // a double linked list.
9962 // 9982 //
9963 // When the hash table changes the iterators are called to update their [index] 9983 // When the OrderedHashTable is rehashed it adds a reference from the old table
9964 // and [count]. The hash table calls [EntryRemoved], [TableCompacted] as well 9984 // to the new table as well as storing enough data about the changes so that the
9965 // as [TableCleared]. 9985 // iterator [index] can be adjusted accordingly.
9966 // 9986 //
9967 // When an iterator is done it closes itself. It removes itself from the double 9987 // When the [Next] result from the iterator is requested, the iterator checks if
9968 // linked list and it sets its [table] to undefined, no longer keeping the 9988 // there is a newer table that it needs to transition to.
9969 // [table] alive.
9970 template<class Derived, class TableType> 9989 template<class Derived, class TableType>
9971 class OrderedHashTableIterator: public JSObject { 9990 class OrderedHashTableIterator: public JSObject {
9972 public: 9991 public:
9973 // [table]: the backing hash table mapping keys to values. 9992 // [table]: the backing hash table mapping keys to values.
9974 DECL_ACCESSORS(table, Object) 9993 DECL_ACCESSORS(table, Object)
9975 9994
9976 // [index]: The index into the data table. 9995 // [index]: The index into the data table.
9977 DECL_ACCESSORS(index, Smi) 9996 DECL_ACCESSORS(index, Smi)
9978 9997
9979 // [count]: The logical index into the data table, ignoring the holes.
9980 DECL_ACCESSORS(count, Smi)
9981
9982 // [kind]: The kind of iteration this is. One of the [Kind] enum values. 9998 // [kind]: The kind of iteration this is. One of the [Kind] enum values.
9983 DECL_ACCESSORS(kind, Smi) 9999 DECL_ACCESSORS(kind, Smi)
9984 10000
9985 // [next_iterator]: Used as a double linked list for the live iterators.
9986 DECL_ACCESSORS(next_iterator, Object)
9987
9988 // [previous_iterator]: Used as a double linked list for the live iterators.
9989 DECL_ACCESSORS(previous_iterator, Object)
9990
9991 #ifdef OBJECT_PRINT 10001 #ifdef OBJECT_PRINT
9992 void OrderedHashTableIteratorPrint(FILE* out); 10002 void OrderedHashTableIteratorPrint(FILE* out);
9993 #endif 10003 #endif
9994 10004
9995 static const int kTableOffset = JSObject::kHeaderSize; 10005 static const int kTableOffset = JSObject::kHeaderSize;
9996 static const int kIndexOffset = kTableOffset + kPointerSize; 10006 static const int kIndexOffset = kTableOffset + kPointerSize;
9997 static const int kCountOffset = kIndexOffset + kPointerSize; 10007 static const int kKindOffset = kIndexOffset + kPointerSize;
9998 static const int kKindOffset = kCountOffset + kPointerSize; 10008 static const int kSize = kKindOffset + kPointerSize;
9999 static const int kNextIteratorOffset = kKindOffset + kPointerSize;
10000 static const int kPreviousIteratorOffset = kNextIteratorOffset + kPointerSize;
10001 static const int kSize = kPreviousIteratorOffset + kPointerSize;
10002 10009
10003 enum Kind { 10010 enum Kind {
10004 kKindKeys = 1, 10011 kKindKeys = 1,
10005 kKindValues = 2, 10012 kKindValues = 2,
10006 kKindEntries = 3 10013 kKindEntries = 3
10007 }; 10014 };
10008 10015
10009 // Called by the underlying [table] when an entry is removed.
10010 void EntryRemoved(int index);
10011
10012 // Called by the underlying [table] when it is compacted/rehashed.
10013 void TableCompacted() {
10014 // All holes have been removed so index is now same as count.
10015 set_index(count());
10016 }
10017
10018 // Called by the underlying [table] when it is cleared.
10019 void TableCleared() {
10020 set_index(Smi::FromInt(0));
10021 set_count(Smi::FromInt(0));
10022 }
10023
10024 // Removes the iterator from the double linked list and removes its reference
10025 // back to the [table].
10026 void Close();
10027
10028 // Returns an iterator result object: {value: any, done: boolean} and moves 10016 // Returns an iterator result object: {value: any, done: boolean} and moves
10029 // the index to the next valid entry. Closes the iterator if moving past the 10017 // the index to the next valid entry. Closes the iterator if moving past the
10030 // end. 10018 // end.
10031 static Handle<JSObject> Next(Handle<Derived> iterator); 10019 static Handle<JSObject> Next(Handle<Derived> iterator);
10032 10020
10033 protected: 10021 protected:
10034 static Handle<Derived> CreateInternal( 10022 static Handle<Derived> CreateInternal(
10035 Handle<Map> map, Handle<TableType> table, int kind); 10023 Handle<Map> map, Handle<TableType> table, int kind);
10036 10024
10037 private: 10025 private:
10038 // Ensures [index] is not pointing to a hole. 10026 void Transition();
10039 void Seek();
10040
10041 // Moves [index] to next valid entry. Closes the iterator if moving past the
10042 // end.
10043 void MoveNext();
10044
10045 bool Closed() {
10046 return table()->IsUndefined();
10047 }
10048 10027
10049 DISALLOW_IMPLICIT_CONSTRUCTORS(OrderedHashTableIterator); 10028 DISALLOW_IMPLICIT_CONSTRUCTORS(OrderedHashTableIterator);
10050 }; 10029 };
10051 10030
10052 10031
10053 class JSSetIterator: public OrderedHashTableIterator<JSSetIterator, 10032 class JSSetIterator: public OrderedHashTableIterator<JSSetIterator,
10054 OrderedHashSet> { 10033 OrderedHashSet> {
10055 public: 10034 public:
10056 // Creates a new iterator associated with [table]. 10035 // Creates a new iterator associated with [table].
10057 // [kind] needs to be one of the OrderedHashTableIterator Kind enum values. 10036 // [kind] needs to be one of the OrderedHashTableIterator Kind enum values.
10058 static inline Handle<JSSetIterator> Create( 10037 static inline Handle<JSSetIterator> Create(
10059 Handle<OrderedHashSet> table, int kind); 10038 Handle<OrderedHashSet> table, int kind);
10060 10039
10061 // Dispatched behavior. 10040 // Dispatched behavior.
10062 DECLARE_PRINTER(JSSetIterator) 10041 DECLARE_PRINTER(JSSetIterator)
10063 DECLARE_VERIFIER(JSSetIterator) 10042 DECLARE_VERIFIER(JSSetIterator)
10064 10043
10065 // Casting. 10044 // Casting.
10066 static inline JSSetIterator* cast(Object* obj); 10045 static inline JSSetIterator* cast(Object* obj);
10067 10046
10068 static Handle<Object> ValueForKind( 10047 static Handle<Object> ValueForKind(
10069 Handle<JSSetIterator> iterator, int entry_index); 10048 Handle<JSSetIterator> iterator,
10049 int entry_index);
10070 10050
10071 private: 10051 private:
10072 DISALLOW_IMPLICIT_CONSTRUCTORS(JSSetIterator); 10052 DISALLOW_IMPLICIT_CONSTRUCTORS(JSSetIterator);
10073 }; 10053 };
10074 10054
10075 10055
10076 class JSMapIterator: public OrderedHashTableIterator<JSMapIterator, 10056 class JSMapIterator: public OrderedHashTableIterator<JSMapIterator,
10077 OrderedHashMap> { 10057 OrderedHashMap> {
10078 public: 10058 public:
10079 // Creates a new iterator associated with [table]. 10059 // Creates a new iterator associated with [table].
10080 // [kind] needs to be one of the OrderedHashTableIterator Kind enum values. 10060 // [kind] needs to be one of the OrderedHashTableIterator Kind enum values.
10081 static inline Handle<JSMapIterator> Create( 10061 static inline Handle<JSMapIterator> Create(
10082 Handle<OrderedHashMap> table, int kind); 10062 Handle<OrderedHashMap> table, int kind);
10083 10063
10084 // Dispatched behavior. 10064 // Dispatched behavior.
10085 DECLARE_PRINTER(JSMapIterator) 10065 DECLARE_PRINTER(JSMapIterator)
10086 DECLARE_VERIFIER(JSMapIterator) 10066 DECLARE_VERIFIER(JSMapIterator)
10087 10067
10088 // Casting. 10068 // Casting.
10089 static inline JSMapIterator* cast(Object* obj); 10069 static inline JSMapIterator* cast(Object* obj);
10090 10070
10091 static Handle<Object> ValueForKind( 10071 static Handle<Object> ValueForKind(
10092 Handle<JSMapIterator> iterator, int entry_index); 10072 Handle<JSMapIterator> iterator,
10073 int entry_index);
10093 10074
10094 private: 10075 private:
10095 DISALLOW_IMPLICIT_CONSTRUCTORS(JSMapIterator); 10076 DISALLOW_IMPLICIT_CONSTRUCTORS(JSMapIterator);
10096 }; 10077 };
10097 10078
10098 10079
10099 // Base class for both JSWeakMap and JSWeakSet 10080 // Base class for both JSWeakMap and JSWeakSet
10100 class JSWeakCollection: public JSObject { 10081 class JSWeakCollection: public JSObject {
10101 public: 10082 public:
10102 // [table]: the backing hash table mapping keys to values. 10083 // [table]: the backing hash table mapping keys to values.
(...skipping 1014 matching lines...) Expand 10 before | Expand all | Expand 10 after
11117 } else { 11098 } else {
11118 value &= ~(1 << bit_position); 11099 value &= ~(1 << bit_position);
11119 } 11100 }
11120 return value; 11101 return value;
11121 } 11102 }
11122 }; 11103 };
11123 11104
11124 } } // namespace v8::internal 11105 } } // namespace v8::internal
11125 11106
11126 #endif // V8_OBJECTS_H_ 11107 #endif // V8_OBJECTS_H_
OLDNEW
« no previous file with comments | « src/collection.js ('k') | src/objects.cc » ('j') | src/objects.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698