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