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

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: Created 4 years, 6 months 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/lookup.cc » ('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 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 516
517 void Validate(Handle<JSObject> holder) final { 517 void Validate(Handle<JSObject> holder) final {
518 DisallowHeapAllocation no_gc; 518 DisallowHeapAllocation no_gc;
519 Subclass::ValidateImpl(holder); 519 Subclass::ValidateImpl(holder);
520 } 520 }
521 521
522 static bool IsPackedImpl(Handle<JSObject> holder, 522 static bool IsPackedImpl(Handle<JSObject> holder,
523 Handle<FixedArrayBase> backing_store, uint32_t start, 523 Handle<FixedArrayBase> backing_store, uint32_t start,
524 uint32_t end) { 524 uint32_t end) {
525 if (IsFastPackedElementsKind(kind())) return true; 525 if (IsFastPackedElementsKind(kind())) return true;
526 Isolate* isolate = backing_store->GetIsolate();
526 for (uint32_t i = start; i < end; i++) { 527 for (uint32_t i = start; i < end; i++) {
527 if (!Subclass::HasElementImpl(holder, i, backing_store, ALL_PROPERTIES)) { 528 if (!Subclass::HasElementImpl(isolate, holder, i, backing_store,
529 ALL_PROPERTIES)) {
528 return false; 530 return false;
529 } 531 }
530 } 532 }
531 return true; 533 return true;
532 } 534 }
533 535
534 static void TryTransitionResultArrayToPacked(Handle<JSArray> array) { 536 static void TryTransitionResultArrayToPacked(Handle<JSArray> array) {
535 if (!IsHoleyElementsKind(kind())) return; 537 if (!IsHoleyElementsKind(kind())) return;
536 int length = Smi::cast(array->length())->value(); 538 int length = Smi::cast(array->length())->value();
537 Handle<FixedArrayBase> backing_store(array->elements()); 539 Handle<FixedArrayBase> backing_store(array->elements());
538 if (!Subclass::IsPackedImpl(array, backing_store, 0, length)) { 540 if (!Subclass::IsPackedImpl(array, backing_store, 0, length)) {
539 return; 541 return;
540 } 542 }
541 ElementsKind packed_kind = GetPackedElementsKind(kind()); 543 ElementsKind packed_kind = GetPackedElementsKind(kind());
542 Handle<Map> new_map = 544 Handle<Map> new_map =
543 JSObject::GetElementsTransitionMap(array, packed_kind); 545 JSObject::GetElementsTransitionMap(array, packed_kind);
544 JSObject::MigrateToMap(array, new_map); 546 JSObject::MigrateToMap(array, new_map);
545 if (FLAG_trace_elements_transitions) { 547 if (FLAG_trace_elements_transitions) {
546 JSObject::PrintElementsTransition(stdout, array, kind(), backing_store, 548 JSObject::PrintElementsTransition(stdout, array, kind(), backing_store,
547 packed_kind, backing_store); 549 packed_kind, backing_store);
548 } 550 }
549 } 551 }
550 552
551 bool HasElement(Handle<JSObject> holder, uint32_t index, 553 bool HasElement(Handle<JSObject> holder, uint32_t index,
552 Handle<FixedArrayBase> backing_store, 554 Handle<FixedArrayBase> backing_store,
553 PropertyFilter filter) final { 555 PropertyFilter filter) final {
554 return Subclass::HasElementImpl(holder, index, backing_store, filter); 556 return Subclass::HasElementImpl(holder->GetIsolate(), holder, index,
557 backing_store, filter);
555 } 558 }
556 559
557 static bool HasElementImpl(Handle<JSObject> holder, uint32_t index, 560 static bool HasElementImpl(Isolate* isolate, Handle<JSObject> holder,
561 uint32_t index,
558 Handle<FixedArrayBase> backing_store, 562 Handle<FixedArrayBase> backing_store,
559 PropertyFilter filter) { 563 PropertyFilter filter) {
560 return Subclass::GetEntryForIndexImpl(*holder, *backing_store, index, 564 return Subclass::GetEntryForIndexImpl(isolate, *holder, *backing_store,
561 filter) != kMaxUInt32; 565 index, filter) != kMaxUInt32;
562 } 566 }
563 567
564 bool HasAccessors(JSObject* holder) final { 568 bool HasAccessors(JSObject* holder) final {
565 return Subclass::HasAccessorsImpl(holder, holder->elements()); 569 return Subclass::HasAccessorsImpl(holder, holder->elements());
566 } 570 }
567 571
568 static bool HasAccessorsImpl(JSObject* holder, 572 static bool HasAccessorsImpl(JSObject* holder,
569 FixedArrayBase* backing_store) { 573 FixedArrayBase* backing_store) {
570 return false; 574 return false;
571 } 575 }
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 } else { 726 } else {
723 // Check whether the backing store should be expanded. 727 // Check whether the backing store should be expanded.
724 capacity = Max(length, JSObject::NewElementsCapacity(capacity)); 728 capacity = Max(length, JSObject::NewElementsCapacity(capacity));
725 Subclass::GrowCapacityAndConvertImpl(array, capacity); 729 Subclass::GrowCapacityAndConvertImpl(array, capacity);
726 } 730 }
727 731
728 array->set_length(Smi::FromInt(length)); 732 array->set_length(Smi::FromInt(length));
729 JSObject::ValidateElements(array); 733 JSObject::ValidateElements(array);
730 } 734 }
731 735
736 uint32_t NumberOfElements(JSObject* receiver) final {
737 return Subclass::NumberOfElementsImpl(receiver, receiver->elements());
738 }
739
740 static uint32_t NumberOfElementsImpl(JSObject* receiver,
741 FixedArrayBase* backing_store) {
742 UNREACHABLE();
743 }
744
732 static uint32_t GetMaxIndex(JSObject* receiver, FixedArrayBase* elements) { 745 static uint32_t GetMaxIndex(JSObject* receiver, FixedArrayBase* elements) {
733 if (receiver->IsJSArray()) { 746 if (receiver->IsJSArray()) {
734 DCHECK(JSArray::cast(receiver)->length()->IsSmi()); 747 DCHECK(JSArray::cast(receiver)->length()->IsSmi());
735 return static_cast<uint32_t>( 748 return static_cast<uint32_t>(
736 Smi::cast(JSArray::cast(receiver)->length())->value()); 749 Smi::cast(JSArray::cast(receiver)->length())->value());
737 } 750 }
738 return Subclass::GetCapacityImpl(receiver, elements); 751 return Subclass::GetCapacityImpl(receiver, elements);
739 } 752 }
740 753
741 static uint32_t GetMaxNumberOfEntries(JSObject* receiver, 754 static uint32_t GetMaxNumberOfEntries(JSObject* receiver,
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 object, handle(object->elements(), isolate), &accumulator); 905 object, handle(object->elements(), isolate), &accumulator);
893 Handle<FixedArray> keys = accumulator.GetKeys(); 906 Handle<FixedArray> keys = accumulator.GetKeys();
894 907
895 for (int i = 0; i < keys->length(); ++i) { 908 for (int i = 0; i < keys->length(); ++i) {
896 Handle<Object> key(keys->get(i), isolate); 909 Handle<Object> key(keys->get(i), isolate);
897 Handle<Object> value; 910 Handle<Object> value;
898 uint32_t index; 911 uint32_t index;
899 if (!key->ToUint32(&index)) continue; 912 if (!key->ToUint32(&index)) continue;
900 913
901 uint32_t entry = Subclass::GetEntryForIndexImpl( 914 uint32_t entry = Subclass::GetEntryForIndexImpl(
902 *object, object->elements(), index, filter); 915 isolate, *object, object->elements(), index, filter);
903 if (entry == kMaxUInt32) continue; 916 if (entry == kMaxUInt32) continue;
904 917
905 PropertyDetails details = Subclass::GetDetailsImpl(*object, entry); 918 PropertyDetails details = Subclass::GetDetailsImpl(*object, entry);
906 919
907 if (details.kind() == kData) { 920 if (details.kind() == kData) {
908 value = Subclass::GetImpl(object, entry); 921 value = Subclass::GetImpl(object, entry);
909 } else { 922 } else {
910 LookupIterator it(isolate, object, index, LookupIterator::OWN); 923 LookupIterator it(isolate, object, index, LookupIterator::OWN);
911 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 924 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
912 isolate, value, Object::GetProperty(&it), Nothing<bool>()); 925 isolate, value, Object::GetProperty(&it), Nothing<bool>());
(...skipping 15 matching lines...) Expand all
928 Subclass::CollectElementIndicesImpl(object, backing_store, keys); 941 Subclass::CollectElementIndicesImpl(object, backing_store, keys);
929 } 942 }
930 943
931 static void CollectElementIndicesImpl(Handle<JSObject> object, 944 static void CollectElementIndicesImpl(Handle<JSObject> object,
932 Handle<FixedArrayBase> backing_store, 945 Handle<FixedArrayBase> backing_store,
933 KeyAccumulator* keys) { 946 KeyAccumulator* keys) {
934 DCHECK_NE(DICTIONARY_ELEMENTS, kind()); 947 DCHECK_NE(DICTIONARY_ELEMENTS, kind());
935 // Non-dictionary elements can't have all-can-read accessors. 948 // Non-dictionary elements can't have all-can-read accessors.
936 uint32_t length = Subclass::GetMaxIndex(*object, *backing_store); 949 uint32_t length = Subclass::GetMaxIndex(*object, *backing_store);
937 PropertyFilter filter = keys->filter(); 950 PropertyFilter filter = keys->filter();
938 Factory* factory = keys->isolate()->factory(); 951 Isolate* isolate = keys->isolate();
952 Factory* factory = isolate->factory();
939 for (uint32_t i = 0; i < length; i++) { 953 for (uint32_t i = 0; i < length; i++) {
940 if (Subclass::HasElementImpl(object, i, backing_store, filter)) { 954 if (Subclass::HasElementImpl(isolate, object, i, backing_store, filter)) {
941 keys->AddKey(factory->NewNumberFromUint(i)); 955 keys->AddKey(factory->NewNumberFromUint(i));
942 } 956 }
943 } 957 }
944 } 958 }
945 959
946 static Handle<FixedArray> DirectCollectElementIndicesImpl( 960 static Handle<FixedArray> DirectCollectElementIndicesImpl(
947 Isolate* isolate, Handle<JSObject> object, 961 Isolate* isolate, Handle<JSObject> object,
948 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, 962 Handle<FixedArrayBase> backing_store, GetKeysConversion convert,
949 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, 963 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices,
950 uint32_t insertion_index = 0) { 964 uint32_t insertion_index = 0) {
951 uint32_t length = Subclass::GetMaxIndex(*object, *backing_store); 965 uint32_t length = Subclass::GetMaxIndex(*object, *backing_store);
952 for (uint32_t i = 0; i < length; i++) { 966 for (uint32_t i = 0; i < length; i++) {
953 if (Subclass::HasElementImpl(object, i, backing_store, filter)) { 967 if (Subclass::HasElementImpl(isolate, object, i, backing_store, filter)) {
954 if (convert == GetKeysConversion::kConvertToString) { 968 if (convert == GetKeysConversion::kConvertToString) {
955 Handle<String> index_string = isolate->factory()->Uint32ToString(i); 969 Handle<String> index_string = isolate->factory()->Uint32ToString(i);
956 list->set(insertion_index, *index_string); 970 list->set(insertion_index, *index_string);
957 } else { 971 } else {
958 list->set(insertion_index, Smi::FromInt(i), SKIP_WRITE_BARRIER); 972 list->set(insertion_index, Smi::FromInt(i), SKIP_WRITE_BARRIER);
959 } 973 }
960 insertion_index++; 974 insertion_index++;
961 } 975 }
962 } 976 }
963 *nof_indices = insertion_index; 977 *nof_indices = insertion_index;
964 return list; 978 return list;
965 } 979 }
966 980
967 Handle<FixedArray> PrependElementIndices(Handle<JSObject> object, 981 Handle<FixedArray> PrependElementIndices(Handle<JSObject> object,
968 Handle<FixedArrayBase> backing_store, 982 Handle<FixedArrayBase> backing_store,
969 Handle<FixedArray> keys, 983 Handle<FixedArray> keys,
970 GetKeysConversion convert, 984 GetKeysConversion convert,
971 PropertyFilter filter) final { 985 PropertyFilter filter) final {
972 return Subclass::PrependElementIndicesImpl(object, backing_store, keys, 986 return Subclass::PrependElementIndicesImpl(object, backing_store, keys,
973 convert, filter); 987 convert, filter);
974 } 988 }
975 989
990 static uint32_t EstimatePrependElementSize(JSObject* object,
991 FixedArrayBase* backing_store,
992 uint32_t length) {
993 if (kind() == FAST_HOLEY_ELEMENTS) {
Igor Sheludko 2016/06/07 14:50:01 FAST_HOLEY_DOUBLE_ELEMENTS ?
994 if (FixedDoubleArray::SizeFor(length) <=
995 Page::kMaxRegularHeapObjectSize) {
996 return length;
997 }
998 } else if (FixedArray::SizeFor(length) <= Page::kMaxRegularHeapObjectSize) {
999 return length;
1000 }
1001 return Subclass::NumberOfElementsImpl(object, backing_store);
1002 }
1003
976 static Handle<FixedArray> PrependElementIndicesImpl( 1004 static Handle<FixedArray> PrependElementIndicesImpl(
977 Handle<JSObject> object, Handle<FixedArrayBase> backing_store, 1005 Handle<JSObject> object, Handle<FixedArrayBase> backing_store,
978 Handle<FixedArray> keys, GetKeysConversion convert, 1006 Handle<FixedArray> keys, GetKeysConversion convert,
979 PropertyFilter filter) { 1007 PropertyFilter filter) {
980 Isolate* isolate = object->GetIsolate(); 1008 Isolate* isolate = object->GetIsolate();
981 uint32_t nof_property_keys = keys->length(); 1009 uint32_t nof_property_keys = keys->length();
982 uint32_t initial_list_length = 1010 uint32_t initial_list_length =
983 Subclass::GetCapacityImpl(*object, *backing_store); 1011 Subclass::GetMaxNumberOfEntries(*object, *backing_store);
Igor Sheludko 2016/06/07 14:50:01 It does not have to be called for holey kinds. May
984 initial_list_length += nof_property_keys; 1012 initial_list_length += nof_property_keys;
985 1013
1014 if (IsHoleyElementsKind(kind())) {
1015 // If we overestimate the result list size we might end up in old space
Michael Lippautz 2016/06/07 17:28:27 s/old space/large object space/
1016 // which doesn't free memory on shrinking the list. Hence we try to
1017 // estimate the final size for holey backing stores more precisely here.
1018 initial_list_length = EstimatePrependElementSize(*object, *backing_store,
1019 initial_list_length);
1020 }
1021
986 // Collect the element indices into a new list. 1022 // Collect the element indices into a new list.
987 uint32_t nof_indices = 0; 1023 uint32_t nof_indices = 0;
988 Handle<FixedArray> combined_keys = 1024 Handle<FixedArray> combined_keys =
989 isolate->factory()->NewFixedArray(initial_list_length); 1025 isolate->factory()->NewFixedArray(initial_list_length);
990 combined_keys = Subclass::DirectCollectElementIndicesImpl( 1026 combined_keys = Subclass::DirectCollectElementIndicesImpl(
991 isolate, object, backing_store, convert, filter, combined_keys, 1027 isolate, object, backing_store, convert, filter, combined_keys,
992 &nof_indices); 1028 &nof_indices);
993 1029
994 // Sort the indices list if necessary. 1030 // Sort the indices list if necessary.
995 if (IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind())) { 1031 if (IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind())) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1042 1078
1043 uint32_t GetCapacity(JSObject* holder, FixedArrayBase* backing_store) final { 1079 uint32_t GetCapacity(JSObject* holder, FixedArrayBase* backing_store) final {
1044 return Subclass::GetCapacityImpl(holder, backing_store); 1080 return Subclass::GetCapacityImpl(holder, backing_store);
1045 } 1081 }
1046 1082
1047 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, 1083 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store,
1048 uint32_t entry) { 1084 uint32_t entry) {
1049 return entry; 1085 return entry;
1050 } 1086 }
1051 1087
1052 static uint32_t GetEntryForIndexImpl(JSObject* holder, 1088 static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject* holder,
1053 FixedArrayBase* backing_store, 1089 FixedArrayBase* backing_store,
1054 uint32_t index, PropertyFilter filter) { 1090 uint32_t index, PropertyFilter filter) {
1055 if (IsHoleyElementsKind(kind())) { 1091 if (IsHoleyElementsKind(kind())) {
1056 return index < Subclass::GetCapacityImpl(holder, backing_store) && 1092 return index < Subclass::GetCapacityImpl(holder, backing_store) &&
1057 !BackingStore::cast(backing_store)->is_the_hole(index) 1093 !BackingStore::cast(backing_store)
1094 ->is_the_hole(isolate, index)
1058 ? index 1095 ? index
1059 : kMaxUInt32; 1096 : kMaxUInt32;
1060 } else { 1097 } else {
1061 uint32_t length = Subclass::GetMaxIndex(holder, backing_store); 1098 uint32_t length = Subclass::GetMaxIndex(holder, backing_store);
1062 return index < length ? index : kMaxUInt32; 1099 return index < length ? index : kMaxUInt32;
1063 } 1100 }
1064 } 1101 }
1065 1102
1066 uint32_t GetEntryForIndex(JSObject* holder, FixedArrayBase* backing_store, 1103 uint32_t GetEntryForIndex(Isolate* isolate, JSObject* holder,
1104 FixedArrayBase* backing_store,
1067 uint32_t index) final { 1105 uint32_t index) final {
1068 return Subclass::GetEntryForIndexImpl(holder, backing_store, index, 1106 return Subclass::GetEntryForIndexImpl(isolate, holder, backing_store, index,
1069 ALL_PROPERTIES); 1107 ALL_PROPERTIES);
1070 } 1108 }
1071 1109
1072 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 1110 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
1073 uint32_t entry) { 1111 uint32_t entry) {
1074 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); 1112 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
1075 } 1113 }
1076 1114
1077 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { 1115 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) {
1078 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); 1116 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
(...skipping 20 matching lines...) Expand all
1099 // We cannot properly estimate this for dictionaries. 1137 // We cannot properly estimate this for dictionaries.
1100 UNREACHABLE(); 1138 UNREACHABLE();
1101 } 1139 }
1102 1140
1103 static uint32_t GetMaxNumberOfEntries(JSObject* receiver, 1141 static uint32_t GetMaxNumberOfEntries(JSObject* receiver,
1104 FixedArrayBase* backing_store) { 1142 FixedArrayBase* backing_store) {
1105 SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store); 1143 SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store);
1106 return dict->NumberOfElements(); 1144 return dict->NumberOfElements();
1107 } 1145 }
1108 1146
1147 static uint32_t NumberOfElementsImpl(JSObject* receiver,
1148 FixedArrayBase* backing_store) {
1149 return GetMaxNumberOfEntries(receiver, backing_store);
1150 }
1151
1109 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, 1152 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array,
1110 uint32_t length, 1153 uint32_t length,
1111 Handle<FixedArrayBase> backing_store) { 1154 Handle<FixedArrayBase> backing_store) {
1112 Handle<SeededNumberDictionary> dict = 1155 Handle<SeededNumberDictionary> dict =
1113 Handle<SeededNumberDictionary>::cast(backing_store); 1156 Handle<SeededNumberDictionary>::cast(backing_store);
1114 int capacity = dict->Capacity(); 1157 int capacity = dict->Capacity();
1115 uint32_t old_length = 0; 1158 uint32_t old_length = 0;
1116 CHECK(array->length()->ToArrayLength(&old_length)); 1159 CHECK(array->length()->ToArrayLength(&old_length));
1117 if (length < old_length) { 1160 if (length < old_length) {
1118 if (dict->requires_slow_elements()) { 1161 if (dict->requires_slow_elements()) {
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1245 : handle(SeededNumberDictionary::cast(object->elements())); 1288 : handle(SeededNumberDictionary::cast(object->elements()));
1246 Handle<SeededNumberDictionary> new_dictionary = 1289 Handle<SeededNumberDictionary> new_dictionary =
1247 SeededNumberDictionary::AddNumberEntry( 1290 SeededNumberDictionary::AddNumberEntry(
1248 dictionary, index, value, details, 1291 dictionary, index, value, details,
1249 object->map()->is_prototype_map()); 1292 object->map()->is_prototype_map());
1250 if (attributes != NONE) object->RequireSlowElements(*new_dictionary); 1293 if (attributes != NONE) object->RequireSlowElements(*new_dictionary);
1251 if (dictionary.is_identical_to(new_dictionary)) return; 1294 if (dictionary.is_identical_to(new_dictionary)) return;
1252 object->set_elements(*new_dictionary); 1295 object->set_elements(*new_dictionary);
1253 } 1296 }
1254 1297
1255 static bool HasEntryImpl(FixedArrayBase* store, uint32_t entry) { 1298 static bool HasEntryImpl(Isolate* isolate, FixedArrayBase* store,
1299 uint32_t entry) {
1256 DisallowHeapAllocation no_gc; 1300 DisallowHeapAllocation no_gc;
1257 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); 1301 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
1258 Object* index = dict->KeyAt(entry); 1302 Object* index = dict->KeyAt(entry);
1259 return !index->IsTheHole(dict->GetIsolate()); 1303 return !index->IsTheHole(isolate);
1260 } 1304 }
1261 1305
1262 static uint32_t GetIndexForEntryImpl(FixedArrayBase* store, uint32_t entry) { 1306 static uint32_t GetIndexForEntryImpl(FixedArrayBase* store, uint32_t entry) {
1263 DisallowHeapAllocation no_gc; 1307 DisallowHeapAllocation no_gc;
1264 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); 1308 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
1265 uint32_t result = 0; 1309 uint32_t result = 0;
1266 CHECK(dict->KeyAt(entry)->ToArrayIndex(&result)); 1310 CHECK(dict->KeyAt(entry)->ToArrayIndex(&result));
1267 return result; 1311 return result;
1268 } 1312 }
1269 1313
1270 static uint32_t GetEntryForIndexImpl(JSObject* holder, FixedArrayBase* store, 1314 static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject* holder,
1271 uint32_t index, PropertyFilter filter) { 1315 FixedArrayBase* store, uint32_t index,
1316 PropertyFilter filter) {
1272 DisallowHeapAllocation no_gc; 1317 DisallowHeapAllocation no_gc;
1273 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store); 1318 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store);
1274 int entry = dictionary->FindEntry(index); 1319 int entry = dictionary->FindEntry(isolate, index);
1275 if (entry == SeededNumberDictionary::kNotFound) return kMaxUInt32; 1320 if (entry == SeededNumberDictionary::kNotFound) return kMaxUInt32;
1276 if (filter != ALL_PROPERTIES) { 1321 if (filter != ALL_PROPERTIES) {
1277 PropertyDetails details = dictionary->DetailsAt(entry); 1322 PropertyDetails details = dictionary->DetailsAt(entry);
1278 PropertyAttributes attr = details.attributes(); 1323 PropertyAttributes attr = details.attributes();
1279 if ((attr & filter) != 0) return kMaxUInt32; 1324 if ((attr & filter) != 0) return kMaxUInt32;
1280 } 1325 }
1281 return static_cast<uint32_t>(entry); 1326 return static_cast<uint32_t>(entry);
1282 } 1327 }
1283 1328
1284 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { 1329 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1373 *nof_indices = insertion_index; 1418 *nof_indices = insertion_index;
1374 return list; 1419 return list;
1375 } 1420 }
1376 1421
1377 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, 1422 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
1378 KeyAccumulator* accumulator, 1423 KeyAccumulator* accumulator,
1379 AddKeyConversion convert) { 1424 AddKeyConversion convert) {
1380 Isolate* isolate = accumulator->isolate(); 1425 Isolate* isolate = accumulator->isolate();
1381 Handle<Object> undefined = isolate->factory()->undefined_value(); 1426 Handle<Object> undefined = isolate->factory()->undefined_value();
1382 Handle<Object> the_hole = isolate->factory()->the_hole_value(); 1427 Handle<Object> the_hole = isolate->factory()->the_hole_value();
1383 SeededNumberDictionary* dictionary = 1428 Handle<SeededNumberDictionary> dictionary(
1384 SeededNumberDictionary::cast(receiver->elements()); 1429 SeededNumberDictionary::cast(receiver->elements()), isolate);
1385 int capacity = dictionary->Capacity(); 1430 int capacity = dictionary->Capacity();
1386 for (int i = 0; i < capacity; i++) { 1431 for (int i = 0; i < capacity; i++) {
1387 Object* k = dictionary->KeyAt(i); 1432 Object* k = dictionary->KeyAt(i);
1388 if (k == *undefined) continue; 1433 if (k == *undefined) continue;
1389 if (k == *the_hole) continue; 1434 if (k == *the_hole) continue;
1390 if (dictionary->IsDeleted(i)) continue; 1435 if (dictionary->IsDeleted(i)) continue;
1391 Object* value = dictionary->ValueAt(i); 1436 Object* value = dictionary->ValueAt(i);
1392 DCHECK(!value->IsTheHole(isolate)); 1437 DCHECK(!value->IsTheHole(isolate));
1393 DCHECK(!value->IsAccessorPair()); 1438 DCHECK(!value->IsAccessorPair());
1394 DCHECK(!value->IsAccessorInfo()); 1439 DCHECK(!value->IsAccessorInfo());
(...skipping 25 matching lines...) Expand all
1420 1465
1421 int capacity = object->GetFastElementsUsage(); 1466 int capacity = object->GetFastElementsUsage();
1422 Handle<SeededNumberDictionary> dictionary = 1467 Handle<SeededNumberDictionary> dictionary =
1423 SeededNumberDictionary::New(isolate, capacity); 1468 SeededNumberDictionary::New(isolate, capacity);
1424 1469
1425 PropertyDetails details = PropertyDetails::Empty(); 1470 PropertyDetails details = PropertyDetails::Empty();
1426 bool used_as_prototype = object->map()->is_prototype_map(); 1471 bool used_as_prototype = object->map()->is_prototype_map();
1427 int j = 0; 1472 int j = 0;
1428 for (int i = 0; j < capacity; i++) { 1473 for (int i = 0; j < capacity; i++) {
1429 if (IsHoleyElementsKind(kind)) { 1474 if (IsHoleyElementsKind(kind)) {
1430 if (BackingStore::cast(*store)->is_the_hole(i)) continue; 1475 if (BackingStore::cast(*store)->is_the_hole(isolate, i)) continue;
1431 } 1476 }
1432 Handle<Object> value = Subclass::GetImpl(*store, i); 1477 Handle<Object> value = Subclass::GetImpl(*store, i);
1433 dictionary = SeededNumberDictionary::AddNumberEntry( 1478 dictionary = SeededNumberDictionary::AddNumberEntry(
1434 dictionary, i, value, details, used_as_prototype); 1479 dictionary, i, value, details, used_as_prototype);
1435 j++; 1480 j++;
1436 } 1481 }
1437 return dictionary; 1482 return dictionary;
1438 } 1483 }
1439 1484
1440 static void DeleteAtEnd(Handle<JSObject> obj, 1485 static void DeleteAtEnd(Handle<JSObject> obj,
1441 Handle<BackingStore> backing_store, uint32_t entry) { 1486 Handle<BackingStore> backing_store, uint32_t entry) {
1442 uint32_t length = static_cast<uint32_t>(backing_store->length()); 1487 uint32_t length = static_cast<uint32_t>(backing_store->length());
1443 Heap* heap = obj->GetHeap(); 1488 Isolate* isolate = obj->GetIsolate();
1444 for (; entry > 0; entry--) { 1489 for (; entry > 0; entry--) {
1445 if (!backing_store->is_the_hole(entry - 1)) break; 1490 if (!backing_store->is_the_hole(isolate, entry - 1)) break;
1446 } 1491 }
1447 if (entry == 0) { 1492 if (entry == 0) {
1448 FixedArray* empty = heap->empty_fixed_array(); 1493 FixedArray* empty = isolate->heap()->empty_fixed_array();
1449 // Dynamically ask for the elements kind here since we manually redirect 1494 // Dynamically ask for the elements kind here since we manually redirect
1450 // the operations for argument backing stores. 1495 // the operations for argument backing stores.
1451 if (obj->GetElementsKind() == FAST_SLOPPY_ARGUMENTS_ELEMENTS) { 1496 if (obj->GetElementsKind() == FAST_SLOPPY_ARGUMENTS_ELEMENTS) {
1452 FixedArray::cast(obj->elements())->set(1, empty); 1497 FixedArray::cast(obj->elements())->set(1, empty);
1453 } else { 1498 } else {
1454 obj->set_elements(empty); 1499 obj->set_elements(empty);
1455 } 1500 }
1456 return; 1501 return;
1457 } 1502 }
1458 1503
1459 heap->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(*backing_store, 1504 isolate->heap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(
1460 length - entry); 1505 *backing_store, length - entry);
1461 } 1506 }
1462 1507
1463 static void DeleteCommon(Handle<JSObject> obj, uint32_t entry, 1508 static void DeleteCommon(Handle<JSObject> obj, uint32_t entry,
1464 Handle<FixedArrayBase> store) { 1509 Handle<FixedArrayBase> store) {
1465 DCHECK(obj->HasFastSmiOrObjectElements() || obj->HasFastDoubleElements() || 1510 DCHECK(obj->HasFastSmiOrObjectElements() || obj->HasFastDoubleElements() ||
1466 obj->HasFastArgumentsElements() || 1511 obj->HasFastArgumentsElements() ||
1467 obj->HasFastStringWrapperElements()); 1512 obj->HasFastStringWrapperElements());
1468 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(store); 1513 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(store);
1469 if (!obj->IsJSArray() && 1514 if (!obj->IsJSArray() &&
1470 entry == static_cast<uint32_t>(store->length()) - 1) { 1515 entry == static_cast<uint32_t>(store->length()) - 1) {
1471 DeleteAtEnd(obj, backing_store, entry); 1516 DeleteAtEnd(obj, backing_store, entry);
1472 return; 1517 return;
1473 } 1518 }
1474 1519
1520 Isolate* isolate = obj->GetIsolate();
1475 backing_store->set_the_hole(entry); 1521 backing_store->set_the_hole(entry);
1476 1522
1477 // TODO(verwaest): Move this out of elements.cc. 1523 // TODO(verwaest): Move this out of elements.cc.
1478 // If an old space backing store is larger than a certain size and 1524 // If an old space backing store is larger than a certain size and
1479 // has too few used values, normalize it. 1525 // has too few used values, normalize it.
1480 // To avoid doing the check on every delete we require at least 1526 // To avoid doing the check on every delete we require at least
1481 // one adjacent hole to the value being deleted. 1527 // one adjacent hole to the value being deleted.
1482 const int kMinLengthForSparsenessCheck = 64; 1528 const int kMinLengthForSparsenessCheck = 64;
1483 if (backing_store->length() < kMinLengthForSparsenessCheck) return; 1529 if (backing_store->length() < kMinLengthForSparsenessCheck) return;
1484 if (backing_store->GetHeap()->InNewSpace(*backing_store)) return; 1530 if (backing_store->GetHeap()->InNewSpace(*backing_store)) return;
1485 uint32_t length = 0; 1531 uint32_t length = 0;
1486 if (obj->IsJSArray()) { 1532 if (obj->IsJSArray()) {
1487 JSArray::cast(*obj)->length()->ToArrayLength(&length); 1533 JSArray::cast(*obj)->length()->ToArrayLength(&length);
1488 } else { 1534 } else {
1489 length = static_cast<uint32_t>(store->length()); 1535 length = static_cast<uint32_t>(store->length());
1490 } 1536 }
1491 if ((entry > 0 && backing_store->is_the_hole(entry - 1)) || 1537 if ((entry > 0 && backing_store->is_the_hole(isolate, entry - 1)) ||
1492 (entry + 1 < length && backing_store->is_the_hole(entry + 1))) { 1538 (entry + 1 < length &&
1539 backing_store->is_the_hole(isolate, entry + 1))) {
1493 if (!obj->IsJSArray()) { 1540 if (!obj->IsJSArray()) {
1494 uint32_t i; 1541 uint32_t i;
1495 for (i = entry + 1; i < length; i++) { 1542 for (i = entry + 1; i < length; i++) {
1496 if (!backing_store->is_the_hole(i)) break; 1543 if (!backing_store->is_the_hole(isolate, i)) break;
1497 } 1544 }
1498 if (i == length) { 1545 if (i == length) {
1499 DeleteAtEnd(obj, backing_store, entry); 1546 DeleteAtEnd(obj, backing_store, entry);
1500 return; 1547 return;
1501 } 1548 }
1502 } 1549 }
1503 int num_used = 0; 1550 int num_used = 0;
1504 for (int i = 0; i < backing_store->length(); ++i) { 1551 for (int i = 0; i < backing_store->length(); ++i) {
1505 if (!backing_store->is_the_hole(i)) { 1552 if (!backing_store->is_the_hole(isolate, i)) {
1506 ++num_used; 1553 ++num_used;
1507 // Bail out if a number dictionary wouldn't be able to save at least 1554 // Bail out if a number dictionary wouldn't be able to save at least
1508 // 75% space. 1555 // 75% space.
1509 if (4 * SeededNumberDictionary::ComputeCapacity(num_used) * 1556 if (4 * SeededNumberDictionary::ComputeCapacity(num_used) *
1510 SeededNumberDictionary::kEntrySize > 1557 SeededNumberDictionary::kEntrySize >
1511 backing_store->length()) { 1558 backing_store->length()) {
1512 return; 1559 return;
1513 } 1560 }
1514 } 1561 }
1515 } 1562 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1556 ElementsKind kind = KindTraits::Kind; 1603 ElementsKind kind = KindTraits::Kind;
1557 if (IsFastPackedElementsKind(kind)) { 1604 if (IsFastPackedElementsKind(kind)) {
1558 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind)); 1605 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind));
1559 } 1606 }
1560 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) { 1607 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) {
1561 JSObject::EnsureWritableFastElements(obj); 1608 JSObject::EnsureWritableFastElements(obj);
1562 } 1609 }
1563 DeleteCommon(obj, entry, handle(obj->elements())); 1610 DeleteCommon(obj, entry, handle(obj->elements()));
1564 } 1611 }
1565 1612
1566 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) { 1613 static bool HasEntryImpl(Isolate* isolate, FixedArrayBase* backing_store,
1567 return !BackingStore::cast(backing_store)->is_the_hole(entry); 1614 uint32_t entry) {
1615 return !BackingStore::cast(backing_store)->is_the_hole(isolate, entry);
1616 }
1617
1618 static uint32_t NumberOfElementsImpl(JSObject* receiver,
1619 FixedArrayBase* backing_store) {
1620 uint32_t max_index = Subclass::GetMaxIndex(receiver, backing_store);
1621 if (IsFastPackedElementsKind(Subclass::kind())) return max_index;
1622 Isolate* isolate = receiver->GetIsolate();
1623 uint32_t count = 0;
1624 for (uint32_t i = 0; i < max_index; i++) {
1625 if (Subclass::HasEntryImpl(isolate, backing_store, i)) count++;
1626 }
1627 return count;
1568 } 1628 }
1569 1629
1570 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, 1630 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
1571 KeyAccumulator* accumulator, 1631 KeyAccumulator* accumulator,
1572 AddKeyConversion convert) { 1632 AddKeyConversion convert) {
1573 Handle<FixedArrayBase> elements(receiver->elements(), 1633 Isolate* isolate = accumulator->isolate();
1574 accumulator->isolate()); 1634 Handle<FixedArrayBase> elements(receiver->elements(), isolate);
1575 uint32_t length = Subclass::GetMaxNumberOfEntries(*receiver, *elements); 1635 uint32_t length = Subclass::GetMaxNumberOfEntries(*receiver, *elements);
1576 for (uint32_t i = 0; i < length; i++) { 1636 for (uint32_t i = 0; i < length; i++) {
1577 if (IsFastPackedElementsKind(KindTraits::Kind) || 1637 if (IsFastPackedElementsKind(KindTraits::Kind) ||
1578 HasEntryImpl(*elements, i)) { 1638 HasEntryImpl(isolate, *elements, i)) {
1579 accumulator->AddKey(Subclass::GetImpl(*elements, i), convert); 1639 accumulator->AddKey(Subclass::GetImpl(*elements, i), convert);
1580 } 1640 }
1581 } 1641 }
1582 } 1642 }
1583 1643
1584 static void ValidateContents(Handle<JSObject> holder, int length) { 1644 static void ValidateContents(Handle<JSObject> holder, int length) {
1585 #if DEBUG 1645 #if DEBUG
1586 Isolate* isolate = holder->GetIsolate(); 1646 Isolate* isolate = holder->GetIsolate();
1587 Heap* heap = isolate->heap(); 1647 Heap* heap = isolate->heap();
1588 HandleScope scope(isolate); 1648 HandleScope scope(isolate);
1589 Handle<FixedArrayBase> elements(holder->elements(), isolate); 1649 Handle<FixedArrayBase> elements(holder->elements(), isolate);
1590 Map* map = elements->map(); 1650 Map* map = elements->map();
1591 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) { 1651 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) {
1592 DCHECK_NE(map, heap->fixed_double_array_map()); 1652 DCHECK_NE(map, heap->fixed_double_array_map());
1593 } else if (IsFastDoubleElementsKind(KindTraits::Kind)) { 1653 } else if (IsFastDoubleElementsKind(KindTraits::Kind)) {
1594 DCHECK_NE(map, heap->fixed_cow_array_map()); 1654 DCHECK_NE(map, heap->fixed_cow_array_map());
1595 if (map == heap->fixed_array_map()) DCHECK_EQ(0, length); 1655 if (map == heap->fixed_array_map()) DCHECK_EQ(0, length);
1596 } else { 1656 } else {
1597 UNREACHABLE(); 1657 UNREACHABLE();
1598 } 1658 }
1599 if (length == 0) return; // nothing to do! 1659 if (length == 0) return; // nothing to do!
1600 #if ENABLE_SLOW_DCHECKS 1660 #if ENABLE_SLOW_DCHECKS
1601 DisallowHeapAllocation no_gc; 1661 DisallowHeapAllocation no_gc;
1602 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); 1662 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements);
1603 if (IsFastSmiElementsKind(KindTraits::Kind)) { 1663 if (IsFastSmiElementsKind(KindTraits::Kind)) {
1604 for (int i = 0; i < length; i++) { 1664 for (int i = 0; i < length; i++) {
1605 DCHECK(BackingStore::get(*backing_store, i, isolate)->IsSmi() || 1665 DCHECK(BackingStore::get(*backing_store, i, isolate)->IsSmi() ||
1606 (IsFastHoleyElementsKind(KindTraits::Kind) && 1666 (IsFastHoleyElementsKind(KindTraits::Kind) &&
1607 backing_store->is_the_hole(i))); 1667 backing_store->is_the_hole(isolate, i)));
1608 } 1668 }
1609 } else if (KindTraits::Kind == FAST_ELEMENTS || 1669 } else if (KindTraits::Kind == FAST_ELEMENTS ||
1610 KindTraits::Kind == FAST_DOUBLE_ELEMENTS) { 1670 KindTraits::Kind == FAST_DOUBLE_ELEMENTS) {
1611 for (int i = 0; i < length; i++) { 1671 for (int i = 0; i < length; i++) {
1612 DCHECK(!backing_store->is_the_hole(i)); 1672 DCHECK(!backing_store->is_the_hole(isolate, i));
1613 } 1673 }
1614 } else { 1674 } else {
1615 DCHECK(IsFastHoleyElementsKind(KindTraits::Kind)); 1675 DCHECK(IsFastHoleyElementsKind(KindTraits::Kind));
1616 } 1676 }
1617 #endif 1677 #endif
1618 #endif 1678 #endif
1619 } 1679 }
1620 1680
1621 static Handle<Object> PopImpl(Handle<JSArray> receiver) { 1681 static Handle<Object> PopImpl(Handle<JSArray> receiver) {
1622 return Subclass::RemoveElement(receiver, AT_END); 1682 return Subclass::RemoveElement(receiver, AT_END);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1704 1764
1705 receiver->set_length(Smi::FromInt(new_length)); 1765 receiver->set_length(Smi::FromInt(new_length));
1706 Subclass::TryTransitionResultArrayToPacked(deleted_elements); 1766 Subclass::TryTransitionResultArrayToPacked(deleted_elements);
1707 return deleted_elements; 1767 return deleted_elements;
1708 } 1768 }
1709 1769
1710 static Maybe<bool> CollectValuesOrEntriesImpl( 1770 static Maybe<bool> CollectValuesOrEntriesImpl(
1711 Isolate* isolate, Handle<JSObject> object, 1771 Isolate* isolate, Handle<JSObject> object,
1712 Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, 1772 Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items,
1713 PropertyFilter filter) { 1773 PropertyFilter filter) {
1774 Handle<BackingStore> elements(BackingStore::cast(object->elements()),
1775 isolate);
1714 int count = 0; 1776 int count = 0;
1715 uint32_t length = object->elements()->length(); 1777 uint32_t length = elements->length();
1716 for (uint32_t index = 0; index < length; ++index) { 1778 for (uint32_t index = 0; index < length; ++index) {
1717 if (!HasEntryImpl(object->elements(), index)) continue; 1779 if (!HasEntryImpl(isolate, *elements, index)) continue;
1718 Handle<Object> value = Subclass::GetImpl(object->elements(), index); 1780 Handle<Object> value = Subclass::GetImpl(*elements, index);
1719 if (get_entries) { 1781 if (get_entries) {
1720 value = MakeEntryPair(isolate, index, value); 1782 value = MakeEntryPair(isolate, index, value);
1721 } 1783 }
1722 values_or_entries->set(count++, *value); 1784 values_or_entries->set(count++, *value);
1723 } 1785 }
1724 *nof_items = count; 1786 *nof_items = count;
1725 return Just(true); 1787 return Just(true);
1726 } 1788 }
1727 1789
1728 static void MoveElements(Isolate* isolate, Handle<JSArray> receiver, 1790 static void MoveElements(Isolate* isolate, Handle<JSArray> receiver,
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1898 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, 1960 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
1899 Object* value, WriteBarrierMode mode) { 1961 Object* value, WriteBarrierMode mode) {
1900 FixedArray::cast(backing_store)->set(entry, value, mode); 1962 FixedArray::cast(backing_store)->set(entry, value, mode);
1901 } 1963 }
1902 1964
1903 static Object* GetRaw(FixedArray* backing_store, uint32_t entry) { 1965 static Object* GetRaw(FixedArray* backing_store, uint32_t entry) {
1904 uint32_t index = Subclass::GetIndexForEntryImpl(backing_store, entry); 1966 uint32_t index = Subclass::GetIndexForEntryImpl(backing_store, entry);
1905 return backing_store->get(index); 1967 return backing_store->get(index);
1906 } 1968 }
1907 1969
1908
1909 // NOTE: this method violates the handlified function signature convention: 1970 // NOTE: this method violates the handlified function signature convention:
1910 // raw pointer parameters in the function that allocates. 1971 // raw pointer parameters in the function that allocates.
1911 // See ElementsAccessor::CopyElements() for details. 1972 // See ElementsAccessor::CopyElements() for details.
1912 // This method could actually allocate if copying from double elements to 1973 // This method could actually allocate if copying from double elements to
1913 // object elements. 1974 // object elements.
1914 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, 1975 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
1915 FixedArrayBase* to, ElementsKind from_kind, 1976 FixedArrayBase* to, ElementsKind from_kind,
1916 uint32_t to_start, int packed_size, 1977 uint32_t to_start, int packed_size,
1917 int copy_size) { 1978 int copy_size) {
1918 DisallowHeapAllocation no_gc; 1979 DisallowHeapAllocation no_gc;
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
2137 2198
2138 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { 2199 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) {
2139 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell); 2200 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell);
2140 } 2201 }
2141 2202
2142 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 2203 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
2143 uint32_t entry) { 2204 uint32_t entry) {
2144 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell); 2205 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell);
2145 } 2206 }
2146 2207
2147 static bool HasElementImpl(Handle<JSObject> holder, uint32_t index, 2208 static bool HasElementImpl(Isolate* isolate, Handle<JSObject> holder,
2209 uint32_t index,
2148 Handle<FixedArrayBase> backing_store, 2210 Handle<FixedArrayBase> backing_store,
2149 PropertyFilter filter) { 2211 PropertyFilter filter) {
2150 return index < AccessorClass::GetCapacityImpl(*holder, *backing_store); 2212 return index < AccessorClass::GetCapacityImpl(*holder, *backing_store);
2151 } 2213 }
2152 2214
2153 static bool HasAccessorsImpl(JSObject* holder, 2215 static bool HasAccessorsImpl(JSObject* holder,
2154 FixedArrayBase* backing_store) { 2216 FixedArrayBase* backing_store) {
2155 return false; 2217 return false;
2156 } 2218 }
2157 2219
2158 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, 2220 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array,
2159 uint32_t length, 2221 uint32_t length,
2160 Handle<FixedArrayBase> backing_store) { 2222 Handle<FixedArrayBase> backing_store) {
2161 // External arrays do not support changing their length. 2223 // External arrays do not support changing their length.
2162 UNREACHABLE(); 2224 UNREACHABLE();
2163 } 2225 }
2164 2226
2165 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { 2227 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) {
2166 UNREACHABLE(); 2228 UNREACHABLE();
2167 } 2229 }
2168 2230
2169 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, 2231 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store,
2170 uint32_t entry) { 2232 uint32_t entry) {
2171 return entry; 2233 return entry;
2172 } 2234 }
2173 2235
2174 static uint32_t GetEntryForIndexImpl(JSObject* holder, 2236 static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject* holder,
2175 FixedArrayBase* backing_store, 2237 FixedArrayBase* backing_store,
2176 uint32_t index, PropertyFilter filter) { 2238 uint32_t index, PropertyFilter filter) {
2177 return index < AccessorClass::GetCapacityImpl(holder, backing_store) 2239 return index < AccessorClass::GetCapacityImpl(holder, backing_store)
2178 ? index 2240 ? index
2179 : kMaxUInt32; 2241 : kMaxUInt32;
2180 } 2242 }
2181 2243
2182 static uint32_t GetCapacityImpl(JSObject* holder, 2244 static uint32_t GetCapacityImpl(JSObject* holder,
2183 FixedArrayBase* backing_store) { 2245 FixedArrayBase* backing_store) {
2184 JSArrayBufferView* view = JSArrayBufferView::cast(holder); 2246 JSArrayBufferView* view = JSArrayBufferView::cast(holder);
2185 if (view->WasNeutered()) return 0; 2247 if (view->WasNeutered()) return 0;
2186 return backing_store->length(); 2248 return backing_store->length();
2187 } 2249 }
2188 2250
2251 static uint32_t NumberOfElementsImpl(JSObject* receiver,
2252 FixedArrayBase* backing_store) {
2253 return AccessorClass::GetCapacityImpl(receiver, backing_store);
2254 }
2255
2189 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, 2256 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
2190 KeyAccumulator* accumulator, 2257 KeyAccumulator* accumulator,
2191 AddKeyConversion convert) { 2258 AddKeyConversion convert) {
2192 Handle<FixedArrayBase> elements(receiver->elements()); 2259 Handle<FixedArrayBase> elements(receiver->elements());
2193 uint32_t length = AccessorClass::GetCapacityImpl(*receiver, *elements); 2260 uint32_t length = AccessorClass::GetCapacityImpl(*receiver, *elements);
2194 for (uint32_t i = 0; i < length; i++) { 2261 for (uint32_t i = 0; i < length; i++) {
2195 Handle<Object> value = AccessorClass::GetImpl(*elements, i); 2262 Handle<Object> value = AccessorClass::GetImpl(*elements, i);
2196 accumulator->AddKey(value, convert); 2263 accumulator->AddKey(value, convert);
2197 } 2264 }
2198 } 2265 }
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
2314 FixedArrayBase* backing_store) { 2381 FixedArrayBase* backing_store) {
2315 FixedArray* parameter_map = FixedArray::cast(backing_store); 2382 FixedArray* parameter_map = FixedArray::cast(backing_store);
2316 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 2383 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
2317 return parameter_map->length() - 2 + 2384 return parameter_map->length() - 2 +
2318 ArgumentsAccessor::GetCapacityImpl(holder, arguments); 2385 ArgumentsAccessor::GetCapacityImpl(holder, arguments);
2319 } 2386 }
2320 2387
2321 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, 2388 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
2322 KeyAccumulator* accumulator, 2389 KeyAccumulator* accumulator,
2323 AddKeyConversion convert) { 2390 AddKeyConversion convert) {
2324 FixedArrayBase* elements = receiver->elements(); 2391 Isolate* isolate = accumulator->isolate();
2325 uint32_t length = GetCapacityImpl(*receiver, elements); 2392 Handle<FixedArrayBase> elements(receiver->elements(), isolate);
2393 uint32_t length = GetCapacityImpl(*receiver, *elements);
2326 for (uint32_t entry = 0; entry < length; entry++) { 2394 for (uint32_t entry = 0; entry < length; entry++) {
2327 if (!HasEntryImpl(elements, entry)) continue; 2395 if (!HasEntryImpl(isolate, *elements, entry)) continue;
2328 Handle<Object> value = GetImpl(elements, entry); 2396 Handle<Object> value = GetImpl(*elements, entry);
2329 accumulator->AddKey(value, convert); 2397 accumulator->AddKey(value, convert);
2330 } 2398 }
2331 } 2399 }
2332 2400
2333 static bool HasEntryImpl(FixedArrayBase* parameters, uint32_t entry) { 2401 static bool HasEntryImpl(Isolate* isolate, FixedArrayBase* parameters,
2402 uint32_t entry) {
2334 FixedArray* parameter_map = FixedArray::cast(parameters); 2403 FixedArray* parameter_map = FixedArray::cast(parameters);
2335 uint32_t length = parameter_map->length() - 2; 2404 uint32_t length = parameter_map->length() - 2;
2336 if (entry < length) { 2405 if (entry < length) {
2337 return !GetParameterMapArg(parameter_map, entry) 2406 return !GetParameterMapArg(parameter_map, entry)->IsTheHole(isolate);
2338 ->IsTheHole(parameter_map->GetIsolate());
2339 } 2407 }
2340 2408
2341 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 2409 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
2342 return ArgumentsAccessor::HasEntryImpl(arguments, entry - length); 2410 return ArgumentsAccessor::HasEntryImpl(isolate, arguments, entry - length);
2343 } 2411 }
2344 2412
2345 static bool HasAccessorsImpl(JSObject* holder, 2413 static bool HasAccessorsImpl(JSObject* holder,
2346 FixedArrayBase* backing_store) { 2414 FixedArrayBase* backing_store) {
2347 FixedArray* parameter_map = FixedArray::cast(backing_store); 2415 FixedArray* parameter_map = FixedArray::cast(backing_store);
2348 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 2416 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
2349 return ArgumentsAccessor::HasAccessorsImpl(holder, arguments); 2417 return ArgumentsAccessor::HasAccessorsImpl(holder, arguments);
2350 } 2418 }
2351 2419
2352 static uint32_t GetIndexForEntryImpl(FixedArrayBase* parameters, 2420 static uint32_t GetIndexForEntryImpl(FixedArrayBase* parameters,
2353 uint32_t entry) { 2421 uint32_t entry) {
2354 FixedArray* parameter_map = FixedArray::cast(parameters); 2422 FixedArray* parameter_map = FixedArray::cast(parameters);
2355 uint32_t length = parameter_map->length() - 2; 2423 uint32_t length = parameter_map->length() - 2;
2356 if (entry < length) return entry; 2424 if (entry < length) return entry;
2357 2425
2358 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 2426 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
2359 return ArgumentsAccessor::GetIndexForEntryImpl(arguments, entry - length); 2427 return ArgumentsAccessor::GetIndexForEntryImpl(arguments, entry - length);
2360 } 2428 }
2361 2429
2362 static uint32_t GetEntryForIndexImpl(JSObject* holder, 2430 static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject* holder,
2363 FixedArrayBase* parameters, 2431 FixedArrayBase* parameters,
2364 uint32_t index, PropertyFilter filter) { 2432 uint32_t index, PropertyFilter filter) {
2365 FixedArray* parameter_map = FixedArray::cast(parameters); 2433 FixedArray* parameter_map = FixedArray::cast(parameters);
2366 Object* probe = GetParameterMapArg(parameter_map, index); 2434 Object* probe = GetParameterMapArg(parameter_map, index);
2367 if (!probe->IsTheHole(holder->GetIsolate())) return index; 2435 if (!probe->IsTheHole(isolate)) return index;
2368 2436
2369 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 2437 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
2370 uint32_t entry = ArgumentsAccessor::GetEntryForIndexImpl(holder, arguments, 2438 uint32_t entry = ArgumentsAccessor::GetEntryForIndexImpl(
2371 index, filter); 2439 isolate, holder, arguments, index, filter);
2372 if (entry == kMaxUInt32) return kMaxUInt32; 2440 if (entry == kMaxUInt32) return kMaxUInt32;
2373 return (parameter_map->length() - 2) + entry; 2441 return (parameter_map->length() - 2) + entry;
2374 } 2442 }
2375 2443
2376 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { 2444 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) {
2377 FixedArray* parameter_map = FixedArray::cast(holder->elements()); 2445 FixedArray* parameter_map = FixedArray::cast(holder->elements());
2378 uint32_t length = parameter_map->length() - 2; 2446 uint32_t length = parameter_map->length() - 2;
2379 if (entry < length) { 2447 if (entry < length) {
2380 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); 2448 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
2381 } 2449 }
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
2554 uint32_t end) { 2622 uint32_t end) {
2555 Isolate* isolate = receiver->GetIsolate(); 2623 Isolate* isolate = receiver->GetIsolate();
2556 uint32_t result_len = end < start ? 0u : end - start; 2624 uint32_t result_len = end < start ? 0u : end - start;
2557 Handle<JSArray> result_array = isolate->factory()->NewJSArray( 2625 Handle<JSArray> result_array = isolate->factory()->NewJSArray(
2558 FAST_HOLEY_ELEMENTS, result_len, result_len); 2626 FAST_HOLEY_ELEMENTS, result_len, result_len);
2559 DisallowHeapAllocation no_gc; 2627 DisallowHeapAllocation no_gc;
2560 FixedArray* elements = FixedArray::cast(result_array->elements()); 2628 FixedArray* elements = FixedArray::cast(result_array->elements());
2561 FixedArray* parameters = FixedArray::cast(receiver->elements()); 2629 FixedArray* parameters = FixedArray::cast(receiver->elements());
2562 uint32_t insertion_index = 0; 2630 uint32_t insertion_index = 0;
2563 for (uint32_t i = start; i < end; i++) { 2631 for (uint32_t i = start; i < end; i++) {
2564 uint32_t entry = 2632 uint32_t entry = GetEntryForIndexImpl(isolate, *receiver, parameters, i,
2565 GetEntryForIndexImpl(*receiver, parameters, i, ALL_PROPERTIES); 2633 ALL_PROPERTIES);
2566 if (entry != kMaxUInt32 && HasEntryImpl(parameters, entry)) { 2634 if (entry != kMaxUInt32 && HasEntryImpl(isolate, parameters, entry)) {
2567 elements->set(insertion_index, *GetImpl(parameters, entry)); 2635 elements->set(insertion_index, *GetImpl(parameters, entry));
2568 } else { 2636 } else {
2569 elements->set_the_hole(insertion_index); 2637 elements->set_the_hole(insertion_index);
2570 } 2638 }
2571 insertion_index++; 2639 insertion_index++;
2572 } 2640 }
2573 return result_array; 2641 return result_array;
2574 } 2642 }
2575 2643
2576 static Handle<SeededNumberDictionary> NormalizeImpl( 2644 static Handle<SeededNumberDictionary> NormalizeImpl(
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
2679 uint32_t length = static_cast<uint32_t>(GetString(holder)->length()); 2747 uint32_t length = static_cast<uint32_t>(GetString(holder)->length());
2680 if (entry < length) { 2748 if (entry < length) {
2681 PropertyAttributes attributes = 2749 PropertyAttributes attributes =
2682 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE); 2750 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
2683 return PropertyDetails(attributes, v8::internal::DATA, 0, 2751 return PropertyDetails(attributes, v8::internal::DATA, 0,
2684 PropertyCellType::kNoCell); 2752 PropertyCellType::kNoCell);
2685 } 2753 }
2686 return BackingStoreAccessor::GetDetailsImpl(holder, entry - length); 2754 return BackingStoreAccessor::GetDetailsImpl(holder, entry - length);
2687 } 2755 }
2688 2756
2689 static uint32_t GetEntryForIndexImpl(JSObject* holder, 2757 static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject* holder,
2690 FixedArrayBase* backing_store, 2758 FixedArrayBase* backing_store,
2691 uint32_t index, PropertyFilter filter) { 2759 uint32_t index, PropertyFilter filter) {
2692 uint32_t length = static_cast<uint32_t>(GetString(holder)->length()); 2760 uint32_t length = static_cast<uint32_t>(GetString(holder)->length());
2693 if (index < length) return index; 2761 if (index < length) return index;
2694 uint32_t backing_store_entry = BackingStoreAccessor::GetEntryForIndexImpl( 2762 uint32_t backing_store_entry = BackingStoreAccessor::GetEntryForIndexImpl(
2695 holder, backing_store, index, filter); 2763 isolate, holder, backing_store, index, filter);
2696 if (backing_store_entry == kMaxUInt32) return kMaxUInt32; 2764 if (backing_store_entry == kMaxUInt32) return kMaxUInt32;
2697 DCHECK(backing_store_entry < kMaxUInt32 - length); 2765 DCHECK(backing_store_entry < kMaxUInt32 - length);
2698 return backing_store_entry + length; 2766 return backing_store_entry + length;
2699 } 2767 }
2700 2768
2701 static void DeleteImpl(Handle<JSObject> holder, uint32_t entry) { 2769 static void DeleteImpl(Handle<JSObject> holder, uint32_t entry) {
2702 uint32_t length = static_cast<uint32_t>(GetString(*holder)->length()); 2770 uint32_t length = static_cast<uint32_t>(GetString(*holder)->length());
2703 if (entry < length) { 2771 if (entry < length) {
2704 return; // String contents can't be deleted. 2772 return; // String contents can't be deleted.
2705 } 2773 }
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
3043 insertion_index += len; 3111 insertion_index += len;
3044 } 3112 }
3045 3113
3046 DCHECK_EQ(insertion_index, result_len); 3114 DCHECK_EQ(insertion_index, result_len);
3047 return result_array; 3115 return result_array;
3048 } 3116 }
3049 3117
3050 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; 3118 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL;
3051 } // namespace internal 3119 } // namespace internal
3052 } // namespace v8 3120 } // namespace v8
OLDNEW
« no previous file with comments | « src/elements.h ('k') | src/lookup.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698