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 |