OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/elements.h" | 5 #include "src/elements.h" |
6 | 6 |
7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
9 #include "src/factory.h" | 9 #include "src/factory.h" |
10 #include "src/isolate-inl.h" | 10 #include "src/isolate-inl.h" |
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |