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 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 | 559 |
560 void Validate(Handle<JSObject> holder) final { | 560 void Validate(Handle<JSObject> holder) final { |
561 DisallowHeapAllocation no_gc; | 561 DisallowHeapAllocation no_gc; |
562 Subclass::ValidateImpl(holder); | 562 Subclass::ValidateImpl(holder); |
563 } | 563 } |
564 | 564 |
565 static bool IsPackedImpl(Handle<JSObject> holder, | 565 static bool IsPackedImpl(Handle<JSObject> holder, |
566 Handle<FixedArrayBase> backing_store, uint32_t start, | 566 Handle<FixedArrayBase> backing_store, uint32_t start, |
567 uint32_t end) { | 567 uint32_t end) { |
568 if (IsFastPackedElementsKind(kind())) return true; | 568 if (IsFastPackedElementsKind(kind())) return true; |
| 569 Isolate* isolate = backing_store->GetIsolate(); |
569 for (uint32_t i = start; i < end; i++) { | 570 for (uint32_t i = start; i < end; i++) { |
570 if (!Subclass::HasElementImpl(holder, i, backing_store, ALL_PROPERTIES)) { | 571 if (!Subclass::HasElementImpl(isolate, holder, i, backing_store, |
| 572 ALL_PROPERTIES)) { |
571 return false; | 573 return false; |
572 } | 574 } |
573 } | 575 } |
574 return true; | 576 return true; |
575 } | 577 } |
576 | 578 |
577 static void TryTransitionResultArrayToPacked(Handle<JSArray> array) { | 579 static void TryTransitionResultArrayToPacked(Handle<JSArray> array) { |
578 if (!IsHoleyElementsKind(kind())) return; | 580 if (!IsHoleyElementsKind(kind())) return; |
579 int length = Smi::cast(array->length())->value(); | 581 int length = Smi::cast(array->length())->value(); |
580 Handle<FixedArrayBase> backing_store(array->elements()); | 582 Handle<FixedArrayBase> backing_store(array->elements()); |
581 if (!Subclass::IsPackedImpl(array, backing_store, 0, length)) { | 583 if (!Subclass::IsPackedImpl(array, backing_store, 0, length)) { |
582 return; | 584 return; |
583 } | 585 } |
584 ElementsKind packed_kind = GetPackedElementsKind(kind()); | 586 ElementsKind packed_kind = GetPackedElementsKind(kind()); |
585 Handle<Map> new_map = | 587 Handle<Map> new_map = |
586 JSObject::GetElementsTransitionMap(array, packed_kind); | 588 JSObject::GetElementsTransitionMap(array, packed_kind); |
587 JSObject::MigrateToMap(array, new_map); | 589 JSObject::MigrateToMap(array, new_map); |
588 if (FLAG_trace_elements_transitions) { | 590 if (FLAG_trace_elements_transitions) { |
589 JSObject::PrintElementsTransition(stdout, array, kind(), backing_store, | 591 JSObject::PrintElementsTransition(stdout, array, kind(), backing_store, |
590 packed_kind, backing_store); | 592 packed_kind, backing_store); |
591 } | 593 } |
592 } | 594 } |
593 | 595 |
594 bool HasElement(Handle<JSObject> holder, uint32_t index, | 596 bool HasElement(Handle<JSObject> holder, uint32_t index, |
595 Handle<FixedArrayBase> backing_store, | 597 Handle<FixedArrayBase> backing_store, |
596 PropertyFilter filter) final { | 598 PropertyFilter filter) final { |
597 return Subclass::HasElementImpl(holder, index, backing_store, filter); | 599 return Subclass::HasElementImpl(holder->GetIsolate(), holder, index, |
| 600 backing_store, filter); |
598 } | 601 } |
599 | 602 |
600 static bool HasElementImpl(Handle<JSObject> holder, uint32_t index, | 603 static bool HasElementImpl(Isolate* isolate, Handle<JSObject> holder, |
| 604 uint32_t index, |
601 Handle<FixedArrayBase> backing_store, | 605 Handle<FixedArrayBase> backing_store, |
602 PropertyFilter filter) { | 606 PropertyFilter filter) { |
603 return Subclass::GetEntryForIndexImpl(*holder, *backing_store, index, | 607 return Subclass::GetEntryForIndexImpl(isolate, *holder, *backing_store, |
604 filter) != kMaxUInt32; | 608 index, filter) != kMaxUInt32; |
605 } | 609 } |
606 | 610 |
607 bool HasAccessors(JSObject* holder) final { | 611 bool HasAccessors(JSObject* holder) final { |
608 return Subclass::HasAccessorsImpl(holder, holder->elements()); | 612 return Subclass::HasAccessorsImpl(holder, holder->elements()); |
609 } | 613 } |
610 | 614 |
611 static bool HasAccessorsImpl(JSObject* holder, | 615 static bool HasAccessorsImpl(JSObject* holder, |
612 FixedArrayBase* backing_store) { | 616 FixedArrayBase* backing_store) { |
613 return false; | 617 return false; |
614 } | 618 } |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 } else { | 769 } else { |
766 // Check whether the backing store should be expanded. | 770 // Check whether the backing store should be expanded. |
767 capacity = Max(length, JSObject::NewElementsCapacity(capacity)); | 771 capacity = Max(length, JSObject::NewElementsCapacity(capacity)); |
768 Subclass::GrowCapacityAndConvertImpl(array, capacity); | 772 Subclass::GrowCapacityAndConvertImpl(array, capacity); |
769 } | 773 } |
770 | 774 |
771 array->set_length(Smi::FromInt(length)); | 775 array->set_length(Smi::FromInt(length)); |
772 JSObject::ValidateElements(array); | 776 JSObject::ValidateElements(array); |
773 } | 777 } |
774 | 778 |
| 779 uint32_t NumberOfElements(JSObject* receiver) final { |
| 780 return Subclass::NumberOfElementsImpl(receiver, receiver->elements()); |
| 781 } |
| 782 |
| 783 static uint32_t NumberOfElementsImpl(JSObject* receiver, |
| 784 FixedArrayBase* backing_store) { |
| 785 UNREACHABLE(); |
| 786 } |
| 787 |
775 static uint32_t GetMaxIndex(JSObject* receiver, FixedArrayBase* elements) { | 788 static uint32_t GetMaxIndex(JSObject* receiver, FixedArrayBase* elements) { |
776 if (receiver->IsJSArray()) { | 789 if (receiver->IsJSArray()) { |
777 DCHECK(JSArray::cast(receiver)->length()->IsSmi()); | 790 DCHECK(JSArray::cast(receiver)->length()->IsSmi()); |
778 return static_cast<uint32_t>( | 791 return static_cast<uint32_t>( |
779 Smi::cast(JSArray::cast(receiver)->length())->value()); | 792 Smi::cast(JSArray::cast(receiver)->length())->value()); |
780 } | 793 } |
781 return Subclass::GetCapacityImpl(receiver, elements); | 794 return Subclass::GetCapacityImpl(receiver, elements); |
782 } | 795 } |
783 | 796 |
784 static uint32_t GetMaxNumberOfEntries(JSObject* receiver, | 797 static uint32_t GetMaxNumberOfEntries(JSObject* receiver, |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1008 object, handle(object->elements(), isolate), &accumulator); | 1021 object, handle(object->elements(), isolate), &accumulator); |
1009 Handle<FixedArray> keys = accumulator.GetKeys(); | 1022 Handle<FixedArray> keys = accumulator.GetKeys(); |
1010 | 1023 |
1011 for (int i = 0; i < keys->length(); ++i) { | 1024 for (int i = 0; i < keys->length(); ++i) { |
1012 Handle<Object> key(keys->get(i), isolate); | 1025 Handle<Object> key(keys->get(i), isolate); |
1013 Handle<Object> value; | 1026 Handle<Object> value; |
1014 uint32_t index; | 1027 uint32_t index; |
1015 if (!key->ToUint32(&index)) continue; | 1028 if (!key->ToUint32(&index)) continue; |
1016 | 1029 |
1017 uint32_t entry = Subclass::GetEntryForIndexImpl( | 1030 uint32_t entry = Subclass::GetEntryForIndexImpl( |
1018 *object, object->elements(), index, filter); | 1031 isolate, *object, object->elements(), index, filter); |
1019 if (entry == kMaxUInt32) continue; | 1032 if (entry == kMaxUInt32) continue; |
1020 | 1033 |
1021 PropertyDetails details = Subclass::GetDetailsImpl(*object, entry); | 1034 PropertyDetails details = Subclass::GetDetailsImpl(*object, entry); |
1022 | 1035 |
1023 if (details.kind() == kData) { | 1036 if (details.kind() == kData) { |
1024 value = Subclass::GetImpl(object, entry); | 1037 value = Subclass::GetImpl(object, entry); |
1025 } else { | 1038 } else { |
1026 LookupIterator it(isolate, object, index, LookupIterator::OWN); | 1039 LookupIterator it(isolate, object, index, LookupIterator::OWN); |
1027 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 1040 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
1028 isolate, value, Object::GetProperty(&it), Nothing<bool>()); | 1041 isolate, value, Object::GetProperty(&it), Nothing<bool>()); |
(...skipping 15 matching lines...) Expand all Loading... |
1044 Subclass::CollectElementIndicesImpl(object, backing_store, keys); | 1057 Subclass::CollectElementIndicesImpl(object, backing_store, keys); |
1045 } | 1058 } |
1046 | 1059 |
1047 static void CollectElementIndicesImpl(Handle<JSObject> object, | 1060 static void CollectElementIndicesImpl(Handle<JSObject> object, |
1048 Handle<FixedArrayBase> backing_store, | 1061 Handle<FixedArrayBase> backing_store, |
1049 KeyAccumulator* keys) { | 1062 KeyAccumulator* keys) { |
1050 DCHECK_NE(DICTIONARY_ELEMENTS, kind()); | 1063 DCHECK_NE(DICTIONARY_ELEMENTS, kind()); |
1051 // Non-dictionary elements can't have all-can-read accessors. | 1064 // Non-dictionary elements can't have all-can-read accessors. |
1052 uint32_t length = Subclass::GetMaxIndex(*object, *backing_store); | 1065 uint32_t length = Subclass::GetMaxIndex(*object, *backing_store); |
1053 PropertyFilter filter = keys->filter(); | 1066 PropertyFilter filter = keys->filter(); |
1054 Factory* factory = keys->isolate()->factory(); | 1067 Isolate* isolate = keys->isolate(); |
| 1068 Factory* factory = isolate->factory(); |
1055 for (uint32_t i = 0; i < length; i++) { | 1069 for (uint32_t i = 0; i < length; i++) { |
1056 if (Subclass::HasElementImpl(object, i, backing_store, filter)) { | 1070 if (Subclass::HasElementImpl(isolate, object, i, backing_store, filter)) { |
1057 keys->AddKey(factory->NewNumberFromUint(i)); | 1071 keys->AddKey(factory->NewNumberFromUint(i)); |
1058 } | 1072 } |
1059 } | 1073 } |
1060 } | 1074 } |
1061 | 1075 |
1062 static Handle<FixedArray> DirectCollectElementIndicesImpl( | 1076 static Handle<FixedArray> DirectCollectElementIndicesImpl( |
1063 Isolate* isolate, Handle<JSObject> object, | 1077 Isolate* isolate, Handle<JSObject> object, |
1064 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, | 1078 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, |
1065 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, | 1079 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, |
1066 uint32_t insertion_index = 0) { | 1080 uint32_t insertion_index = 0) { |
1067 uint32_t length = Subclass::GetMaxIndex(*object, *backing_store); | 1081 uint32_t length = Subclass::GetMaxIndex(*object, *backing_store); |
1068 for (uint32_t i = 0; i < length; i++) { | 1082 for (uint32_t i = 0; i < length; i++) { |
1069 if (Subclass::HasElementImpl(object, i, backing_store, filter)) { | 1083 if (Subclass::HasElementImpl(isolate, object, i, backing_store, filter)) { |
1070 if (convert == GetKeysConversion::kConvertToString) { | 1084 if (convert == GetKeysConversion::kConvertToString) { |
1071 Handle<String> index_string = isolate->factory()->Uint32ToString(i); | 1085 Handle<String> index_string = isolate->factory()->Uint32ToString(i); |
1072 list->set(insertion_index, *index_string); | 1086 list->set(insertion_index, *index_string); |
1073 } else { | 1087 } else { |
1074 list->set(insertion_index, Smi::FromInt(i), SKIP_WRITE_BARRIER); | 1088 list->set(insertion_index, Smi::FromInt(i), SKIP_WRITE_BARRIER); |
1075 } | 1089 } |
1076 insertion_index++; | 1090 insertion_index++; |
1077 } | 1091 } |
1078 } | 1092 } |
1079 *nof_indices = insertion_index; | 1093 *nof_indices = insertion_index; |
1080 return list; | 1094 return list; |
1081 } | 1095 } |
1082 | 1096 |
1083 MaybeHandle<FixedArray> PrependElementIndices( | 1097 MaybeHandle<FixedArray> PrependElementIndices( |
1084 Handle<JSObject> object, Handle<FixedArrayBase> backing_store, | 1098 Handle<JSObject> object, Handle<FixedArrayBase> backing_store, |
1085 Handle<FixedArray> keys, GetKeysConversion convert, | 1099 Handle<FixedArray> keys, GetKeysConversion convert, |
1086 PropertyFilter filter) final { | 1100 PropertyFilter filter) final { |
1087 return Subclass::PrependElementIndicesImpl(object, backing_store, keys, | 1101 return Subclass::PrependElementIndicesImpl(object, backing_store, keys, |
1088 convert, filter); | 1102 convert, filter); |
1089 } | 1103 } |
1090 | 1104 |
1091 static MaybeHandle<FixedArray> PrependElementIndicesImpl( | 1105 static MaybeHandle<FixedArray> PrependElementIndicesImpl( |
1092 Handle<JSObject> object, Handle<FixedArrayBase> backing_store, | 1106 Handle<JSObject> object, Handle<FixedArrayBase> backing_store, |
1093 Handle<FixedArray> keys, GetKeysConversion convert, | 1107 Handle<FixedArray> keys, GetKeysConversion convert, |
1094 PropertyFilter filter) { | 1108 PropertyFilter filter) { |
1095 Isolate* isolate = object->GetIsolate(); | 1109 Isolate* isolate = object->GetIsolate(); |
1096 uint32_t nof_property_keys = keys->length(); | 1110 uint32_t nof_property_keys = keys->length(); |
1097 uint32_t initial_list_length = | 1111 uint32_t initial_list_length = |
1098 Subclass::GetMaxNumberOfEntries(*object, *backing_store); | 1112 Subclass::GetMaxNumberOfEntries(*object, *backing_store); |
| 1113 |
1099 initial_list_length += nof_property_keys; | 1114 initial_list_length += nof_property_keys; |
1100 if (initial_list_length > FixedArray::kMaxLength || | 1115 if (initial_list_length > FixedArray::kMaxLength || |
1101 initial_list_length < nof_property_keys) { | 1116 initial_list_length < nof_property_keys) { |
1102 return isolate->Throw<FixedArray>(isolate->factory()->NewRangeError( | 1117 return isolate->Throw<FixedArray>(isolate->factory()->NewRangeError( |
1103 MessageTemplate::kInvalidArrayLength)); | 1118 MessageTemplate::kInvalidArrayLength)); |
1104 } | 1119 } |
1105 | 1120 |
| 1121 // Collect the element indices into a new list. |
| 1122 MaybeHandle<FixedArray> raw_array = |
| 1123 isolate->factory()->TryNewFixedArray(initial_list_length); |
| 1124 Handle<FixedArray> combined_keys; |
| 1125 |
| 1126 // If we have a holey backing store try to precisely estimate the backing |
| 1127 // store size as a last emergency measure if we cannot allocate the big |
| 1128 // array. |
| 1129 if (!raw_array.ToHandle(&combined_keys)) { |
| 1130 if (IsHoleyElementsKind(kind())) { |
| 1131 // If we overestimate the result list size we might end up in the |
| 1132 // large-object space which doesn't free memory on shrinking the list. |
| 1133 // Hence we try to estimate the final size for holey backing stores more |
| 1134 // precisely here. |
| 1135 initial_list_length = |
| 1136 Subclass::NumberOfElementsImpl(*object, *backing_store); |
| 1137 initial_list_length += nof_property_keys; |
| 1138 } |
| 1139 combined_keys = isolate->factory()->NewFixedArray(initial_list_length); |
| 1140 } |
| 1141 |
| 1142 uint32_t nof_indices = 0; |
1106 bool needs_sorting = | 1143 bool needs_sorting = |
1107 IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind()); | 1144 IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind()); |
1108 | |
1109 // Collect the element indices into a new list. | |
1110 uint32_t nof_indices = 0; | |
1111 Handle<FixedArray> combined_keys = | |
1112 isolate->factory()->NewFixedArray(initial_list_length); | |
1113 combined_keys = Subclass::DirectCollectElementIndicesImpl( | 1145 combined_keys = Subclass::DirectCollectElementIndicesImpl( |
1114 isolate, object, backing_store, | 1146 isolate, object, backing_store, |
1115 needs_sorting ? GetKeysConversion::kKeepNumbers : convert, filter, | 1147 needs_sorting ? GetKeysConversion::kKeepNumbers : convert, filter, |
1116 combined_keys, &nof_indices); | 1148 combined_keys, &nof_indices); |
1117 | 1149 |
1118 if (needs_sorting) { | 1150 if (needs_sorting) { |
1119 SortIndices(combined_keys, nof_indices); | 1151 SortIndices(combined_keys, nof_indices); |
1120 // Indices from dictionary elements should only be converted after | 1152 // Indices from dictionary elements should only be converted after |
1121 // sorting. | 1153 // sorting. |
1122 if (convert == GetKeysConversion::kConvertToString) { | 1154 if (convert == GetKeysConversion::kConvertToString) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1185 uint32_t length) final { | 1217 uint32_t length) final { |
1186 return Subclass::IndexOfValueImpl(isolate, receiver, value, start_from, | 1218 return Subclass::IndexOfValueImpl(isolate, receiver, value, start_from, |
1187 length); | 1219 length); |
1188 } | 1220 } |
1189 | 1221 |
1190 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, | 1222 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, |
1191 uint32_t entry) { | 1223 uint32_t entry) { |
1192 return entry; | 1224 return entry; |
1193 } | 1225 } |
1194 | 1226 |
1195 static uint32_t GetEntryForIndexImpl(JSObject* holder, | 1227 static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject* holder, |
1196 FixedArrayBase* backing_store, | 1228 FixedArrayBase* backing_store, |
1197 uint32_t index, PropertyFilter filter) { | 1229 uint32_t index, PropertyFilter filter) { |
1198 uint32_t length = Subclass::GetMaxIndex(holder, backing_store); | 1230 uint32_t length = Subclass::GetMaxIndex(holder, backing_store); |
1199 if (IsHoleyElementsKind(kind())) { | 1231 if (IsHoleyElementsKind(kind())) { |
1200 return index < length && | 1232 return index < length && |
1201 !BackingStore::cast(backing_store)->is_the_hole(index) | 1233 !BackingStore::cast(backing_store) |
| 1234 ->is_the_hole(isolate, index) |
1202 ? index | 1235 ? index |
1203 : kMaxUInt32; | 1236 : kMaxUInt32; |
1204 } else { | 1237 } else { |
1205 return index < length ? index : kMaxUInt32; | 1238 return index < length ? index : kMaxUInt32; |
1206 } | 1239 } |
1207 } | 1240 } |
1208 | 1241 |
1209 uint32_t GetEntryForIndex(JSObject* holder, FixedArrayBase* backing_store, | 1242 uint32_t GetEntryForIndex(Isolate* isolate, JSObject* holder, |
| 1243 FixedArrayBase* backing_store, |
1210 uint32_t index) final { | 1244 uint32_t index) final { |
1211 return Subclass::GetEntryForIndexImpl(holder, backing_store, index, | 1245 return Subclass::GetEntryForIndexImpl(isolate, holder, backing_store, index, |
1212 ALL_PROPERTIES); | 1246 ALL_PROPERTIES); |
1213 } | 1247 } |
1214 | 1248 |
1215 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, | 1249 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, |
1216 uint32_t entry) { | 1250 uint32_t entry) { |
1217 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); | 1251 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); |
1218 } | 1252 } |
1219 | 1253 |
1220 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { | 1254 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { |
1221 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); | 1255 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); |
(...skipping 16 matching lines...) Expand all Loading... |
1238 : ElementsAccessorBase<DictionaryElementsAccessor, | 1272 : ElementsAccessorBase<DictionaryElementsAccessor, |
1239 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} | 1273 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} |
1240 | 1274 |
1241 static uint32_t GetMaxIndex(JSObject* receiver, FixedArrayBase* elements) { | 1275 static uint32_t GetMaxIndex(JSObject* receiver, FixedArrayBase* elements) { |
1242 // We cannot properly estimate this for dictionaries. | 1276 // We cannot properly estimate this for dictionaries. |
1243 UNREACHABLE(); | 1277 UNREACHABLE(); |
1244 } | 1278 } |
1245 | 1279 |
1246 static uint32_t GetMaxNumberOfEntries(JSObject* receiver, | 1280 static uint32_t GetMaxNumberOfEntries(JSObject* receiver, |
1247 FixedArrayBase* backing_store) { | 1281 FixedArrayBase* backing_store) { |
| 1282 return NumberOfElementsImpl(receiver, backing_store); |
| 1283 } |
| 1284 |
| 1285 static uint32_t NumberOfElementsImpl(JSObject* receiver, |
| 1286 FixedArrayBase* backing_store) { |
1248 SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store); | 1287 SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store); |
1249 return dict->NumberOfElements(); | 1288 return dict->NumberOfElements(); |
1250 } | 1289 } |
1251 | 1290 |
1252 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, | 1291 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, |
1253 uint32_t length, | 1292 uint32_t length, |
1254 Handle<FixedArrayBase> backing_store) { | 1293 Handle<FixedArrayBase> backing_store) { |
1255 Handle<SeededNumberDictionary> dict = | 1294 Handle<SeededNumberDictionary> dict = |
1256 Handle<SeededNumberDictionary>::cast(backing_store); | 1295 Handle<SeededNumberDictionary>::cast(backing_store); |
1257 int capacity = dict->Capacity(); | 1296 int capacity = dict->Capacity(); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1386 : handle(SeededNumberDictionary::cast(object->elements())); | 1425 : handle(SeededNumberDictionary::cast(object->elements())); |
1387 Handle<SeededNumberDictionary> new_dictionary = | 1426 Handle<SeededNumberDictionary> new_dictionary = |
1388 SeededNumberDictionary::AddNumberEntry( | 1427 SeededNumberDictionary::AddNumberEntry( |
1389 dictionary, index, value, details, | 1428 dictionary, index, value, details, |
1390 object->map()->is_prototype_map()); | 1429 object->map()->is_prototype_map()); |
1391 if (attributes != NONE) object->RequireSlowElements(*new_dictionary); | 1430 if (attributes != NONE) object->RequireSlowElements(*new_dictionary); |
1392 if (dictionary.is_identical_to(new_dictionary)) return; | 1431 if (dictionary.is_identical_to(new_dictionary)) return; |
1393 object->set_elements(*new_dictionary); | 1432 object->set_elements(*new_dictionary); |
1394 } | 1433 } |
1395 | 1434 |
1396 static bool HasEntryImpl(FixedArrayBase* store, uint32_t entry) { | 1435 static bool HasEntryImpl(Isolate* isolate, FixedArrayBase* store, |
| 1436 uint32_t entry) { |
1397 DisallowHeapAllocation no_gc; | 1437 DisallowHeapAllocation no_gc; |
1398 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); | 1438 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); |
1399 Object* index = dict->KeyAt(entry); | 1439 Object* index = dict->KeyAt(entry); |
1400 return !index->IsTheHole(dict->GetIsolate()); | 1440 return !index->IsTheHole(isolate); |
1401 } | 1441 } |
1402 | 1442 |
1403 static uint32_t GetIndexForEntryImpl(FixedArrayBase* store, uint32_t entry) { | 1443 static uint32_t GetIndexForEntryImpl(FixedArrayBase* store, uint32_t entry) { |
1404 DisallowHeapAllocation no_gc; | 1444 DisallowHeapAllocation no_gc; |
1405 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); | 1445 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); |
1406 uint32_t result = 0; | 1446 uint32_t result = 0; |
1407 CHECK(dict->KeyAt(entry)->ToArrayIndex(&result)); | 1447 CHECK(dict->KeyAt(entry)->ToArrayIndex(&result)); |
1408 return result; | 1448 return result; |
1409 } | 1449 } |
1410 | 1450 |
1411 static uint32_t GetEntryForIndexImpl(JSObject* holder, FixedArrayBase* store, | 1451 static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject* holder, |
1412 uint32_t index, PropertyFilter filter) { | 1452 FixedArrayBase* store, uint32_t index, |
| 1453 PropertyFilter filter) { |
1413 DisallowHeapAllocation no_gc; | 1454 DisallowHeapAllocation no_gc; |
1414 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store); | 1455 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store); |
1415 int entry = dictionary->FindEntry(index); | 1456 int entry = dictionary->FindEntry(isolate, index); |
1416 if (entry == SeededNumberDictionary::kNotFound) return kMaxUInt32; | 1457 if (entry == SeededNumberDictionary::kNotFound) return kMaxUInt32; |
1417 if (filter != ALL_PROPERTIES) { | 1458 if (filter != ALL_PROPERTIES) { |
1418 PropertyDetails details = dictionary->DetailsAt(entry); | 1459 PropertyDetails details = dictionary->DetailsAt(entry); |
1419 PropertyAttributes attr = details.attributes(); | 1460 PropertyAttributes attr = details.attributes(); |
1420 if ((attr & filter) != 0) return kMaxUInt32; | 1461 if ((attr & filter) != 0) return kMaxUInt32; |
1421 } | 1462 } |
1422 return static_cast<uint32_t>(entry); | 1463 return static_cast<uint32_t>(entry); |
1423 } | 1464 } |
1424 | 1465 |
1425 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { | 1466 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1501 *nof_indices = insertion_index; | 1542 *nof_indices = insertion_index; |
1502 return list; | 1543 return list; |
1503 } | 1544 } |
1504 | 1545 |
1505 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, | 1546 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, |
1506 KeyAccumulator* accumulator, | 1547 KeyAccumulator* accumulator, |
1507 AddKeyConversion convert) { | 1548 AddKeyConversion convert) { |
1508 Isolate* isolate = accumulator->isolate(); | 1549 Isolate* isolate = accumulator->isolate(); |
1509 Handle<Object> undefined = isolate->factory()->undefined_value(); | 1550 Handle<Object> undefined = isolate->factory()->undefined_value(); |
1510 Handle<Object> the_hole = isolate->factory()->the_hole_value(); | 1551 Handle<Object> the_hole = isolate->factory()->the_hole_value(); |
1511 SeededNumberDictionary* dictionary = | 1552 Handle<SeededNumberDictionary> dictionary( |
1512 SeededNumberDictionary::cast(receiver->elements()); | 1553 SeededNumberDictionary::cast(receiver->elements()), isolate); |
1513 int capacity = dictionary->Capacity(); | 1554 int capacity = dictionary->Capacity(); |
1514 for (int i = 0; i < capacity; i++) { | 1555 for (int i = 0; i < capacity; i++) { |
1515 Object* k = dictionary->KeyAt(i); | 1556 Object* k = dictionary->KeyAt(i); |
1516 if (k == *undefined) continue; | 1557 if (k == *undefined) continue; |
1517 if (k == *the_hole) continue; | 1558 if (k == *the_hole) continue; |
1518 if (dictionary->IsDeleted(i)) continue; | 1559 if (dictionary->IsDeleted(i)) continue; |
1519 Object* value = dictionary->ValueAt(i); | 1560 Object* value = dictionary->ValueAt(i); |
1520 DCHECK(!value->IsTheHole(isolate)); | 1561 DCHECK(!value->IsTheHole(isolate)); |
1521 DCHECK(!value->IsAccessorPair()); | 1562 DCHECK(!value->IsAccessorPair()); |
1522 DCHECK(!value->IsAccessorInfo()); | 1563 DCHECK(!value->IsAccessorInfo()); |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1722 | 1763 |
1723 int capacity = object->GetFastElementsUsage(); | 1764 int capacity = object->GetFastElementsUsage(); |
1724 Handle<SeededNumberDictionary> dictionary = | 1765 Handle<SeededNumberDictionary> dictionary = |
1725 SeededNumberDictionary::New(isolate, capacity); | 1766 SeededNumberDictionary::New(isolate, capacity); |
1726 | 1767 |
1727 PropertyDetails details = PropertyDetails::Empty(); | 1768 PropertyDetails details = PropertyDetails::Empty(); |
1728 bool used_as_prototype = object->map()->is_prototype_map(); | 1769 bool used_as_prototype = object->map()->is_prototype_map(); |
1729 int j = 0; | 1770 int j = 0; |
1730 for (int i = 0; j < capacity; i++) { | 1771 for (int i = 0; j < capacity; i++) { |
1731 if (IsHoleyElementsKind(kind)) { | 1772 if (IsHoleyElementsKind(kind)) { |
1732 if (BackingStore::cast(*store)->is_the_hole(i)) continue; | 1773 if (BackingStore::cast(*store)->is_the_hole(isolate, i)) continue; |
1733 } | 1774 } |
1734 Handle<Object> value = Subclass::GetImpl(*store, i); | 1775 Handle<Object> value = Subclass::GetImpl(*store, i); |
1735 dictionary = SeededNumberDictionary::AddNumberEntry( | 1776 dictionary = SeededNumberDictionary::AddNumberEntry( |
1736 dictionary, i, value, details, used_as_prototype); | 1777 dictionary, i, value, details, used_as_prototype); |
1737 j++; | 1778 j++; |
1738 } | 1779 } |
1739 return dictionary; | 1780 return dictionary; |
1740 } | 1781 } |
1741 | 1782 |
1742 static void DeleteAtEnd(Handle<JSObject> obj, | 1783 static void DeleteAtEnd(Handle<JSObject> obj, |
1743 Handle<BackingStore> backing_store, uint32_t entry) { | 1784 Handle<BackingStore> backing_store, uint32_t entry) { |
1744 uint32_t length = static_cast<uint32_t>(backing_store->length()); | 1785 uint32_t length = static_cast<uint32_t>(backing_store->length()); |
1745 Heap* heap = obj->GetHeap(); | 1786 Isolate* isolate = obj->GetIsolate(); |
1746 for (; entry > 0; entry--) { | 1787 for (; entry > 0; entry--) { |
1747 if (!backing_store->is_the_hole(entry - 1)) break; | 1788 if (!backing_store->is_the_hole(isolate, entry - 1)) break; |
1748 } | 1789 } |
1749 if (entry == 0) { | 1790 if (entry == 0) { |
1750 FixedArray* empty = heap->empty_fixed_array(); | 1791 FixedArray* empty = isolate->heap()->empty_fixed_array(); |
1751 // Dynamically ask for the elements kind here since we manually redirect | 1792 // Dynamically ask for the elements kind here since we manually redirect |
1752 // the operations for argument backing stores. | 1793 // the operations for argument backing stores. |
1753 if (obj->GetElementsKind() == FAST_SLOPPY_ARGUMENTS_ELEMENTS) { | 1794 if (obj->GetElementsKind() == FAST_SLOPPY_ARGUMENTS_ELEMENTS) { |
1754 FixedArray::cast(obj->elements())->set(1, empty); | 1795 FixedArray::cast(obj->elements())->set(1, empty); |
1755 } else { | 1796 } else { |
1756 obj->set_elements(empty); | 1797 obj->set_elements(empty); |
1757 } | 1798 } |
1758 return; | 1799 return; |
1759 } | 1800 } |
1760 | 1801 |
1761 heap->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(*backing_store, | 1802 isolate->heap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>( |
1762 length - entry); | 1803 *backing_store, length - entry); |
1763 } | 1804 } |
1764 | 1805 |
1765 static void DeleteCommon(Handle<JSObject> obj, uint32_t entry, | 1806 static void DeleteCommon(Handle<JSObject> obj, uint32_t entry, |
1766 Handle<FixedArrayBase> store) { | 1807 Handle<FixedArrayBase> store) { |
1767 DCHECK(obj->HasFastSmiOrObjectElements() || obj->HasFastDoubleElements() || | 1808 DCHECK(obj->HasFastSmiOrObjectElements() || obj->HasFastDoubleElements() || |
1768 obj->HasFastArgumentsElements() || | 1809 obj->HasFastArgumentsElements() || |
1769 obj->HasFastStringWrapperElements()); | 1810 obj->HasFastStringWrapperElements()); |
1770 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(store); | 1811 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(store); |
1771 if (!obj->IsJSArray() && | 1812 if (!obj->IsJSArray() && |
1772 entry == static_cast<uint32_t>(store->length()) - 1) { | 1813 entry == static_cast<uint32_t>(store->length()) - 1) { |
1773 DeleteAtEnd(obj, backing_store, entry); | 1814 DeleteAtEnd(obj, backing_store, entry); |
1774 return; | 1815 return; |
1775 } | 1816 } |
1776 | 1817 |
| 1818 Isolate* isolate = obj->GetIsolate(); |
1777 backing_store->set_the_hole(entry); | 1819 backing_store->set_the_hole(entry); |
1778 | 1820 |
1779 // TODO(verwaest): Move this out of elements.cc. | 1821 // TODO(verwaest): Move this out of elements.cc. |
1780 // If an old space backing store is larger than a certain size and | 1822 // If an old space backing store is larger than a certain size and |
1781 // has too few used values, normalize it. | 1823 // has too few used values, normalize it. |
1782 // To avoid doing the check on every delete we require at least | 1824 // To avoid doing the check on every delete we require at least |
1783 // one adjacent hole to the value being deleted. | 1825 // one adjacent hole to the value being deleted. |
1784 const int kMinLengthForSparsenessCheck = 64; | 1826 const int kMinLengthForSparsenessCheck = 64; |
1785 if (backing_store->length() < kMinLengthForSparsenessCheck) return; | 1827 if (backing_store->length() < kMinLengthForSparsenessCheck) return; |
1786 if (backing_store->GetHeap()->InNewSpace(*backing_store)) return; | 1828 if (backing_store->GetHeap()->InNewSpace(*backing_store)) return; |
1787 uint32_t length = 0; | 1829 uint32_t length = 0; |
1788 if (obj->IsJSArray()) { | 1830 if (obj->IsJSArray()) { |
1789 JSArray::cast(*obj)->length()->ToArrayLength(&length); | 1831 JSArray::cast(*obj)->length()->ToArrayLength(&length); |
1790 } else { | 1832 } else { |
1791 length = static_cast<uint32_t>(store->length()); | 1833 length = static_cast<uint32_t>(store->length()); |
1792 } | 1834 } |
1793 if ((entry > 0 && backing_store->is_the_hole(entry - 1)) || | 1835 if ((entry > 0 && backing_store->is_the_hole(isolate, entry - 1)) || |
1794 (entry + 1 < length && backing_store->is_the_hole(entry + 1))) { | 1836 (entry + 1 < length && |
| 1837 backing_store->is_the_hole(isolate, entry + 1))) { |
1795 if (!obj->IsJSArray()) { | 1838 if (!obj->IsJSArray()) { |
1796 uint32_t i; | 1839 uint32_t i; |
1797 for (i = entry + 1; i < length; i++) { | 1840 for (i = entry + 1; i < length; i++) { |
1798 if (!backing_store->is_the_hole(i)) break; | 1841 if (!backing_store->is_the_hole(isolate, i)) break; |
1799 } | 1842 } |
1800 if (i == length) { | 1843 if (i == length) { |
1801 DeleteAtEnd(obj, backing_store, entry); | 1844 DeleteAtEnd(obj, backing_store, entry); |
1802 return; | 1845 return; |
1803 } | 1846 } |
1804 } | 1847 } |
1805 int num_used = 0; | 1848 int num_used = 0; |
1806 for (int i = 0; i < backing_store->length(); ++i) { | 1849 for (int i = 0; i < backing_store->length(); ++i) { |
1807 if (!backing_store->is_the_hole(i)) { | 1850 if (!backing_store->is_the_hole(isolate, i)) { |
1808 ++num_used; | 1851 ++num_used; |
1809 // Bail out if a number dictionary wouldn't be able to save at least | 1852 // Bail out if a number dictionary wouldn't be able to save at least |
1810 // 75% space. | 1853 // 75% space. |
1811 if (4 * SeededNumberDictionary::ComputeCapacity(num_used) * | 1854 if (4 * SeededNumberDictionary::ComputeCapacity(num_used) * |
1812 SeededNumberDictionary::kEntrySize > | 1855 SeededNumberDictionary::kEntrySize > |
1813 backing_store->length()) { | 1856 backing_store->length()) { |
1814 return; | 1857 return; |
1815 } | 1858 } |
1816 } | 1859 } |
1817 } | 1860 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1858 ElementsKind kind = KindTraits::Kind; | 1901 ElementsKind kind = KindTraits::Kind; |
1859 if (IsFastPackedElementsKind(kind)) { | 1902 if (IsFastPackedElementsKind(kind)) { |
1860 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind)); | 1903 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind)); |
1861 } | 1904 } |
1862 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) { | 1905 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) { |
1863 JSObject::EnsureWritableFastElements(obj); | 1906 JSObject::EnsureWritableFastElements(obj); |
1864 } | 1907 } |
1865 DeleteCommon(obj, entry, handle(obj->elements())); | 1908 DeleteCommon(obj, entry, handle(obj->elements())); |
1866 } | 1909 } |
1867 | 1910 |
1868 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) { | 1911 static bool HasEntryImpl(Isolate* isolate, FixedArrayBase* backing_store, |
1869 return !BackingStore::cast(backing_store)->is_the_hole(entry); | 1912 uint32_t entry) { |
| 1913 return !BackingStore::cast(backing_store)->is_the_hole(isolate, entry); |
| 1914 } |
| 1915 |
| 1916 static uint32_t NumberOfElementsImpl(JSObject* receiver, |
| 1917 FixedArrayBase* backing_store) { |
| 1918 uint32_t max_index = Subclass::GetMaxIndex(receiver, backing_store); |
| 1919 if (IsFastPackedElementsKind(Subclass::kind())) return max_index; |
| 1920 Isolate* isolate = receiver->GetIsolate(); |
| 1921 uint32_t count = 0; |
| 1922 for (uint32_t i = 0; i < max_index; i++) { |
| 1923 if (Subclass::HasEntryImpl(isolate, backing_store, i)) count++; |
| 1924 } |
| 1925 return count; |
1870 } | 1926 } |
1871 | 1927 |
1872 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, | 1928 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, |
1873 KeyAccumulator* accumulator, | 1929 KeyAccumulator* accumulator, |
1874 AddKeyConversion convert) { | 1930 AddKeyConversion convert) { |
1875 Handle<FixedArrayBase> elements(receiver->elements(), | 1931 Isolate* isolate = accumulator->isolate(); |
1876 accumulator->isolate()); | 1932 Handle<FixedArrayBase> elements(receiver->elements(), isolate); |
1877 uint32_t length = Subclass::GetMaxNumberOfEntries(*receiver, *elements); | 1933 uint32_t length = Subclass::GetMaxNumberOfEntries(*receiver, *elements); |
1878 for (uint32_t i = 0; i < length; i++) { | 1934 for (uint32_t i = 0; i < length; i++) { |
1879 if (IsFastPackedElementsKind(KindTraits::Kind) || | 1935 if (IsFastPackedElementsKind(KindTraits::Kind) || |
1880 HasEntryImpl(*elements, i)) { | 1936 HasEntryImpl(isolate, *elements, i)) { |
1881 accumulator->AddKey(Subclass::GetImpl(*elements, i), convert); | 1937 accumulator->AddKey(Subclass::GetImpl(*elements, i), convert); |
1882 } | 1938 } |
1883 } | 1939 } |
1884 } | 1940 } |
1885 | 1941 |
1886 static void ValidateContents(Handle<JSObject> holder, int length) { | 1942 static void ValidateContents(Handle<JSObject> holder, int length) { |
1887 #if DEBUG | 1943 #if DEBUG |
1888 Isolate* isolate = holder->GetIsolate(); | 1944 Isolate* isolate = holder->GetIsolate(); |
1889 Heap* heap = isolate->heap(); | 1945 Heap* heap = isolate->heap(); |
1890 HandleScope scope(isolate); | 1946 HandleScope scope(isolate); |
1891 Handle<FixedArrayBase> elements(holder->elements(), isolate); | 1947 Handle<FixedArrayBase> elements(holder->elements(), isolate); |
1892 Map* map = elements->map(); | 1948 Map* map = elements->map(); |
1893 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) { | 1949 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) { |
1894 DCHECK_NE(map, heap->fixed_double_array_map()); | 1950 DCHECK_NE(map, heap->fixed_double_array_map()); |
1895 } else if (IsFastDoubleElementsKind(KindTraits::Kind)) { | 1951 } else if (IsFastDoubleElementsKind(KindTraits::Kind)) { |
1896 DCHECK_NE(map, heap->fixed_cow_array_map()); | 1952 DCHECK_NE(map, heap->fixed_cow_array_map()); |
1897 if (map == heap->fixed_array_map()) DCHECK_EQ(0, length); | 1953 if (map == heap->fixed_array_map()) DCHECK_EQ(0, length); |
1898 } else { | 1954 } else { |
1899 UNREACHABLE(); | 1955 UNREACHABLE(); |
1900 } | 1956 } |
1901 if (length == 0) return; // nothing to do! | 1957 if (length == 0) return; // nothing to do! |
1902 #if ENABLE_SLOW_DCHECKS | 1958 #if ENABLE_SLOW_DCHECKS |
1903 DisallowHeapAllocation no_gc; | 1959 DisallowHeapAllocation no_gc; |
1904 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); | 1960 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); |
1905 if (IsFastSmiElementsKind(KindTraits::Kind)) { | 1961 if (IsFastSmiElementsKind(KindTraits::Kind)) { |
1906 for (int i = 0; i < length; i++) { | 1962 for (int i = 0; i < length; i++) { |
1907 DCHECK(BackingStore::get(*backing_store, i, isolate)->IsSmi() || | 1963 DCHECK(BackingStore::get(*backing_store, i, isolate)->IsSmi() || |
1908 (IsFastHoleyElementsKind(KindTraits::Kind) && | 1964 (IsFastHoleyElementsKind(KindTraits::Kind) && |
1909 backing_store->is_the_hole(i))); | 1965 backing_store->is_the_hole(isolate, i))); |
1910 } | 1966 } |
1911 } else if (KindTraits::Kind == FAST_ELEMENTS || | 1967 } else if (KindTraits::Kind == FAST_ELEMENTS || |
1912 KindTraits::Kind == FAST_DOUBLE_ELEMENTS) { | 1968 KindTraits::Kind == FAST_DOUBLE_ELEMENTS) { |
1913 for (int i = 0; i < length; i++) { | 1969 for (int i = 0; i < length; i++) { |
1914 DCHECK(!backing_store->is_the_hole(i)); | 1970 DCHECK(!backing_store->is_the_hole(isolate, i)); |
1915 } | 1971 } |
1916 } else { | 1972 } else { |
1917 DCHECK(IsFastHoleyElementsKind(KindTraits::Kind)); | 1973 DCHECK(IsFastHoleyElementsKind(KindTraits::Kind)); |
1918 } | 1974 } |
1919 #endif | 1975 #endif |
1920 #endif | 1976 #endif |
1921 } | 1977 } |
1922 | 1978 |
1923 static Handle<Object> PopImpl(Handle<JSArray> receiver) { | 1979 static Handle<Object> PopImpl(Handle<JSArray> receiver) { |
1924 return Subclass::RemoveElement(receiver, AT_END); | 1980 return Subclass::RemoveElement(receiver, AT_END); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2006 | 2062 |
2007 receiver->set_length(Smi::FromInt(new_length)); | 2063 receiver->set_length(Smi::FromInt(new_length)); |
2008 Subclass::TryTransitionResultArrayToPacked(deleted_elements); | 2064 Subclass::TryTransitionResultArrayToPacked(deleted_elements); |
2009 return deleted_elements; | 2065 return deleted_elements; |
2010 } | 2066 } |
2011 | 2067 |
2012 static Maybe<bool> CollectValuesOrEntriesImpl( | 2068 static Maybe<bool> CollectValuesOrEntriesImpl( |
2013 Isolate* isolate, Handle<JSObject> object, | 2069 Isolate* isolate, Handle<JSObject> object, |
2014 Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, | 2070 Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, |
2015 PropertyFilter filter) { | 2071 PropertyFilter filter) { |
| 2072 Handle<BackingStore> elements(BackingStore::cast(object->elements()), |
| 2073 isolate); |
2016 int count = 0; | 2074 int count = 0; |
2017 uint32_t length = object->elements()->length(); | 2075 uint32_t length = elements->length(); |
2018 for (uint32_t index = 0; index < length; ++index) { | 2076 for (uint32_t index = 0; index < length; ++index) { |
2019 if (!HasEntryImpl(object->elements(), index)) continue; | 2077 if (!HasEntryImpl(isolate, *elements, index)) continue; |
2020 Handle<Object> value = Subclass::GetImpl(object->elements(), index); | 2078 Handle<Object> value = Subclass::GetImpl(*elements, index); |
2021 if (get_entries) { | 2079 if (get_entries) { |
2022 value = MakeEntryPair(isolate, index, value); | 2080 value = MakeEntryPair(isolate, index, value); |
2023 } | 2081 } |
2024 values_or_entries->set(count++, *value); | 2082 values_or_entries->set(count++, *value); |
2025 } | 2083 } |
2026 *nof_items = count; | 2084 *nof_items = count; |
2027 return Just(true); | 2085 return Just(true); |
2028 } | 2086 } |
2029 | 2087 |
2030 static void MoveElements(Isolate* isolate, Handle<JSArray> receiver, | 2088 static void MoveElements(Isolate* isolate, Handle<JSArray> receiver, |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2350 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, | 2408 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, |
2351 Object* value, WriteBarrierMode mode) { | 2409 Object* value, WriteBarrierMode mode) { |
2352 FixedArray::cast(backing_store)->set(entry, value, mode); | 2410 FixedArray::cast(backing_store)->set(entry, value, mode); |
2353 } | 2411 } |
2354 | 2412 |
2355 static Object* GetRaw(FixedArray* backing_store, uint32_t entry) { | 2413 static Object* GetRaw(FixedArray* backing_store, uint32_t entry) { |
2356 uint32_t index = Subclass::GetIndexForEntryImpl(backing_store, entry); | 2414 uint32_t index = Subclass::GetIndexForEntryImpl(backing_store, entry); |
2357 return backing_store->get(index); | 2415 return backing_store->get(index); |
2358 } | 2416 } |
2359 | 2417 |
2360 | |
2361 // NOTE: this method violates the handlified function signature convention: | 2418 // NOTE: this method violates the handlified function signature convention: |
2362 // raw pointer parameters in the function that allocates. | 2419 // raw pointer parameters in the function that allocates. |
2363 // See ElementsAccessor::CopyElements() for details. | 2420 // See ElementsAccessor::CopyElements() for details. |
2364 // This method could actually allocate if copying from double elements to | 2421 // This method could actually allocate if copying from double elements to |
2365 // object elements. | 2422 // object elements. |
2366 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, | 2423 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, |
2367 FixedArrayBase* to, ElementsKind from_kind, | 2424 FixedArrayBase* to, ElementsKind from_kind, |
2368 uint32_t to_start, int packed_size, | 2425 uint32_t to_start, int packed_size, |
2369 int copy_size) { | 2426 int copy_size) { |
2370 DisallowHeapAllocation no_gc; | 2427 DisallowHeapAllocation no_gc; |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2649 | 2706 |
2650 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { | 2707 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { |
2651 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell); | 2708 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell); |
2652 } | 2709 } |
2653 | 2710 |
2654 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, | 2711 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, |
2655 uint32_t entry) { | 2712 uint32_t entry) { |
2656 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell); | 2713 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell); |
2657 } | 2714 } |
2658 | 2715 |
2659 static bool HasElementImpl(Handle<JSObject> holder, uint32_t index, | 2716 static bool HasElementImpl(Isolate* isolate, Handle<JSObject> holder, |
| 2717 uint32_t index, |
2660 Handle<FixedArrayBase> backing_store, | 2718 Handle<FixedArrayBase> backing_store, |
2661 PropertyFilter filter) { | 2719 PropertyFilter filter) { |
2662 return index < AccessorClass::GetCapacityImpl(*holder, *backing_store); | 2720 return index < AccessorClass::GetCapacityImpl(*holder, *backing_store); |
2663 } | 2721 } |
2664 | 2722 |
2665 static bool HasAccessorsImpl(JSObject* holder, | 2723 static bool HasAccessorsImpl(JSObject* holder, |
2666 FixedArrayBase* backing_store) { | 2724 FixedArrayBase* backing_store) { |
2667 return false; | 2725 return false; |
2668 } | 2726 } |
2669 | 2727 |
2670 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, | 2728 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, |
2671 uint32_t length, | 2729 uint32_t length, |
2672 Handle<FixedArrayBase> backing_store) { | 2730 Handle<FixedArrayBase> backing_store) { |
2673 // External arrays do not support changing their length. | 2731 // External arrays do not support changing their length. |
2674 UNREACHABLE(); | 2732 UNREACHABLE(); |
2675 } | 2733 } |
2676 | 2734 |
2677 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { | 2735 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { |
2678 UNREACHABLE(); | 2736 UNREACHABLE(); |
2679 } | 2737 } |
2680 | 2738 |
2681 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, | 2739 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, |
2682 uint32_t entry) { | 2740 uint32_t entry) { |
2683 return entry; | 2741 return entry; |
2684 } | 2742 } |
2685 | 2743 |
2686 static uint32_t GetEntryForIndexImpl(JSObject* holder, | 2744 static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject* holder, |
2687 FixedArrayBase* backing_store, | 2745 FixedArrayBase* backing_store, |
2688 uint32_t index, PropertyFilter filter) { | 2746 uint32_t index, PropertyFilter filter) { |
2689 return index < AccessorClass::GetCapacityImpl(holder, backing_store) | 2747 return index < AccessorClass::GetCapacityImpl(holder, backing_store) |
2690 ? index | 2748 ? index |
2691 : kMaxUInt32; | 2749 : kMaxUInt32; |
2692 } | 2750 } |
2693 | 2751 |
2694 static uint32_t GetCapacityImpl(JSObject* holder, | 2752 static uint32_t GetCapacityImpl(JSObject* holder, |
2695 FixedArrayBase* backing_store) { | 2753 FixedArrayBase* backing_store) { |
2696 JSArrayBufferView* view = JSArrayBufferView::cast(holder); | 2754 JSArrayBufferView* view = JSArrayBufferView::cast(holder); |
2697 if (view->WasNeutered()) return 0; | 2755 if (view->WasNeutered()) return 0; |
2698 return backing_store->length(); | 2756 return backing_store->length(); |
2699 } | 2757 } |
2700 | 2758 |
| 2759 static uint32_t NumberOfElementsImpl(JSObject* receiver, |
| 2760 FixedArrayBase* backing_store) { |
| 2761 return AccessorClass::GetCapacityImpl(receiver, backing_store); |
| 2762 } |
| 2763 |
2701 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, | 2764 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, |
2702 KeyAccumulator* accumulator, | 2765 KeyAccumulator* accumulator, |
2703 AddKeyConversion convert) { | 2766 AddKeyConversion convert) { |
2704 Handle<FixedArrayBase> elements(receiver->elements()); | 2767 Handle<FixedArrayBase> elements(receiver->elements()); |
2705 uint32_t length = AccessorClass::GetCapacityImpl(*receiver, *elements); | 2768 uint32_t length = AccessorClass::GetCapacityImpl(*receiver, *elements); |
2706 for (uint32_t i = 0; i < length; i++) { | 2769 for (uint32_t i = 0; i < length; i++) { |
2707 Handle<Object> value = AccessorClass::GetImpl(*elements, i); | 2770 Handle<Object> value = AccessorClass::GetImpl(*elements, i); |
2708 accumulator->AddKey(value, convert); | 2771 accumulator->AddKey(value, convert); |
2709 } | 2772 } |
2710 } | 2773 } |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2929 } | 2992 } |
2930 | 2993 |
2931 static uint32_t GetMaxNumberOfEntries(JSObject* holder, | 2994 static uint32_t GetMaxNumberOfEntries(JSObject* holder, |
2932 FixedArrayBase* backing_store) { | 2995 FixedArrayBase* backing_store) { |
2933 FixedArray* parameter_map = FixedArray::cast(backing_store); | 2996 FixedArray* parameter_map = FixedArray::cast(backing_store); |
2934 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 2997 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
2935 return parameter_map->length() - 2 + | 2998 return parameter_map->length() - 2 + |
2936 ArgumentsAccessor::GetMaxNumberOfEntries(holder, arguments); | 2999 ArgumentsAccessor::GetMaxNumberOfEntries(holder, arguments); |
2937 } | 3000 } |
2938 | 3001 |
| 3002 static uint32_t NumberOfElementsImpl(JSObject* receiver, |
| 3003 FixedArrayBase* backing_store) { |
| 3004 FixedArray* parameter_map = FixedArray::cast(backing_store); |
| 3005 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
| 3006 uint32_t nof_elements = 0; |
| 3007 uint32_t length = parameter_map->length() - 2; |
| 3008 for (uint32_t entry = 0; entry < length; entry++) { |
| 3009 if (HasParameterMapArg(parameter_map, entry)) nof_elements++; |
| 3010 } |
| 3011 return nof_elements + |
| 3012 ArgumentsAccessor::NumberOfElementsImpl(receiver, arguments); |
| 3013 } |
| 3014 |
2939 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, | 3015 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, |
2940 KeyAccumulator* accumulator, | 3016 KeyAccumulator* accumulator, |
2941 AddKeyConversion convert) { | 3017 AddKeyConversion convert) { |
2942 FixedArrayBase* elements = receiver->elements(); | 3018 Isolate* isolate = accumulator->isolate(); |
2943 uint32_t length = GetCapacityImpl(*receiver, elements); | 3019 Handle<FixedArrayBase> elements(receiver->elements(), isolate); |
| 3020 uint32_t length = GetCapacityImpl(*receiver, *elements); |
2944 for (uint32_t entry = 0; entry < length; entry++) { | 3021 for (uint32_t entry = 0; entry < length; entry++) { |
2945 if (!HasEntryImpl(elements, entry)) continue; | 3022 if (!HasEntryImpl(isolate, *elements, entry)) continue; |
2946 Handle<Object> value = GetImpl(elements, entry); | 3023 Handle<Object> value = GetImpl(*elements, entry); |
2947 accumulator->AddKey(value, convert); | 3024 accumulator->AddKey(value, convert); |
2948 } | 3025 } |
2949 } | 3026 } |
2950 | 3027 |
2951 static bool HasEntryImpl(FixedArrayBase* parameters, uint32_t entry) { | 3028 static bool HasEntryImpl(Isolate* isolate, FixedArrayBase* parameters, |
| 3029 uint32_t entry) { |
2952 FixedArray* parameter_map = FixedArray::cast(parameters); | 3030 FixedArray* parameter_map = FixedArray::cast(parameters); |
2953 uint32_t length = parameter_map->length() - 2; | 3031 uint32_t length = parameter_map->length() - 2; |
2954 if (entry < length) { | 3032 if (entry < length) { |
2955 return HasParameterMapArg(parameter_map, entry); | 3033 return HasParameterMapArg(parameter_map, entry); |
2956 } | 3034 } |
2957 | 3035 |
2958 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 3036 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
2959 return ArgumentsAccessor::HasEntryImpl(arguments, entry - length); | 3037 return ArgumentsAccessor::HasEntryImpl(isolate, arguments, entry - length); |
2960 } | 3038 } |
2961 | 3039 |
2962 static bool HasAccessorsImpl(JSObject* holder, | 3040 static bool HasAccessorsImpl(JSObject* holder, |
2963 FixedArrayBase* backing_store) { | 3041 FixedArrayBase* backing_store) { |
2964 FixedArray* parameter_map = FixedArray::cast(backing_store); | 3042 FixedArray* parameter_map = FixedArray::cast(backing_store); |
2965 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 3043 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
2966 return ArgumentsAccessor::HasAccessorsImpl(holder, arguments); | 3044 return ArgumentsAccessor::HasAccessorsImpl(holder, arguments); |
2967 } | 3045 } |
2968 | 3046 |
2969 static uint32_t GetIndexForEntryImpl(FixedArrayBase* parameters, | 3047 static uint32_t GetIndexForEntryImpl(FixedArrayBase* parameters, |
2970 uint32_t entry) { | 3048 uint32_t entry) { |
2971 FixedArray* parameter_map = FixedArray::cast(parameters); | 3049 FixedArray* parameter_map = FixedArray::cast(parameters); |
2972 uint32_t length = parameter_map->length() - 2; | 3050 uint32_t length = parameter_map->length() - 2; |
2973 if (entry < length) return entry; | 3051 if (entry < length) return entry; |
2974 | 3052 |
2975 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 3053 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
2976 return ArgumentsAccessor::GetIndexForEntryImpl(arguments, entry - length); | 3054 return ArgumentsAccessor::GetIndexForEntryImpl(arguments, entry - length); |
2977 } | 3055 } |
2978 | 3056 |
2979 static uint32_t GetEntryForIndexImpl(JSObject* holder, | 3057 static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject* holder, |
2980 FixedArrayBase* parameters, | 3058 FixedArrayBase* parameters, |
2981 uint32_t index, PropertyFilter filter) { | 3059 uint32_t index, PropertyFilter filter) { |
2982 FixedArray* parameter_map = FixedArray::cast(parameters); | 3060 FixedArray* parameter_map = FixedArray::cast(parameters); |
2983 if (HasParameterMapArg(parameter_map, index)) return index; | 3061 if (HasParameterMapArg(parameter_map, index)) return index; |
2984 | 3062 |
2985 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 3063 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
2986 uint32_t entry = ArgumentsAccessor::GetEntryForIndexImpl(holder, arguments, | 3064 uint32_t entry = ArgumentsAccessor::GetEntryForIndexImpl( |
2987 index, filter); | 3065 isolate, holder, arguments, index, filter); |
2988 if (entry == kMaxUInt32) return kMaxUInt32; | 3066 if (entry == kMaxUInt32) return kMaxUInt32; |
2989 return (parameter_map->length() - 2) + entry; | 3067 return (parameter_map->length() - 2) + entry; |
2990 } | 3068 } |
2991 | 3069 |
2992 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { | 3070 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { |
2993 FixedArray* parameter_map = FixedArray::cast(holder->elements()); | 3071 FixedArray* parameter_map = FixedArray::cast(holder->elements()); |
2994 uint32_t length = parameter_map->length() - 2; | 3072 uint32_t length = parameter_map->length() - 2; |
2995 if (entry < length) { | 3073 if (entry < length) { |
2996 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); | 3074 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); |
2997 } | 3075 } |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3064 Handle<JSObject> object, | 3142 Handle<JSObject> object, |
3065 Handle<Object> value, | 3143 Handle<Object> value, |
3066 uint32_t start_from, uint32_t length) { | 3144 uint32_t start_from, uint32_t length) { |
3067 DCHECK(JSObject::PrototypeHasNoElements(isolate, *object)); | 3145 DCHECK(JSObject::PrototypeHasNoElements(isolate, *object)); |
3068 Handle<Map> original_map = handle(object->map(), isolate); | 3146 Handle<Map> original_map = handle(object->map(), isolate); |
3069 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()), | 3147 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()), |
3070 isolate); | 3148 isolate); |
3071 bool search_for_hole = value->IsUndefined(isolate); | 3149 bool search_for_hole = value->IsUndefined(isolate); |
3072 | 3150 |
3073 for (uint32_t k = start_from; k < length; ++k) { | 3151 for (uint32_t k = start_from; k < length; ++k) { |
3074 uint32_t entry = | 3152 uint32_t entry = GetEntryForIndexImpl(isolate, *object, *parameter_map, k, |
3075 GetEntryForIndexImpl(*object, *parameter_map, k, ALL_PROPERTIES); | 3153 ALL_PROPERTIES); |
3076 if (entry == kMaxUInt32) { | 3154 if (entry == kMaxUInt32) { |
3077 if (search_for_hole) return Just(true); | 3155 if (search_for_hole) return Just(true); |
3078 continue; | 3156 continue; |
3079 } | 3157 } |
3080 | 3158 |
3081 Handle<Object> element_k = GetImpl(*parameter_map, entry); | 3159 Handle<Object> element_k = GetImpl(*parameter_map, entry); |
3082 | 3160 |
3083 if (element_k->IsAccessorPair()) { | 3161 if (element_k->IsAccessorPair()) { |
3084 LookupIterator it(isolate, object, k, LookupIterator::OWN); | 3162 LookupIterator it(isolate, object, k, LookupIterator::OWN); |
3085 DCHECK(it.IsFound()); | 3163 DCHECK(it.IsFound()); |
(...skipping 18 matching lines...) Expand all Loading... |
3104 static Maybe<int64_t> IndexOfValueImpl(Isolate* isolate, | 3182 static Maybe<int64_t> IndexOfValueImpl(Isolate* isolate, |
3105 Handle<JSObject> object, | 3183 Handle<JSObject> object, |
3106 Handle<Object> value, | 3184 Handle<Object> value, |
3107 uint32_t start_from, uint32_t length) { | 3185 uint32_t start_from, uint32_t length) { |
3108 DCHECK(JSObject::PrototypeHasNoElements(isolate, *object)); | 3186 DCHECK(JSObject::PrototypeHasNoElements(isolate, *object)); |
3109 Handle<Map> original_map = handle(object->map(), isolate); | 3187 Handle<Map> original_map = handle(object->map(), isolate); |
3110 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()), | 3188 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()), |
3111 isolate); | 3189 isolate); |
3112 | 3190 |
3113 for (uint32_t k = start_from; k < length; ++k) { | 3191 for (uint32_t k = start_from; k < length; ++k) { |
3114 uint32_t entry = | 3192 uint32_t entry = GetEntryForIndexImpl(isolate, *object, *parameter_map, k, |
3115 GetEntryForIndexImpl(*object, *parameter_map, k, ALL_PROPERTIES); | 3193 ALL_PROPERTIES); |
3116 if (entry == kMaxUInt32) { | 3194 if (entry == kMaxUInt32) { |
3117 continue; | 3195 continue; |
3118 } | 3196 } |
3119 | 3197 |
3120 Handle<Object> element_k = GetImpl(*parameter_map, entry); | 3198 Handle<Object> element_k = GetImpl(*parameter_map, entry); |
3121 | 3199 |
3122 if (element_k->IsAccessorPair()) { | 3200 if (element_k->IsAccessorPair()) { |
3123 LookupIterator it(isolate, object, k, LookupIterator::OWN); | 3201 LookupIterator it(isolate, object, k, LookupIterator::OWN); |
3124 DCHECK(it.IsFound()); | 3202 DCHECK(it.IsFound()); |
3125 DCHECK_EQ(it.state(), LookupIterator::ACCESSOR); | 3203 DCHECK_EQ(it.state(), LookupIterator::ACCESSOR); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3252 uint32_t end) { | 3330 uint32_t end) { |
3253 Isolate* isolate = receiver->GetIsolate(); | 3331 Isolate* isolate = receiver->GetIsolate(); |
3254 uint32_t result_len = end < start ? 0u : end - start; | 3332 uint32_t result_len = end < start ? 0u : end - start; |
3255 Handle<JSArray> result_array = isolate->factory()->NewJSArray( | 3333 Handle<JSArray> result_array = isolate->factory()->NewJSArray( |
3256 FAST_HOLEY_ELEMENTS, result_len, result_len); | 3334 FAST_HOLEY_ELEMENTS, result_len, result_len); |
3257 DisallowHeapAllocation no_gc; | 3335 DisallowHeapAllocation no_gc; |
3258 FixedArray* elements = FixedArray::cast(result_array->elements()); | 3336 FixedArray* elements = FixedArray::cast(result_array->elements()); |
3259 FixedArray* parameters = FixedArray::cast(receiver->elements()); | 3337 FixedArray* parameters = FixedArray::cast(receiver->elements()); |
3260 uint32_t insertion_index = 0; | 3338 uint32_t insertion_index = 0; |
3261 for (uint32_t i = start; i < end; i++) { | 3339 for (uint32_t i = start; i < end; i++) { |
3262 uint32_t entry = | 3340 uint32_t entry = GetEntryForIndexImpl(isolate, *receiver, parameters, i, |
3263 GetEntryForIndexImpl(*receiver, parameters, i, ALL_PROPERTIES); | 3341 ALL_PROPERTIES); |
3264 if (entry != kMaxUInt32 && HasEntryImpl(parameters, entry)) { | 3342 if (entry != kMaxUInt32 && HasEntryImpl(isolate, parameters, entry)) { |
3265 elements->set(insertion_index, *GetImpl(parameters, entry)); | 3343 elements->set(insertion_index, *GetImpl(parameters, entry)); |
3266 } else { | 3344 } else { |
3267 elements->set_the_hole(insertion_index); | 3345 elements->set_the_hole(insertion_index); |
3268 } | 3346 } |
3269 insertion_index++; | 3347 insertion_index++; |
3270 } | 3348 } |
3271 return result_array; | 3349 return result_array; |
3272 } | 3350 } |
3273 | 3351 |
3274 static Handle<SeededNumberDictionary> NormalizeImpl( | 3352 static Handle<SeededNumberDictionary> NormalizeImpl( |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3377 uint32_t length = static_cast<uint32_t>(GetString(holder)->length()); | 3455 uint32_t length = static_cast<uint32_t>(GetString(holder)->length()); |
3378 if (entry < length) { | 3456 if (entry < length) { |
3379 PropertyAttributes attributes = | 3457 PropertyAttributes attributes = |
3380 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE); | 3458 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE); |
3381 return PropertyDetails(attributes, v8::internal::DATA, 0, | 3459 return PropertyDetails(attributes, v8::internal::DATA, 0, |
3382 PropertyCellType::kNoCell); | 3460 PropertyCellType::kNoCell); |
3383 } | 3461 } |
3384 return BackingStoreAccessor::GetDetailsImpl(holder, entry - length); | 3462 return BackingStoreAccessor::GetDetailsImpl(holder, entry - length); |
3385 } | 3463 } |
3386 | 3464 |
3387 static uint32_t GetEntryForIndexImpl(JSObject* holder, | 3465 static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject* holder, |
3388 FixedArrayBase* backing_store, | 3466 FixedArrayBase* backing_store, |
3389 uint32_t index, PropertyFilter filter) { | 3467 uint32_t index, PropertyFilter filter) { |
3390 uint32_t length = static_cast<uint32_t>(GetString(holder)->length()); | 3468 uint32_t length = static_cast<uint32_t>(GetString(holder)->length()); |
3391 if (index < length) return index; | 3469 if (index < length) return index; |
3392 uint32_t backing_store_entry = BackingStoreAccessor::GetEntryForIndexImpl( | 3470 uint32_t backing_store_entry = BackingStoreAccessor::GetEntryForIndexImpl( |
3393 holder, backing_store, index, filter); | 3471 isolate, holder, backing_store, index, filter); |
3394 if (backing_store_entry == kMaxUInt32) return kMaxUInt32; | 3472 if (backing_store_entry == kMaxUInt32) return kMaxUInt32; |
3395 DCHECK(backing_store_entry < kMaxUInt32 - length); | 3473 DCHECK(backing_store_entry < kMaxUInt32 - length); |
3396 return backing_store_entry + length; | 3474 return backing_store_entry + length; |
3397 } | 3475 } |
3398 | 3476 |
3399 static void DeleteImpl(Handle<JSObject> holder, uint32_t entry) { | 3477 static void DeleteImpl(Handle<JSObject> holder, uint32_t entry) { |
3400 uint32_t length = static_cast<uint32_t>(GetString(*holder)->length()); | 3478 uint32_t length = static_cast<uint32_t>(GetString(*holder)->length()); |
3401 if (entry < length) { | 3479 if (entry < length) { |
3402 return; // String contents can't be deleted. | 3480 return; // String contents can't be deleted. |
3403 } | 3481 } |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3490 if (from_kind == SLOW_STRING_WRAPPER_ELEMENTS) { | 3568 if (from_kind == SLOW_STRING_WRAPPER_ELEMENTS) { |
3491 CopyDictionaryToObjectElements(from, from_start, to, FAST_HOLEY_ELEMENTS, | 3569 CopyDictionaryToObjectElements(from, from_start, to, FAST_HOLEY_ELEMENTS, |
3492 to_start, copy_size); | 3570 to_start, copy_size); |
3493 } else { | 3571 } else { |
3494 DCHECK_EQ(FAST_STRING_WRAPPER_ELEMENTS, from_kind); | 3572 DCHECK_EQ(FAST_STRING_WRAPPER_ELEMENTS, from_kind); |
3495 CopyObjectToObjectElements(from, FAST_HOLEY_ELEMENTS, from_start, to, | 3573 CopyObjectToObjectElements(from, FAST_HOLEY_ELEMENTS, from_start, to, |
3496 FAST_HOLEY_ELEMENTS, to_start, copy_size); | 3574 FAST_HOLEY_ELEMENTS, to_start, copy_size); |
3497 } | 3575 } |
3498 } | 3576 } |
3499 | 3577 |
| 3578 static uint32_t NumberOfElementsImpl(JSObject* object, |
| 3579 FixedArrayBase* backing_store) { |
| 3580 uint32_t length = GetString(object)->length(); |
| 3581 return length + |
| 3582 BackingStoreAccessor::NumberOfElementsImpl(object, backing_store); |
| 3583 } |
| 3584 |
3500 private: | 3585 private: |
3501 static String* GetString(JSObject* holder) { | 3586 static String* GetString(JSObject* holder) { |
3502 DCHECK(holder->IsJSValue()); | 3587 DCHECK(holder->IsJSValue()); |
3503 JSValue* js_value = JSValue::cast(holder); | 3588 JSValue* js_value = JSValue::cast(holder); |
3504 DCHECK(js_value->value()->IsString()); | 3589 DCHECK(js_value->value()->IsString()); |
3505 return String::cast(js_value->value()); | 3590 return String::cast(js_value->value()); |
3506 } | 3591 } |
3507 }; | 3592 }; |
3508 | 3593 |
3509 class FastStringWrapperElementsAccessor | 3594 class FastStringWrapperElementsAccessor |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3741 insertion_index += len; | 3826 insertion_index += len; |
3742 } | 3827 } |
3743 | 3828 |
3744 DCHECK_EQ(insertion_index, result_len); | 3829 DCHECK_EQ(insertion_index, result_len); |
3745 return result_array; | 3830 return result_array; |
3746 } | 3831 } |
3747 | 3832 |
3748 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 3833 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
3749 } // namespace internal | 3834 } // namespace internal |
3750 } // namespace v8 | 3835 } // namespace v8 |
OLD | NEW |