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 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 isolate->builtins()->builtin(Builtins::kFunctionPrototypeApply); | 438 isolate->builtins()->builtin(Builtins::kFunctionPrototypeApply); |
439 if (raw_frame->unchecked_code() == apply_builtin) { | 439 if (raw_frame->unchecked_code() == apply_builtin) { |
440 PrintF("apply from "); | 440 PrintF("apply from "); |
441 it.Advance(); | 441 it.Advance(); |
442 raw_frame = it.frame(); | 442 raw_frame = it.frame(); |
443 } | 443 } |
444 } | 444 } |
445 JavaScriptFrame::PrintTop(isolate, stdout, false, true); | 445 JavaScriptFrame::PrintTop(isolate, stdout, false, true); |
446 } | 446 } |
447 | 447 |
448 static void SortIndices( | |
449 Handle<FixedArray> indices, uint32_t sort_size, | |
450 WriteBarrierMode write_barrier_mode = UPDATE_WRITE_BARRIER) { | |
451 struct { | |
452 bool operator()(Object* a, Object* b) { | |
453 if (!a->IsUndefined()) { | |
454 if (b->IsUndefined()) return true; | |
455 return a->Number() < b->Number(); | |
456 } | |
457 return b->IsUndefined(); | |
458 } | |
459 } cmp; | |
460 Object** start = | |
461 reinterpret_cast<Object**>(indices->GetFirstElementAddress()); | |
462 std::sort(start, start + sort_size, cmp); | |
463 if (write_barrier_mode != SKIP_WRITE_BARRIER) { | |
464 FIXED_ARRAY_ELEMENTS_WRITE_BARRIER(indices->GetIsolate()->heap(), *indices, | |
465 0, sort_size); | |
466 } | |
467 } | |
468 | 448 |
469 // Base class for element handler implementations. Contains the | 449 // Base class for element handler implementations. Contains the |
470 // the common logic for objects with different ElementsKinds. | 450 // the common logic for objects with different ElementsKinds. |
471 // Subclasses must specialize method for which the element | 451 // Subclasses must specialize method for which the element |
472 // implementation differs from the base class implementation. | 452 // implementation differs from the base class implementation. |
473 // | 453 // |
474 // This class is intended to be used in the following way: | 454 // This class is intended to be used in the following way: |
475 // | 455 // |
476 // class SomeElementsAccessor : | 456 // class SomeElementsAccessor : |
477 // public ElementsAccessorBase<SomeElementsAccessor, | 457 // public ElementsAccessorBase<SomeElementsAccessor, |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
722 } else { | 702 } else { |
723 // Check whether the backing store should be expanded. | 703 // Check whether the backing store should be expanded. |
724 capacity = Max(length, JSObject::NewElementsCapacity(capacity)); | 704 capacity = Max(length, JSObject::NewElementsCapacity(capacity)); |
725 Subclass::GrowCapacityAndConvertImpl(array, capacity); | 705 Subclass::GrowCapacityAndConvertImpl(array, capacity); |
726 } | 706 } |
727 | 707 |
728 array->set_length(Smi::FromInt(length)); | 708 array->set_length(Smi::FromInt(length)); |
729 JSObject::ValidateElements(array); | 709 JSObject::ValidateElements(array); |
730 } | 710 } |
731 | 711 |
732 static uint32_t GetMaxIndex(JSObject* receiver, FixedArrayBase* elements) { | 712 static uint32_t GetIterationLength(JSObject* receiver, |
| 713 FixedArrayBase* elements) { |
733 if (receiver->IsJSArray()) { | 714 if (receiver->IsJSArray()) { |
734 DCHECK(JSArray::cast(receiver)->length()->IsSmi()); | 715 DCHECK(JSArray::cast(receiver)->length()->IsSmi()); |
735 return static_cast<uint32_t>( | 716 return static_cast<uint32_t>( |
736 Smi::cast(JSArray::cast(receiver)->length())->value()); | 717 Smi::cast(JSArray::cast(receiver)->length())->value()); |
737 } | 718 } |
738 return Subclass::GetCapacityImpl(receiver, elements); | 719 return Subclass::GetCapacityImpl(receiver, elements); |
739 } | 720 } |
740 | 721 |
741 static uint32_t GetMaxNumberOfEntries(JSObject* receiver, | |
742 FixedArrayBase* elements) { | |
743 return Subclass::GetMaxIndex(receiver, elements); | |
744 } | |
745 | |
746 static Handle<FixedArrayBase> ConvertElementsWithCapacity( | 722 static Handle<FixedArrayBase> ConvertElementsWithCapacity( |
747 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, | 723 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, |
748 ElementsKind from_kind, uint32_t capacity) { | 724 ElementsKind from_kind, uint32_t capacity) { |
749 return ConvertElementsWithCapacity( | 725 return ConvertElementsWithCapacity( |
750 object, old_elements, from_kind, capacity, 0, 0, | 726 object, old_elements, from_kind, capacity, 0, 0, |
751 ElementsAccessor::kCopyToEndAndInitializeToHole); | 727 ElementsAccessor::kCopyToEndAndInitializeToHole); |
752 } | 728 } |
753 | 729 |
754 static Handle<FixedArrayBase> ConvertElementsWithCapacity( | 730 static Handle<FixedArrayBase> ConvertElementsWithCapacity( |
755 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, | 731 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
880 return Subclass::CollectValuesOrEntriesImpl( | 856 return Subclass::CollectValuesOrEntriesImpl( |
881 isolate, object, values_or_entries, get_entries, nof_items, filter); | 857 isolate, object, values_or_entries, get_entries, nof_items, filter); |
882 } | 858 } |
883 | 859 |
884 static Maybe<bool> CollectValuesOrEntriesImpl( | 860 static Maybe<bool> CollectValuesOrEntriesImpl( |
885 Isolate* isolate, Handle<JSObject> object, | 861 Isolate* isolate, Handle<JSObject> object, |
886 Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, | 862 Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, |
887 PropertyFilter filter) { | 863 PropertyFilter filter) { |
888 int count = 0; | 864 int count = 0; |
889 KeyAccumulator accumulator(isolate, OWN_ONLY, ALL_PROPERTIES); | 865 KeyAccumulator accumulator(isolate, OWN_ONLY, ALL_PROPERTIES); |
| 866 accumulator.NextPrototype(); |
890 Subclass::CollectElementIndicesImpl( | 867 Subclass::CollectElementIndicesImpl( |
891 object, handle(object->elements(), isolate), &accumulator); | 868 object, handle(object->elements(), isolate), &accumulator); |
892 Handle<FixedArray> keys = accumulator.GetKeys(); | 869 Handle<FixedArray> keys = accumulator.GetKeys(); |
893 | 870 |
894 for (int i = 0; i < keys->length(); ++i) { | 871 for (int i = 0; i < keys->length(); ++i) { |
895 Handle<Object> key(keys->get(i), isolate); | 872 Handle<Object> key(keys->get(i), isolate); |
896 Handle<Object> value; | 873 Handle<Object> value; |
897 uint32_t index; | 874 uint32_t index; |
898 if (!key->ToUint32(&index)) continue; | 875 if (!key->ToUint32(&index)) continue; |
899 | 876 |
(...skipping 25 matching lines...) Expand all Loading... |
925 KeyAccumulator* keys) final { | 902 KeyAccumulator* keys) final { |
926 if (keys->filter() & ONLY_ALL_CAN_READ) return; | 903 if (keys->filter() & ONLY_ALL_CAN_READ) return; |
927 Subclass::CollectElementIndicesImpl(object, backing_store, keys); | 904 Subclass::CollectElementIndicesImpl(object, backing_store, keys); |
928 } | 905 } |
929 | 906 |
930 static void CollectElementIndicesImpl(Handle<JSObject> object, | 907 static void CollectElementIndicesImpl(Handle<JSObject> object, |
931 Handle<FixedArrayBase> backing_store, | 908 Handle<FixedArrayBase> backing_store, |
932 KeyAccumulator* keys) { | 909 KeyAccumulator* keys) { |
933 DCHECK_NE(DICTIONARY_ELEMENTS, kind()); | 910 DCHECK_NE(DICTIONARY_ELEMENTS, kind()); |
934 // Non-dictionary elements can't have all-can-read accessors. | 911 // Non-dictionary elements can't have all-can-read accessors. |
935 uint32_t length = Subclass::GetMaxIndex(*object, *backing_store); | 912 uint32_t length = GetIterationLength(*object, *backing_store); |
936 PropertyFilter filter = keys->filter(); | 913 PropertyFilter filter = keys->filter(); |
937 Factory* factory = keys->isolate()->factory(); | |
938 for (uint32_t i = 0; i < length; i++) { | 914 for (uint32_t i = 0; i < length; i++) { |
939 if (Subclass::HasElementImpl(object, i, backing_store, filter)) { | 915 if (Subclass::HasElementImpl(object, i, backing_store, filter)) { |
940 keys->AddKey(factory->NewNumberFromUint(i)); | 916 keys->AddKey(i); |
941 } | 917 } |
942 } | 918 } |
943 } | 919 } |
944 | 920 |
945 static Handle<FixedArray> DirectCollectElementIndicesImpl( | 921 static Handle<FixedArray> DirectCollectElementIndicesImpl( |
946 Isolate* isolate, Handle<JSObject> object, | 922 Isolate* isolate, Handle<JSObject> object, |
947 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, | 923 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, |
948 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, | 924 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, |
949 uint32_t insertion_index = 0) { | 925 uint32_t insertion_index = 0) { |
950 uint32_t length = Subclass::GetMaxIndex(*object, *backing_store); | 926 uint32_t length = Subclass::GetIterationLength(*object, *backing_store); |
951 for (uint32_t i = 0; i < length; i++) { | 927 for (uint32_t i = 0; i < length; i++) { |
952 if (Subclass::HasElementImpl(object, i, backing_store, filter)) { | 928 if (Subclass::HasElementImpl(object, i, backing_store, filter)) { |
953 if (convert == CONVERT_TO_STRING) { | 929 if (convert == CONVERT_TO_STRING) { |
954 Handle<String> index_string = isolate->factory()->Uint32ToString(i); | 930 Handle<String> index_string = isolate->factory()->Uint32ToString(i); |
955 list->set(insertion_index, *index_string); | 931 list->set(insertion_index, *index_string); |
956 } else { | 932 } else { |
957 list->set(insertion_index, Smi::FromInt(i), SKIP_WRITE_BARRIER); | 933 list->set(insertion_index, Smi::FromInt(i), SKIP_WRITE_BARRIER); |
958 } | 934 } |
959 insertion_index++; | 935 insertion_index++; |
960 } | 936 } |
(...skipping 24 matching lines...) Expand all Loading... |
985 // Collect the element indices into a new list. | 961 // Collect the element indices into a new list. |
986 uint32_t nof_indices = 0; | 962 uint32_t nof_indices = 0; |
987 Handle<FixedArray> combined_keys = | 963 Handle<FixedArray> combined_keys = |
988 isolate->factory()->NewFixedArray(initial_list_length); | 964 isolate->factory()->NewFixedArray(initial_list_length); |
989 combined_keys = Subclass::DirectCollectElementIndicesImpl( | 965 combined_keys = Subclass::DirectCollectElementIndicesImpl( |
990 isolate, object, backing_store, convert, filter, combined_keys, | 966 isolate, object, backing_store, convert, filter, combined_keys, |
991 &nof_indices); | 967 &nof_indices); |
992 | 968 |
993 // Sort the indices list if necessary. | 969 // Sort the indices list if necessary. |
994 if (IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind())) { | 970 if (IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind())) { |
995 SortIndices(combined_keys, nof_indices, SKIP_WRITE_BARRIER); | 971 struct { |
| 972 bool operator()(Object* a, Object* b) { |
| 973 if (!a->IsUndefined()) { |
| 974 if (b->IsUndefined()) return true; |
| 975 return a->Number() < b->Number(); |
| 976 } |
| 977 return !b->IsUndefined(); |
| 978 } |
| 979 } cmp; |
| 980 Object** start = |
| 981 reinterpret_cast<Object**>(combined_keys->GetFirstElementAddress()); |
| 982 std::sort(start, start + nof_indices, cmp); |
996 uint32_t array_length = 0; | 983 uint32_t array_length = 0; |
997 // Indices from dictionary elements should only be converted after | 984 // Indices from dictionary elements should only be converted after |
998 // sorting. | 985 // sorting. |
999 if (convert == CONVERT_TO_STRING) { | 986 if (convert == CONVERT_TO_STRING) { |
1000 for (uint32_t i = 0; i < nof_indices; i++) { | 987 for (uint32_t i = 0; i < nof_indices; i++) { |
1001 Handle<Object> index_string = isolate->factory()->Uint32ToString( | 988 Handle<Object> index_string = isolate->factory()->Uint32ToString( |
1002 combined_keys->get(i)->Number()); | 989 combined_keys->get(i)->Number()); |
1003 combined_keys->set(i, *index_string); | 990 combined_keys->set(i, *index_string); |
1004 } | 991 } |
1005 } else if (!(object->IsJSArray() && | 992 } else if (!(object->IsJSArray() && |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1050 | 1037 |
1051 static uint32_t GetEntryForIndexImpl(JSObject* holder, | 1038 static uint32_t GetEntryForIndexImpl(JSObject* holder, |
1052 FixedArrayBase* backing_store, | 1039 FixedArrayBase* backing_store, |
1053 uint32_t index, PropertyFilter filter) { | 1040 uint32_t index, PropertyFilter filter) { |
1054 if (IsHoleyElementsKind(kind())) { | 1041 if (IsHoleyElementsKind(kind())) { |
1055 return index < Subclass::GetCapacityImpl(holder, backing_store) && | 1042 return index < Subclass::GetCapacityImpl(holder, backing_store) && |
1056 !BackingStore::cast(backing_store)->is_the_hole(index) | 1043 !BackingStore::cast(backing_store)->is_the_hole(index) |
1057 ? index | 1044 ? index |
1058 : kMaxUInt32; | 1045 : kMaxUInt32; |
1059 } else { | 1046 } else { |
1060 uint32_t length = Subclass::GetMaxIndex(holder, backing_store); | 1047 uint32_t length = GetIterationLength(holder, backing_store); |
1061 return index < length ? index : kMaxUInt32; | 1048 return index < length ? index : kMaxUInt32; |
1062 } | 1049 } |
1063 } | 1050 } |
1064 | 1051 |
1065 uint32_t GetEntryForIndex(JSObject* holder, FixedArrayBase* backing_store, | 1052 uint32_t GetEntryForIndex(JSObject* holder, FixedArrayBase* backing_store, |
1066 uint32_t index) final { | 1053 uint32_t index) final { |
1067 return Subclass::GetEntryForIndexImpl(holder, backing_store, index, | 1054 return Subclass::GetEntryForIndexImpl(holder, backing_store, index, |
1068 ALL_PROPERTIES); | 1055 ALL_PROPERTIES); |
1069 } | 1056 } |
1070 | 1057 |
(...skipping 16 matching lines...) Expand all Loading... |
1087 | 1074 |
1088 | 1075 |
1089 class DictionaryElementsAccessor | 1076 class DictionaryElementsAccessor |
1090 : public ElementsAccessorBase<DictionaryElementsAccessor, | 1077 : public ElementsAccessorBase<DictionaryElementsAccessor, |
1091 ElementsKindTraits<DICTIONARY_ELEMENTS> > { | 1078 ElementsKindTraits<DICTIONARY_ELEMENTS> > { |
1092 public: | 1079 public: |
1093 explicit DictionaryElementsAccessor(const char* name) | 1080 explicit DictionaryElementsAccessor(const char* name) |
1094 : ElementsAccessorBase<DictionaryElementsAccessor, | 1081 : ElementsAccessorBase<DictionaryElementsAccessor, |
1095 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} | 1082 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} |
1096 | 1083 |
1097 static uint32_t GetMaxIndex(JSObject* receiver, FixedArrayBase* elements) { | 1084 static uint32_t GetIterationLength(JSObject* receiver, |
1098 // We cannot properly estimate this for dictionaries. | 1085 FixedArrayBase* elements) { |
1099 UNREACHABLE(); | 1086 uint32_t length; |
1100 } | 1087 if (receiver->IsJSArray()) { |
1101 | 1088 // Special-case GetIterationLength for dictionary elements since the |
1102 static uint32_t GetMaxNumberOfEntries(JSObject* receiver, | 1089 // length of the array might be a HeapNumber. |
1103 FixedArrayBase* backing_store) { | 1090 JSArray::cast(receiver)->length()->ToArrayLength(&length); |
1104 SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store); | 1091 } else { |
1105 return dict->NumberOfElements(); | 1092 length = GetCapacityImpl(receiver, elements); |
| 1093 } |
| 1094 return length; |
1106 } | 1095 } |
1107 | 1096 |
1108 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, | 1097 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, |
1109 uint32_t length, | 1098 uint32_t length, |
1110 Handle<FixedArrayBase> backing_store) { | 1099 Handle<FixedArrayBase> backing_store) { |
1111 Handle<SeededNumberDictionary> dict = | 1100 Handle<SeededNumberDictionary> dict = |
1112 Handle<SeededNumberDictionary>::cast(backing_store); | 1101 Handle<SeededNumberDictionary>::cast(backing_store); |
1113 int capacity = dict->Capacity(); | 1102 int capacity = dict->Capacity(); |
1114 uint32_t old_length = 0; | 1103 uint32_t old_length = 0; |
1115 CHECK(array->length()->ToArrayLength(&old_length)); | 1104 CHECK(array->length()->ToArrayLength(&old_length)); |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1317 if (raw_key == undefined || raw_key == the_hole) { | 1306 if (raw_key == undefined || raw_key == the_hole) { |
1318 return kMaxUInt32; | 1307 return kMaxUInt32; |
1319 } | 1308 } |
1320 return FilterKey(dictionary, entry, raw_key, filter); | 1309 return FilterKey(dictionary, entry, raw_key, filter); |
1321 } | 1310 } |
1322 | 1311 |
1323 static void CollectElementIndicesImpl(Handle<JSObject> object, | 1312 static void CollectElementIndicesImpl(Handle<JSObject> object, |
1324 Handle<FixedArrayBase> backing_store, | 1313 Handle<FixedArrayBase> backing_store, |
1325 KeyAccumulator* keys) { | 1314 KeyAccumulator* keys) { |
1326 if (keys->filter() & SKIP_STRINGS) return; | 1315 if (keys->filter() & SKIP_STRINGS) return; |
1327 Factory* factory = keys->isolate()->factory(); | 1316 Isolate* isolate = keys->isolate(); |
1328 Handle<Object> undefined = factory->undefined_value(); | 1317 Handle<Object> undefined = isolate->factory()->undefined_value(); |
1329 Handle<Object> the_hole = factory->the_hole_value(); | 1318 Handle<Object> the_hole = isolate->factory()->the_hole_value(); |
1330 Handle<SeededNumberDictionary> dictionary = | 1319 Handle<SeededNumberDictionary> dictionary = |
1331 Handle<SeededNumberDictionary>::cast(backing_store); | 1320 Handle<SeededNumberDictionary>::cast(backing_store); |
1332 int capacity = dictionary->Capacity(); | 1321 int capacity = dictionary->Capacity(); |
1333 Handle<FixedArray> elements = | |
1334 factory->NewFixedArray(GetMaxNumberOfEntries(*object, *backing_store)); | |
1335 int insertion_index = 0; | |
1336 PropertyFilter filter = keys->filter(); | 1322 PropertyFilter filter = keys->filter(); |
1337 for (int i = 0; i < capacity; i++) { | 1323 for (int i = 0; i < capacity; i++) { |
1338 uint32_t key = | 1324 uint32_t key = |
1339 GetKeyForEntryImpl(dictionary, i, filter, *undefined, *the_hole); | 1325 GetKeyForEntryImpl(dictionary, i, filter, *undefined, *the_hole); |
1340 if (key == kMaxUInt32) continue; | 1326 if (key == kMaxUInt32) continue; |
1341 elements->set(insertion_index, *factory->NewNumberFromUint(key)); | 1327 keys->AddKey(key); |
1342 insertion_index++; | |
1343 } | 1328 } |
1344 SortIndices(elements, insertion_index); | 1329 |
1345 for (int i = 0; i < insertion_index; i++) { | 1330 keys->SortCurrentElementsList(); |
1346 keys->AddKey(elements->get(i)); | |
1347 } | |
1348 } | 1331 } |
1349 | 1332 |
1350 static Handle<FixedArray> DirectCollectElementIndicesImpl( | 1333 static Handle<FixedArray> DirectCollectElementIndicesImpl( |
1351 Isolate* isolate, Handle<JSObject> object, | 1334 Isolate* isolate, Handle<JSObject> object, |
1352 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, | 1335 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, |
1353 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, | 1336 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, |
1354 uint32_t insertion_index = 0) { | 1337 uint32_t insertion_index = 0) { |
1355 if (filter & SKIP_STRINGS) return list; | 1338 if (filter & SKIP_STRINGS) return list; |
1356 if (filter & ONLY_ALL_CAN_READ) return list; | 1339 if (filter & ONLY_ALL_CAN_READ) return list; |
1357 | 1340 |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1562 } | 1545 } |
1563 | 1546 |
1564 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) { | 1547 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) { |
1565 return !BackingStore::cast(backing_store)->is_the_hole(entry); | 1548 return !BackingStore::cast(backing_store)->is_the_hole(entry); |
1566 } | 1549 } |
1567 | 1550 |
1568 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, | 1551 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, |
1569 KeyAccumulator* accumulator, | 1552 KeyAccumulator* accumulator, |
1570 AddKeyConversion convert) { | 1553 AddKeyConversion convert) { |
1571 Handle<FixedArrayBase> elements(receiver->elements(), | 1554 Handle<FixedArrayBase> elements(receiver->elements(), |
1572 accumulator->isolate()); | 1555 receiver->GetIsolate()); |
1573 uint32_t length = Subclass::GetMaxNumberOfEntries(*receiver, *elements); | 1556 uint32_t length = Subclass::GetIterationLength(*receiver, *elements); |
1574 for (uint32_t i = 0; i < length; i++) { | 1557 for (uint32_t i = 0; i < length; i++) { |
1575 if (IsFastPackedElementsKind(KindTraits::Kind) || | 1558 if (IsFastPackedElementsKind(KindTraits::Kind) || |
1576 HasEntryImpl(*elements, i)) { | 1559 HasEntryImpl(*elements, i)) { |
1577 accumulator->AddKey(Subclass::GetImpl(*elements, i), convert); | 1560 accumulator->AddKey(Subclass::GetImpl(*elements, i), convert); |
1578 } | 1561 } |
1579 } | 1562 } |
1580 } | 1563 } |
1581 | 1564 |
1582 static void ValidateContents(Handle<JSObject> holder, int length) { | 1565 static void ValidateContents(Handle<JSObject> holder, int length) { |
1583 #if DEBUG | 1566 #if DEBUG |
(...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2396 // would enable GC of the context. | 2379 // would enable GC of the context. |
2397 parameter_map->set_the_hole(entry + 2); | 2380 parameter_map->set_the_hole(entry + 2); |
2398 } else { | 2381 } else { |
2399 Subclass::DeleteFromArguments(obj, entry - length); | 2382 Subclass::DeleteFromArguments(obj, entry - length); |
2400 } | 2383 } |
2401 } | 2384 } |
2402 | 2385 |
2403 static void CollectElementIndicesImpl(Handle<JSObject> object, | 2386 static void CollectElementIndicesImpl(Handle<JSObject> object, |
2404 Handle<FixedArrayBase> backing_store, | 2387 Handle<FixedArrayBase> backing_store, |
2405 KeyAccumulator* keys) { | 2388 KeyAccumulator* keys) { |
2406 Isolate* isolate = keys->isolate(); | 2389 FixedArray* parameter_map = FixedArray::cast(*backing_store); |
2407 uint32_t nof_indices = 0; | 2390 uint32_t length = parameter_map->length() - 2; |
2408 Handle<FixedArray> indices = isolate->factory()->NewFixedArray( | 2391 for (uint32_t i = 0; i < length; ++i) { |
2409 GetCapacityImpl(*object, *backing_store)); | 2392 if (!parameter_map->get(i + 2)->IsTheHole()) { |
2410 DirectCollectElementIndicesImpl(isolate, object, backing_store, | 2393 keys->AddKey(i); |
2411 KEEP_NUMBERS, ENUMERABLE_STRINGS, indices, | 2394 } |
2412 &nof_indices); | 2395 } |
2413 SortIndices(indices, nof_indices); | 2396 |
2414 for (uint32_t i = 0; i < nof_indices; i++) { | 2397 Handle<FixedArrayBase> store(FixedArrayBase::cast(parameter_map->get(1))); |
2415 keys->AddKey(indices->get(i)); | 2398 ArgumentsAccessor::CollectElementIndicesImpl(object, store, keys); |
| 2399 if (Subclass::kind() == FAST_SLOPPY_ARGUMENTS_ELEMENTS) { |
| 2400 keys->SortCurrentElementsList(); |
2416 } | 2401 } |
2417 } | 2402 } |
2418 | 2403 |
2419 static Handle<FixedArray> DirectCollectElementIndicesImpl( | 2404 static Handle<FixedArray> DirectCollectElementIndicesImpl( |
2420 Isolate* isolate, Handle<JSObject> object, | 2405 Isolate* isolate, Handle<JSObject> object, |
2421 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, | 2406 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, |
2422 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, | 2407 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, |
2423 uint32_t insertion_index = 0) { | 2408 uint32_t insertion_index = 0) { |
2424 FixedArray* parameter_map = FixedArray::cast(*backing_store); | 2409 FixedArray* parameter_map = FixedArray::cast(*backing_store); |
2425 uint32_t length = parameter_map->length() - 2; | 2410 uint32_t length = parameter_map->length() - 2; |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2753 convert); | 2738 convert); |
2754 } | 2739 } |
2755 BackingStoreAccessor::AddElementsToKeyAccumulatorImpl(receiver, accumulator, | 2740 BackingStoreAccessor::AddElementsToKeyAccumulatorImpl(receiver, accumulator, |
2756 convert); | 2741 convert); |
2757 } | 2742 } |
2758 | 2743 |
2759 static void CollectElementIndicesImpl(Handle<JSObject> object, | 2744 static void CollectElementIndicesImpl(Handle<JSObject> object, |
2760 Handle<FixedArrayBase> backing_store, | 2745 Handle<FixedArrayBase> backing_store, |
2761 KeyAccumulator* keys) { | 2746 KeyAccumulator* keys) { |
2762 uint32_t length = GetString(*object)->length(); | 2747 uint32_t length = GetString(*object)->length(); |
2763 Factory* factory = keys->isolate()->factory(); | |
2764 for (uint32_t i = 0; i < length; i++) { | 2748 for (uint32_t i = 0; i < length; i++) { |
2765 keys->AddKey(factory->NewNumberFromUint(i)); | 2749 keys->AddKey(i); |
2766 } | 2750 } |
2767 BackingStoreAccessor::CollectElementIndicesImpl(object, backing_store, | 2751 BackingStoreAccessor::CollectElementIndicesImpl(object, backing_store, |
2768 keys); | 2752 keys); |
2769 } | 2753 } |
2770 | 2754 |
2771 static void GrowCapacityAndConvertImpl(Handle<JSObject> object, | 2755 static void GrowCapacityAndConvertImpl(Handle<JSObject> object, |
2772 uint32_t capacity) { | 2756 uint32_t capacity) { |
2773 Handle<FixedArrayBase> old_elements(object->elements()); | 2757 Handle<FixedArrayBase> old_elements(object->elements()); |
2774 ElementsKind from_kind = object->GetElementsKind(); | 2758 ElementsKind from_kind = object->GetElementsKind(); |
2775 // 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 |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3040 insertion_index += len; | 3024 insertion_index += len; |
3041 } | 3025 } |
3042 | 3026 |
3043 DCHECK_EQ(insertion_index, result_len); | 3027 DCHECK_EQ(insertion_index, result_len); |
3044 return result_array; | 3028 return result_array; |
3045 } | 3029 } |
3046 | 3030 |
3047 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 3031 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
3048 } // namespace internal | 3032 } // namespace internal |
3049 } // namespace v8 | 3033 } // namespace v8 |
OLD | NEW |