| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <iomanip> | 5 #include <iomanip> |
| 6 #include <sstream> | 6 #include <sstream> |
| 7 | 7 |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
| (...skipping 13958 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13969 | 13969 |
| 13970 | 13970 |
| 13971 // Certain compilers request function template instantiation when they | 13971 // Certain compilers request function template instantiation when they |
| 13972 // see the definition of the other template functions in the | 13972 // see the definition of the other template functions in the |
| 13973 // class. This requires us to have the template functions put | 13973 // class. This requires us to have the template functions put |
| 13974 // together, so even though this function belongs in objects-debug.cc, | 13974 // together, so even though this function belongs in objects-debug.cc, |
| 13975 // we keep it here instead to satisfy certain compilers. | 13975 // we keep it here instead to satisfy certain compilers. |
| 13976 #ifdef OBJECT_PRINT | 13976 #ifdef OBJECT_PRINT |
| 13977 template <typename Derived, typename Shape, typename Key> | 13977 template <typename Derived, typename Shape, typename Key> |
| 13978 void Dictionary<Derived, Shape, Key>::Print(std::ostream& os) { // NOLINT | 13978 void Dictionary<Derived, Shape, Key>::Print(std::ostream& os) { // NOLINT |
| 13979 int capacity = DerivedHashTable::Capacity(); | 13979 int capacity = this->Capacity(); |
| 13980 for (int i = 0; i < capacity; i++) { | 13980 for (int i = 0; i < capacity; i++) { |
| 13981 Object* k = DerivedHashTable::KeyAt(i); | 13981 Object* k = this->KeyAt(i); |
| 13982 if (DerivedHashTable::IsKey(k)) { | 13982 if (this->IsKey(k)) { |
| 13983 os << " "; | 13983 os << " "; |
| 13984 if (k->IsString()) { | 13984 if (k->IsString()) { |
| 13985 String::cast(k)->StringPrint(os); | 13985 String::cast(k)->StringPrint(os); |
| 13986 } else { | 13986 } else { |
| 13987 os << Brief(k); | 13987 os << Brief(k); |
| 13988 } | 13988 } |
| 13989 os << ": " << Brief(ValueAt(i)) << " " << DetailsAt(i) << "\n"; | 13989 os << ": " << Brief(ValueAt(i)) << " " << DetailsAt(i) << "\n"; |
| 13990 } | 13990 } |
| 13991 } | 13991 } |
| 13992 } | 13992 } |
| 13993 #endif | 13993 #endif |
| 13994 | 13994 |
| 13995 | 13995 |
| 13996 template<typename Derived, typename Shape, typename Key> | 13996 template<typename Derived, typename Shape, typename Key> |
| 13997 void Dictionary<Derived, Shape, Key>::CopyValuesTo(FixedArray* elements) { | 13997 void Dictionary<Derived, Shape, Key>::CopyValuesTo(FixedArray* elements) { |
| 13998 int pos = 0; | 13998 int pos = 0; |
| 13999 int capacity = DerivedHashTable::Capacity(); | 13999 int capacity = this->Capacity(); |
| 14000 DisallowHeapAllocation no_gc; | 14000 DisallowHeapAllocation no_gc; |
| 14001 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); | 14001 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); |
| 14002 for (int i = 0; i < capacity; i++) { | 14002 for (int i = 0; i < capacity; i++) { |
| 14003 Object* k = Dictionary::KeyAt(i); | 14003 Object* k = this->KeyAt(i); |
| 14004 if (Dictionary::IsKey(k)) { | 14004 if (this->IsKey(k)) { |
| 14005 elements->set(pos++, ValueAt(i), mode); | 14005 elements->set(pos++, ValueAt(i), mode); |
| 14006 } | 14006 } |
| 14007 } | 14007 } |
| 14008 DCHECK(pos == elements->length()); | 14008 DCHECK(pos == elements->length()); |
| 14009 } | 14009 } |
| 14010 | 14010 |
| 14011 | 14011 |
| 14012 InterceptorInfo* JSObject::GetNamedInterceptor() { | 14012 InterceptorInfo* JSObject::GetNamedInterceptor() { |
| 14013 DCHECK(map()->has_named_interceptor()); | 14013 DCHECK(map()->has_named_interceptor()); |
| 14014 JSFunction* constructor = JSFunction::cast(map()->GetConstructor()); | 14014 JSFunction* constructor = JSFunction::cast(map()->GetConstructor()); |
| (...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14728 Handle<Derived> table = Handle<Derived>::cast(array); | 14728 Handle<Derived> table = Handle<Derived>::cast(array); |
| 14729 | 14729 |
| 14730 table->SetNumberOfElements(0); | 14730 table->SetNumberOfElements(0); |
| 14731 table->SetNumberOfDeletedElements(0); | 14731 table->SetNumberOfDeletedElements(0); |
| 14732 table->SetCapacity(capacity); | 14732 table->SetCapacity(capacity); |
| 14733 return table; | 14733 return table; |
| 14734 } | 14734 } |
| 14735 | 14735 |
| 14736 | 14736 |
| 14737 // Find entry for key otherwise return kNotFound. | 14737 // Find entry for key otherwise return kNotFound. |
| 14738 int NameDictionary::FindEntry(Handle<Name> key) { | 14738 template <typename Derived, typename Shape> |
| 14739 int NameDictionaryBase<Derived, Shape>::FindEntry(Handle<Name> key) { |
| 14739 if (!key->IsUniqueName()) { | 14740 if (!key->IsUniqueName()) { |
| 14740 return DerivedHashTable::FindEntry(key); | 14741 return DerivedDictionary::FindEntry(key); |
| 14741 } | 14742 } |
| 14742 | 14743 |
| 14743 // Optimized for unique names. Knowledge of the key type allows: | 14744 // Optimized for unique names. Knowledge of the key type allows: |
| 14744 // 1. Move the check if the key is unique out of the loop. | 14745 // 1. Move the check if the key is unique out of the loop. |
| 14745 // 2. Avoid comparing hash codes in unique-to-unique comparison. | 14746 // 2. Avoid comparing hash codes in unique-to-unique comparison. |
| 14746 // 3. Detect a case when a dictionary key is not unique but the key is. | 14747 // 3. Detect a case when a dictionary key is not unique but the key is. |
| 14747 // In case of positive result the dictionary key may be replaced by the | 14748 // In case of positive result the dictionary key may be replaced by the |
| 14748 // internalized string with minimal performance penalty. It gives a chance | 14749 // internalized string with minimal performance penalty. It gives a chance |
| 14749 // to perform further lookups in code stubs (and significant performance | 14750 // to perform further lookups in code stubs (and significant performance |
| 14750 // boost a certain style of code). | 14751 // boost a certain style of code). |
| 14751 | 14752 |
| 14752 // EnsureCapacity will guarantee the hash table is never full. | 14753 // EnsureCapacity will guarantee the hash table is never full. |
| 14753 uint32_t capacity = Capacity(); | 14754 uint32_t capacity = this->Capacity(); |
| 14754 uint32_t entry = FirstProbe(key->Hash(), capacity); | 14755 uint32_t entry = Derived::FirstProbe(key->Hash(), capacity); |
| 14755 uint32_t count = 1; | 14756 uint32_t count = 1; |
| 14756 | 14757 |
| 14757 while (true) { | 14758 while (true) { |
| 14758 int index = EntryToIndex(entry); | 14759 int index = Derived::EntryToIndex(entry); |
| 14759 Object* element = get(index); | 14760 Object* element = this->get(index); |
| 14760 if (element->IsUndefined()) break; // Empty entry. | 14761 if (element->IsUndefined()) break; // Empty entry. |
| 14761 if (*key == element) return entry; | 14762 if (*key == element) return entry; |
| 14762 if (!element->IsUniqueName() && | 14763 if (!element->IsUniqueName() && |
| 14763 !element->IsTheHole() && | 14764 !element->IsTheHole() && |
| 14764 Name::cast(element)->Equals(*key)) { | 14765 Name::cast(element)->Equals(*key)) { |
| 14765 // Replace a key that is a non-internalized string by the equivalent | 14766 // Replace a key that is a non-internalized string by the equivalent |
| 14766 // internalized string for faster further lookups. | 14767 // internalized string for faster further lookups. |
| 14767 set(index, *key); | 14768 this->set(index, *key); |
| 14768 return entry; | 14769 return entry; |
| 14769 } | 14770 } |
| 14770 DCHECK(element->IsTheHole() || !Name::cast(element)->Equals(*key)); | 14771 DCHECK(element->IsTheHole() || !Name::cast(element)->Equals(*key)); |
| 14771 entry = NextProbe(entry, count++, capacity); | 14772 entry = Derived::NextProbe(entry, count++, capacity); |
| 14772 } | 14773 } |
| 14773 return kNotFound; | 14774 return Derived::kNotFound; |
| 14774 } | 14775 } |
| 14775 | 14776 |
| 14776 | 14777 |
| 14777 template<typename Derived, typename Shape, typename Key> | 14778 template<typename Derived, typename Shape, typename Key> |
| 14778 void HashTable<Derived, Shape, Key>::Rehash( | 14779 void HashTable<Derived, Shape, Key>::Rehash( |
| 14779 Handle<Derived> new_table, | 14780 Handle<Derived> new_table, |
| 14780 Key key) { | 14781 Key key) { |
| 14781 DCHECK(NumberOfElements() < new_table->Capacity()); | 14782 DCHECK(NumberOfElements() < new_table->Capacity()); |
| 14782 | 14783 |
| 14783 DisallowHeapAllocation no_gc; | 14784 DisallowHeapAllocation no_gc; |
| 14784 WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc); | 14785 WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc); |
| 14785 | 14786 |
| 14786 // Copy prefix to new array. | 14787 // Copy prefix to new array. |
| 14787 for (int i = kPrefixStartIndex; | 14788 for (int i = kPrefixStartIndex; |
| 14788 i < kPrefixStartIndex + Shape::kPrefixSize; | 14789 i < kPrefixStartIndex + Shape::kPrefixSize; |
| 14789 i++) { | 14790 i++) { |
| 14790 new_table->set(i, get(i), mode); | 14791 new_table->set(i, get(i), mode); |
| 14791 } | 14792 } |
| 14792 | 14793 |
| 14793 // Rehash the elements. | 14794 // Rehash the elements. |
| 14794 int capacity = Capacity(); | 14795 int capacity = this->Capacity(); |
| 14795 for (int i = 0; i < capacity; i++) { | 14796 for (int i = 0; i < capacity; i++) { |
| 14796 uint32_t from_index = EntryToIndex(i); | 14797 uint32_t from_index = EntryToIndex(i); |
| 14797 Object* k = get(from_index); | 14798 Object* k = this->get(from_index); |
| 14798 if (IsKey(k)) { | 14799 if (IsKey(k)) { |
| 14799 uint32_t hash = HashTable::HashForObject(key, k); | 14800 uint32_t hash = this->HashForObject(key, k); |
| 14800 uint32_t insertion_index = | 14801 uint32_t insertion_index = |
| 14801 EntryToIndex(new_table->FindInsertionEntry(hash)); | 14802 EntryToIndex(new_table->FindInsertionEntry(hash)); |
| 14802 for (int j = 0; j < Shape::kEntrySize; j++) { | 14803 for (int j = 0; j < Shape::kEntrySize; j++) { |
| 14803 new_table->set(insertion_index + j, get(from_index + j), mode); | 14804 new_table->set(insertion_index + j, get(from_index + j), mode); |
| 14804 } | 14805 } |
| 14805 } | 14806 } |
| 14806 } | 14807 } |
| 14807 new_table->SetNumberOfElements(NumberOfElements()); | 14808 new_table->SetNumberOfElements(NumberOfElements()); |
| 14808 new_table->SetNumberOfDeletedElements(0); | 14809 new_table->SetNumberOfDeletedElements(0); |
| 14809 } | 14810 } |
| 14810 | 14811 |
| 14811 | 14812 |
| 14812 template<typename Derived, typename Shape, typename Key> | 14813 template<typename Derived, typename Shape, typename Key> |
| 14813 uint32_t HashTable<Derived, Shape, Key>::EntryForProbe( | 14814 uint32_t HashTable<Derived, Shape, Key>::EntryForProbe( |
| 14814 Key key, | 14815 Key key, |
| 14815 Object* k, | 14816 Object* k, |
| 14816 int probe, | 14817 int probe, |
| 14817 uint32_t expected) { | 14818 uint32_t expected) { |
| 14818 uint32_t hash = HashTable::HashForObject(key, k); | 14819 uint32_t hash = this->HashForObject(key, k); |
| 14819 uint32_t capacity = Capacity(); | 14820 uint32_t capacity = this->Capacity(); |
| 14820 uint32_t entry = FirstProbe(hash, capacity); | 14821 uint32_t entry = FirstProbe(hash, capacity); |
| 14821 for (int i = 1; i < probe; i++) { | 14822 for (int i = 1; i < probe; i++) { |
| 14822 if (entry == expected) return expected; | 14823 if (entry == expected) return expected; |
| 14823 entry = NextProbe(entry, i, capacity); | 14824 entry = NextProbe(entry, i, capacity); |
| 14824 } | 14825 } |
| 14825 return entry; | 14826 return entry; |
| 14826 } | 14827 } |
| 14827 | 14828 |
| 14828 | 14829 |
| 14829 template<typename Derived, typename Shape, typename Key> | 14830 template<typename Derived, typename Shape, typename Key> |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15073 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, | 15074 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, |
| 15074 uint32_t>::HasComplexElements<DictionaryEntryType::kCells>(); | 15075 uint32_t>::HasComplexElements<DictionaryEntryType::kCells>(); |
| 15075 | 15076 |
| 15076 template bool | 15077 template bool |
| 15077 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, | 15078 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, |
| 15078 uint32_t>::HasComplexElements<DictionaryEntryType::kObjects>(); | 15079 uint32_t>::HasComplexElements<DictionaryEntryType::kObjects>(); |
| 15079 | 15080 |
| 15080 template int HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, | 15081 template int HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, |
| 15081 uint32_t>::FindEntry(uint32_t); | 15082 uint32_t>::FindEntry(uint32_t); |
| 15082 | 15083 |
| 15084 template int NameDictionaryBase<NameDictionary, NameDictionaryShape>::FindEntry( |
| 15085 Handle<Name>); |
| 15086 |
| 15083 | 15087 |
| 15084 Handle<Object> JSObject::PrepareSlowElementsForSort( | 15088 Handle<Object> JSObject::PrepareSlowElementsForSort( |
| 15085 Handle<JSObject> object, uint32_t limit) { | 15089 Handle<JSObject> object, uint32_t limit) { |
| 15086 DCHECK(object->HasDictionaryElements()); | 15090 DCHECK(object->HasDictionaryElements()); |
| 15087 Isolate* isolate = object->GetIsolate(); | 15091 Isolate* isolate = object->GetIsolate(); |
| 15088 // Must stay in dictionary mode, either because of requires_slow_elements, | 15092 // Must stay in dictionary mode, either because of requires_slow_elements, |
| 15089 // or because we are not going to sort (and therefore compact) all of the | 15093 // or because we are not going to sort (and therefore compact) all of the |
| 15090 // elements. | 15094 // elements. |
| 15091 Handle<SeededNumberDictionary> dict(object->element_dictionary(), isolate); | 15095 Handle<SeededNumberDictionary> dict(object->element_dictionary(), isolate); |
| 15092 Handle<SeededNumberDictionary> new_dict = | 15096 Handle<SeededNumberDictionary> new_dict = |
| (...skipping 1070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16163 } | 16167 } |
| 16164 UNREACHABLE(); | 16168 UNREACHABLE(); |
| 16165 return false; | 16169 return false; |
| 16166 } | 16170 } |
| 16167 | 16171 |
| 16168 | 16172 |
| 16169 template <typename Derived, typename Shape, typename Key> | 16173 template <typename Derived, typename Shape, typename Key> |
| 16170 template <DictionaryEntryType type> | 16174 template <DictionaryEntryType type> |
| 16171 int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes( | 16175 int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes( |
| 16172 PropertyAttributes filter) { | 16176 PropertyAttributes filter) { |
| 16173 int capacity = DerivedHashTable::Capacity(); | 16177 int capacity = this->Capacity(); |
| 16174 int result = 0; | 16178 int result = 0; |
| 16175 for (int i = 0; i < capacity; i++) { | 16179 for (int i = 0; i < capacity; i++) { |
| 16176 Object* k = DerivedHashTable::KeyAt(i); | 16180 Object* k = this->KeyAt(i); |
| 16177 if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) { | 16181 if (this->IsKey(k) && !FilterKey(k, filter)) { |
| 16178 if (IsDeleted<type>(this, i)) continue; | 16182 if (IsDeleted<type>(this, i)) continue; |
| 16179 PropertyDetails details = DetailsAt(i); | 16183 PropertyDetails details = DetailsAt(i); |
| 16180 PropertyAttributes attr = details.attributes(); | 16184 PropertyAttributes attr = details.attributes(); |
| 16181 if ((attr & filter) == 0) result++; | 16185 if ((attr & filter) == 0) result++; |
| 16182 } | 16186 } |
| 16183 } | 16187 } |
| 16184 return result; | 16188 return result; |
| 16185 } | 16189 } |
| 16186 | 16190 |
| 16187 | 16191 |
| 16188 template <typename Derived, typename Shape, typename Key> | 16192 template <typename Derived, typename Shape, typename Key> |
| 16189 template <DictionaryEntryType type> | 16193 template <DictionaryEntryType type> |
| 16190 bool Dictionary<Derived, Shape, Key>::HasComplexElements() { | 16194 bool Dictionary<Derived, Shape, Key>::HasComplexElements() { |
| 16191 int capacity = DerivedHashTable::Capacity(); | 16195 int capacity = this->Capacity(); |
| 16192 for (int i = 0; i < capacity; i++) { | 16196 for (int i = 0; i < capacity; i++) { |
| 16193 Object* k = DerivedHashTable::KeyAt(i); | 16197 Object* k = this->KeyAt(i); |
| 16194 if (DerivedHashTable::IsKey(k) && !FilterKey(k, NONE)) { | 16198 if (this->IsKey(k) && !FilterKey(k, NONE)) { |
| 16195 if (IsDeleted<type>(this, i)) continue; | 16199 if (IsDeleted<type>(this, i)) continue; |
| 16196 PropertyDetails details = DetailsAt(i); | 16200 PropertyDetails details = DetailsAt(i); |
| 16197 if (details.type() == ACCESSOR_CONSTANT) return true; | 16201 if (details.type() == ACCESSOR_CONSTANT) return true; |
| 16198 PropertyAttributes attr = details.attributes(); | 16202 PropertyAttributes attr = details.attributes(); |
| 16199 if (attr & (READ_ONLY | DONT_DELETE | DONT_ENUM)) return true; | 16203 if (attr & (READ_ONLY | DONT_DELETE | DONT_ENUM)) return true; |
| 16200 } | 16204 } |
| 16201 } | 16205 } |
| 16202 return false; | 16206 return false; |
| 16203 } | 16207 } |
| 16204 | 16208 |
| 16205 | 16209 |
| 16206 template <typename Derived, typename Shape, typename Key> | 16210 template <typename Derived, typename Shape, typename Key> |
| 16207 template <DictionaryEntryType type> | 16211 template <DictionaryEntryType type> |
| 16208 void Dictionary<Derived, Shape, Key>::CopyKeysTo( | 16212 void Dictionary<Derived, Shape, Key>::CopyKeysTo( |
| 16209 FixedArray* storage, PropertyAttributes filter, | 16213 FixedArray* storage, PropertyAttributes filter, |
| 16210 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { | 16214 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { |
| 16211 DCHECK(storage->length() >= NumberOfElementsFilterAttributes<type>(filter)); | 16215 DCHECK(storage->length() >= NumberOfElementsFilterAttributes<type>(filter)); |
| 16212 int capacity = DerivedHashTable::Capacity(); | 16216 int capacity = this->Capacity(); |
| 16213 int index = 0; | 16217 int index = 0; |
| 16214 for (int i = 0; i < capacity; i++) { | 16218 for (int i = 0; i < capacity; i++) { |
| 16215 Object* k = DerivedHashTable::KeyAt(i); | 16219 Object* k = this->KeyAt(i); |
| 16216 if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) { | 16220 if (this->IsKey(k) && !FilterKey(k, filter)) { |
| 16217 if (IsDeleted<type>(this, i)) continue; | 16221 if (IsDeleted<type>(this, i)) continue; |
| 16218 PropertyDetails details = DetailsAt(i); | 16222 PropertyDetails details = DetailsAt(i); |
| 16219 PropertyAttributes attr = details.attributes(); | 16223 PropertyAttributes attr = details.attributes(); |
| 16220 if ((attr & filter) == 0) storage->set(index++, k); | 16224 if ((attr & filter) == 0) storage->set(index++, k); |
| 16221 } | 16225 } |
| 16222 } | 16226 } |
| 16223 if (sort_mode == Dictionary::SORTED) { | 16227 if (sort_mode == Dictionary::SORTED) { |
| 16224 storage->SortPairs(storage, index); | 16228 storage->SortPairs(storage, index); |
| 16225 } | 16229 } |
| 16226 DCHECK(storage->length() >= index); | 16230 DCHECK(storage->length() >= index); |
| 16227 } | 16231 } |
| 16228 | 16232 |
| 16229 | 16233 |
| 16234 template <typename Dictionary> |
| 16230 struct EnumIndexComparator { | 16235 struct EnumIndexComparator { |
| 16231 explicit EnumIndexComparator(NameDictionary* dict) : dict(dict) { } | 16236 explicit EnumIndexComparator(Dictionary* dict) : dict(dict) {} |
| 16232 bool operator() (Smi* a, Smi* b) { | 16237 bool operator() (Smi* a, Smi* b) { |
| 16233 PropertyDetails da(dict->DetailsAt(a->value())); | 16238 PropertyDetails da(dict->DetailsAt(a->value())); |
| 16234 PropertyDetails db(dict->DetailsAt(b->value())); | 16239 PropertyDetails db(dict->DetailsAt(b->value())); |
| 16235 return da.dictionary_index() < db.dictionary_index(); | 16240 return da.dictionary_index() < db.dictionary_index(); |
| 16236 } | 16241 } |
| 16237 NameDictionary* dict; | 16242 Dictionary* dict; |
| 16238 }; | 16243 }; |
| 16239 | 16244 |
| 16240 | 16245 |
| 16246 template <typename Derived, typename Shape, typename Key> |
| 16241 template <DictionaryEntryType type> | 16247 template <DictionaryEntryType type> |
| 16242 void NameDictionary::CopyEnumKeysTo(FixedArray* storage) { | 16248 void Dictionary<Derived, Shape, Key>::CopyEnumKeysTo(FixedArray* storage) { |
| 16243 int length = storage->length(); | 16249 int length = storage->length(); |
| 16244 int capacity = Capacity(); | 16250 int capacity = this->Capacity(); |
| 16245 int properties = 0; | 16251 int properties = 0; |
| 16246 for (int i = 0; i < capacity; i++) { | 16252 for (int i = 0; i < capacity; i++) { |
| 16247 Object* k = KeyAt(i); | 16253 Object* k = this->KeyAt(i); |
| 16248 if (IsKey(k) && !k->IsSymbol()) { | 16254 if (this->IsKey(k) && !k->IsSymbol()) { |
| 16249 PropertyDetails details = DetailsAt(i); | 16255 PropertyDetails details = DetailsAt(i); |
| 16250 if (details.IsDontEnum() || IsDeleted<type>(this, i)) continue; | 16256 if (details.IsDontEnum() || IsDeleted<type>(this, i)) continue; |
| 16251 storage->set(properties, Smi::FromInt(i)); | 16257 storage->set(properties, Smi::FromInt(i)); |
| 16252 properties++; | 16258 properties++; |
| 16253 if (properties == length) break; | 16259 if (properties == length) break; |
| 16254 } | 16260 } |
| 16255 } | 16261 } |
| 16256 CHECK_EQ(length, properties); | 16262 CHECK_EQ(length, properties); |
| 16257 EnumIndexComparator cmp(this); | 16263 EnumIndexComparator<Derived> cmp(static_cast<Derived*>(this)); |
| 16258 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress()); | 16264 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress()); |
| 16259 std::sort(start, start + length, cmp); | 16265 std::sort(start, start + length, cmp); |
| 16260 for (int i = 0; i < length; i++) { | 16266 for (int i = 0; i < length; i++) { |
| 16261 int index = Smi::cast(storage->get(i))->value(); | 16267 int index = Smi::cast(storage->get(i))->value(); |
| 16262 storage->set(i, KeyAt(index)); | 16268 storage->set(i, this->KeyAt(index)); |
| 16263 } | 16269 } |
| 16264 } | 16270 } |
| 16265 | 16271 |
| 16266 | 16272 |
| 16267 template <typename Derived, typename Shape, typename Key> | 16273 template <typename Derived, typename Shape, typename Key> |
| 16268 template <DictionaryEntryType type> | 16274 template <DictionaryEntryType type> |
| 16269 void Dictionary<Derived, Shape, Key>::CopyKeysTo( | 16275 void Dictionary<Derived, Shape, Key>::CopyKeysTo( |
| 16270 FixedArray* storage, int index, PropertyAttributes filter, | 16276 FixedArray* storage, int index, PropertyAttributes filter, |
| 16271 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { | 16277 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { |
| 16272 DCHECK(storage->length() >= NumberOfElementsFilterAttributes<type>(filter)); | 16278 DCHECK(storage->length() >= NumberOfElementsFilterAttributes<type>(filter)); |
| 16273 int capacity = DerivedHashTable::Capacity(); | 16279 int capacity = this->Capacity(); |
| 16274 for (int i = 0; i < capacity; i++) { | 16280 for (int i = 0; i < capacity; i++) { |
| 16275 Object* k = DerivedHashTable::KeyAt(i); | 16281 Object* k = this->KeyAt(i); |
| 16276 if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) { | 16282 if (this->IsKey(k) && !FilterKey(k, filter)) { |
| 16277 if (IsDeleted<type>(this, i)) continue; | 16283 if (IsDeleted<type>(this, i)) continue; |
| 16278 PropertyDetails details = DetailsAt(i); | 16284 PropertyDetails details = DetailsAt(i); |
| 16279 PropertyAttributes attr = details.attributes(); | 16285 PropertyAttributes attr = details.attributes(); |
| 16280 if ((attr & filter) == 0) storage->set(index++, k); | 16286 if ((attr & filter) == 0) storage->set(index++, k); |
| 16281 } | 16287 } |
| 16282 } | 16288 } |
| 16283 if (sort_mode == Dictionary::SORTED) { | 16289 if (sort_mode == Dictionary::SORTED) { |
| 16284 storage->SortPairs(storage, index); | 16290 storage->SortPairs(storage, index); |
| 16285 } | 16291 } |
| 16286 DCHECK(storage->length() >= index); | 16292 DCHECK(storage->length() >= index); |
| 16287 } | 16293 } |
| 16288 | 16294 |
| 16289 | 16295 |
| 16290 // Backwards lookup (slow). | 16296 // Backwards lookup (slow). |
| 16291 template<typename Derived, typename Shape, typename Key> | 16297 template<typename Derived, typename Shape, typename Key> |
| 16292 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { | 16298 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { |
| 16293 int capacity = DerivedHashTable::Capacity(); | 16299 int capacity = this->Capacity(); |
| 16294 for (int i = 0; i < capacity; i++) { | 16300 for (int i = 0; i < capacity; i++) { |
| 16295 Object* k = DerivedHashTable::KeyAt(i); | 16301 Object* k = this->KeyAt(i); |
| 16296 if (Dictionary::IsKey(k)) { | 16302 if (this->IsKey(k)) { |
| 16297 Object* e = ValueAt(i); | 16303 Object* e = ValueAt(i); |
| 16298 // TODO(dcarney): this should be templatized. | 16304 // TODO(dcarney): this should be templatized. |
| 16299 if (e->IsPropertyCell()) { | 16305 if (e->IsPropertyCell()) { |
| 16300 e = PropertyCell::cast(e)->value(); | 16306 e = PropertyCell::cast(e)->value(); |
| 16301 } | 16307 } |
| 16302 if (e == value) return k; | 16308 if (e == value) return k; |
| 16303 } | 16309 } |
| 16304 } | 16310 } |
| 16305 Heap* heap = Dictionary::GetHeap(); | 16311 Heap* heap = Dictionary::GetHeap(); |
| 16306 return heap->undefined_value(); | 16312 return heap->undefined_value(); |
| (...skipping 1040 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17347 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, | 17353 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, |
| 17348 Handle<Object> new_value) { | 17354 Handle<Object> new_value) { |
| 17349 if (cell->value() != *new_value) { | 17355 if (cell->value() != *new_value) { |
| 17350 cell->set_value(*new_value); | 17356 cell->set_value(*new_value); |
| 17351 Isolate* isolate = cell->GetIsolate(); | 17357 Isolate* isolate = cell->GetIsolate(); |
| 17352 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17358 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 17353 isolate, DependentCode::kPropertyCellChangedGroup); | 17359 isolate, DependentCode::kPropertyCellChangedGroup); |
| 17354 } | 17360 } |
| 17355 } | 17361 } |
| 17356 } } // namespace v8::internal | 17362 } } // namespace v8::internal |
| OLD | NEW |