OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 // - HeapObject (superclass for everything allocated in the heap) | 59 // - HeapObject (superclass for everything allocated in the heap) |
60 // - JSReceiver (suitable for property access) | 60 // - JSReceiver (suitable for property access) |
61 // - JSObject | 61 // - JSObject |
62 // - JSArray | 62 // - JSArray |
63 // - JSArrayBuffer | 63 // - JSArrayBuffer |
64 // - JSArrayBufferView | 64 // - JSArrayBufferView |
65 // - JSTypedArray | 65 // - JSTypedArray |
66 // - JSDataView | 66 // - JSDataView |
67 // - JSSet | 67 // - JSSet |
68 // - JSMap | 68 // - JSMap |
| 69 // - JSSetIterator |
| 70 // - JSMapIterator |
69 // - JSWeakCollection | 71 // - JSWeakCollection |
70 // - JSWeakMap | 72 // - JSWeakMap |
71 // - JSWeakSet | 73 // - JSWeakSet |
72 // - JSRegExp | 74 // - JSRegExp |
73 // - JSFunction | 75 // - JSFunction |
74 // - JSGeneratorObject | 76 // - JSGeneratorObject |
75 // - JSModule | 77 // - JSModule |
76 // - GlobalObject | 78 // - GlobalObject |
77 // - JSGlobalObject | 79 // - JSGlobalObject |
78 // - JSBuiltinsObject | 80 // - JSBuiltinsObject |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 V(JS_GLOBAL_OBJECT_TYPE) \ | 440 V(JS_GLOBAL_OBJECT_TYPE) \ |
439 V(JS_BUILTINS_OBJECT_TYPE) \ | 441 V(JS_BUILTINS_OBJECT_TYPE) \ |
440 V(JS_GLOBAL_PROXY_TYPE) \ | 442 V(JS_GLOBAL_PROXY_TYPE) \ |
441 V(JS_ARRAY_TYPE) \ | 443 V(JS_ARRAY_TYPE) \ |
442 V(JS_ARRAY_BUFFER_TYPE) \ | 444 V(JS_ARRAY_BUFFER_TYPE) \ |
443 V(JS_TYPED_ARRAY_TYPE) \ | 445 V(JS_TYPED_ARRAY_TYPE) \ |
444 V(JS_DATA_VIEW_TYPE) \ | 446 V(JS_DATA_VIEW_TYPE) \ |
445 V(JS_PROXY_TYPE) \ | 447 V(JS_PROXY_TYPE) \ |
446 V(JS_SET_TYPE) \ | 448 V(JS_SET_TYPE) \ |
447 V(JS_MAP_TYPE) \ | 449 V(JS_MAP_TYPE) \ |
| 450 V(JS_SET_ITERATOR_TYPE) \ |
| 451 V(JS_MAP_ITERATOR_TYPE) \ |
448 V(JS_WEAK_MAP_TYPE) \ | 452 V(JS_WEAK_MAP_TYPE) \ |
449 V(JS_WEAK_SET_TYPE) \ | 453 V(JS_WEAK_SET_TYPE) \ |
450 V(JS_REGEXP_TYPE) \ | 454 V(JS_REGEXP_TYPE) \ |
451 \ | 455 \ |
452 V(JS_FUNCTION_TYPE) \ | 456 V(JS_FUNCTION_TYPE) \ |
453 V(JS_FUNCTION_PROXY_TYPE) \ | 457 V(JS_FUNCTION_PROXY_TYPE) \ |
454 V(DEBUG_INFO_TYPE) \ | 458 V(DEBUG_INFO_TYPE) \ |
455 V(BREAK_POINT_INFO_TYPE) | 459 V(BREAK_POINT_INFO_TYPE) |
456 | 460 |
457 | 461 |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
786 JS_MODULE_TYPE, | 790 JS_MODULE_TYPE, |
787 JS_GLOBAL_OBJECT_TYPE, | 791 JS_GLOBAL_OBJECT_TYPE, |
788 JS_BUILTINS_OBJECT_TYPE, | 792 JS_BUILTINS_OBJECT_TYPE, |
789 JS_GLOBAL_PROXY_TYPE, | 793 JS_GLOBAL_PROXY_TYPE, |
790 JS_ARRAY_TYPE, | 794 JS_ARRAY_TYPE, |
791 JS_ARRAY_BUFFER_TYPE, | 795 JS_ARRAY_BUFFER_TYPE, |
792 JS_TYPED_ARRAY_TYPE, | 796 JS_TYPED_ARRAY_TYPE, |
793 JS_DATA_VIEW_TYPE, | 797 JS_DATA_VIEW_TYPE, |
794 JS_SET_TYPE, | 798 JS_SET_TYPE, |
795 JS_MAP_TYPE, | 799 JS_MAP_TYPE, |
| 800 JS_SET_ITERATOR_TYPE, |
| 801 JS_MAP_ITERATOR_TYPE, |
796 JS_WEAK_MAP_TYPE, | 802 JS_WEAK_MAP_TYPE, |
797 JS_WEAK_SET_TYPE, | 803 JS_WEAK_SET_TYPE, |
798 | 804 |
799 JS_REGEXP_TYPE, | 805 JS_REGEXP_TYPE, |
800 | 806 |
801 JS_FUNCTION_TYPE, // LAST_JS_OBJECT_TYPE, LAST_JS_RECEIVER_TYPE | 807 JS_FUNCTION_TYPE, // LAST_JS_OBJECT_TYPE, LAST_JS_RECEIVER_TYPE |
802 | 808 |
803 // Pseudo-types | 809 // Pseudo-types |
804 FIRST_TYPE = 0x0, | 810 FIRST_TYPE = 0x0, |
805 LAST_TYPE = JS_FUNCTION_TYPE, | 811 LAST_TYPE = JS_FUNCTION_TYPE, |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1033 V(Boolean) \ | 1039 V(Boolean) \ |
1034 V(JSArray) \ | 1040 V(JSArray) \ |
1035 V(JSArrayBuffer) \ | 1041 V(JSArrayBuffer) \ |
1036 V(JSArrayBufferView) \ | 1042 V(JSArrayBufferView) \ |
1037 V(JSTypedArray) \ | 1043 V(JSTypedArray) \ |
1038 V(JSDataView) \ | 1044 V(JSDataView) \ |
1039 V(JSProxy) \ | 1045 V(JSProxy) \ |
1040 V(JSFunctionProxy) \ | 1046 V(JSFunctionProxy) \ |
1041 V(JSSet) \ | 1047 V(JSSet) \ |
1042 V(JSMap) \ | 1048 V(JSMap) \ |
| 1049 V(JSSetIterator) \ |
| 1050 V(JSMapIterator) \ |
1043 V(JSWeakCollection) \ | 1051 V(JSWeakCollection) \ |
1044 V(JSWeakMap) \ | 1052 V(JSWeakMap) \ |
1045 V(JSWeakSet) \ | 1053 V(JSWeakSet) \ |
1046 V(JSRegExp) \ | 1054 V(JSRegExp) \ |
1047 V(HashTable) \ | 1055 V(HashTable) \ |
1048 V(Dictionary) \ | 1056 V(Dictionary) \ |
1049 V(StringTable) \ | 1057 V(StringTable) \ |
1050 V(JSFunctionResultCache) \ | 1058 V(JSFunctionResultCache) \ |
1051 V(NormalizedMapCache) \ | 1059 V(NormalizedMapCache) \ |
1052 V(CompilationCacheTable) \ | 1060 V(CompilationCacheTable) \ |
(...skipping 3255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4308 // equality operator and Object::GetHash() for the hash function. | 4316 // equality operator and Object::GetHash() for the hash function. |
4309 // | 4317 // |
4310 // Based on the "Deterministic Hash Table" as described by Jason Orendorff at | 4318 // Based on the "Deterministic Hash Table" as described by Jason Orendorff at |
4311 // https://wiki.mozilla.org/User:Jorend/Deterministic_hash_tables | 4319 // https://wiki.mozilla.org/User:Jorend/Deterministic_hash_tables |
4312 // Originally attributed to Tyler Close. | 4320 // Originally attributed to Tyler Close. |
4313 // | 4321 // |
4314 // Memory layout: | 4322 // Memory layout: |
4315 // [0]: bucket count | 4323 // [0]: bucket count |
4316 // [1]: element count | 4324 // [1]: element count |
4317 // [2]: deleted element count | 4325 // [2]: deleted element count |
4318 // [3..(NumberOfBuckets() - 1)]: "hash table", where each item is an offset | 4326 // [3]: live iterators (doubly-linked list) |
| 4327 // [4..(NumberOfBuckets() - 1)]: "hash table", where each item is an offset |
4319 // into the data table (see below) where the | 4328 // into the data table (see below) where the |
4320 // first item in this bucket is stored. | 4329 // first item in this bucket is stored. |
4321 // [3 + NumberOfBuckets()..length]: "data table", an array of length | 4330 // [4 + NumberOfBuckets()..length]: "data table", an array of length |
4322 // Capacity() * kEntrySize, where the first entrysize | 4331 // Capacity() * kEntrySize, where the first entrysize |
4323 // items are handled by the derived class and the | 4332 // items are handled by the derived class and the |
4324 // item at kChainOffset is another entry into the | 4333 // item at kChainOffset is another entry into the |
4325 // data table indicating the next entry in this hash | 4334 // data table indicating the next entry in this hash |
4326 // bucket. | 4335 // bucket. |
4327 template<class Derived, int entrysize> | 4336 template<class Derived, class Iterator, int entrysize> |
4328 class OrderedHashTable: public FixedArray { | 4337 class OrderedHashTable: public FixedArray { |
4329 public: | 4338 public: |
4330 // Returns an OrderedHashTable with a capacity of at least |capacity|. | 4339 // Returns an OrderedHashTable with a capacity of at least |capacity|. |
4331 static Handle<Derived> Allocate( | 4340 static Handle<Derived> Allocate( |
4332 Isolate* isolate, int capacity, PretenureFlag pretenure = NOT_TENURED); | 4341 Isolate* isolate, int capacity, PretenureFlag pretenure = NOT_TENURED); |
4333 | 4342 |
4334 // Returns an OrderedHashTable (possibly |table|) with enough space | 4343 // Returns an OrderedHashTable (possibly |table|) with enough space |
4335 // to add at least one new element. | 4344 // to add at least one new element. |
4336 static Handle<Derived> EnsureGrowable(Handle<Derived> table); | 4345 static Handle<Derived> EnsureGrowable(Handle<Derived> table); |
4337 | 4346 |
4338 // Returns an OrderedHashTable (possibly |table|) that's shrunken | 4347 // Returns an OrderedHashTable (possibly |table|) that's shrunken |
4339 // if possible. | 4348 // if possible. |
4340 static Handle<Derived> Shrink(Handle<Derived> table); | 4349 static Handle<Derived> Shrink(Handle<Derived> table); |
4341 | 4350 |
| 4351 // Returns a new empty OrderedHashTable and updates all the iterators to |
| 4352 // point to the new table. |
| 4353 static Handle<Derived> Clear(Handle<Derived> table); |
| 4354 |
4342 // Returns kNotFound if the key isn't present. | 4355 // Returns kNotFound if the key isn't present. |
4343 int FindEntry(Object* key); | 4356 int FindEntry(Object* key); |
4344 | 4357 |
4345 int NumberOfElements() { | 4358 int NumberOfElements() { |
4346 return Smi::cast(get(kNumberOfElementsIndex))->value(); | 4359 return Smi::cast(get(kNumberOfElementsIndex))->value(); |
4347 } | 4360 } |
4348 | 4361 |
4349 int NumberOfDeletedElements() { | 4362 int NumberOfDeletedElements() { |
4350 return Smi::cast(get(kNumberOfDeletedElementsIndex))->value(); | 4363 return Smi::cast(get(kNumberOfDeletedElementsIndex))->value(); |
4351 } | 4364 } |
4352 | 4365 |
| 4366 int UsedCapacity() { return NumberOfElements() + NumberOfDeletedElements(); } |
| 4367 |
4353 int NumberOfBuckets() { | 4368 int NumberOfBuckets() { |
4354 return Smi::cast(get(kNumberOfBucketsIndex))->value(); | 4369 return Smi::cast(get(kNumberOfBucketsIndex))->value(); |
4355 } | 4370 } |
4356 | 4371 |
| 4372 Object* iterators() { return get(kIteratorsIndex); } |
| 4373 |
| 4374 void set_iterators(Object* value) { set(kIteratorsIndex, value); } |
| 4375 |
4357 // Returns the index into the data table where the new entry | 4376 // Returns the index into the data table where the new entry |
4358 // should be placed. The table is assumed to have enough space | 4377 // should be placed. The table is assumed to have enough space |
4359 // for a new entry. | 4378 // for a new entry. |
4360 int AddEntry(int hash); | 4379 int AddEntry(int hash); |
4361 | 4380 |
4362 // Removes the entry, and puts the_hole in entrysize pointers | 4381 // Removes the entry, and puts the_hole in entrysize pointers |
4363 // (leaving the hash table chain intact). | 4382 // (leaving the hash table chain intact). |
4364 void RemoveEntry(int entry); | 4383 void RemoveEntry(int entry); |
4365 | 4384 |
4366 // Returns an index into |this| for the given entry. | 4385 // Returns an index into |this| for the given entry. |
4367 int EntryToIndex(int entry) { | 4386 int EntryToIndex(int entry) { |
4368 return kHashTableStartIndex + NumberOfBuckets() + (entry * kEntrySize); | 4387 return kHashTableStartIndex + NumberOfBuckets() + (entry * kEntrySize); |
4369 } | 4388 } |
4370 | 4389 |
| 4390 Object* KeyAt(int entry) { return get(EntryToIndex(entry)); } |
| 4391 |
4371 static const int kNotFound = -1; | 4392 static const int kNotFound = -1; |
| 4393 static const int kMinCapacity = 4; |
4372 | 4394 |
4373 private: | 4395 private: |
4374 static Handle<Derived> Rehash(Handle<Derived> table, int new_capacity); | 4396 static Handle<Derived> Rehash(Handle<Derived> table, int new_capacity); |
4375 | 4397 |
4376 void SetNumberOfBuckets(int num) { | 4398 void SetNumberOfBuckets(int num) { |
4377 set(kNumberOfBucketsIndex, Smi::FromInt(num)); | 4399 set(kNumberOfBucketsIndex, Smi::FromInt(num)); |
4378 } | 4400 } |
4379 | 4401 |
4380 void SetNumberOfElements(int num) { | 4402 void SetNumberOfElements(int num) { |
4381 set(kNumberOfElementsIndex, Smi::FromInt(num)); | 4403 set(kNumberOfElementsIndex, Smi::FromInt(num)); |
4382 } | 4404 } |
4383 | 4405 |
4384 void SetNumberOfDeletedElements(int num) { | 4406 void SetNumberOfDeletedElements(int num) { |
4385 set(kNumberOfDeletedElementsIndex, Smi::FromInt(num)); | 4407 set(kNumberOfDeletedElementsIndex, Smi::FromInt(num)); |
4386 } | 4408 } |
4387 | 4409 |
4388 int Capacity() { | 4410 int Capacity() { |
4389 return NumberOfBuckets() * kLoadFactor; | 4411 return NumberOfBuckets() * kLoadFactor; |
4390 } | 4412 } |
4391 | 4413 |
4392 Object* KeyAt(int entry) { return get(EntryToIndex(entry)); } | |
4393 | |
4394 // Returns the next entry for the given entry. | 4414 // Returns the next entry for the given entry. |
4395 int ChainAt(int entry) { | 4415 int ChainAt(int entry) { |
4396 return Smi::cast(get(EntryToIndex(entry) + kChainOffset))->value(); | 4416 return Smi::cast(get(EntryToIndex(entry) + kChainOffset))->value(); |
4397 } | 4417 } |
4398 | 4418 |
4399 int HashToBucket(int hash) { | 4419 int HashToBucket(int hash) { |
4400 return hash & (NumberOfBuckets() - 1); | 4420 return hash & (NumberOfBuckets() - 1); |
4401 } | 4421 } |
4402 | 4422 |
4403 int HashToEntry(int hash) { | 4423 int HashToEntry(int hash) { |
4404 int bucket = HashToBucket(hash); | 4424 int bucket = HashToBucket(hash); |
4405 return Smi::cast(get(kHashTableStartIndex + bucket))->value(); | 4425 return Smi::cast(get(kHashTableStartIndex + bucket))->value(); |
4406 } | 4426 } |
4407 | 4427 |
4408 static const int kNumberOfBucketsIndex = 0; | 4428 static const int kNumberOfBucketsIndex = 0; |
4409 static const int kNumberOfElementsIndex = kNumberOfBucketsIndex + 1; | 4429 static const int kNumberOfElementsIndex = kNumberOfBucketsIndex + 1; |
4410 static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1; | 4430 static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1; |
4411 static const int kHashTableStartIndex = kNumberOfDeletedElementsIndex + 1; | 4431 static const int kIteratorsIndex = kNumberOfDeletedElementsIndex + 1; |
| 4432 static const int kHashTableStartIndex = kIteratorsIndex + 1; |
4412 | 4433 |
4413 static const int kEntrySize = entrysize + 1; | 4434 static const int kEntrySize = entrysize + 1; |
4414 static const int kChainOffset = entrysize; | 4435 static const int kChainOffset = entrysize; |
4415 | 4436 |
4416 static const int kLoadFactor = 2; | 4437 static const int kLoadFactor = 2; |
4417 static const int kMaxCapacity = | 4438 static const int kMaxCapacity = |
4418 (FixedArray::kMaxLength - kHashTableStartIndex) | 4439 (FixedArray::kMaxLength - kHashTableStartIndex) |
4419 / (1 + (kEntrySize * kLoadFactor)); | 4440 / (1 + (kEntrySize * kLoadFactor)); |
4420 }; | 4441 }; |
4421 | 4442 |
4422 | 4443 |
4423 class OrderedHashSet: public OrderedHashTable<OrderedHashSet, 1> { | 4444 class JSSetIterator; |
| 4445 |
| 4446 |
| 4447 class OrderedHashSet: public OrderedHashTable< |
| 4448 OrderedHashSet, JSSetIterator, 1> { |
4424 public: | 4449 public: |
4425 static OrderedHashSet* cast(Object* obj) { | 4450 static OrderedHashSet* cast(Object* obj) { |
4426 ASSERT(obj->IsOrderedHashTable()); | 4451 ASSERT(obj->IsOrderedHashTable()); |
4427 return reinterpret_cast<OrderedHashSet*>(obj); | 4452 return reinterpret_cast<OrderedHashSet*>(obj); |
4428 } | 4453 } |
4429 | 4454 |
4430 bool Contains(Object* key); | 4455 bool Contains(Object* key); |
4431 static Handle<OrderedHashSet> Add( | 4456 static Handle<OrderedHashSet> Add( |
4432 Handle<OrderedHashSet> table, Handle<Object> key); | 4457 Handle<OrderedHashSet> table, Handle<Object> key); |
4433 static Handle<OrderedHashSet> Remove( | 4458 static Handle<OrderedHashSet> Remove( |
4434 Handle<OrderedHashSet> table, Handle<Object> key); | 4459 Handle<OrderedHashSet> table, Handle<Object> key); |
4435 }; | 4460 }; |
4436 | 4461 |
4437 | 4462 |
4438 class OrderedHashMap: public OrderedHashTable<OrderedHashMap, 2> { | 4463 class JSMapIterator; |
| 4464 |
| 4465 |
| 4466 class OrderedHashMap:public OrderedHashTable< |
| 4467 OrderedHashMap, JSMapIterator, 2> { |
4439 public: | 4468 public: |
4440 static OrderedHashMap* cast(Object* obj) { | 4469 static OrderedHashMap* cast(Object* obj) { |
4441 ASSERT(obj->IsOrderedHashTable()); | 4470 ASSERT(obj->IsOrderedHashTable()); |
4442 return reinterpret_cast<OrderedHashMap*>(obj); | 4471 return reinterpret_cast<OrderedHashMap*>(obj); |
4443 } | 4472 } |
4444 | 4473 |
4445 Object* Lookup(Object* key); | 4474 Object* Lookup(Object* key); |
4446 static Handle<OrderedHashMap> Put( | 4475 static Handle<OrderedHashMap> Put( |
4447 Handle<OrderedHashMap> table, | 4476 Handle<OrderedHashMap> table, |
4448 Handle<Object> key, | 4477 Handle<Object> key, |
(...skipping 3134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7583 static const int kContinuationOffset = kReceiverOffset + kPointerSize; | 7612 static const int kContinuationOffset = kReceiverOffset + kPointerSize; |
7584 static const int kOperandStackOffset = kContinuationOffset + kPointerSize; | 7613 static const int kOperandStackOffset = kContinuationOffset + kPointerSize; |
7585 static const int kStackHandlerIndexOffset = | 7614 static const int kStackHandlerIndexOffset = |
7586 kOperandStackOffset + kPointerSize; | 7615 kOperandStackOffset + kPointerSize; |
7587 static const int kSize = kStackHandlerIndexOffset + kPointerSize; | 7616 static const int kSize = kStackHandlerIndexOffset + kPointerSize; |
7588 | 7617 |
7589 // Resume mode, for use by runtime functions. | 7618 // Resume mode, for use by runtime functions. |
7590 enum ResumeMode { NEXT, THROW }; | 7619 enum ResumeMode { NEXT, THROW }; |
7591 | 7620 |
7592 // Yielding from a generator returns an object with the following inobject | 7621 // Yielding from a generator returns an object with the following inobject |
7593 // properties. See Context::generator_result_map() for the map. | 7622 // properties. See Context::iterator_result_map() for the map. |
7594 static const int kResultValuePropertyIndex = 0; | 7623 static const int kResultValuePropertyIndex = 0; |
7595 static const int kResultDonePropertyIndex = 1; | 7624 static const int kResultDonePropertyIndex = 1; |
7596 static const int kResultPropertyCount = 2; | 7625 static const int kResultPropertyCount = 2; |
7597 | 7626 |
7598 static const int kResultValuePropertyOffset = JSObject::kHeaderSize; | 7627 static const int kResultValuePropertyOffset = JSObject::kHeaderSize; |
7599 static const int kResultDonePropertyOffset = | 7628 static const int kResultDonePropertyOffset = |
7600 kResultValuePropertyOffset + kPointerSize; | 7629 kResultValuePropertyOffset + kPointerSize; |
7601 static const int kResultSize = kResultDonePropertyOffset + kPointerSize; | 7630 static const int kResultSize = kResultDonePropertyOffset + kPointerSize; |
7602 | 7631 |
7603 private: | 7632 private: |
(...skipping 2461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10065 DECLARE_VERIFIER(JSMap) | 10094 DECLARE_VERIFIER(JSMap) |
10066 | 10095 |
10067 static const int kTableOffset = JSObject::kHeaderSize; | 10096 static const int kTableOffset = JSObject::kHeaderSize; |
10068 static const int kSize = kTableOffset + kPointerSize; | 10097 static const int kSize = kTableOffset + kPointerSize; |
10069 | 10098 |
10070 private: | 10099 private: |
10071 DISALLOW_IMPLICIT_CONSTRUCTORS(JSMap); | 10100 DISALLOW_IMPLICIT_CONSTRUCTORS(JSMap); |
10072 }; | 10101 }; |
10073 | 10102 |
10074 | 10103 |
| 10104 // OrderedHashTableIterator is an iterator that iterates over the keys and |
| 10105 // values of an OrderedHashTable. |
| 10106 // |
| 10107 // The hash table has a reference to the iterator and the iterators themselves |
| 10108 // have references to the [next_iterator] and [previous_iterator], thus creating |
| 10109 // a double linked list. |
| 10110 // |
| 10111 // When the hash table changes the iterators are called to update their [index] |
| 10112 // and [count]. The hash table calls [EntryRemoved], [TableCompacted] as well |
| 10113 // as [TableCleared]. |
| 10114 // |
| 10115 // When an iterator is done it closes itself. It removes itself from the double |
| 10116 // linked list and it sets its [table] to undefined, no longer keeping the |
| 10117 // [table] alive. |
| 10118 template<class Derived, class TableType> |
| 10119 class OrderedHashTableIterator: public JSObject { |
| 10120 public: |
| 10121 // [table]: the backing hash table mapping keys to values. |
| 10122 DECL_ACCESSORS(table, Object) |
| 10123 |
| 10124 // [index]: The index into the data table. |
| 10125 DECL_ACCESSORS(index, Smi) |
| 10126 |
| 10127 // [count]: The logical index into the data table, ignoring the holes. |
| 10128 DECL_ACCESSORS(count, Smi) |
| 10129 |
| 10130 // [kind]: The kind of iteration this is. One of the [Kind] enum values. |
| 10131 DECL_ACCESSORS(kind, Smi) |
| 10132 |
| 10133 // [next_iterator]: Used as a double linked list for the live iterators. |
| 10134 DECL_ACCESSORS(next_iterator, Object) |
| 10135 |
| 10136 // [previous_iterator]: Used as a double linked list for the live iterators. |
| 10137 DECL_ACCESSORS(previous_iterator, Object) |
| 10138 |
| 10139 #ifdef OBJECT_PRINT |
| 10140 void OrderedHashTableIteratorPrint(FILE* out); |
| 10141 #endif |
| 10142 |
| 10143 static const int kTableOffset = JSObject::kHeaderSize; |
| 10144 static const int kIndexOffset = kTableOffset + kPointerSize; |
| 10145 static const int kCountOffset = kIndexOffset + kPointerSize; |
| 10146 static const int kKindOffset = kCountOffset + kPointerSize; |
| 10147 static const int kNextIteratorOffset = kKindOffset + kPointerSize; |
| 10148 static const int kPreviousIteratorOffset = kNextIteratorOffset + kPointerSize; |
| 10149 static const int kSize = kPreviousIteratorOffset + kPointerSize; |
| 10150 |
| 10151 enum Kind { |
| 10152 kKindKeys = 1, |
| 10153 kKindValues = 2, |
| 10154 kKindEntries = 3 |
| 10155 }; |
| 10156 |
| 10157 // Called by the underlying [table] when an entry is removed. |
| 10158 void EntryRemoved(int index); |
| 10159 |
| 10160 // Called by the underlying [table] when it is compacted/rehashed. |
| 10161 void TableCompacted() { |
| 10162 // All holes have been removed so index is now same as count. |
| 10163 set_index(count()); |
| 10164 } |
| 10165 |
| 10166 // Called by the underlying [table] when it is cleared. |
| 10167 void TableCleared() { |
| 10168 set_index(Smi::FromInt(0)); |
| 10169 set_count(Smi::FromInt(0)); |
| 10170 } |
| 10171 |
| 10172 // Removes the iterator from the double linked list and removes its reference |
| 10173 // back to the [table]. |
| 10174 void Close(); |
| 10175 |
| 10176 // Returns an iterator result object: {value: any, done: boolean} and moves |
| 10177 // the index to the next valid entry. Closes the iterator if moving past the |
| 10178 // end. |
| 10179 static Handle<JSObject> Next(Handle<Derived> iterator); |
| 10180 |
| 10181 protected: |
| 10182 static Handle<Derived> CreateInternal( |
| 10183 Handle<Map> map, Handle<TableType> table, int kind); |
| 10184 |
| 10185 private: |
| 10186 // Ensures [index] is not pointing to a hole. |
| 10187 void Seek(); |
| 10188 |
| 10189 // Moves [index] to next valid entry. Closes the iterator if moving past the |
| 10190 // end. |
| 10191 void MoveNext(); |
| 10192 |
| 10193 bool Closed() { |
| 10194 return table()->IsUndefined(); |
| 10195 } |
| 10196 |
| 10197 DISALLOW_IMPLICIT_CONSTRUCTORS(OrderedHashTableIterator); |
| 10198 }; |
| 10199 |
| 10200 |
| 10201 class JSSetIterator: public OrderedHashTableIterator<JSSetIterator, |
| 10202 OrderedHashSet> { |
| 10203 public: |
| 10204 // Creates a new iterator associated with [table]. |
| 10205 // [kind] needs to be one of the OrderedHashTableIterator Kind enum values. |
| 10206 static inline Handle<JSSetIterator> Create( |
| 10207 Handle<OrderedHashSet> table, int kind); |
| 10208 |
| 10209 // Dispatched behavior. |
| 10210 DECLARE_PRINTER(JSSetIterator) |
| 10211 DECLARE_VERIFIER(JSSetIterator) |
| 10212 |
| 10213 // Casting. |
| 10214 static inline JSSetIterator* cast(Object* obj); |
| 10215 |
| 10216 static Handle<Object> ValueForKind( |
| 10217 Handle<JSSetIterator> iterator, int entry_index); |
| 10218 |
| 10219 private: |
| 10220 DISALLOW_IMPLICIT_CONSTRUCTORS(JSSetIterator); |
| 10221 }; |
| 10222 |
| 10223 |
| 10224 class JSMapIterator: public OrderedHashTableIterator<JSMapIterator, |
| 10225 OrderedHashMap> { |
| 10226 public: |
| 10227 // Creates a new iterator associated with [table]. |
| 10228 // [kind] needs to be one of the OrderedHashTableIterator Kind enum values. |
| 10229 static inline Handle<JSMapIterator> Create( |
| 10230 Handle<OrderedHashMap> table, int kind); |
| 10231 |
| 10232 // Dispatched behavior. |
| 10233 DECLARE_PRINTER(JSMapIterator) |
| 10234 DECLARE_VERIFIER(JSMapIterator) |
| 10235 |
| 10236 // Casting. |
| 10237 static inline JSMapIterator* cast(Object* obj); |
| 10238 |
| 10239 static Handle<Object> ValueForKind( |
| 10240 Handle<JSMapIterator> iterator, int entry_index); |
| 10241 |
| 10242 private: |
| 10243 DISALLOW_IMPLICIT_CONSTRUCTORS(JSMapIterator); |
| 10244 }; |
| 10245 |
| 10246 |
10075 // Base class for both JSWeakMap and JSWeakSet | 10247 // Base class for both JSWeakMap and JSWeakSet |
10076 class JSWeakCollection: public JSObject { | 10248 class JSWeakCollection: public JSObject { |
10077 public: | 10249 public: |
10078 // [table]: the backing hash table mapping keys to values. | 10250 // [table]: the backing hash table mapping keys to values. |
10079 DECL_ACCESSORS(table, Object) | 10251 DECL_ACCESSORS(table, Object) |
10080 | 10252 |
10081 // [next]: linked list of encountered weak maps during GC. | 10253 // [next]: linked list of encountered weak maps during GC. |
10082 DECL_ACCESSORS(next, Object) | 10254 DECL_ACCESSORS(next, Object) |
10083 | 10255 |
10084 static const int kTableOffset = JSObject::kHeaderSize; | 10256 static const int kTableOffset = JSObject::kHeaderSize; |
(...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11095 } else { | 11267 } else { |
11096 value &= ~(1 << bit_position); | 11268 value &= ~(1 << bit_position); |
11097 } | 11269 } |
11098 return value; | 11270 return value; |
11099 } | 11271 } |
11100 }; | 11272 }; |
11101 | 11273 |
11102 } } // namespace v8::internal | 11274 } } // namespace v8::internal |
11103 | 11275 |
11104 #endif // V8_OBJECTS_H_ | 11276 #endif // V8_OBJECTS_H_ |
OLD | NEW |