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/isolate-inl.h" | 10 #include "src/isolate-inl.h" |
(...skipping 847 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
858 } | 858 } |
859 | 859 |
860 static Maybe<bool> CollectValuesOrEntriesImpl( | 860 static Maybe<bool> CollectValuesOrEntriesImpl( |
861 Isolate* isolate, Handle<JSObject> object, | 861 Isolate* isolate, Handle<JSObject> object, |
862 Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, | 862 Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, |
863 PropertyFilter filter) { | 863 PropertyFilter filter) { |
864 int count = 0; | 864 int count = 0; |
865 KeyAccumulator accumulator(isolate, OWN_ONLY, ALL_PROPERTIES); | 865 KeyAccumulator accumulator(isolate, OWN_ONLY, ALL_PROPERTIES); |
866 accumulator.NextPrototype(); | 866 accumulator.NextPrototype(); |
867 Subclass::CollectElementIndicesImpl( | 867 Subclass::CollectElementIndicesImpl( |
868 object, handle(object->elements(), isolate), &accumulator, kMaxUInt32, | 868 object, handle(object->elements(), isolate), &accumulator); |
869 ALL_PROPERTIES, 0); | |
870 Handle<FixedArray> keys = accumulator.GetKeys(); | 869 Handle<FixedArray> keys = accumulator.GetKeys(); |
871 | 870 |
872 for (int i = 0; i < keys->length(); ++i) { | 871 for (int i = 0; i < keys->length(); ++i) { |
873 Handle<Object> key(keys->get(i), isolate); | 872 Handle<Object> key(keys->get(i), isolate); |
874 Handle<Object> value; | 873 Handle<Object> value; |
875 uint32_t index; | 874 uint32_t index; |
876 if (!key->ToUint32(&index)) continue; | 875 if (!key->ToUint32(&index)) continue; |
877 | 876 |
878 uint32_t entry = Subclass::GetEntryForIndexImpl( | 877 uint32_t entry = Subclass::GetEntryForIndexImpl( |
879 *object, object->elements(), index, filter); | 878 *object, object->elements(), index, filter); |
(...skipping 13 matching lines...) Expand all Loading... |
893 } | 892 } |
894 values_or_entries->set(count++, *value); | 893 values_or_entries->set(count++, *value); |
895 } | 894 } |
896 | 895 |
897 *nof_items = count; | 896 *nof_items = count; |
898 return Just(true); | 897 return Just(true); |
899 } | 898 } |
900 | 899 |
901 void CollectElementIndices(Handle<JSObject> object, | 900 void CollectElementIndices(Handle<JSObject> object, |
902 Handle<FixedArrayBase> backing_store, | 901 Handle<FixedArrayBase> backing_store, |
903 KeyAccumulator* keys, uint32_t range, | 902 KeyAccumulator* keys) final { |
904 PropertyFilter filter, uint32_t offset) final { | 903 if (keys->filter() & ONLY_ALL_CAN_READ) return; |
905 if (filter & ONLY_ALL_CAN_READ) return; | 904 Subclass::CollectElementIndicesImpl(object, backing_store, keys); |
906 Subclass::CollectElementIndicesImpl(object, backing_store, keys, range, | |
907 filter, offset); | |
908 } | 905 } |
909 | 906 |
910 static void CollectElementIndicesImpl(Handle<JSObject> object, | 907 static void CollectElementIndicesImpl(Handle<JSObject> object, |
911 Handle<FixedArrayBase> backing_store, | 908 Handle<FixedArrayBase> backing_store, |
912 KeyAccumulator* keys, uint32_t range, | 909 KeyAccumulator* keys) { |
913 PropertyFilter filter, | |
914 uint32_t offset) { | |
915 DCHECK_NE(DICTIONARY_ELEMENTS, kind()); | 910 DCHECK_NE(DICTIONARY_ELEMENTS, kind()); |
916 // Non-dictionary elements can't have all-can-read accessors. | 911 // Non-dictionary elements can't have all-can-read accessors. |
917 uint32_t length = GetIterationLength(*object, *backing_store); | 912 uint32_t length = GetIterationLength(*object, *backing_store); |
918 if (range < length) length = range; | 913 PropertyFilter filter = keys->filter(); |
919 for (uint32_t i = offset; i < length; i++) { | 914 for (uint32_t i = 0; i < length; i++) { |
920 if (Subclass::HasElementImpl(object, i, backing_store, filter)) { | 915 if (Subclass::HasElementImpl(object, i, backing_store, filter)) { |
921 keys->AddKey(i); | 916 keys->AddKey(i); |
922 } | 917 } |
923 } | 918 } |
924 } | 919 } |
925 | 920 |
926 static Handle<FixedArray> DirectCollectElementIndicesImpl( | 921 static Handle<FixedArray> DirectCollectElementIndicesImpl( |
927 Isolate* isolate, Handle<JSObject> object, | 922 Isolate* isolate, Handle<JSObject> object, |
928 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, | 923 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, |
929 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, | 924 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1309 Object* raw_key = dictionary->KeyAt(entry); | 1304 Object* raw_key = dictionary->KeyAt(entry); |
1310 // Replace the IsKey check with a direct comparison which is much faster. | 1305 // Replace the IsKey check with a direct comparison which is much faster. |
1311 if (raw_key == undefined || raw_key == the_hole) { | 1306 if (raw_key == undefined || raw_key == the_hole) { |
1312 return kMaxUInt32; | 1307 return kMaxUInt32; |
1313 } | 1308 } |
1314 return FilterKey(dictionary, entry, raw_key, filter); | 1309 return FilterKey(dictionary, entry, raw_key, filter); |
1315 } | 1310 } |
1316 | 1311 |
1317 static void CollectElementIndicesImpl(Handle<JSObject> object, | 1312 static void CollectElementIndicesImpl(Handle<JSObject> object, |
1318 Handle<FixedArrayBase> backing_store, | 1313 Handle<FixedArrayBase> backing_store, |
1319 KeyAccumulator* keys, uint32_t range, | 1314 KeyAccumulator* keys) { |
1320 PropertyFilter filter, | 1315 if (keys->filter() & SKIP_STRINGS) return; |
1321 uint32_t offset) { | |
1322 if (filter & SKIP_STRINGS) return; | |
1323 Isolate* isolate = keys->isolate(); | 1316 Isolate* isolate = keys->isolate(); |
1324 Handle<Object> undefined = isolate->factory()->undefined_value(); | 1317 Handle<Object> undefined = isolate->factory()->undefined_value(); |
1325 Handle<Object> the_hole = isolate->factory()->the_hole_value(); | 1318 Handle<Object> the_hole = isolate->factory()->the_hole_value(); |
1326 Handle<SeededNumberDictionary> dictionary = | 1319 Handle<SeededNumberDictionary> dictionary = |
1327 Handle<SeededNumberDictionary>::cast(backing_store); | 1320 Handle<SeededNumberDictionary>::cast(backing_store); |
1328 int capacity = dictionary->Capacity(); | 1321 int capacity = dictionary->Capacity(); |
| 1322 PropertyFilter filter = keys->filter(); |
1329 for (int i = 0; i < capacity; i++) { | 1323 for (int i = 0; i < capacity; i++) { |
1330 uint32_t key = | 1324 uint32_t key = |
1331 GetKeyForEntryImpl(dictionary, i, filter, *undefined, *the_hole); | 1325 GetKeyForEntryImpl(dictionary, i, filter, *undefined, *the_hole); |
1332 if (key == kMaxUInt32) continue; | 1326 if (key == kMaxUInt32) continue; |
1333 keys->AddKey(key); | 1327 keys->AddKey(key); |
1334 } | 1328 } |
1335 | 1329 |
1336 keys->SortCurrentElementsList(); | 1330 keys->SortCurrentElementsList(); |
1337 } | 1331 } |
1338 | 1332 |
(...skipping 1045 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2384 // parameter, and revert to normal elements in that case. That | 2378 // parameter, and revert to normal elements in that case. That |
2385 // would enable GC of the context. | 2379 // would enable GC of the context. |
2386 parameter_map->set_the_hole(entry + 2); | 2380 parameter_map->set_the_hole(entry + 2); |
2387 } else { | 2381 } else { |
2388 Subclass::DeleteFromArguments(obj, entry - length); | 2382 Subclass::DeleteFromArguments(obj, entry - length); |
2389 } | 2383 } |
2390 } | 2384 } |
2391 | 2385 |
2392 static void CollectElementIndicesImpl(Handle<JSObject> object, | 2386 static void CollectElementIndicesImpl(Handle<JSObject> object, |
2393 Handle<FixedArrayBase> backing_store, | 2387 Handle<FixedArrayBase> backing_store, |
2394 KeyAccumulator* keys, uint32_t range, | 2388 KeyAccumulator* keys) { |
2395 PropertyFilter filter, | |
2396 uint32_t offset) { | |
2397 FixedArray* parameter_map = FixedArray::cast(*backing_store); | 2389 FixedArray* parameter_map = FixedArray::cast(*backing_store); |
2398 uint32_t length = parameter_map->length() - 2; | 2390 uint32_t length = parameter_map->length() - 2; |
2399 if (range < length) length = range; | 2391 for (uint32_t i = 0; i < length; ++i) { |
2400 | |
2401 for (uint32_t i = offset; i < length; ++i) { | |
2402 if (!parameter_map->get(i + 2)->IsTheHole()) { | 2392 if (!parameter_map->get(i + 2)->IsTheHole()) { |
2403 keys->AddKey(i); | 2393 keys->AddKey(i); |
2404 } | 2394 } |
2405 } | 2395 } |
2406 | 2396 |
2407 Handle<FixedArrayBase> store(FixedArrayBase::cast(parameter_map->get(1))); | 2397 Handle<FixedArrayBase> store(FixedArrayBase::cast(parameter_map->get(1))); |
2408 ArgumentsAccessor::CollectElementIndicesImpl(object, store, keys, range, | 2398 ArgumentsAccessor::CollectElementIndicesImpl(object, store, keys); |
2409 filter, offset); | |
2410 if (Subclass::kind() == FAST_SLOPPY_ARGUMENTS_ELEMENTS) { | 2399 if (Subclass::kind() == FAST_SLOPPY_ARGUMENTS_ELEMENTS) { |
2411 keys->SortCurrentElementsList(); | 2400 keys->SortCurrentElementsList(); |
2412 } | 2401 } |
2413 } | 2402 } |
2414 | 2403 |
2415 static Handle<FixedArray> DirectCollectElementIndicesImpl( | 2404 static Handle<FixedArray> DirectCollectElementIndicesImpl( |
2416 Isolate* isolate, Handle<JSObject> object, | 2405 Isolate* isolate, Handle<JSObject> object, |
2417 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, | 2406 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, |
2418 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, | 2407 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, |
2419 uint32_t insertion_index = 0) { | 2408 uint32_t insertion_index = 0) { |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2747 isolate->factory()->LookupSingleCharacterStringFromCode( | 2736 isolate->factory()->LookupSingleCharacterStringFromCode( |
2748 string->Get(i)), | 2737 string->Get(i)), |
2749 convert); | 2738 convert); |
2750 } | 2739 } |
2751 BackingStoreAccessor::AddElementsToKeyAccumulatorImpl(receiver, accumulator, | 2740 BackingStoreAccessor::AddElementsToKeyAccumulatorImpl(receiver, accumulator, |
2752 convert); | 2741 convert); |
2753 } | 2742 } |
2754 | 2743 |
2755 static void CollectElementIndicesImpl(Handle<JSObject> object, | 2744 static void CollectElementIndicesImpl(Handle<JSObject> object, |
2756 Handle<FixedArrayBase> backing_store, | 2745 Handle<FixedArrayBase> backing_store, |
2757 KeyAccumulator* keys, uint32_t range, | 2746 KeyAccumulator* keys) { |
2758 PropertyFilter filter, | |
2759 uint32_t offset) { | |
2760 uint32_t length = GetString(*object)->length(); | 2747 uint32_t length = GetString(*object)->length(); |
2761 for (uint32_t i = 0; i < length; i++) { | 2748 for (uint32_t i = 0; i < length; i++) { |
2762 keys->AddKey(i); | 2749 keys->AddKey(i); |
2763 } | 2750 } |
2764 BackingStoreAccessor::CollectElementIndicesImpl(object, backing_store, keys, | 2751 BackingStoreAccessor::CollectElementIndicesImpl(object, backing_store, |
2765 range, filter, offset); | 2752 keys); |
2766 } | 2753 } |
2767 | 2754 |
2768 static void GrowCapacityAndConvertImpl(Handle<JSObject> object, | 2755 static void GrowCapacityAndConvertImpl(Handle<JSObject> object, |
2769 uint32_t capacity) { | 2756 uint32_t capacity) { |
2770 Handle<FixedArrayBase> old_elements(object->elements()); | 2757 Handle<FixedArrayBase> old_elements(object->elements()); |
2771 ElementsKind from_kind = object->GetElementsKind(); | 2758 ElementsKind from_kind = object->GetElementsKind(); |
2772 // This method should only be called if there's a reason to update the | 2759 // This method should only be called if there's a reason to update the |
2773 // elements. | 2760 // elements. |
2774 DCHECK(from_kind == SLOW_STRING_WRAPPER_ELEMENTS || | 2761 DCHECK(from_kind == SLOW_STRING_WRAPPER_ELEMENTS || |
2775 static_cast<uint32_t>(old_elements->length()) < capacity); | 2762 static_cast<uint32_t>(old_elements->length()) < capacity); |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3051 insertion_index += len; | 3038 insertion_index += len; |
3052 } | 3039 } |
3053 | 3040 |
3054 DCHECK_EQ(insertion_index, result_len); | 3041 DCHECK_EQ(insertion_index, result_len); |
3055 return result_array; | 3042 return result_array; |
3056 } | 3043 } |
3057 | 3044 |
3058 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 3045 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
3059 } // namespace internal | 3046 } // namespace internal |
3060 } // namespace v8 | 3047 } // namespace v8 |
OLD | NEW |