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