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

Side by Side Diff: src/objects.cc

Issue 236143002: ES6: Add support for Map.prototype.forEach and Set.prototype.forEach (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 8 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
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 1674 matching lines...) Expand 10 before | Expand all | Expand 10 after
1685 case JS_GENERATOR_OBJECT_TYPE: 1685 case JS_GENERATOR_OBJECT_TYPE:
1686 case JS_MODULE_TYPE: 1686 case JS_MODULE_TYPE:
1687 case JS_VALUE_TYPE: 1687 case JS_VALUE_TYPE:
1688 case JS_DATE_TYPE: 1688 case JS_DATE_TYPE:
1689 case JS_ARRAY_TYPE: 1689 case JS_ARRAY_TYPE:
1690 case JS_ARRAY_BUFFER_TYPE: 1690 case JS_ARRAY_BUFFER_TYPE:
1691 case JS_TYPED_ARRAY_TYPE: 1691 case JS_TYPED_ARRAY_TYPE:
1692 case JS_DATA_VIEW_TYPE: 1692 case JS_DATA_VIEW_TYPE:
1693 case JS_SET_TYPE: 1693 case JS_SET_TYPE:
1694 case JS_MAP_TYPE: 1694 case JS_MAP_TYPE:
1695 case JS_SET_ITERATOR_TYPE:
1696 case JS_MAP_ITERATOR_TYPE:
1695 case JS_WEAK_MAP_TYPE: 1697 case JS_WEAK_MAP_TYPE:
1696 case JS_WEAK_SET_TYPE: 1698 case JS_WEAK_SET_TYPE:
1697 case JS_REGEXP_TYPE: 1699 case JS_REGEXP_TYPE:
1698 case JS_GLOBAL_PROXY_TYPE: 1700 case JS_GLOBAL_PROXY_TYPE:
1699 case JS_GLOBAL_OBJECT_TYPE: 1701 case JS_GLOBAL_OBJECT_TYPE:
1700 case JS_BUILTINS_OBJECT_TYPE: 1702 case JS_BUILTINS_OBJECT_TYPE:
1701 case JS_MESSAGE_OBJECT_TYPE: 1703 case JS_MESSAGE_OBJECT_TYPE:
1702 JSObject::BodyDescriptor::IterateBody(this, object_size, v); 1704 JSObject::BodyDescriptor::IterateBody(this, object_size, v);
1703 break; 1705 break;
1704 case JS_FUNCTION_TYPE: 1706 case JS_FUNCTION_TYPE:
(...skipping 14030 matching lines...) Expand 10 before | Expand all | Expand 10 after
15735 } 15737 }
15736 15738
15737 15739
15738 void WeakHashTable::AddEntry(int entry, Object* key, Object* value) { 15740 void WeakHashTable::AddEntry(int entry, Object* key, Object* value) {
15739 set(EntryToIndex(entry), key); 15741 set(EntryToIndex(entry), key);
15740 set(EntryToValueIndex(entry), value); 15742 set(EntryToValueIndex(entry), value);
15741 ElementAdded(); 15743 ElementAdded();
15742 } 15744 }
15743 15745
15744 15746
15745 template<class Derived, int entrysize> 15747 template<class Derived, class Iterator, int entrysize>
15746 Handle<Derived> OrderedHashTable<Derived, entrysize>::Allocate( 15748 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Allocate(
15747 Isolate* isolate, int capacity, PretenureFlag pretenure) { 15749 Isolate* isolate, int capacity, PretenureFlag pretenure) {
15748 // Capacity must be a power of two, since we depend on being able 15750 // Capacity must be a power of two, since we depend on being able
15749 // to divide and multiple by 2 (kLoadFactor) to derive capacity 15751 // to divide and multiple by 2 (kLoadFactor) to derive capacity
15750 // from number of buckets. If we decide to change kLoadFactor 15752 // from number of buckets. If we decide to change kLoadFactor
15751 // to something other than 2, capacity should be stored as another 15753 // to something other than 2, capacity should be stored as another
15752 // field of this object. 15754 // field of this object.
15753 const int kMinCapacity = 4; 15755 const int kMinCapacity = 4;
15754 capacity = RoundUpToPowerOf2(Max(kMinCapacity, capacity)); 15756 capacity = RoundUpToPowerOf2(Max(kMinCapacity, capacity));
15755 if (capacity > kMaxCapacity) { 15757 if (capacity > kMaxCapacity) {
15756 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); 15758 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true);
15757 } 15759 }
15758 int num_buckets = capacity / kLoadFactor; 15760 int num_buckets = capacity / kLoadFactor;
15759 Handle<FixedArray> backing_store = isolate->factory()->NewFixedArray( 15761 Handle<FixedArray> backing_store = isolate->factory()->NewFixedArray(
15760 kHashTableStartIndex + num_buckets + (capacity * kEntrySize), pretenure); 15762 kHashTableStartIndex + num_buckets + (capacity * kEntrySize), pretenure);
15761 backing_store->set_map_no_write_barrier( 15763 backing_store->set_map_no_write_barrier(
15762 isolate->heap()->ordered_hash_table_map()); 15764 isolate->heap()->ordered_hash_table_map());
15763 Handle<Derived> table = Handle<Derived>::cast(backing_store); 15765 Handle<Derived> table = Handle<Derived>::cast(backing_store);
15764 for (int i = 0; i < num_buckets; ++i) { 15766 for (int i = 0; i < num_buckets; ++i) {
15765 table->set(kHashTableStartIndex + i, Smi::FromInt(kNotFound)); 15767 table->set(kHashTableStartIndex + i, Smi::FromInt(kNotFound));
15766 } 15768 }
15767 table->SetNumberOfBuckets(num_buckets); 15769 table->SetNumberOfBuckets(num_buckets);
15768 table->SetNumberOfElements(0); 15770 table->SetNumberOfElements(0);
15769 table->SetNumberOfDeletedElements(0); 15771 table->SetNumberOfDeletedElements(0);
15772 table->set_iterators(table->GetHeap()->undefined_value());
adamk 2014/04/14 19:15:42 Nit: s/table->GetHeap()/isolate->heap()/ (as above
arv (Not doing code reviews) 2014/04/14 19:51:49 Done.
15770 return table; 15773 return table;
15771 } 15774 }
15772 15775
15773 15776
15774 template<class Derived, int entrysize> 15777 template<class Derived, class Iterator, int entrysize>
15775 Handle<Derived> OrderedHashTable<Derived, entrysize>::EnsureGrowable( 15778 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::EnsureGrowable(
15776 Handle<Derived> table) { 15779 Handle<Derived> table) {
15777 int nof = table->NumberOfElements(); 15780 int nof = table->NumberOfElements();
15778 int nod = table->NumberOfDeletedElements(); 15781 int nod = table->NumberOfDeletedElements();
15779 int capacity = table->Capacity(); 15782 int capacity = table->Capacity();
15780 if ((nof + nod) < capacity) return table; 15783 if ((nof + nod) < capacity) return table;
15781 // Don't need to grow if we can simply clear out deleted entries instead. 15784 // Don't need to grow if we can simply clear out deleted entries instead.
15782 // Note that we can't compact in place, though, so we always allocate 15785 // Note that we can't compact in place, though, so we always allocate
15783 // a new table. 15786 // a new table.
15784 return Rehash(table, (nod < (capacity >> 1)) ? capacity << 1 : capacity); 15787 return Rehash(table, (nod < (capacity >> 1)) ? capacity << 1 : capacity);
15785 } 15788 }
15786 15789
15787 15790
15788 template<class Derived, int entrysize> 15791 template<class Derived, class Iterator, int entrysize>
15789 Handle<Derived> OrderedHashTable<Derived, entrysize>::Shrink( 15792 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Shrink(
15790 Handle<Derived> table) { 15793 Handle<Derived> table) {
15791 int nof = table->NumberOfElements(); 15794 int nof = table->NumberOfElements();
15792 int capacity = table->Capacity(); 15795 int capacity = table->Capacity();
15793 if (nof > (capacity >> 2)) return table; 15796 if (nof > (capacity >> 2)) return table;
15794 return Rehash(table, capacity / 2); 15797 return Rehash(table, capacity / 2);
15795 } 15798 }
15796 15799
15797 15800
15798 template<class Derived, int entrysize> 15801 template<class Derived, class Iterator, int entrysize>
15799 Handle<Derived> OrderedHashTable<Derived, entrysize>::Rehash( 15802 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Clear(
15803 Handle<Derived> table) {
15804 int new_capacity = 4;
adamk 2014/04/14 19:15:42 This magic number probably means kMinCapacity in A
arv (Not doing code reviews) 2014/04/14 19:51:49 Done.
15805 Handle<Derived> new_table =
15806 Allocate(table->GetIsolate(),
15807 new_capacity,
15808 table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED);
15809
15810 for (Object* object = table->iterators();
adamk 2014/04/14 19:15:42 Putting a DisallowHeapAllocation above this loop w
arv (Not doing code reviews) 2014/04/14 19:51:49 Done.
15811 !object->IsUndefined();
15812 object = Iterator::cast(object)->next_iterator()) {
15813 Iterator::cast(object)->TableCleared();
15814 Iterator::cast(object)->set_table(*new_table);
15815 }
15816
15817 new_table->set_iterators(table->iterators());
15818 table->set_iterators(table->GetHeap()->undefined_value());
15819
15820 return new_table;
15821 }
15822
15823
15824 template<class Derived, class Iterator, int entrysize>
15825 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash(
15800 Handle<Derived> table, int new_capacity) { 15826 Handle<Derived> table, int new_capacity) {
15801 Handle<Derived> new_table = 15827 Handle<Derived> new_table =
15802 Allocate(table->GetIsolate(), 15828 Allocate(table->GetIsolate(),
15803 new_capacity, 15829 new_capacity,
15804 table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED); 15830 table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED);
15805 int nof = table->NumberOfElements(); 15831 int nof = table->NumberOfElements();
15806 int nod = table->NumberOfDeletedElements(); 15832 int nod = table->NumberOfDeletedElements();
15807 int new_buckets = new_table->NumberOfBuckets(); 15833 int new_buckets = new_table->NumberOfBuckets();
15808 int new_entry = 0; 15834 int new_entry = 0;
15809 for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) { 15835 for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) {
15810 Object* key = table->KeyAt(old_entry); 15836 Object* key = table->KeyAt(old_entry);
15811 if (key->IsTheHole()) continue; 15837 if (key->IsTheHole()) continue;
15812 Object* hash = key->GetHash(); 15838 Object* hash = key->GetHash();
15813 int bucket = Smi::cast(hash)->value() & (new_buckets - 1); 15839 int bucket = Smi::cast(hash)->value() & (new_buckets - 1);
15814 Object* chain_entry = new_table->get(kHashTableStartIndex + bucket); 15840 Object* chain_entry = new_table->get(kHashTableStartIndex + bucket);
15815 new_table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry)); 15841 new_table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry));
15816 int new_index = new_table->EntryToIndex(new_entry); 15842 int new_index = new_table->EntryToIndex(new_entry);
15817 int old_index = table->EntryToIndex(old_entry); 15843 int old_index = table->EntryToIndex(old_entry);
15818 for (int i = 0; i < entrysize; ++i) { 15844 for (int i = 0; i < entrysize; ++i) {
15819 Object* value = table->get(old_index + i); 15845 Object* value = table->get(old_index + i);
15820 new_table->set(new_index + i, value); 15846 new_table->set(new_index + i, value);
15821 } 15847 }
15822 new_table->set(new_index + kChainOffset, chain_entry); 15848 new_table->set(new_index + kChainOffset, chain_entry);
15823 ++new_entry; 15849 ++new_entry;
15824 } 15850 }
15825 new_table->SetNumberOfElements(nof); 15851 new_table->SetNumberOfElements(nof);
15852 new_table->set_iterators(table->iterators());
15853
15854 for (Object* object = table->iterators();
adamk 2014/04/14 19:15:42 Same as above, DisallowHeapAllocation
arv (Not doing code reviews) 2014/04/14 19:51:49 Done.
15855 !object->IsUndefined();
15856 object = Iterator::cast(object)->next_iterator()) {
15857 Iterator::cast(object)->TableCompacted();
15858 Iterator::cast(object)->set_table(*new_table);
15859 }
15860
15826 return new_table; 15861 return new_table;
15827 } 15862 }
15828 15863
15829 15864
15830 template<class Derived, int entrysize> 15865 template<class Derived, class Iterator, int entrysize>
15831 int OrderedHashTable<Derived, entrysize>::FindEntry(Object* key) { 15866 int OrderedHashTable<Derived, Iterator, entrysize>::FindEntry(Object* key) {
15832 ASSERT(!key->IsTheHole()); 15867 ASSERT(!key->IsTheHole());
15833 Object* hash = key->GetHash(); 15868 Object* hash = key->GetHash();
15834 if (hash->IsUndefined()) return kNotFound; 15869 if (hash->IsUndefined()) return kNotFound;
15835 for (int entry = HashToEntry(Smi::cast(hash)->value()); 15870 for (int entry = HashToEntry(Smi::cast(hash)->value());
15836 entry != kNotFound; 15871 entry != kNotFound;
15837 entry = ChainAt(entry)) { 15872 entry = ChainAt(entry)) {
15838 Object* candidate = KeyAt(entry); 15873 Object* candidate = KeyAt(entry);
15839 if (candidate->SameValue(key)) 15874 if (candidate->SameValue(key))
15840 return entry; 15875 return entry;
15841 } 15876 }
15842 return kNotFound; 15877 return kNotFound;
15843 } 15878 }
15844 15879
15845 15880
15846 template<class Derived, int entrysize> 15881 template<class Derived, class Iterator, int entrysize>
15847 int OrderedHashTable<Derived, entrysize>::AddEntry(int hash) { 15882 int OrderedHashTable<Derived, Iterator, entrysize>::AddEntry(int hash) {
15848 int entry = NumberOfElements() + NumberOfDeletedElements(); 15883 int entry = NumberOfElements() + NumberOfDeletedElements();
15849 int bucket = HashToBucket(hash); 15884 int bucket = HashToBucket(hash);
15850 int index = EntryToIndex(entry); 15885 int index = EntryToIndex(entry);
15851 Object* chain_entry = get(kHashTableStartIndex + bucket); 15886 Object* chain_entry = get(kHashTableStartIndex + bucket);
15852 set(kHashTableStartIndex + bucket, Smi::FromInt(entry)); 15887 set(kHashTableStartIndex + bucket, Smi::FromInt(entry));
15853 set(index + kChainOffset, chain_entry); 15888 set(index + kChainOffset, chain_entry);
15854 SetNumberOfElements(NumberOfElements() + 1); 15889 SetNumberOfElements(NumberOfElements() + 1);
15855 return index; 15890 return index;
15856 } 15891 }
15857 15892
15858 15893
15859 template<class Derived, int entrysize> 15894 template<class Derived, class Iterator, int entrysize>
15860 void OrderedHashTable<Derived, entrysize>::RemoveEntry(int entry) { 15895 void OrderedHashTable<Derived, Iterator, entrysize>::RemoveEntry(int entry) {
15861 int index = EntryToIndex(entry); 15896 int index = EntryToIndex(entry);
15862 for (int i = 0; i < entrysize; ++i) { 15897 for (int i = 0; i < entrysize; ++i) {
15863 set_the_hole(index + i); 15898 set_the_hole(index + i);
15864 } 15899 }
15865 SetNumberOfElements(NumberOfElements() - 1); 15900 SetNumberOfElements(NumberOfElements() - 1);
15866 SetNumberOfDeletedElements(NumberOfDeletedElements() + 1); 15901 SetNumberOfDeletedElements(NumberOfDeletedElements() + 1);
15902
15903 for (Object* object = iterators();
adamk 2014/04/14 19:15:42 And one more DisallowHeapAllocation.
arv (Not doing code reviews) 2014/04/14 19:51:49 Done.
15904 !object->IsUndefined();
15905 object = Iterator::cast(object)->next_iterator()) {
15906 Iterator::cast(object)->EntryRemoved(entry);
15907 }
15867 } 15908 }
15868 15909
15869 15910
15870 template class OrderedHashTable<OrderedHashSet, 1>; 15911 template<class Derived, class Iterator, int entrysize>
15871 template class OrderedHashTable<OrderedHashMap, 2>; 15912 Handle<Iterator> OrderedHashTable<
15913 Derived, Iterator, entrysize>::CreateIterator(int kind) {
15914 Handle<Iterator> new_iterator = Iterator::Create(GetIsolate());
15915 new_iterator->set_previous_iterator(GetHeap()->undefined_value());
15916 new_iterator->set_table(this);
adamk 2014/04/14 19:15:42 You triggered an allocation above, but are referri
15917 new_iterator->set_index(Smi::FromInt(0));
15918 new_iterator->set_count(Smi::FromInt(0));
15919 new_iterator->set_kind(Smi::FromInt(kind));
15920
15921 Object* old_iterator = iterators();
15922 if (!old_iterator->IsUndefined()) {
15923 Iterator::cast(old_iterator)->set_previous_iterator(*new_iterator);
15924 new_iterator->set_next_iterator(old_iterator);
15925 } else {
15926 new_iterator->set_next_iterator(GetHeap()->undefined_value());
adamk 2014/04/14 19:15:42 Nit: whitespace off here (extra space)
arv (Not doing code reviews) 2014/04/14 19:51:49 Done.
15927 }
15928
15929 set_iterators(*new_iterator);
15930
15931 return new_iterator;
15932 }
15933
15934
15935 template class OrderedHashTable<OrderedHashSet, JSSetIterator, 1>;
15936 template class OrderedHashTable<OrderedHashMap, JSMapIterator, 2>;
15872 15937
15873 15938
15874 bool OrderedHashSet::Contains(Object* key) { 15939 bool OrderedHashSet::Contains(Object* key) {
15875 return FindEntry(key) != kNotFound; 15940 return FindEntry(key) != kNotFound;
15876 } 15941 }
15877 15942
15878 15943
15879 Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table, 15944 Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table,
15880 Handle<Object> key) { 15945 Handle<Object> key) {
15881 if (table->FindEntry(*key) != kNotFound) return table; 15946 if (table->FindEntry(*key) != kNotFound) return table;
15882 15947
15883 table = EnsureGrowable(table); 15948 table = EnsureGrowable(table);
15884 15949
15885 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate()); 15950 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate());
15886 int index = table->AddEntry(Smi::cast(*hash)->value()); 15951 int index = table->AddEntry(Smi::cast(*hash)->value());
15887 table->set(index, *key); 15952 table->set(index, *key);
15888 return table; 15953 return table;
15889 } 15954 }
15890 15955
15891 15956
15892 Handle<OrderedHashSet> OrderedHashSet::Remove(Handle<OrderedHashSet> table, 15957 Handle<OrderedHashSet> OrderedHashSet::Remove(Handle<OrderedHashSet> table,
15893 Handle<Object> key) { 15958 Handle<Object> key) {
15894 int entry = table->FindEntry(*key); 15959 int entry = table->FindEntry(*key);
15895 if (entry == kNotFound) return table; 15960 if (entry == kNotFound) return table;
15896 table->RemoveEntry(entry); 15961 table->RemoveEntry(entry);
15897 // TODO(adamk): Don't shrink if we're being iterated over
15898 return Shrink(table); 15962 return Shrink(table);
15899 } 15963 }
15900 15964
15901 15965
15902 Object* OrderedHashMap::Lookup(Object* key) { 15966 Object* OrderedHashMap::Lookup(Object* key) {
15903 int entry = FindEntry(key); 15967 int entry = FindEntry(key);
15904 if (entry == kNotFound) return GetHeap()->the_hole_value(); 15968 if (entry == kNotFound) return GetHeap()->the_hole_value();
15905 return ValueAt(entry); 15969 return ValueAt(entry);
15906 } 15970 }
15907 15971
15908 15972
15909 Handle<OrderedHashMap> OrderedHashMap::Put(Handle<OrderedHashMap> table, 15973 Handle<OrderedHashMap> OrderedHashMap::Put(Handle<OrderedHashMap> table,
15910 Handle<Object> key, 15974 Handle<Object> key,
15911 Handle<Object> value) { 15975 Handle<Object> value) {
15912 int entry = table->FindEntry(*key); 15976 int entry = table->FindEntry(*key);
15913 15977
15914 if (value->IsTheHole()) { 15978 if (value->IsTheHole()) {
15915 if (entry == kNotFound) return table; 15979 if (entry == kNotFound) return table;
15916 table->RemoveEntry(entry); 15980 table->RemoveEntry(entry);
15917 // TODO(adamk): Only shrink if not iterating
15918 return Shrink(table); 15981 return Shrink(table);
15919 } 15982 }
15920 15983
15921 if (entry != kNotFound) { 15984 if (entry != kNotFound) {
15922 table->set(table->EntryToIndex(entry) + kValueOffset, *value); 15985 table->set(table->EntryToIndex(entry) + kValueOffset, *value);
15923 return table; 15986 return table;
15924 } 15987 }
15925 15988
15926 table = EnsureGrowable(table); 15989 table = EnsureGrowable(table);
15927 15990
15928 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate()); 15991 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate());
15929 int index = table->AddEntry(Smi::cast(*hash)->value()); 15992 int index = table->AddEntry(Smi::cast(*hash)->value());
15930 table->set(index, *key); 15993 table->set(index, *key);
15931 table->set(index + kValueOffset, *value); 15994 table->set(index + kValueOffset, *value);
15932 return table; 15995 return table;
15933 } 15996 }
15934 15997
15935 15998
15999 template<class Derived, class TableType>
16000 void OrderedHashTableIterator<Derived, TableType>::EntryRemoved(int index) {
16001 int i = this->index()->value();
16002 if (index < i) {
16003 set_count(Smi::FromInt(count()->value() - 1));
16004 }
16005 if (index == i) {
16006 Seek();
16007 }
16008 }
16009
16010
16011 template<class Derived, class TableType>
16012 void OrderedHashTableIterator<Derived, TableType>::Close() {
16013 if (Closed()) return;
16014
16015 TableType* table = TableType::cast(this->table());
16016 Object* previous = previous_iterator();
16017 Object* next = next_iterator();
16018
16019 if (previous->IsUndefined()) {
16020 ASSERT_EQ(table->iterators(), this);
16021 table->set_iterators(next);
16022 } else {
16023 ASSERT_EQ(Derived::cast(previous)->next_iterator(), this);
16024 Derived::cast(previous)->set_next_iterator(next);
16025 }
16026
16027 if (!next->IsUndefined()) {
16028 ASSERT_EQ(Derived::cast(next)->previous_iterator(), this);
16029 Derived::cast(next)->set_previous_iterator(previous);
16030 }
16031
16032 set_previous_iterator(GetHeap()->undefined_value());
16033 set_next_iterator(GetHeap()->undefined_value());
16034 set_table(GetHeap()->undefined_value());
16035 }
16036
16037
16038 template<class Derived, class TableType>
16039 void OrderedHashTableIterator<Derived, TableType>::Seek() {
16040 ASSERT(!Closed());
16041
16042 int index = this->index()->value();
16043
16044 TableType* table = TableType::cast(this->table());
16045 int element_count =
16046 table->NumberOfElements() + table->NumberOfDeletedElements();
adamk 2014/04/14 19:15:42 I see this a lot, maybe OrderedHashTable should ex
arv (Not doing code reviews) 2014/04/14 19:51:49 Any suggestion for a name?
adamk 2014/04/14 21:25:54 FilledCapacity()? UsedCapacity()?
16047
16048 while (index < element_count && table->KeyAt(index)->IsTheHole()) {
16049 index++;
16050 }
16051 set_index(Smi::FromInt(index));
16052 }
16053
16054
16055 template<class Derived, class TableType>
16056 void OrderedHashTableIterator<Derived, TableType>::MoveNext() {
16057 ASSERT(!Closed());
16058
16059 int index = this->index()->value() + 1;
16060 int count = this->count()->value() + 1;
16061 set_index(Smi::FromInt(index));
16062 set_count(Smi::FromInt(count));
16063 Seek();
16064
16065 TableType* table = TableType::cast(this->table());
16066 int element_count =
16067 table->NumberOfElements() + table->NumberOfDeletedElements();
16068
16069 if (index >= element_count) {
16070 Close();
16071 }
16072 }
16073
16074
16075 template<class Derived, class TableType>
16076 Handle<JSObject> OrderedHashTableIterator<Derived, TableType>::Next() {
16077 Isolate* isolate = GetIsolate();
16078 Factory* factory = isolate->factory();
16079
16080 Object* object = this->table();
16081
16082 if (!object->IsUndefined()) {
16083 TableType* table = TableType::cast(object);
16084 int index = this->index()->value();
16085 if (index < table->NumberOfElements() + table->NumberOfDeletedElements()) {
16086 int entry_index = table->EntryToIndex(index);
16087 Handle<Object> value =
16088 static_cast<Derived*>(this)->ValueForKind(entry_index);
16089 MoveNext();
16090 return factory->CreateIteratorResultObject(value, false);
adamk 2014/04/14 19:15:42 Method should be static since it does allocation.
adamk 2014/04/14 19:15:42 I notice you pass false here unconditionally, even
arv (Not doing code reviews) 2014/04/14 19:51:49 I think you are right. I'll review the spec and ad
arv (Not doing code reviews) 2014/04/14 21:41:56 Done.
16091 }
16092 }
16093
16094 return factory->CreateIteratorResultObject(factory->undefined_value(), true);
16095 }
16096
16097
16098 template class OrderedHashTableIterator<JSSetIterator, OrderedHashSet>;
16099 template class OrderedHashTableIterator<JSMapIterator, OrderedHashMap>;
16100
16101
16102 Handle<JSSetIterator> JSSetIterator::Create(Isolate* isolate) {
16103 Handle<Map> map =
16104 isolate->factory()->NewMap(JS_SET_ITERATOR_TYPE, JSSetIterator::kSize);
16105 return
16106 Handle<JSSetIterator>::cast(isolate->factory()->NewJSObjectFromMap(map));
16107 }
16108
16109
16110 Handle<Object> JSSetIterator::ValueForKind(int entry_index) {
16111 int kind = this->kind()->value();
16112 ASSERT(kind == kKindValues || kind == kKindEntries);
adamk 2014/04/14 19:15:42 I suppose it's arbitrary, but I was surprised at t
arv (Not doing code reviews) 2014/04/14 19:51:49 This follows from the spec. Set.prototype has valu
16113
16114 Isolate* isolate = GetIsolate();
16115 Factory* factory = isolate->factory();
16116 OrderedHashSet* table = OrderedHashSet::cast(this->table());
16117
16118 Handle<Object> value = Handle<Object>(table->get(entry_index), isolate);
16119
16120 if (kind == kKindEntries) {
16121 Handle<FixedArray> array = factory->NewFixedArray(2);
adamk 2014/04/14 19:15:42 This method should be static since it does allocat
arv (Not doing code reviews) 2014/04/14 21:41:56 Done.
16122 array->set(0, *value);
16123 array->set(1, *value);
16124 return factory->NewJSArrayWithElements(array);
16125 }
16126
16127 return value;
16128 }
16129
16130
16131 Handle<JSMapIterator> JSMapIterator::Create(Isolate* isolate) {
16132 Handle<Map> map =
16133 isolate->factory()->NewMap(JS_MAP_ITERATOR_TYPE, JSMapIterator::kSize);
16134 return Handle<JSMapIterator>::cast(
16135 isolate->factory()->NewJSObjectFromMap(map));
16136 }
16137
16138
16139 Handle<Object> JSMapIterator::ValueForKind(int entry_index) {
16140 int kind = this->kind()->value();
16141 ASSERT(kind == kKindKeys || kind == kKindValues || kind == kKindEntries);
16142
16143 Isolate* isolate = GetIsolate();
16144 Factory* factory = isolate->factory();
16145 OrderedHashMap* table = OrderedHashMap::cast(this->table());
16146
16147 switch (kind) {
16148 case kKindKeys:
16149 return Handle<Object>(table->get(entry_index), isolate);
16150
16151 case kKindValues:
16152 return Handle<Object>(table->get(entry_index + 1), isolate);
16153
16154 case kKindEntries: {
16155 Object* key = table->get(entry_index);
16156 Object* value = table->get(entry_index + 1);
16157 Handle<FixedArray> array = factory->NewFixedArray(2);
16158 array->set(0, key);
16159 array->set(1, value);
16160 return factory->NewJSArrayWithElements(array);
adamk 2014/04/14 19:15:42 Same as above, should be static.
arv (Not doing code reviews) 2014/04/14 21:41:56 Done.
16161 }
16162 }
16163
16164 UNREACHABLE();
16165 return factory->undefined_value();
16166 }
16167
16168
15936 DeclaredAccessorDescriptorIterator::DeclaredAccessorDescriptorIterator( 16169 DeclaredAccessorDescriptorIterator::DeclaredAccessorDescriptorIterator(
15937 DeclaredAccessorDescriptor* descriptor) 16170 DeclaredAccessorDescriptor* descriptor)
15938 : array_(descriptor->serialized_data()->GetDataStartAddress()), 16171 : array_(descriptor->serialized_data()->GetDataStartAddress()),
15939 length_(descriptor->serialized_data()->length()), 16172 length_(descriptor->serialized_data()->length()),
15940 offset_(0) { 16173 offset_(0) {
15941 } 16174 }
15942 16175
15943 16176
15944 const DeclaredAccessorDescriptorData* 16177 const DeclaredAccessorDescriptorData*
15945 DeclaredAccessorDescriptorIterator::Next() { 16178 DeclaredAccessorDescriptorIterator::Next() {
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after
16517 #define ERROR_MESSAGES_TEXTS(C, T) T, 16750 #define ERROR_MESSAGES_TEXTS(C, T) T,
16518 static const char* error_messages_[] = { 16751 static const char* error_messages_[] = {
16519 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16752 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16520 }; 16753 };
16521 #undef ERROR_MESSAGES_TEXTS 16754 #undef ERROR_MESSAGES_TEXTS
16522 return error_messages_[reason]; 16755 return error_messages_[reason];
16523 } 16756 }
16524 16757
16525 16758
16526 } } // namespace v8::internal 16759 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698