| 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 |