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