Chromium Code Reviews| 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; | |
| 15754 capacity = RoundUpToPowerOf2(Max(kMinCapacity, capacity)); | 15755 capacity = RoundUpToPowerOf2(Max(kMinCapacity, capacity)); |
| 15755 if (capacity > kMaxCapacity) { | 15756 if (capacity > kMaxCapacity) { |
| 15756 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); | 15757 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); |
| 15757 } | 15758 } |
| 15758 int num_buckets = capacity / kLoadFactor; | 15759 int num_buckets = capacity / kLoadFactor; |
| 15759 Handle<FixedArray> backing_store = isolate->factory()->NewFixedArray( | 15760 Handle<FixedArray> backing_store = isolate->factory()->NewFixedArray( |
| 15760 kHashTableStartIndex + num_buckets + (capacity * kEntrySize), pretenure); | 15761 kHashTableStartIndex + num_buckets + (capacity * kEntrySize), pretenure); |
| 15761 backing_store->set_map_no_write_barrier( | 15762 backing_store->set_map_no_write_barrier( |
| 15762 isolate->heap()->ordered_hash_table_map()); | 15763 isolate->heap()->ordered_hash_table_map()); |
| 15763 Handle<Derived> table = Handle<Derived>::cast(backing_store); | 15764 Handle<Derived> table = Handle<Derived>::cast(backing_store); |
| 15764 for (int i = 0; i < num_buckets; ++i) { | 15765 for (int i = 0; i < num_buckets; ++i) { |
| 15765 table->set(kHashTableStartIndex + i, Smi::FromInt(kNotFound)); | 15766 table->set(kHashTableStartIndex + i, Smi::FromInt(kNotFound)); |
| 15766 } | 15767 } |
| 15767 table->SetNumberOfBuckets(num_buckets); | 15768 table->SetNumberOfBuckets(num_buckets); |
| 15768 table->SetNumberOfElements(0); | 15769 table->SetNumberOfElements(0); |
| 15769 table->SetNumberOfDeletedElements(0); | 15770 table->SetNumberOfDeletedElements(0); |
| 15771 table->set_iterators(isolate->heap()->undefined_value()); | |
| 15770 return table; | 15772 return table; |
| 15771 } | 15773 } |
| 15772 | 15774 |
| 15773 | 15775 |
| 15774 template<class Derived, int entrysize> | 15776 template<class Derived, class Iterator, int entrysize> |
| 15775 Handle<Derived> OrderedHashTable<Derived, entrysize>::EnsureGrowable( | 15777 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::EnsureGrowable( |
| 15776 Handle<Derived> table) { | 15778 Handle<Derived> table) { |
| 15777 int nof = table->NumberOfElements(); | 15779 int nof = table->NumberOfElements(); |
| 15778 int nod = table->NumberOfDeletedElements(); | 15780 int nod = table->NumberOfDeletedElements(); |
| 15779 int capacity = table->Capacity(); | 15781 int capacity = table->Capacity(); |
| 15780 if ((nof + nod) < capacity) return table; | 15782 if ((nof + nod) < capacity) return table; |
| 15781 // Don't need to grow if we can simply clear out deleted entries instead. | 15783 // 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 | 15784 // Note that we can't compact in place, though, so we always allocate |
| 15783 // a new table. | 15785 // a new table. |
| 15784 return Rehash(table, (nod < (capacity >> 1)) ? capacity << 1 : capacity); | 15786 return Rehash(table, (nod < (capacity >> 1)) ? capacity << 1 : capacity); |
| 15785 } | 15787 } |
| 15786 | 15788 |
| 15787 | 15789 |
| 15788 template<class Derived, int entrysize> | 15790 template<class Derived, class Iterator, int entrysize> |
| 15789 Handle<Derived> OrderedHashTable<Derived, entrysize>::Shrink( | 15791 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Shrink( |
| 15790 Handle<Derived> table) { | 15792 Handle<Derived> table) { |
| 15791 int nof = table->NumberOfElements(); | 15793 int nof = table->NumberOfElements(); |
| 15792 int capacity = table->Capacity(); | 15794 int capacity = table->Capacity(); |
| 15793 if (nof > (capacity >> 2)) return table; | 15795 if (nof > (capacity >> 2)) return table; |
| 15794 return Rehash(table, capacity / 2); | 15796 return Rehash(table, capacity / 2); |
| 15795 } | 15797 } |
| 15796 | 15798 |
| 15797 | 15799 |
| 15798 template<class Derived, int entrysize> | 15800 template<class Derived, class Iterator, int entrysize> |
| 15799 Handle<Derived> OrderedHashTable<Derived, entrysize>::Rehash( | 15801 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Clear( |
| 15802 Handle<Derived> table) { | |
| 15803 Handle<Derived> new_table = | |
| 15804 Allocate(table->GetIsolate(), | |
| 15805 kMinCapacity, | |
| 15806 table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED); | |
| 15807 | |
| 15808 new_table->set_iterators(table->iterators()); | |
| 15809 table->set_iterators(table->GetHeap()->undefined_value()); | |
| 15810 | |
| 15811 DisallowHeapAllocation no_allocation; | |
| 15812 for (Object* object = new_table->iterators(); | |
| 15813 !object->IsUndefined(); | |
| 15814 object = Iterator::cast(object)->next_iterator()) { | |
| 15815 Iterator::cast(object)->TableCleared(); | |
| 15816 Iterator::cast(object)->set_table(*new_table); | |
| 15817 } | |
| 15818 | |
| 15819 return new_table; | |
| 15820 } | |
| 15821 | |
| 15822 | |
| 15823 template<class Derived, class Iterator, int entrysize> | |
| 15824 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash( | |
| 15800 Handle<Derived> table, int new_capacity) { | 15825 Handle<Derived> table, int new_capacity) { |
| 15801 Handle<Derived> new_table = | 15826 Handle<Derived> new_table = |
| 15802 Allocate(table->GetIsolate(), | 15827 Allocate(table->GetIsolate(), |
| 15803 new_capacity, | 15828 new_capacity, |
| 15804 table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED); | 15829 table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED); |
| 15805 int nof = table->NumberOfElements(); | 15830 int nof = table->NumberOfElements(); |
| 15806 int nod = table->NumberOfDeletedElements(); | 15831 int nod = table->NumberOfDeletedElements(); |
| 15807 int new_buckets = new_table->NumberOfBuckets(); | 15832 int new_buckets = new_table->NumberOfBuckets(); |
| 15808 int new_entry = 0; | 15833 int new_entry = 0; |
| 15809 for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) { | 15834 for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) { |
| 15810 Object* key = table->KeyAt(old_entry); | 15835 Object* key = table->KeyAt(old_entry); |
| 15811 if (key->IsTheHole()) continue; | 15836 if (key->IsTheHole()) continue; |
| 15812 Object* hash = key->GetHash(); | 15837 Object* hash = key->GetHash(); |
| 15813 int bucket = Smi::cast(hash)->value() & (new_buckets - 1); | 15838 int bucket = Smi::cast(hash)->value() & (new_buckets - 1); |
| 15814 Object* chain_entry = new_table->get(kHashTableStartIndex + bucket); | 15839 Object* chain_entry = new_table->get(kHashTableStartIndex + bucket); |
| 15815 new_table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry)); | 15840 new_table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry)); |
| 15816 int new_index = new_table->EntryToIndex(new_entry); | 15841 int new_index = new_table->EntryToIndex(new_entry); |
| 15817 int old_index = table->EntryToIndex(old_entry); | 15842 int old_index = table->EntryToIndex(old_entry); |
| 15818 for (int i = 0; i < entrysize; ++i) { | 15843 for (int i = 0; i < entrysize; ++i) { |
| 15819 Object* value = table->get(old_index + i); | 15844 Object* value = table->get(old_index + i); |
| 15820 new_table->set(new_index + i, value); | 15845 new_table->set(new_index + i, value); |
| 15821 } | 15846 } |
| 15822 new_table->set(new_index + kChainOffset, chain_entry); | 15847 new_table->set(new_index + kChainOffset, chain_entry); |
| 15823 ++new_entry; | 15848 ++new_entry; |
| 15824 } | 15849 } |
| 15825 new_table->SetNumberOfElements(nof); | 15850 new_table->SetNumberOfElements(nof); |
| 15851 | |
| 15852 new_table->set_iterators(table->iterators()); | |
| 15853 table->set_iterators(table->GetHeap()->undefined_value()); | |
| 15854 | |
| 15855 DisallowHeapAllocation no_allocation; | |
| 15856 for (Object* object = new_table->iterators(); | |
| 15857 !object->IsUndefined(); | |
| 15858 object = Iterator::cast(object)->next_iterator()) { | |
| 15859 Iterator::cast(object)->TableCompacted(); | |
| 15860 Iterator::cast(object)->set_table(*new_table); | |
| 15861 } | |
| 15862 | |
| 15826 return new_table; | 15863 return new_table; |
| 15827 } | 15864 } |
| 15828 | 15865 |
| 15829 | 15866 |
| 15830 template<class Derived, int entrysize> | 15867 template<class Derived, class Iterator, int entrysize> |
| 15831 int OrderedHashTable<Derived, entrysize>::FindEntry(Object* key) { | 15868 int OrderedHashTable<Derived, Iterator, entrysize>::FindEntry(Object* key) { |
| 15832 ASSERT(!key->IsTheHole()); | 15869 ASSERT(!key->IsTheHole()); |
| 15833 Object* hash = key->GetHash(); | 15870 Object* hash = key->GetHash(); |
| 15834 if (hash->IsUndefined()) return kNotFound; | 15871 if (hash->IsUndefined()) return kNotFound; |
| 15835 for (int entry = HashToEntry(Smi::cast(hash)->value()); | 15872 for (int entry = HashToEntry(Smi::cast(hash)->value()); |
| 15836 entry != kNotFound; | 15873 entry != kNotFound; |
| 15837 entry = ChainAt(entry)) { | 15874 entry = ChainAt(entry)) { |
| 15838 Object* candidate = KeyAt(entry); | 15875 Object* candidate = KeyAt(entry); |
| 15839 if (candidate->SameValue(key)) | 15876 if (candidate->SameValue(key)) |
| 15840 return entry; | 15877 return entry; |
| 15841 } | 15878 } |
| 15842 return kNotFound; | 15879 return kNotFound; |
| 15843 } | 15880 } |
| 15844 | 15881 |
| 15845 | 15882 |
| 15846 template<class Derived, int entrysize> | 15883 template<class Derived, class Iterator, int entrysize> |
| 15847 int OrderedHashTable<Derived, entrysize>::AddEntry(int hash) { | 15884 int OrderedHashTable<Derived, Iterator, entrysize>::AddEntry(int hash) { |
| 15848 int entry = NumberOfElements() + NumberOfDeletedElements(); | 15885 int entry = NumberOfElements() + NumberOfDeletedElements(); |
| 15849 int bucket = HashToBucket(hash); | 15886 int bucket = HashToBucket(hash); |
| 15850 int index = EntryToIndex(entry); | 15887 int index = EntryToIndex(entry); |
| 15851 Object* chain_entry = get(kHashTableStartIndex + bucket); | 15888 Object* chain_entry = get(kHashTableStartIndex + bucket); |
| 15852 set(kHashTableStartIndex + bucket, Smi::FromInt(entry)); | 15889 set(kHashTableStartIndex + bucket, Smi::FromInt(entry)); |
| 15853 set(index + kChainOffset, chain_entry); | 15890 set(index + kChainOffset, chain_entry); |
| 15854 SetNumberOfElements(NumberOfElements() + 1); | 15891 SetNumberOfElements(NumberOfElements() + 1); |
| 15855 return index; | 15892 return index; |
| 15856 } | 15893 } |
| 15857 | 15894 |
| 15858 | 15895 |
| 15859 template<class Derived, int entrysize> | 15896 template<class Derived, class Iterator, int entrysize> |
| 15860 void OrderedHashTable<Derived, entrysize>::RemoveEntry(int entry) { | 15897 void OrderedHashTable<Derived, Iterator, entrysize>::RemoveEntry(int entry) { |
| 15861 int index = EntryToIndex(entry); | 15898 int index = EntryToIndex(entry); |
| 15862 for (int i = 0; i < entrysize; ++i) { | 15899 for (int i = 0; i < entrysize; ++i) { |
| 15863 set_the_hole(index + i); | 15900 set_the_hole(index + i); |
| 15864 } | 15901 } |
| 15865 SetNumberOfElements(NumberOfElements() - 1); | 15902 SetNumberOfElements(NumberOfElements() - 1); |
| 15866 SetNumberOfDeletedElements(NumberOfDeletedElements() + 1); | 15903 SetNumberOfDeletedElements(NumberOfDeletedElements() + 1); |
| 15904 | |
| 15905 DisallowHeapAllocation no_allocation; | |
| 15906 for (Object* object = iterators(); | |
| 15907 !object->IsUndefined(); | |
| 15908 object = Iterator::cast(object)->next_iterator()) { | |
| 15909 Iterator::cast(object)->EntryRemoved(entry); | |
| 15910 } | |
| 15867 } | 15911 } |
| 15868 | 15912 |
| 15869 | 15913 |
| 15870 template class OrderedHashTable<OrderedHashSet, 1>; | 15914 template<class Derived, class Iterator, int entrysize> |
| 15871 template class OrderedHashTable<OrderedHashMap, 2>; | 15915 Handle<Iterator> OrderedHashTable<Derived, Iterator, entrysize>::CreateIterator( |
| 15916 Handle<Derived> table, | |
| 15917 int kind) { | |
| 15918 Object* undefined = table->GetHeap()->undefined_value(); | |
|
adamk
2014/04/14 21:25:54
Please use a Handle here (available from isolate->
arv (Not doing code reviews)
2014/04/14 22:13:27
Done.
| |
| 15919 Handle<Iterator> new_iterator = Iterator::Create(table->GetIsolate()); | |
| 15920 new_iterator->set_previous_iterator(undefined); | |
| 15921 new_iterator->set_table(*table); | |
| 15922 new_iterator->set_index(Smi::FromInt(0)); | |
| 15923 new_iterator->set_count(Smi::FromInt(0)); | |
| 15924 new_iterator->set_kind(Smi::FromInt(kind)); | |
| 15925 | |
| 15926 Object* old_iterator = table->iterators(); | |
|
adamk
2014/04/14 21:25:54
Style-wise I'd also handl-ify this one (in case mo
arv (Not doing code reviews)
2014/04/14 22:13:27
Done.
| |
| 15927 if (!old_iterator->IsUndefined()) { | |
| 15928 Iterator::cast(old_iterator)->set_previous_iterator(*new_iterator); | |
| 15929 new_iterator->set_next_iterator(old_iterator); | |
| 15930 } else { | |
| 15931 new_iterator->set_next_iterator(undefined); | |
| 15932 } | |
| 15933 | |
| 15934 table->set_iterators(*new_iterator); | |
| 15935 | |
| 15936 return new_iterator; | |
| 15937 } | |
| 15938 | |
| 15939 | |
| 15940 template class OrderedHashTable<OrderedHashSet, JSSetIterator, 1>; | |
| 15941 template class OrderedHashTable<OrderedHashMap, JSMapIterator, 2>; | |
| 15872 | 15942 |
| 15873 | 15943 |
| 15874 bool OrderedHashSet::Contains(Object* key) { | 15944 bool OrderedHashSet::Contains(Object* key) { |
| 15875 return FindEntry(key) != kNotFound; | 15945 return FindEntry(key) != kNotFound; |
| 15876 } | 15946 } |
| 15877 | 15947 |
| 15878 | 15948 |
| 15879 Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table, | 15949 Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table, |
| 15880 Handle<Object> key) { | 15950 Handle<Object> key) { |
| 15881 if (table->FindEntry(*key) != kNotFound) return table; | 15951 if (table->FindEntry(*key) != kNotFound) return table; |
| 15882 | 15952 |
| 15883 table = EnsureGrowable(table); | 15953 table = EnsureGrowable(table); |
| 15884 | 15954 |
| 15885 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate()); | 15955 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate()); |
| 15886 int index = table->AddEntry(Smi::cast(*hash)->value()); | 15956 int index = table->AddEntry(Smi::cast(*hash)->value()); |
| 15887 table->set(index, *key); | 15957 table->set(index, *key); |
| 15888 return table; | 15958 return table; |
| 15889 } | 15959 } |
| 15890 | 15960 |
| 15891 | 15961 |
| 15892 Handle<OrderedHashSet> OrderedHashSet::Remove(Handle<OrderedHashSet> table, | 15962 Handle<OrderedHashSet> OrderedHashSet::Remove(Handle<OrderedHashSet> table, |
| 15893 Handle<Object> key) { | 15963 Handle<Object> key) { |
| 15894 int entry = table->FindEntry(*key); | 15964 int entry = table->FindEntry(*key); |
| 15895 if (entry == kNotFound) return table; | 15965 if (entry == kNotFound) return table; |
| 15896 table->RemoveEntry(entry); | 15966 table->RemoveEntry(entry); |
| 15897 // TODO(adamk): Don't shrink if we're being iterated over | |
| 15898 return Shrink(table); | 15967 return Shrink(table); |
| 15899 } | 15968 } |
| 15900 | 15969 |
| 15901 | 15970 |
| 15902 Object* OrderedHashMap::Lookup(Object* key) { | 15971 Object* OrderedHashMap::Lookup(Object* key) { |
| 15903 int entry = FindEntry(key); | 15972 int entry = FindEntry(key); |
| 15904 if (entry == kNotFound) return GetHeap()->the_hole_value(); | 15973 if (entry == kNotFound) return GetHeap()->the_hole_value(); |
| 15905 return ValueAt(entry); | 15974 return ValueAt(entry); |
| 15906 } | 15975 } |
| 15907 | 15976 |
| 15908 | 15977 |
| 15909 Handle<OrderedHashMap> OrderedHashMap::Put(Handle<OrderedHashMap> table, | 15978 Handle<OrderedHashMap> OrderedHashMap::Put(Handle<OrderedHashMap> table, |
| 15910 Handle<Object> key, | 15979 Handle<Object> key, |
| 15911 Handle<Object> value) { | 15980 Handle<Object> value) { |
| 15912 int entry = table->FindEntry(*key); | 15981 int entry = table->FindEntry(*key); |
| 15913 | 15982 |
| 15914 if (value->IsTheHole()) { | 15983 if (value->IsTheHole()) { |
| 15915 if (entry == kNotFound) return table; | 15984 if (entry == kNotFound) return table; |
| 15916 table->RemoveEntry(entry); | 15985 table->RemoveEntry(entry); |
| 15917 // TODO(adamk): Only shrink if not iterating | |
| 15918 return Shrink(table); | 15986 return Shrink(table); |
| 15919 } | 15987 } |
| 15920 | 15988 |
| 15921 if (entry != kNotFound) { | 15989 if (entry != kNotFound) { |
| 15922 table->set(table->EntryToIndex(entry) + kValueOffset, *value); | 15990 table->set(table->EntryToIndex(entry) + kValueOffset, *value); |
| 15923 return table; | 15991 return table; |
| 15924 } | 15992 } |
| 15925 | 15993 |
| 15926 table = EnsureGrowable(table); | 15994 table = EnsureGrowable(table); |
| 15927 | 15995 |
| 15928 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate()); | 15996 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate()); |
| 15929 int index = table->AddEntry(Smi::cast(*hash)->value()); | 15997 int index = table->AddEntry(Smi::cast(*hash)->value()); |
| 15930 table->set(index, *key); | 15998 table->set(index, *key); |
| 15931 table->set(index + kValueOffset, *value); | 15999 table->set(index + kValueOffset, *value); |
| 15932 return table; | 16000 return table; |
| 15933 } | 16001 } |
| 15934 | 16002 |
| 15935 | 16003 |
| 16004 template<class Derived, class TableType> | |
| 16005 void OrderedHashTableIterator<Derived, TableType>::EntryRemoved(int index) { | |
| 16006 int i = this->index()->value(); | |
| 16007 if (index < i) { | |
| 16008 set_count(Smi::FromInt(count()->value() - 1)); | |
| 16009 } | |
| 16010 if (index == i) { | |
| 16011 Seek(); | |
| 16012 } | |
| 16013 } | |
| 16014 | |
| 16015 | |
| 16016 template<class Derived, class TableType> | |
| 16017 void OrderedHashTableIterator<Derived, TableType>::Close() { | |
| 16018 if (Closed()) return; | |
| 16019 | |
| 16020 TableType* table = TableType::cast(this->table()); | |
| 16021 Object* previous = previous_iterator(); | |
| 16022 Object* next = next_iterator(); | |
| 16023 | |
| 16024 if (previous->IsUndefined()) { | |
| 16025 ASSERT_EQ(table->iterators(), this); | |
| 16026 table->set_iterators(next); | |
| 16027 } else { | |
| 16028 ASSERT_EQ(Derived::cast(previous)->next_iterator(), this); | |
| 16029 Derived::cast(previous)->set_next_iterator(next); | |
| 16030 } | |
| 16031 | |
| 16032 if (!next->IsUndefined()) { | |
| 16033 ASSERT_EQ(Derived::cast(next)->previous_iterator(), this); | |
| 16034 Derived::cast(next)->set_previous_iterator(previous); | |
| 16035 } | |
| 16036 | |
| 16037 set_previous_iterator(GetHeap()->undefined_value()); | |
| 16038 set_next_iterator(GetHeap()->undefined_value()); | |
| 16039 set_table(GetHeap()->undefined_value()); | |
| 16040 } | |
| 16041 | |
| 16042 | |
| 16043 template<class Derived, class TableType> | |
| 16044 void OrderedHashTableIterator<Derived, TableType>::Seek() { | |
| 16045 ASSERT(!Closed()); | |
| 16046 | |
| 16047 int index = this->index()->value(); | |
| 16048 | |
| 16049 TableType* table = TableType::cast(this->table()); | |
| 16050 int element_count = | |
| 16051 table->NumberOfElements() + table->NumberOfDeletedElements(); | |
| 16052 | |
| 16053 while (index < element_count && table->KeyAt(index)->IsTheHole()) { | |
| 16054 index++; | |
| 16055 } | |
| 16056 set_index(Smi::FromInt(index)); | |
| 16057 } | |
| 16058 | |
| 16059 | |
| 16060 template<class Derived, class TableType> | |
| 16061 void OrderedHashTableIterator<Derived, TableType>::MoveNext() { | |
| 16062 ASSERT(!Closed()); | |
| 16063 | |
| 16064 set_index(Smi::FromInt(index()->value() + 1)); | |
| 16065 set_count(Smi::FromInt(count()->value() + 1)); | |
| 16066 Seek(); | |
| 16067 } | |
| 16068 | |
| 16069 | |
| 16070 template<class Derived, class TableType> | |
| 16071 Handle<JSObject> OrderedHashTableIterator<Derived, TableType>::Next( | |
| 16072 Handle<Derived> iterator) { | |
| 16073 Isolate* isolate = iterator->GetIsolate(); | |
| 16074 Factory* factory = isolate->factory(); | |
| 16075 | |
| 16076 Object* object = iterator->table(); | |
|
adamk
2014/04/14 21:25:54
Need to use a Handle here.
arv (Not doing code reviews)
2014/04/14 22:13:27
Done.
| |
| 16077 | |
| 16078 if (!object->IsUndefined()) { | |
| 16079 TableType* table = TableType::cast(object); | |
| 16080 int index = iterator->index()->value(); | |
| 16081 if (index < table->NumberOfElements() + table->NumberOfDeletedElements()) { | |
| 16082 int entry_index = table->EntryToIndex(index); | |
| 16083 iterator->MoveNext(); | |
| 16084 Handle<Object> value = Derived::ValueForKind(iterator, entry_index); | |
| 16085 return factory->CreateIteratorResultObject(value, false); | |
| 16086 } else { | |
| 16087 iterator->Close(); | |
| 16088 } | |
| 16089 } | |
| 16090 | |
| 16091 return factory->CreateIteratorResultObject(factory->undefined_value(), true); | |
| 16092 } | |
| 16093 | |
| 16094 | |
| 16095 template class OrderedHashTableIterator<JSSetIterator, OrderedHashSet>; | |
| 16096 template class OrderedHashTableIterator<JSMapIterator, OrderedHashMap>; | |
| 16097 | |
| 16098 | |
| 16099 Handle<JSSetIterator> JSSetIterator::Create(Isolate* isolate) { | |
| 16100 Handle<Map> map = | |
| 16101 isolate->factory()->NewMap(JS_SET_ITERATOR_TYPE, JSSetIterator::kSize); | |
| 16102 return | |
| 16103 Handle<JSSetIterator>::cast(isolate->factory()->NewJSObjectFromMap(map)); | |
| 16104 } | |
| 16105 | |
| 16106 | |
| 16107 Handle<Object> JSSetIterator::ValueForKind( | |
| 16108 Handle<JSSetIterator> iterator, int entry_index) { | |
| 16109 int kind = iterator->kind()->value(); | |
| 16110 // Set.prototype only has values and entries. | |
| 16111 ASSERT(kind == kKindValues || kind == kKindEntries); | |
| 16112 | |
| 16113 Isolate* isolate = iterator->GetIsolate(); | |
| 16114 Factory* factory = isolate->factory(); | |
| 16115 OrderedHashSet* table = OrderedHashSet::cast(iterator->table()); | |
|
adamk
2014/04/14 21:25:54
Needs to be a Handle too.
arv (Not doing code reviews)
2014/04/14 22:13:27
Done.
| |
| 16116 | |
| 16117 Handle<Object> value = Handle<Object>(table->get(entry_index), isolate); | |
| 16118 | |
| 16119 if (kind == kKindEntries) { | |
| 16120 Handle<FixedArray> array = factory->NewFixedArray(2); | |
| 16121 array->set(0, *value); | |
| 16122 array->set(1, *value); | |
| 16123 return factory->NewJSArrayWithElements(array); | |
| 16124 } | |
| 16125 | |
| 16126 return value; | |
| 16127 } | |
| 16128 | |
| 16129 | |
| 16130 Handle<JSMapIterator> JSMapIterator::Create(Isolate* isolate) { | |
| 16131 Handle<Map> map = | |
| 16132 isolate->factory()->NewMap(JS_MAP_ITERATOR_TYPE, JSMapIterator::kSize); | |
| 16133 return Handle<JSMapIterator>::cast( | |
| 16134 isolate->factory()->NewJSObjectFromMap(map)); | |
| 16135 } | |
| 16136 | |
| 16137 | |
| 16138 Handle<Object> JSMapIterator::ValueForKind( | |
| 16139 Handle<JSMapIterator> iterator, int entry_index) { | |
| 16140 int kind = iterator->kind()->value(); | |
| 16141 ASSERT(kind == kKindKeys || kind == kKindValues || kind == kKindEntries); | |
| 16142 | |
| 16143 Isolate* isolate = iterator->GetIsolate(); | |
| 16144 Factory* factory = isolate->factory(); | |
| 16145 OrderedHashMap* table = OrderedHashMap::cast(iterator->table()); | |
|
adamk
2014/04/14 21:25:54
And this one too.
arv (Not doing code reviews)
2014/04/14 22:13:27
Done.
| |
| 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); | |
|
adamk
2014/04/14 21:25:54
These both need to be Handles.
arv (Not doing code reviews)
2014/04/14 22:13:27
Done.
| |
| 16157 Handle<FixedArray> array = factory->NewFixedArray(2); | |
| 16158 array->set(0, key); | |
| 16159 array->set(1, value); | |
| 16160 return factory->NewJSArrayWithElements(array); | |
| 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 |