| 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 1656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1667 case JS_GENERATOR_OBJECT_TYPE: | 1667 case JS_GENERATOR_OBJECT_TYPE: |
| 1668 case JS_MODULE_TYPE: | 1668 case JS_MODULE_TYPE: |
| 1669 case JS_VALUE_TYPE: | 1669 case JS_VALUE_TYPE: |
| 1670 case JS_DATE_TYPE: | 1670 case JS_DATE_TYPE: |
| 1671 case JS_ARRAY_TYPE: | 1671 case JS_ARRAY_TYPE: |
| 1672 case JS_ARRAY_BUFFER_TYPE: | 1672 case JS_ARRAY_BUFFER_TYPE: |
| 1673 case JS_TYPED_ARRAY_TYPE: | 1673 case JS_TYPED_ARRAY_TYPE: |
| 1674 case JS_DATA_VIEW_TYPE: | 1674 case JS_DATA_VIEW_TYPE: |
| 1675 case JS_SET_TYPE: | 1675 case JS_SET_TYPE: |
| 1676 case JS_MAP_TYPE: | 1676 case JS_MAP_TYPE: |
| 1677 case JS_SET_ITERATOR_TYPE: | |
| 1678 case JS_MAP_ITERATOR_TYPE: | |
| 1679 case JS_WEAK_MAP_TYPE: | 1677 case JS_WEAK_MAP_TYPE: |
| 1680 case JS_WEAK_SET_TYPE: | 1678 case JS_WEAK_SET_TYPE: |
| 1681 case JS_REGEXP_TYPE: | 1679 case JS_REGEXP_TYPE: |
| 1682 case JS_GLOBAL_PROXY_TYPE: | 1680 case JS_GLOBAL_PROXY_TYPE: |
| 1683 case JS_GLOBAL_OBJECT_TYPE: | 1681 case JS_GLOBAL_OBJECT_TYPE: |
| 1684 case JS_BUILTINS_OBJECT_TYPE: | 1682 case JS_BUILTINS_OBJECT_TYPE: |
| 1685 case JS_MESSAGE_OBJECT_TYPE: | 1683 case JS_MESSAGE_OBJECT_TYPE: |
| 1686 JSObject::BodyDescriptor::IterateBody(this, object_size, v); | 1684 JSObject::BodyDescriptor::IterateBody(this, object_size, v); |
| 1687 break; | 1685 break; |
| 1688 case JS_FUNCTION_TYPE: | 1686 case JS_FUNCTION_TYPE: |
| (...skipping 14125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15814 } | 15812 } |
| 15815 | 15813 |
| 15816 | 15814 |
| 15817 void WeakHashTable::AddEntry(int entry, Object* key, Object* value) { | 15815 void WeakHashTable::AddEntry(int entry, Object* key, Object* value) { |
| 15818 set(EntryToIndex(entry), key); | 15816 set(EntryToIndex(entry), key); |
| 15819 set(EntryToValueIndex(entry), value); | 15817 set(EntryToValueIndex(entry), value); |
| 15820 ElementAdded(); | 15818 ElementAdded(); |
| 15821 } | 15819 } |
| 15822 | 15820 |
| 15823 | 15821 |
| 15824 template<class Derived, class Iterator, int entrysize> | 15822 template<class Derived, int entrysize> |
| 15825 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Allocate( | 15823 Handle<Derived> OrderedHashTable<Derived, entrysize>::Allocate( |
| 15826 Isolate* isolate, int capacity, PretenureFlag pretenure) { | 15824 Isolate* isolate, int capacity, PretenureFlag pretenure) { |
| 15827 // Capacity must be a power of two, since we depend on being able | 15825 // Capacity must be a power of two, since we depend on being able |
| 15828 // to divide and multiple by 2 (kLoadFactor) to derive capacity | 15826 // to divide and multiple by 2 (kLoadFactor) to derive capacity |
| 15829 // from number of buckets. If we decide to change kLoadFactor | 15827 // from number of buckets. If we decide to change kLoadFactor |
| 15830 // to something other than 2, capacity should be stored as another | 15828 // to something other than 2, capacity should be stored as another |
| 15831 // field of this object. | 15829 // field of this object. |
| 15830 const int kMinCapacity = 4; |
| 15832 capacity = RoundUpToPowerOf2(Max(kMinCapacity, capacity)); | 15831 capacity = RoundUpToPowerOf2(Max(kMinCapacity, capacity)); |
| 15833 if (capacity > kMaxCapacity) { | 15832 if (capacity > kMaxCapacity) { |
| 15834 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); | 15833 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); |
| 15835 } | 15834 } |
| 15836 int num_buckets = capacity / kLoadFactor; | 15835 int num_buckets = capacity / kLoadFactor; |
| 15837 Handle<FixedArray> backing_store = isolate->factory()->NewFixedArray( | 15836 Handle<FixedArray> backing_store = isolate->factory()->NewFixedArray( |
| 15838 kHashTableStartIndex + num_buckets + (capacity * kEntrySize), pretenure); | 15837 kHashTableStartIndex + num_buckets + (capacity * kEntrySize), pretenure); |
| 15839 backing_store->set_map_no_write_barrier( | 15838 backing_store->set_map_no_write_barrier( |
| 15840 isolate->heap()->ordered_hash_table_map()); | 15839 isolate->heap()->ordered_hash_table_map()); |
| 15841 Handle<Derived> table = Handle<Derived>::cast(backing_store); | 15840 Handle<Derived> table = Handle<Derived>::cast(backing_store); |
| 15842 for (int i = 0; i < num_buckets; ++i) { | 15841 for (int i = 0; i < num_buckets; ++i) { |
| 15843 table->set(kHashTableStartIndex + i, Smi::FromInt(kNotFound)); | 15842 table->set(kHashTableStartIndex + i, Smi::FromInt(kNotFound)); |
| 15844 } | 15843 } |
| 15845 table->SetNumberOfBuckets(num_buckets); | 15844 table->SetNumberOfBuckets(num_buckets); |
| 15846 table->SetNumberOfElements(0); | 15845 table->SetNumberOfElements(0); |
| 15847 table->SetNumberOfDeletedElements(0); | 15846 table->SetNumberOfDeletedElements(0); |
| 15848 table->set_iterators(isolate->heap()->undefined_value()); | |
| 15849 return table; | 15847 return table; |
| 15850 } | 15848 } |
| 15851 | 15849 |
| 15852 | 15850 |
| 15853 template<class Derived, class Iterator, int entrysize> | 15851 template<class Derived, int entrysize> |
| 15854 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::EnsureGrowable( | 15852 Handle<Derived> OrderedHashTable<Derived, entrysize>::EnsureGrowable( |
| 15855 Handle<Derived> table) { | 15853 Handle<Derived> table) { |
| 15856 int nof = table->NumberOfElements(); | 15854 int nof = table->NumberOfElements(); |
| 15857 int nod = table->NumberOfDeletedElements(); | 15855 int nod = table->NumberOfDeletedElements(); |
| 15858 int capacity = table->Capacity(); | 15856 int capacity = table->Capacity(); |
| 15859 if ((nof + nod) < capacity) return table; | 15857 if ((nof + nod) < capacity) return table; |
| 15860 // Don't need to grow if we can simply clear out deleted entries instead. | 15858 // Don't need to grow if we can simply clear out deleted entries instead. |
| 15861 // Note that we can't compact in place, though, so we always allocate | 15859 // Note that we can't compact in place, though, so we always allocate |
| 15862 // a new table. | 15860 // a new table. |
| 15863 return Rehash(table, (nod < (capacity >> 1)) ? capacity << 1 : capacity); | 15861 return Rehash(table, (nod < (capacity >> 1)) ? capacity << 1 : capacity); |
| 15864 } | 15862 } |
| 15865 | 15863 |
| 15866 | 15864 |
| 15867 template<class Derived, class Iterator, int entrysize> | 15865 template<class Derived, int entrysize> |
| 15868 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Shrink( | 15866 Handle<Derived> OrderedHashTable<Derived, entrysize>::Shrink( |
| 15869 Handle<Derived> table) { | 15867 Handle<Derived> table) { |
| 15870 int nof = table->NumberOfElements(); | 15868 int nof = table->NumberOfElements(); |
| 15871 int capacity = table->Capacity(); | 15869 int capacity = table->Capacity(); |
| 15872 if (nof > (capacity >> 2)) return table; | 15870 if (nof > (capacity >> 2)) return table; |
| 15873 return Rehash(table, capacity / 2); | 15871 return Rehash(table, capacity / 2); |
| 15874 } | 15872 } |
| 15875 | 15873 |
| 15876 | 15874 |
| 15877 template<class Derived, class Iterator, int entrysize> | 15875 template<class Derived, int entrysize> |
| 15878 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Clear( | 15876 Handle<Derived> OrderedHashTable<Derived, entrysize>::Rehash( |
| 15879 Handle<Derived> table) { | |
| 15880 Handle<Derived> new_table = | |
| 15881 Allocate(table->GetIsolate(), | |
| 15882 kMinCapacity, | |
| 15883 table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED); | |
| 15884 | |
| 15885 new_table->set_iterators(table->iterators()); | |
| 15886 table->set_iterators(table->GetHeap()->undefined_value()); | |
| 15887 | |
| 15888 DisallowHeapAllocation no_allocation; | |
| 15889 for (Object* object = new_table->iterators(); | |
| 15890 !object->IsUndefined(); | |
| 15891 object = Iterator::cast(object)->next_iterator()) { | |
| 15892 Iterator::cast(object)->TableCleared(); | |
| 15893 Iterator::cast(object)->set_table(*new_table); | |
| 15894 } | |
| 15895 | |
| 15896 return new_table; | |
| 15897 } | |
| 15898 | |
| 15899 | |
| 15900 template<class Derived, class Iterator, int entrysize> | |
| 15901 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash( | |
| 15902 Handle<Derived> table, int new_capacity) { | 15877 Handle<Derived> table, int new_capacity) { |
| 15903 Handle<Derived> new_table = | 15878 Handle<Derived> new_table = |
| 15904 Allocate(table->GetIsolate(), | 15879 Allocate(table->GetIsolate(), |
| 15905 new_capacity, | 15880 new_capacity, |
| 15906 table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED); | 15881 table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED); |
| 15907 int nof = table->NumberOfElements(); | 15882 int nof = table->NumberOfElements(); |
| 15908 int nod = table->NumberOfDeletedElements(); | 15883 int nod = table->NumberOfDeletedElements(); |
| 15909 int new_buckets = new_table->NumberOfBuckets(); | 15884 int new_buckets = new_table->NumberOfBuckets(); |
| 15910 int new_entry = 0; | 15885 int new_entry = 0; |
| 15911 for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) { | 15886 for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) { |
| 15912 Object* key = table->KeyAt(old_entry); | 15887 Object* key = table->KeyAt(old_entry); |
| 15913 if (key->IsTheHole()) continue; | 15888 if (key->IsTheHole()) continue; |
| 15914 Object* hash = key->GetHash(); | 15889 Object* hash = key->GetHash(); |
| 15915 int bucket = Smi::cast(hash)->value() & (new_buckets - 1); | 15890 int bucket = Smi::cast(hash)->value() & (new_buckets - 1); |
| 15916 Object* chain_entry = new_table->get(kHashTableStartIndex + bucket); | 15891 Object* chain_entry = new_table->get(kHashTableStartIndex + bucket); |
| 15917 new_table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry)); | 15892 new_table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry)); |
| 15918 int new_index = new_table->EntryToIndex(new_entry); | 15893 int new_index = new_table->EntryToIndex(new_entry); |
| 15919 int old_index = table->EntryToIndex(old_entry); | 15894 int old_index = table->EntryToIndex(old_entry); |
| 15920 for (int i = 0; i < entrysize; ++i) { | 15895 for (int i = 0; i < entrysize; ++i) { |
| 15921 Object* value = table->get(old_index + i); | 15896 Object* value = table->get(old_index + i); |
| 15922 new_table->set(new_index + i, value); | 15897 new_table->set(new_index + i, value); |
| 15923 } | 15898 } |
| 15924 new_table->set(new_index + kChainOffset, chain_entry); | 15899 new_table->set(new_index + kChainOffset, chain_entry); |
| 15925 ++new_entry; | 15900 ++new_entry; |
| 15926 } | 15901 } |
| 15927 new_table->SetNumberOfElements(nof); | 15902 new_table->SetNumberOfElements(nof); |
| 15928 | |
| 15929 new_table->set_iterators(table->iterators()); | |
| 15930 table->set_iterators(table->GetHeap()->undefined_value()); | |
| 15931 | |
| 15932 DisallowHeapAllocation no_allocation; | |
| 15933 for (Object* object = new_table->iterators(); | |
| 15934 !object->IsUndefined(); | |
| 15935 object = Iterator::cast(object)->next_iterator()) { | |
| 15936 Iterator::cast(object)->TableCompacted(); | |
| 15937 Iterator::cast(object)->set_table(*new_table); | |
| 15938 } | |
| 15939 | |
| 15940 return new_table; | 15903 return new_table; |
| 15941 } | 15904 } |
| 15942 | 15905 |
| 15943 | 15906 |
| 15944 template<class Derived, class Iterator, int entrysize> | 15907 template<class Derived, int entrysize> |
| 15945 int OrderedHashTable<Derived, Iterator, entrysize>::FindEntry(Object* key) { | 15908 int OrderedHashTable<Derived, entrysize>::FindEntry(Object* key) { |
| 15946 ASSERT(!key->IsTheHole()); | 15909 ASSERT(!key->IsTheHole()); |
| 15947 Object* hash = key->GetHash(); | 15910 Object* hash = key->GetHash(); |
| 15948 if (hash->IsUndefined()) return kNotFound; | 15911 if (hash->IsUndefined()) return kNotFound; |
| 15949 for (int entry = HashToEntry(Smi::cast(hash)->value()); | 15912 for (int entry = HashToEntry(Smi::cast(hash)->value()); |
| 15950 entry != kNotFound; | 15913 entry != kNotFound; |
| 15951 entry = ChainAt(entry)) { | 15914 entry = ChainAt(entry)) { |
| 15952 Object* candidate = KeyAt(entry); | 15915 Object* candidate = KeyAt(entry); |
| 15953 if (candidate->SameValue(key)) | 15916 if (candidate->SameValue(key)) |
| 15954 return entry; | 15917 return entry; |
| 15955 } | 15918 } |
| 15956 return kNotFound; | 15919 return kNotFound; |
| 15957 } | 15920 } |
| 15958 | 15921 |
| 15959 | 15922 |
| 15960 template<class Derived, class Iterator, int entrysize> | 15923 template<class Derived, int entrysize> |
| 15961 int OrderedHashTable<Derived, Iterator, entrysize>::AddEntry(int hash) { | 15924 int OrderedHashTable<Derived, entrysize>::AddEntry(int hash) { |
| 15962 int entry = UsedCapacity(); | 15925 int entry = NumberOfElements() + NumberOfDeletedElements(); |
| 15963 int bucket = HashToBucket(hash); | 15926 int bucket = HashToBucket(hash); |
| 15964 int index = EntryToIndex(entry); | 15927 int index = EntryToIndex(entry); |
| 15965 Object* chain_entry = get(kHashTableStartIndex + bucket); | 15928 Object* chain_entry = get(kHashTableStartIndex + bucket); |
| 15966 set(kHashTableStartIndex + bucket, Smi::FromInt(entry)); | 15929 set(kHashTableStartIndex + bucket, Smi::FromInt(entry)); |
| 15967 set(index + kChainOffset, chain_entry); | 15930 set(index + kChainOffset, chain_entry); |
| 15968 SetNumberOfElements(NumberOfElements() + 1); | 15931 SetNumberOfElements(NumberOfElements() + 1); |
| 15969 return index; | 15932 return index; |
| 15970 } | 15933 } |
| 15971 | 15934 |
| 15972 | 15935 |
| 15973 template<class Derived, class Iterator, int entrysize> | 15936 template<class Derived, int entrysize> |
| 15974 void OrderedHashTable<Derived, Iterator, entrysize>::RemoveEntry(int entry) { | 15937 void OrderedHashTable<Derived, entrysize>::RemoveEntry(int entry) { |
| 15975 int index = EntryToIndex(entry); | 15938 int index = EntryToIndex(entry); |
| 15976 for (int i = 0; i < entrysize; ++i) { | 15939 for (int i = 0; i < entrysize; ++i) { |
| 15977 set_the_hole(index + i); | 15940 set_the_hole(index + i); |
| 15978 } | 15941 } |
| 15979 SetNumberOfElements(NumberOfElements() - 1); | 15942 SetNumberOfElements(NumberOfElements() - 1); |
| 15980 SetNumberOfDeletedElements(NumberOfDeletedElements() + 1); | 15943 SetNumberOfDeletedElements(NumberOfDeletedElements() + 1); |
| 15981 | |
| 15982 DisallowHeapAllocation no_allocation; | |
| 15983 for (Object* object = iterators(); | |
| 15984 !object->IsUndefined(); | |
| 15985 object = Iterator::cast(object)->next_iterator()) { | |
| 15986 Iterator::cast(object)->EntryRemoved(entry); | |
| 15987 } | |
| 15988 } | 15944 } |
| 15989 | 15945 |
| 15990 | 15946 |
| 15991 template class OrderedHashTable<OrderedHashSet, JSSetIterator, 1>; | 15947 template class OrderedHashTable<OrderedHashSet, 1>; |
| 15992 template class OrderedHashTable<OrderedHashMap, JSMapIterator, 2>; | 15948 template class OrderedHashTable<OrderedHashMap, 2>; |
| 15993 | 15949 |
| 15994 | 15950 |
| 15995 bool OrderedHashSet::Contains(Object* key) { | 15951 bool OrderedHashSet::Contains(Object* key) { |
| 15996 return FindEntry(key) != kNotFound; | 15952 return FindEntry(key) != kNotFound; |
| 15997 } | 15953 } |
| 15998 | 15954 |
| 15999 | 15955 |
| 16000 Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table, | 15956 Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table, |
| 16001 Handle<Object> key) { | 15957 Handle<Object> key) { |
| 16002 if (table->FindEntry(*key) != kNotFound) return table; | 15958 if (table->FindEntry(*key) != kNotFound) return table; |
| 16003 | 15959 |
| 16004 table = EnsureGrowable(table); | 15960 table = EnsureGrowable(table); |
| 16005 | 15961 |
| 16006 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate()); | 15962 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate()); |
| 16007 int index = table->AddEntry(Smi::cast(*hash)->value()); | 15963 int index = table->AddEntry(Smi::cast(*hash)->value()); |
| 16008 table->set(index, *key); | 15964 table->set(index, *key); |
| 16009 return table; | 15965 return table; |
| 16010 } | 15966 } |
| 16011 | 15967 |
| 16012 | 15968 |
| 16013 Handle<OrderedHashSet> OrderedHashSet::Remove(Handle<OrderedHashSet> table, | 15969 Handle<OrderedHashSet> OrderedHashSet::Remove(Handle<OrderedHashSet> table, |
| 16014 Handle<Object> key) { | 15970 Handle<Object> key) { |
| 16015 int entry = table->FindEntry(*key); | 15971 int entry = table->FindEntry(*key); |
| 16016 if (entry == kNotFound) return table; | 15972 if (entry == kNotFound) return table; |
| 16017 table->RemoveEntry(entry); | 15973 table->RemoveEntry(entry); |
| 15974 // TODO(adamk): Don't shrink if we're being iterated over |
| 16018 return Shrink(table); | 15975 return Shrink(table); |
| 16019 } | 15976 } |
| 16020 | 15977 |
| 16021 | 15978 |
| 16022 Object* OrderedHashMap::Lookup(Object* key) { | 15979 Object* OrderedHashMap::Lookup(Object* key) { |
| 16023 int entry = FindEntry(key); | 15980 int entry = FindEntry(key); |
| 16024 if (entry == kNotFound) return GetHeap()->the_hole_value(); | 15981 if (entry == kNotFound) return GetHeap()->the_hole_value(); |
| 16025 return ValueAt(entry); | 15982 return ValueAt(entry); |
| 16026 } | 15983 } |
| 16027 | 15984 |
| 16028 | 15985 |
| 16029 Handle<OrderedHashMap> OrderedHashMap::Put(Handle<OrderedHashMap> table, | 15986 Handle<OrderedHashMap> OrderedHashMap::Put(Handle<OrderedHashMap> table, |
| 16030 Handle<Object> key, | 15987 Handle<Object> key, |
| 16031 Handle<Object> value) { | 15988 Handle<Object> value) { |
| 16032 int entry = table->FindEntry(*key); | 15989 int entry = table->FindEntry(*key); |
| 16033 | 15990 |
| 16034 if (value->IsTheHole()) { | 15991 if (value->IsTheHole()) { |
| 16035 if (entry == kNotFound) return table; | 15992 if (entry == kNotFound) return table; |
| 16036 table->RemoveEntry(entry); | 15993 table->RemoveEntry(entry); |
| 15994 // TODO(adamk): Only shrink if not iterating |
| 16037 return Shrink(table); | 15995 return Shrink(table); |
| 16038 } | 15996 } |
| 16039 | 15997 |
| 16040 if (entry != kNotFound) { | 15998 if (entry != kNotFound) { |
| 16041 table->set(table->EntryToIndex(entry) + kValueOffset, *value); | 15999 table->set(table->EntryToIndex(entry) + kValueOffset, *value); |
| 16042 return table; | 16000 return table; |
| 16043 } | 16001 } |
| 16044 | 16002 |
| 16045 table = EnsureGrowable(table); | 16003 table = EnsureGrowable(table); |
| 16046 | 16004 |
| 16047 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate()); | 16005 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate()); |
| 16048 int index = table->AddEntry(Smi::cast(*hash)->value()); | 16006 int index = table->AddEntry(Smi::cast(*hash)->value()); |
| 16049 table->set(index, *key); | 16007 table->set(index, *key); |
| 16050 table->set(index + kValueOffset, *value); | 16008 table->set(index + kValueOffset, *value); |
| 16051 return table; | 16009 return table; |
| 16052 } | 16010 } |
| 16053 | 16011 |
| 16054 | 16012 |
| 16055 template<class Derived, class TableType> | |
| 16056 void OrderedHashTableIterator<Derived, TableType>::EntryRemoved(int index) { | |
| 16057 int i = this->index()->value(); | |
| 16058 if (index < i) { | |
| 16059 set_count(Smi::FromInt(count()->value() - 1)); | |
| 16060 } | |
| 16061 if (index == i) { | |
| 16062 Seek(); | |
| 16063 } | |
| 16064 } | |
| 16065 | |
| 16066 | |
| 16067 template<class Derived, class TableType> | |
| 16068 void OrderedHashTableIterator<Derived, TableType>::Close() { | |
| 16069 if (Closed()) return; | |
| 16070 | |
| 16071 DisallowHeapAllocation no_allocation; | |
| 16072 | |
| 16073 Object* undefined = GetHeap()->undefined_value(); | |
| 16074 TableType* table = TableType::cast(this->table()); | |
| 16075 Object* previous = previous_iterator(); | |
| 16076 Object* next = next_iterator(); | |
| 16077 | |
| 16078 if (previous == undefined) { | |
| 16079 ASSERT_EQ(table->iterators(), this); | |
| 16080 table->set_iterators(next); | |
| 16081 } else { | |
| 16082 ASSERT_EQ(Derived::cast(previous)->next_iterator(), this); | |
| 16083 Derived::cast(previous)->set_next_iterator(next); | |
| 16084 } | |
| 16085 | |
| 16086 if (!next->IsUndefined()) { | |
| 16087 ASSERT_EQ(Derived::cast(next)->previous_iterator(), this); | |
| 16088 Derived::cast(next)->set_previous_iterator(previous); | |
| 16089 } | |
| 16090 | |
| 16091 set_previous_iterator(undefined); | |
| 16092 set_next_iterator(undefined); | |
| 16093 set_table(undefined); | |
| 16094 } | |
| 16095 | |
| 16096 | |
| 16097 template<class Derived, class TableType> | |
| 16098 void OrderedHashTableIterator<Derived, TableType>::Seek() { | |
| 16099 ASSERT(!Closed()); | |
| 16100 | |
| 16101 DisallowHeapAllocation no_allocation; | |
| 16102 | |
| 16103 int index = this->index()->value(); | |
| 16104 | |
| 16105 TableType* table = TableType::cast(this->table()); | |
| 16106 int used_capacity = table->UsedCapacity(); | |
| 16107 | |
| 16108 while (index < used_capacity && table->KeyAt(index)->IsTheHole()) { | |
| 16109 index++; | |
| 16110 } | |
| 16111 set_index(Smi::FromInt(index)); | |
| 16112 } | |
| 16113 | |
| 16114 | |
| 16115 template<class Derived, class TableType> | |
| 16116 void OrderedHashTableIterator<Derived, TableType>::MoveNext() { | |
| 16117 ASSERT(!Closed()); | |
| 16118 | |
| 16119 set_index(Smi::FromInt(index()->value() + 1)); | |
| 16120 set_count(Smi::FromInt(count()->value() + 1)); | |
| 16121 Seek(); | |
| 16122 } | |
| 16123 | |
| 16124 | |
| 16125 template<class Derived, class TableType> | |
| 16126 Handle<JSObject> OrderedHashTableIterator<Derived, TableType>::Next( | |
| 16127 Handle<Derived> iterator) { | |
| 16128 Isolate* isolate = iterator->GetIsolate(); | |
| 16129 Factory* factory = isolate->factory(); | |
| 16130 | |
| 16131 Handle<Object> object(iterator->table(), isolate); | |
| 16132 | |
| 16133 if (!object->IsUndefined()) { | |
| 16134 Handle<TableType> table = Handle<TableType>::cast(object); | |
| 16135 int index = iterator->index()->value(); | |
| 16136 if (index < table->UsedCapacity()) { | |
| 16137 int entry_index = table->EntryToIndex(index); | |
| 16138 iterator->MoveNext(); | |
| 16139 Handle<Object> value = Derived::ValueForKind(iterator, entry_index); | |
| 16140 return factory->NewIteratorResultObject(value, false); | |
| 16141 } else { | |
| 16142 iterator->Close(); | |
| 16143 } | |
| 16144 } | |
| 16145 | |
| 16146 return factory->NewIteratorResultObject(factory->undefined_value(), true); | |
| 16147 } | |
| 16148 | |
| 16149 | |
| 16150 template<class Derived, class TableType> | |
| 16151 Handle<Derived> OrderedHashTableIterator<Derived, TableType>::CreateInternal( | |
| 16152 Handle<Map> map, | |
| 16153 Handle<TableType> table, | |
| 16154 int kind) { | |
| 16155 Isolate* isolate = table->GetIsolate(); | |
| 16156 | |
| 16157 Handle<Object> undefined = isolate->factory()->undefined_value(); | |
| 16158 | |
| 16159 Handle<Derived> new_iterator = Handle<Derived>::cast( | |
| 16160 isolate->factory()->NewJSObjectFromMap(map)); | |
| 16161 new_iterator->set_previous_iterator(*undefined); | |
| 16162 new_iterator->set_table(*table); | |
| 16163 new_iterator->set_index(Smi::FromInt(0)); | |
| 16164 new_iterator->set_count(Smi::FromInt(0)); | |
| 16165 new_iterator->set_kind(Smi::FromInt(kind)); | |
| 16166 | |
| 16167 Handle<Object> old_iterator(table->iterators(), isolate); | |
| 16168 if (!old_iterator->IsUndefined()) { | |
| 16169 Handle<Derived>::cast(old_iterator)->set_previous_iterator(*new_iterator); | |
| 16170 new_iterator->set_next_iterator(*old_iterator); | |
| 16171 } else { | |
| 16172 new_iterator->set_next_iterator(*undefined); | |
| 16173 } | |
| 16174 | |
| 16175 table->set_iterators(*new_iterator); | |
| 16176 | |
| 16177 return new_iterator; | |
| 16178 } | |
| 16179 | |
| 16180 | |
| 16181 template class OrderedHashTableIterator<JSSetIterator, OrderedHashSet>; | |
| 16182 template class OrderedHashTableIterator<JSMapIterator, OrderedHashMap>; | |
| 16183 | |
| 16184 | |
| 16185 Handle<JSSetIterator> JSSetIterator::Create( | |
| 16186 Handle<OrderedHashSet> table, int kind) { | |
| 16187 return CreateInternal(table->GetIsolate()->set_iterator_map(), table, kind); | |
| 16188 } | |
| 16189 | |
| 16190 | |
| 16191 Handle<Object> JSSetIterator::ValueForKind( | |
| 16192 Handle<JSSetIterator> iterator, int entry_index) { | |
| 16193 int kind = iterator->kind()->value(); | |
| 16194 // Set.prototype only has values and entries. | |
| 16195 ASSERT(kind == kKindValues || kind == kKindEntries); | |
| 16196 | |
| 16197 Isolate* isolate = iterator->GetIsolate(); | |
| 16198 Factory* factory = isolate->factory(); | |
| 16199 | |
| 16200 Handle<OrderedHashSet> table( | |
| 16201 OrderedHashSet::cast(iterator->table()), isolate); | |
| 16202 Handle<Object> value = Handle<Object>(table->get(entry_index), isolate); | |
| 16203 | |
| 16204 if (kind == kKindEntries) { | |
| 16205 Handle<FixedArray> array = factory->NewFixedArray(2); | |
| 16206 array->set(0, *value); | |
| 16207 array->set(1, *value); | |
| 16208 return factory->NewJSArrayWithElements(array); | |
| 16209 } | |
| 16210 | |
| 16211 return value; | |
| 16212 } | |
| 16213 | |
| 16214 | |
| 16215 Handle<JSMapIterator> JSMapIterator::Create( | |
| 16216 Handle<OrderedHashMap> table, | |
| 16217 int kind) { | |
| 16218 return CreateInternal(table->GetIsolate()->map_iterator_map(), table, kind); | |
| 16219 } | |
| 16220 | |
| 16221 | |
| 16222 Handle<Object> JSMapIterator::ValueForKind( | |
| 16223 Handle<JSMapIterator> iterator, int entry_index) { | |
| 16224 int kind = iterator->kind()->value(); | |
| 16225 ASSERT(kind == kKindKeys || kind == kKindValues || kind == kKindEntries); | |
| 16226 | |
| 16227 Isolate* isolate = iterator->GetIsolate(); | |
| 16228 Factory* factory = isolate->factory(); | |
| 16229 | |
| 16230 Handle<OrderedHashMap> table( | |
| 16231 OrderedHashMap::cast(iterator->table()), isolate); | |
| 16232 | |
| 16233 switch (kind) { | |
| 16234 case kKindKeys: | |
| 16235 return Handle<Object>(table->get(entry_index), isolate); | |
| 16236 | |
| 16237 case kKindValues: | |
| 16238 return Handle<Object>(table->get(entry_index + 1), isolate); | |
| 16239 | |
| 16240 case kKindEntries: { | |
| 16241 Handle<Object> key(table->get(entry_index), isolate); | |
| 16242 Handle<Object> value(table->get(entry_index + 1), isolate); | |
| 16243 Handle<FixedArray> array = factory->NewFixedArray(2); | |
| 16244 array->set(0, *key); | |
| 16245 array->set(1, *value); | |
| 16246 return factory->NewJSArrayWithElements(array); | |
| 16247 } | |
| 16248 } | |
| 16249 | |
| 16250 UNREACHABLE(); | |
| 16251 return factory->undefined_value(); | |
| 16252 } | |
| 16253 | |
| 16254 | |
| 16255 DeclaredAccessorDescriptorIterator::DeclaredAccessorDescriptorIterator( | 16013 DeclaredAccessorDescriptorIterator::DeclaredAccessorDescriptorIterator( |
| 16256 DeclaredAccessorDescriptor* descriptor) | 16014 DeclaredAccessorDescriptor* descriptor) |
| 16257 : array_(descriptor->serialized_data()->GetDataStartAddress()), | 16015 : array_(descriptor->serialized_data()->GetDataStartAddress()), |
| 16258 length_(descriptor->serialized_data()->length()), | 16016 length_(descriptor->serialized_data()->length()), |
| 16259 offset_(0) { | 16017 offset_(0) { |
| 16260 } | 16018 } |
| 16261 | 16019 |
| 16262 | 16020 |
| 16263 const DeclaredAccessorDescriptorData* | 16021 const DeclaredAccessorDescriptorData* |
| 16264 DeclaredAccessorDescriptorIterator::Next() { | 16022 DeclaredAccessorDescriptorIterator::Next() { |
| (...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16838 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16596 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16839 static const char* error_messages_[] = { | 16597 static const char* error_messages_[] = { |
| 16840 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16598 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16841 }; | 16599 }; |
| 16842 #undef ERROR_MESSAGES_TEXTS | 16600 #undef ERROR_MESSAGES_TEXTS |
| 16843 return error_messages_[reason]; | 16601 return error_messages_[reason]; |
| 16844 } | 16602 } |
| 16845 | 16603 |
| 16846 | 16604 |
| 16847 } } // namespace v8::internal | 16605 } } // namespace v8::internal |
| OLD | NEW |