OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |