| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 "src/elements.h" | 5 #include "src/elements.h" |
| 6 | 6 |
| 7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
| 8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
| 9 #include "src/factory.h" | 9 #include "src/factory.h" |
| 10 #include "src/messages.h" | 10 #include "src/messages.h" |
| (...skipping 821 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 832 // elements. In all the other cases there are no allocations performed and | 832 // elements. In all the other cases there are no allocations performed and |
| 833 // handle creation causes noticeable performance degradation of the builtin. | 833 // handle creation causes noticeable performance degradation of the builtin. |
| 834 ElementsAccessorSubclass::CopyElementsImpl( | 834 ElementsAccessorSubclass::CopyElementsImpl( |
| 835 from, from_start, *to, from_kind, to_start, packed_size, copy_size); | 835 from, from_start, *to, from_kind, to_start, packed_size, copy_size); |
| 836 } | 836 } |
| 837 | 837 |
| 838 void CollectElementIndices(Handle<JSObject> object, | 838 void CollectElementIndices(Handle<JSObject> object, |
| 839 Handle<FixedArrayBase> backing_store, | 839 Handle<FixedArrayBase> backing_store, |
| 840 KeyAccumulator* keys, uint32_t range, | 840 KeyAccumulator* keys, uint32_t range, |
| 841 PropertyFilter filter, uint32_t offset) final { | 841 PropertyFilter filter, uint32_t offset) final { |
| 842 if (filter & ONLY_ALL_CAN_READ) return; |
| 842 ElementsAccessorSubclass::CollectElementIndicesImpl( | 843 ElementsAccessorSubclass::CollectElementIndicesImpl( |
| 843 object, backing_store, keys, range, filter, offset); | 844 object, backing_store, keys, range, filter, offset); |
| 844 } | 845 } |
| 845 | 846 |
| 846 static void CollectElementIndicesImpl(Handle<JSObject> object, | 847 static void CollectElementIndicesImpl(Handle<JSObject> object, |
| 847 Handle<FixedArrayBase> backing_store, | 848 Handle<FixedArrayBase> backing_store, |
| 848 KeyAccumulator* keys, uint32_t range, | 849 KeyAccumulator* keys, uint32_t range, |
| 849 PropertyFilter filter, | 850 PropertyFilter filter, |
| 850 uint32_t offset) { | 851 uint32_t offset) { |
| 851 DCHECK_NE(DICTIONARY_ELEMENTS, kind()); | 852 DCHECK_NE(DICTIONARY_ELEMENTS, kind()); |
| 852 if (filter & ONLY_ALL_CAN_READ) { | 853 // Non-dictionary elements can't have all-can-read accessors. |
| 853 // Non-dictionary elements can't have all-can-read accessors. | |
| 854 return; | |
| 855 } | |
| 856 uint32_t length = GetIterationLength(*object, *backing_store); | 854 uint32_t length = GetIterationLength(*object, *backing_store); |
| 857 if (range < length) length = range; | 855 if (range < length) length = range; |
| 858 for (uint32_t i = offset; i < length; i++) { | 856 for (uint32_t i = offset; i < length; i++) { |
| 859 if (ElementsAccessorSubclass::HasElementImpl(object, i, backing_store, | 857 if (ElementsAccessorSubclass::HasElementImpl(object, i, backing_store, |
| 860 filter)) { | 858 filter)) { |
| 861 keys->AddKey(i); | 859 keys->AddKey(i); |
| 862 } | 860 } |
| 863 } | 861 } |
| 864 } | 862 } |
| 865 | 863 |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1183 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, | 1181 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, |
| 1184 uint32_t entry) { | 1182 uint32_t entry) { |
| 1185 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry); | 1183 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry); |
| 1186 } | 1184 } |
| 1187 | 1185 |
| 1188 static uint32_t GetKeyForEntryImpl(Handle<SeededNumberDictionary> dictionary, | 1186 static uint32_t GetKeyForEntryImpl(Handle<SeededNumberDictionary> dictionary, |
| 1189 int entry, PropertyFilter filter) { | 1187 int entry, PropertyFilter filter) { |
| 1190 DisallowHeapAllocation no_gc; | 1188 DisallowHeapAllocation no_gc; |
| 1191 Object* raw_key = dictionary->KeyAt(entry); | 1189 Object* raw_key = dictionary->KeyAt(entry); |
| 1192 if (!dictionary->IsKey(raw_key)) return kMaxUInt32; | 1190 if (!dictionary->IsKey(raw_key)) return kMaxUInt32; |
| 1193 if (raw_key->FilterKey(filter)) return kMaxUInt32; | 1191 DCHECK(!dictionary->IsDeleted(entry)); |
| 1194 if (dictionary->IsDeleted(entry)) return kMaxUInt32; | |
| 1195 DCHECK(raw_key->IsNumber()); | 1192 DCHECK(raw_key->IsNumber()); |
| 1196 DCHECK_LE(raw_key->Number(), kMaxUInt32); | 1193 DCHECK_LE(raw_key->Number(), kMaxUInt32); |
| 1197 uint32_t key = static_cast<uint32_t>(raw_key->Number()); | |
| 1198 PropertyDetails details = dictionary->DetailsAt(entry); | 1194 PropertyDetails details = dictionary->DetailsAt(entry); |
| 1199 if (filter & ONLY_ALL_CAN_READ) { | |
| 1200 if (details.kind() != kAccessor) return kMaxUInt32; | |
| 1201 Object* accessors = dictionary->ValueAt(entry); | |
| 1202 if (!accessors->IsAccessorInfo()) return kMaxUInt32; | |
| 1203 if (!AccessorInfo::cast(accessors)->all_can_read()) return kMaxUInt32; | |
| 1204 } | |
| 1205 PropertyAttributes attr = details.attributes(); | 1195 PropertyAttributes attr = details.attributes(); |
| 1206 if ((attr & filter) != 0) return kMaxUInt32; | 1196 if ((attr & filter) != 0) return kMaxUInt32; |
| 1207 return key; | 1197 return static_cast<uint32_t>(raw_key->Number()); |
| 1208 } | 1198 } |
| 1209 | 1199 |
| 1210 static void CollectElementIndicesImpl(Handle<JSObject> object, | 1200 static void CollectElementIndicesImpl(Handle<JSObject> object, |
| 1211 Handle<FixedArrayBase> backing_store, | 1201 Handle<FixedArrayBase> backing_store, |
| 1212 KeyAccumulator* keys, uint32_t range, | 1202 KeyAccumulator* keys, uint32_t range, |
| 1213 PropertyFilter filter, | 1203 PropertyFilter filter, |
| 1214 uint32_t offset) { | 1204 uint32_t offset) { |
| 1205 if (filter & SKIP_STRINGS) return; |
| 1215 Handle<SeededNumberDictionary> dictionary = | 1206 Handle<SeededNumberDictionary> dictionary = |
| 1216 Handle<SeededNumberDictionary>::cast(backing_store); | 1207 Handle<SeededNumberDictionary>::cast(backing_store); |
| 1217 int capacity = dictionary->Capacity(); | 1208 int capacity = dictionary->Capacity(); |
| 1218 for (int i = 0; i < capacity; i++) { | 1209 for (int i = 0; i < capacity; i++) { |
| 1219 uint32_t key = GetKeyForEntryImpl(dictionary, i, filter); | 1210 uint32_t key = GetKeyForEntryImpl(dictionary, i, filter); |
| 1220 if (key == kMaxUInt32) continue; | 1211 if (key == kMaxUInt32) continue; |
| 1221 keys->AddKey(key); | 1212 keys->AddKey(key); |
| 1222 } | 1213 } |
| 1223 | 1214 |
| 1224 keys->SortCurrentElementsList(); | 1215 keys->SortCurrentElementsList(); |
| 1225 } | 1216 } |
| 1226 | 1217 |
| 1227 static Handle<FixedArray> DirectCollectElementIndicesImpl( | 1218 static Handle<FixedArray> DirectCollectElementIndicesImpl( |
| 1228 Isolate* isolate, Handle<JSObject> object, | 1219 Isolate* isolate, Handle<JSObject> object, |
| 1229 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, | 1220 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, |
| 1230 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, | 1221 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, |
| 1231 uint32_t insertion_index = 0) { | 1222 uint32_t insertion_index = 0) { |
| 1223 if (filter & SKIP_STRINGS) return list; |
| 1224 if (filter & ONLY_ALL_CAN_READ) return list; |
| 1232 Handle<SeededNumberDictionary> dictionary = | 1225 Handle<SeededNumberDictionary> dictionary = |
| 1233 Handle<SeededNumberDictionary>::cast(backing_store); | 1226 Handle<SeededNumberDictionary>::cast(backing_store); |
| 1234 uint32_t capacity = dictionary->Capacity(); | 1227 uint32_t capacity = dictionary->Capacity(); |
| 1235 for (uint32_t i = 0; i < capacity; i++) { | 1228 for (uint32_t i = 0; i < capacity; i++) { |
| 1236 uint32_t key = GetKeyForEntryImpl(dictionary, i, filter); | 1229 uint32_t key = GetKeyForEntryImpl(dictionary, i, filter); |
| 1237 if (key == kMaxUInt32) continue; | 1230 if (key == kMaxUInt32) continue; |
| 1238 Handle<Object> index = isolate->factory()->NewNumberFromUint(key); | 1231 Handle<Object> index = isolate->factory()->NewNumberFromUint(key); |
| 1239 list->set(insertion_index, *index); | 1232 list->set(insertion_index, *index); |
| 1240 insertion_index++; | 1233 insertion_index++; |
| 1241 } | 1234 } |
| (...skipping 1312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2554 } | 2547 } |
| 2555 BackingStoreAccessor::AddElementsToKeyAccumulatorImpl(receiver, accumulator, | 2548 BackingStoreAccessor::AddElementsToKeyAccumulatorImpl(receiver, accumulator, |
| 2556 convert); | 2549 convert); |
| 2557 } | 2550 } |
| 2558 | 2551 |
| 2559 static void CollectElementIndicesImpl(Handle<JSObject> object, | 2552 static void CollectElementIndicesImpl(Handle<JSObject> object, |
| 2560 Handle<FixedArrayBase> backing_store, | 2553 Handle<FixedArrayBase> backing_store, |
| 2561 KeyAccumulator* keys, uint32_t range, | 2554 KeyAccumulator* keys, uint32_t range, |
| 2562 PropertyFilter filter, | 2555 PropertyFilter filter, |
| 2563 uint32_t offset) { | 2556 uint32_t offset) { |
| 2564 if ((filter & ONLY_ALL_CAN_READ) == 0) { | 2557 uint32_t length = GetString(*object)->length(); |
| 2565 uint32_t length = GetString(*object)->length(); | 2558 for (uint32_t i = 0; i < length; i++) { |
| 2566 for (uint32_t i = 0; i < length; i++) { | 2559 keys->AddKey(i); |
| 2567 keys->AddKey(i); | |
| 2568 } | |
| 2569 } | 2560 } |
| 2570 BackingStoreAccessor::CollectElementIndicesImpl(object, backing_store, keys, | 2561 BackingStoreAccessor::CollectElementIndicesImpl(object, backing_store, keys, |
| 2571 range, filter, offset); | 2562 range, filter, offset); |
| 2572 } | 2563 } |
| 2573 | 2564 |
| 2574 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, | 2565 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, |
| 2575 FixedArrayBase* to, ElementsKind from_kind, | 2566 FixedArrayBase* to, ElementsKind from_kind, |
| 2576 uint32_t to_start, int packed_size, | 2567 uint32_t to_start, int packed_size, |
| 2577 int copy_size) { | 2568 int copy_size) { |
| 2578 BackingStoreAccessor::CopyElementsImpl(from, from_start, to, from_kind, | 2569 BackingStoreAccessor::CopyElementsImpl(from, from_start, to, from_kind, |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2823 } | 2814 } |
| 2824 } | 2815 } |
| 2825 | 2816 |
| 2826 DCHECK(j == result_len); | 2817 DCHECK(j == result_len); |
| 2827 return result_array; | 2818 return result_array; |
| 2828 } | 2819 } |
| 2829 | 2820 |
| 2830 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 2821 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
| 2831 } // namespace internal | 2822 } // namespace internal |
| 2832 } // namespace v8 | 2823 } // namespace v8 |
| OLD | NEW |