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/messages.h" | 10 #include "src/messages.h" |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 for (int i = 0; i < copy_size; i++) { | 421 for (int i = 0; i < copy_size; i++) { |
422 int entry = from->FindEntry(i + from_start); | 422 int entry = from->FindEntry(i + from_start); |
423 if (entry != SeededNumberDictionary::kNotFound) { | 423 if (entry != SeededNumberDictionary::kNotFound) { |
424 to->set(i + to_start, from->ValueAt(entry)->Number()); | 424 to->set(i + to_start, from->ValueAt(entry)->Number()); |
425 } else { | 425 } else { |
426 to->set_the_hole(i + to_start); | 426 to->set_the_hole(i + to_start); |
427 } | 427 } |
428 } | 428 } |
429 } | 429 } |
430 | 430 |
| 431 |
431 static void TraceTopFrame(Isolate* isolate) { | 432 static void TraceTopFrame(Isolate* isolate) { |
432 StackFrameIterator it(isolate); | 433 StackFrameIterator it(isolate); |
433 if (it.done()) { | 434 if (it.done()) { |
434 PrintF("unknown location (no JavaScript frames present)"); | 435 PrintF("unknown location (no JavaScript frames present)"); |
435 return; | 436 return; |
436 } | 437 } |
437 StackFrame* raw_frame = it.frame(); | 438 StackFrame* raw_frame = it.frame(); |
438 if (raw_frame->is_internal()) { | 439 if (raw_frame->is_internal()) { |
439 Code* apply_builtin = | 440 Code* apply_builtin = |
440 isolate->builtins()->builtin(Builtins::kFunctionPrototypeApply); | 441 isolate->builtins()->builtin(Builtins::kFunctionPrototypeApply); |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
722 } else { | 723 } else { |
723 // Check whether the backing store should be expanded. | 724 // Check whether the backing store should be expanded. |
724 capacity = Max(length, JSObject::NewElementsCapacity(capacity)); | 725 capacity = Max(length, JSObject::NewElementsCapacity(capacity)); |
725 ElementsAccessorSubclass::GrowCapacityAndConvertImpl(array, capacity); | 726 ElementsAccessorSubclass::GrowCapacityAndConvertImpl(array, capacity); |
726 } | 727 } |
727 | 728 |
728 array->set_length(Smi::FromInt(length)); | 729 array->set_length(Smi::FromInt(length)); |
729 JSObject::ValidateElements(array); | 730 JSObject::ValidateElements(array); |
730 } | 731 } |
731 | 732 |
732 static uint32_t GetIterationLength(JSObject* receiver, | |
733 FixedArrayBase* elements) { | |
734 if (receiver->IsJSArray()) { | |
735 return static_cast<uint32_t>( | |
736 Smi::cast(JSArray::cast(receiver)->length())->value()); | |
737 } else { | |
738 return ElementsAccessorSubclass::GetCapacityImpl(receiver, elements); | |
739 } | |
740 } | |
741 | |
742 static Handle<FixedArrayBase> ConvertElementsWithCapacity( | 733 static Handle<FixedArrayBase> ConvertElementsWithCapacity( |
743 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, | 734 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, |
744 ElementsKind from_kind, uint32_t capacity) { | 735 ElementsKind from_kind, uint32_t capacity) { |
745 return ConvertElementsWithCapacity( | 736 return ConvertElementsWithCapacity( |
746 object, old_elements, from_kind, capacity, 0, 0, | 737 object, old_elements, from_kind, capacity, 0, 0, |
747 ElementsAccessor::kCopyToEndAndInitializeToHole); | 738 ElementsAccessor::kCopyToEndAndInitializeToHole); |
748 } | 739 } |
749 | 740 |
750 static Handle<FixedArrayBase> ConvertElementsWithCapacity( | 741 static Handle<FixedArrayBase> ConvertElementsWithCapacity( |
751 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, | 742 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
848 // intentionally to avoid ArrayConcat() builtin performance degradation. | 839 // intentionally to avoid ArrayConcat() builtin performance degradation. |
849 // | 840 // |
850 // Details: The idea is that allocations actually happen only in case of | 841 // Details: The idea is that allocations actually happen only in case of |
851 // copying from object with fast double elements to object with object | 842 // copying from object with fast double elements to object with object |
852 // elements. In all the other cases there are no allocations performed and | 843 // elements. In all the other cases there are no allocations performed and |
853 // handle creation causes noticeable performance degradation of the builtin. | 844 // handle creation causes noticeable performance degradation of the builtin. |
854 ElementsAccessorSubclass::CopyElementsImpl( | 845 ElementsAccessorSubclass::CopyElementsImpl( |
855 from, from_start, *to, from_kind, to_start, packed_size, copy_size); | 846 from, from_start, *to, from_kind, to_start, packed_size, copy_size); |
856 } | 847 } |
857 | 848 |
858 void CollectElementIndices(Handle<JSObject> object, | |
859 Handle<FixedArrayBase> backing_store, | |
860 KeyAccumulator* keys, uint32_t range, | |
861 PropertyFilter filter, uint32_t offset) final { | |
862 ElementsAccessorSubclass::CollectElementIndicesImpl( | |
863 object, backing_store, keys, range, filter, offset); | |
864 } | |
865 | |
866 static void CollectElementIndicesImpl(Handle<JSObject> object, | 849 static void CollectElementIndicesImpl(Handle<JSObject> object, |
867 Handle<FixedArrayBase> backing_store, | 850 Handle<FixedArrayBase> backing_store, |
868 KeyAccumulator* keys, uint32_t range, | 851 KeyAccumulator* keys, uint32_t range, |
869 PropertyFilter filter, | 852 PropertyFilter filter, |
870 uint32_t offset) { | 853 uint32_t offset) { |
871 DCHECK_NE(DICTIONARY_ELEMENTS, kind()); | 854 DCHECK_NE(DICTIONARY_ELEMENTS, kind()); |
872 if (filter & ONLY_ALL_CAN_READ) { | 855 if (filter & ONLY_ALL_CAN_READ) { |
873 // Non-dictionary elements can't have all-can-read accessors. | 856 // Non-dictionary elements can't have all-can-read accessors. |
874 return; | 857 return; |
875 } | 858 } |
876 uint32_t length = GetIterationLength(*object, *backing_store); | 859 uint32_t length = 0; |
| 860 if (object->IsJSArray()) { |
| 861 length = Smi::cast(JSArray::cast(*object)->length())->value(); |
| 862 } else { |
| 863 length = |
| 864 ElementsAccessorSubclass::GetCapacityImpl(*object, *backing_store); |
| 865 } |
877 if (range < length) length = range; | 866 if (range < length) length = range; |
878 for (uint32_t i = offset; i < length; i++) { | 867 for (uint32_t i = offset; i < length; i++) { |
879 if (ElementsAccessorSubclass::HasElementImpl(object, i, backing_store, | 868 if (!ElementsAccessorSubclass::HasElementImpl(object, i, backing_store, |
880 filter)) { | 869 filter)) { |
881 keys->AddKey(i); | 870 continue; |
882 } | 871 } |
| 872 keys->AddKey(i); |
883 } | 873 } |
884 } | 874 } |
885 | 875 |
886 static Handle<FixedArray> DirectCollectElementIndicesImpl( | 876 void CollectElementIndices(Handle<JSObject> object, |
887 Isolate* isolate, Handle<JSObject> object, | 877 Handle<FixedArrayBase> backing_store, |
888 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, | 878 KeyAccumulator* keys, uint32_t range, |
889 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices) { | 879 PropertyFilter filter, uint32_t offset) final { |
890 uint32_t length = | 880 ElementsAccessorSubclass::CollectElementIndicesImpl( |
891 ElementsAccessorSubclass::GetIterationLength(*object, *backing_store); | 881 object, backing_store, keys, range, filter, offset); |
892 uint32_t insertion_index = 0; | 882 }; |
893 for (uint32_t i = 0; i < length; i++) { | |
894 if (ElementsAccessorSubclass::HasElementImpl(object, i, backing_store, | |
895 filter)) { | |
896 if (convert == CONVERT_TO_STRING) { | |
897 list->set(insertion_index++, *isolate->factory()->Uint32ToString(i)); | |
898 } else { | |
899 list->set(insertion_index++, Smi::FromInt(i), SKIP_WRITE_BARRIER); | |
900 } | |
901 } | |
902 } | |
903 *nof_indices = insertion_index; | |
904 return list; | |
905 } | |
906 | |
907 Handle<FixedArray> PrependElementIndices(Handle<JSObject> object, | |
908 Handle<FixedArrayBase> backing_store, | |
909 Handle<FixedArray> keys, | |
910 GetKeysConversion convert, | |
911 PropertyFilter filter) final { | |
912 return ElementsAccessorSubclass::PrependElementIndicesImpl( | |
913 object, backing_store, keys, convert, filter); | |
914 } | |
915 | |
916 static Handle<FixedArray> PrependElementIndicesImpl( | |
917 Handle<JSObject> object, Handle<FixedArrayBase> backing_store, | |
918 Handle<FixedArray> keys, GetKeysConversion convert, | |
919 PropertyFilter filter) { | |
920 Isolate* isolate = object->GetIsolate(); | |
921 uint32_t nof_property_keys = keys->length(); | |
922 uint32_t initial_list_length = | |
923 ElementsAccessorSubclass::GetCapacityImpl(*object, *backing_store); | |
924 initial_list_length += nof_property_keys; | |
925 | |
926 // Collect the element indices into a new list. | |
927 uint32_t nof_indices = 0; | |
928 Handle<FixedArray> combined_keys = | |
929 isolate->factory()->NewFixedArray(initial_list_length); | |
930 combined_keys = ElementsAccessorSubclass::DirectCollectElementIndicesImpl( | |
931 isolate, object, backing_store, convert, filter, combined_keys, | |
932 &nof_indices); | |
933 | |
934 // Sort the indices list if necessary. | |
935 if (IsDictionaryElementsKind(kind())) { | |
936 struct { | |
937 bool operator()(Object* a, Object* b) { | |
938 if (!a->IsUndefined()) { | |
939 if (b->IsUndefined()) return true; | |
940 return a->Number() < b->Number(); | |
941 } | |
942 return !b->IsUndefined(); | |
943 } | |
944 } cmp; | |
945 Object** start = | |
946 reinterpret_cast<Object**>(combined_keys->GetFirstElementAddress()); | |
947 std::sort(start, start + nof_indices, cmp); | |
948 // Indices from dictionary elements should only be converted after | |
949 // sorting. | |
950 if (convert == CONVERT_TO_STRING) { | |
951 for (uint32_t i = 0; i < nof_indices; i++) { | |
952 combined_keys->set(i, *isolate->factory()->Uint32ToString( | |
953 combined_keys->get(i)->Number())); | |
954 } | |
955 } | |
956 } | |
957 | |
958 // Copy over the passed-in property keys. | |
959 CopyObjectToObjectElements(*keys, FAST_ELEMENTS, 0, *combined_keys, | |
960 FAST_ELEMENTS, nof_indices, nof_property_keys); | |
961 | |
962 if (IsHoleyElementsKind(kind())) { | |
963 // Shrink combined_keys to the final size. | |
964 int final_size = nof_indices + nof_property_keys; | |
965 DCHECK_LE(final_size, combined_keys->length()); | |
966 combined_keys->Shrink(final_size); | |
967 } | |
968 | |
969 return combined_keys; | |
970 } | |
971 | 883 |
972 void AddElementsToKeyAccumulator(Handle<JSObject> receiver, | 884 void AddElementsToKeyAccumulator(Handle<JSObject> receiver, |
973 KeyAccumulator* accumulator, | 885 KeyAccumulator* accumulator, |
974 AddKeyConversion convert) final { | 886 AddKeyConversion convert) final { |
975 ElementsAccessorSubclass::AddElementsToKeyAccumulatorImpl( | 887 ElementsAccessorSubclass::AddElementsToKeyAccumulatorImpl( |
976 receiver, accumulator, convert); | 888 receiver, accumulator, convert); |
977 } | 889 } |
978 | 890 |
979 static uint32_t GetCapacityImpl(JSObject* holder, | 891 static uint32_t GetCapacityImpl(JSObject* holder, |
980 FixedArrayBase* backing_store) { | 892 FixedArrayBase* backing_store) { |
(...skipping 12 matching lines...) Expand all Loading... |
993 static uint32_t GetEntryForIndexImpl(JSObject* holder, | 905 static uint32_t GetEntryForIndexImpl(JSObject* holder, |
994 FixedArrayBase* backing_store, | 906 FixedArrayBase* backing_store, |
995 uint32_t index, PropertyFilter filter) { | 907 uint32_t index, PropertyFilter filter) { |
996 if (IsHoleyElementsKind(kind())) { | 908 if (IsHoleyElementsKind(kind())) { |
997 return index < ElementsAccessorSubclass::GetCapacityImpl(holder, | 909 return index < ElementsAccessorSubclass::GetCapacityImpl(holder, |
998 backing_store) && | 910 backing_store) && |
999 !BackingStore::cast(backing_store)->is_the_hole(index) | 911 !BackingStore::cast(backing_store)->is_the_hole(index) |
1000 ? index | 912 ? index |
1001 : kMaxUInt32; | 913 : kMaxUInt32; |
1002 } else { | 914 } else { |
1003 uint32_t length = GetIterationLength(holder, backing_store); | 915 uint32_t length = |
| 916 holder->IsJSArray() |
| 917 ? static_cast<uint32_t>( |
| 918 Smi::cast(JSArray::cast(holder)->length())->value()) |
| 919 : ElementsAccessorSubclass::GetCapacityImpl(holder, |
| 920 backing_store); |
1004 return index < length ? index : kMaxUInt32; | 921 return index < length ? index : kMaxUInt32; |
1005 } | 922 } |
1006 } | 923 } |
1007 | 924 |
1008 uint32_t GetEntryForIndex(JSObject* holder, FixedArrayBase* backing_store, | 925 uint32_t GetEntryForIndex(JSObject* holder, FixedArrayBase* backing_store, |
1009 uint32_t index) final { | 926 uint32_t index) final { |
1010 return ElementsAccessorSubclass::GetEntryForIndexImpl( | 927 return ElementsAccessorSubclass::GetEntryForIndexImpl( |
1011 holder, backing_store, index, ALL_PROPERTIES); | 928 holder, backing_store, index, ALL_PROPERTIES); |
1012 } | 929 } |
1013 | 930 |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1195 | 1112 |
1196 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { | 1113 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { |
1197 return GetDetailsImpl(holder->elements(), entry); | 1114 return GetDetailsImpl(holder->elements(), entry); |
1198 } | 1115 } |
1199 | 1116 |
1200 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, | 1117 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, |
1201 uint32_t entry) { | 1118 uint32_t entry) { |
1202 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry); | 1119 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry); |
1203 } | 1120 } |
1204 | 1121 |
1205 static uint32_t GetKeyForEntryImpl(Handle<SeededNumberDictionary> dictionary, | |
1206 int entry, PropertyFilter filter) { | |
1207 DisallowHeapAllocation no_gc; | |
1208 Object* raw_key = dictionary->KeyAt(entry); | |
1209 if (!dictionary->IsKey(raw_key)) return kMaxUInt32; | |
1210 if (raw_key->FilterKey(filter)) return kMaxUInt32; | |
1211 if (dictionary->IsDeleted(entry)) return kMaxUInt32; | |
1212 DCHECK(raw_key->IsNumber()); | |
1213 DCHECK_LE(raw_key->Number(), kMaxUInt32); | |
1214 uint32_t key = static_cast<uint32_t>(raw_key->Number()); | |
1215 PropertyDetails details = dictionary->DetailsAt(entry); | |
1216 if (filter & ONLY_ALL_CAN_READ) { | |
1217 if (details.kind() != kAccessor) return kMaxUInt32; | |
1218 Object* accessors = dictionary->ValueAt(entry); | |
1219 if (!accessors->IsAccessorInfo()) return kMaxUInt32; | |
1220 if (!AccessorInfo::cast(accessors)->all_can_read()) return kMaxUInt32; | |
1221 } | |
1222 PropertyAttributes attr = details.attributes(); | |
1223 if ((attr & filter) != 0) return kMaxUInt32; | |
1224 return key; | |
1225 } | |
1226 | |
1227 static void CollectElementIndicesImpl(Handle<JSObject> object, | 1122 static void CollectElementIndicesImpl(Handle<JSObject> object, |
1228 Handle<FixedArrayBase> backing_store, | 1123 Handle<FixedArrayBase> backing_store, |
1229 KeyAccumulator* keys, uint32_t range, | 1124 KeyAccumulator* keys, uint32_t range, |
1230 PropertyFilter filter, | 1125 PropertyFilter filter, |
1231 uint32_t offset) { | 1126 uint32_t offset) { |
1232 Handle<SeededNumberDictionary> dictionary = | 1127 Handle<SeededNumberDictionary> dictionary = |
1233 Handle<SeededNumberDictionary>::cast(backing_store); | 1128 Handle<SeededNumberDictionary>::cast(backing_store); |
1234 int capacity = dictionary->Capacity(); | 1129 int capacity = dictionary->Capacity(); |
1235 for (int i = 0; i < capacity; i++) { | 1130 for (int i = 0; i < capacity; i++) { |
1236 uint32_t key = GetKeyForEntryImpl(dictionary, i, filter); | 1131 Object* k = dictionary->KeyAt(i); |
1237 if (key == kMaxUInt32) continue; | 1132 if (!dictionary->IsKey(k)) continue; |
1238 keys->AddKey(key); | 1133 if (k->FilterKey(filter)) continue; |
| 1134 if (dictionary->IsDeleted(i)) continue; |
| 1135 DCHECK(k->IsNumber()); |
| 1136 DCHECK_LE(k->Number(), kMaxUInt32); |
| 1137 uint32_t index = static_cast<uint32_t>(k->Number()); |
| 1138 if (index < offset) continue; |
| 1139 PropertyDetails details = dictionary->DetailsAt(i); |
| 1140 if (filter & ONLY_ALL_CAN_READ) { |
| 1141 if (details.kind() != kAccessor) continue; |
| 1142 Object* accessors = dictionary->ValueAt(i); |
| 1143 if (!accessors->IsAccessorInfo()) continue; |
| 1144 if (!AccessorInfo::cast(accessors)->all_can_read()) continue; |
| 1145 } |
| 1146 PropertyAttributes attr = details.attributes(); |
| 1147 if ((attr & filter) != 0) continue; |
| 1148 keys->AddKey(index); |
1239 } | 1149 } |
1240 | 1150 |
1241 keys->SortCurrentElementsList(); | 1151 keys->SortCurrentElementsList(); |
1242 } | 1152 } |
1243 | 1153 |
1244 static Handle<FixedArray> DirectCollectElementIndicesImpl( | |
1245 Isolate* isolate, Handle<JSObject> object, | |
1246 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, | |
1247 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices) { | |
1248 Handle<SeededNumberDictionary> dictionary = | |
1249 Handle<SeededNumberDictionary>::cast(backing_store); | |
1250 uint32_t capacity = dictionary->Capacity(); | |
1251 uint32_t insertion_index = 0; | |
1252 for (uint32_t i = 0; i < capacity; i++) { | |
1253 uint32_t key = GetKeyForEntryImpl(dictionary, i, filter); | |
1254 if (key == kMaxUInt32) continue; | |
1255 list->set(insertion_index++, *isolate->factory()->NewNumberFromUint(key)); | |
1256 } | |
1257 *nof_indices = insertion_index; | |
1258 return list; | |
1259 } | |
1260 | |
1261 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, | 1154 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, |
1262 KeyAccumulator* accumulator, | 1155 KeyAccumulator* accumulator, |
1263 AddKeyConversion convert) { | 1156 AddKeyConversion convert) { |
1264 SeededNumberDictionary* dictionary = | 1157 SeededNumberDictionary* dictionary = |
1265 SeededNumberDictionary::cast(receiver->elements()); | 1158 SeededNumberDictionary::cast(receiver->elements()); |
1266 int capacity = dictionary->Capacity(); | 1159 int capacity = dictionary->Capacity(); |
1267 for (int i = 0; i < capacity; i++) { | 1160 for (int i = 0; i < capacity; i++) { |
1268 Object* k = dictionary->KeyAt(i); | 1161 Object* k = dictionary->KeyAt(i); |
1269 if (!dictionary->IsKey(k)) continue; | 1162 if (!dictionary->IsKey(k)) continue; |
1270 if (dictionary->IsDeleted(i)) continue; | 1163 if (dictionary->IsDeleted(i)) continue; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1415 DeleteCommon(obj, entry, handle(obj->elements())); | 1308 DeleteCommon(obj, entry, handle(obj->elements())); |
1416 } | 1309 } |
1417 | 1310 |
1418 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) { | 1311 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) { |
1419 return !BackingStore::cast(backing_store)->is_the_hole(entry); | 1312 return !BackingStore::cast(backing_store)->is_the_hole(entry); |
1420 } | 1313 } |
1421 | 1314 |
1422 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, | 1315 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, |
1423 KeyAccumulator* accumulator, | 1316 KeyAccumulator* accumulator, |
1424 AddKeyConversion convert) { | 1317 AddKeyConversion convert) { |
| 1318 uint32_t length = 0; |
1425 Handle<FixedArrayBase> elements(receiver->elements(), | 1319 Handle<FixedArrayBase> elements(receiver->elements(), |
1426 receiver->GetIsolate()); | 1320 receiver->GetIsolate()); |
1427 uint32_t length = | 1321 if (receiver->IsJSArray()) { |
1428 FastElementsAccessorSubclass::GetIterationLength(*receiver, *elements); | 1322 length = Smi::cast(JSArray::cast(*receiver)->length())->value(); |
| 1323 } else { |
| 1324 length = |
| 1325 FastElementsAccessorSubclass::GetCapacityImpl(*receiver, *elements); |
| 1326 } |
1429 for (uint32_t i = 0; i < length; i++) { | 1327 for (uint32_t i = 0; i < length; i++) { |
1430 if (IsFastPackedElementsKind(KindTraits::Kind) || | 1328 if (IsFastPackedElementsKind(KindTraits::Kind) || |
1431 HasEntryImpl(*elements, i)) { | 1329 HasEntryImpl(*elements, i)) { |
1432 accumulator->AddKey(FastElementsAccessorSubclass::GetImpl(*elements, i), | 1330 accumulator->AddKey(FastElementsAccessorSubclass::GetImpl(*elements, i), |
1433 convert); | 1331 convert); |
1434 } | 1332 } |
1435 } | 1333 } |
1436 } | 1334 } |
1437 | 1335 |
1438 static void ValidateContents(Handle<JSObject> holder, int length) { | 1336 static void ValidateContents(Handle<JSObject> holder, int length) { |
(...skipping 1343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2782 } | 2680 } |
2783 } | 2681 } |
2784 | 2682 |
2785 DCHECK(j == result_len); | 2683 DCHECK(j == result_len); |
2786 return result_array; | 2684 return result_array; |
2787 } | 2685 } |
2788 | 2686 |
2789 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 2687 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
2790 } // namespace internal | 2688 } // namespace internal |
2791 } // namespace v8 | 2689 } // namespace v8 |
OLD | NEW |