Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(325)

Side by Side Diff: src/elements.cc

Issue 2041963003: [elements] Precisely estimate elements size for large-object limits (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: add missing method on string wrapper Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/elements.h ('k') | src/factory.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/elements.h ('k') | src/factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698