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

Side by Side Diff: src/elements.cc

Issue 1773593003: Revert of [key-accumulator] Starting to reimplement the key-accumulator (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 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/key-accumulator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/elements.h" 5 #include "src/elements.h"
6 6
7 #include "src/arguments.h" 7 #include "src/arguments.h"
8 #include "src/conversions.h" 8 #include "src/conversions.h"
9 #include "src/factory.h" 9 #include "src/factory.h"
10 #include "src/messages.h" 10 #include "src/messages.h"
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 for (int i = 0; i < copy_size; i++) { 421 for (int i = 0; i < copy_size; i++) {
422 int entry = from->FindEntry(i + from_start); 422 int entry = from->FindEntry(i + from_start);
423 if (entry != SeededNumberDictionary::kNotFound) { 423 if (entry != SeededNumberDictionary::kNotFound) {
424 to->set(i + to_start, from->ValueAt(entry)->Number()); 424 to->set(i + to_start, from->ValueAt(entry)->Number());
425 } else { 425 } else {
426 to->set_the_hole(i + to_start); 426 to->set_the_hole(i + to_start);
427 } 427 }
428 } 428 }
429 } 429 }
430 430
431
431 static void TraceTopFrame(Isolate* isolate) { 432 static void TraceTopFrame(Isolate* isolate) {
432 StackFrameIterator it(isolate); 433 StackFrameIterator it(isolate);
433 if (it.done()) { 434 if (it.done()) {
434 PrintF("unknown location (no JavaScript frames present)"); 435 PrintF("unknown location (no JavaScript frames present)");
435 return; 436 return;
436 } 437 }
437 StackFrame* raw_frame = it.frame(); 438 StackFrame* raw_frame = it.frame();
438 if (raw_frame->is_internal()) { 439 if (raw_frame->is_internal()) {
439 Code* apply_builtin = 440 Code* apply_builtin =
440 isolate->builtins()->builtin(Builtins::kFunctionPrototypeApply); 441 isolate->builtins()->builtin(Builtins::kFunctionPrototypeApply);
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 } else { 723 } else {
723 // Check whether the backing store should be expanded. 724 // Check whether the backing store should be expanded.
724 capacity = Max(length, JSObject::NewElementsCapacity(capacity)); 725 capacity = Max(length, JSObject::NewElementsCapacity(capacity));
725 ElementsAccessorSubclass::GrowCapacityAndConvertImpl(array, capacity); 726 ElementsAccessorSubclass::GrowCapacityAndConvertImpl(array, capacity);
726 } 727 }
727 728
728 array->set_length(Smi::FromInt(length)); 729 array->set_length(Smi::FromInt(length));
729 JSObject::ValidateElements(array); 730 JSObject::ValidateElements(array);
730 } 731 }
731 732
732 static uint32_t GetIterationLength(JSObject* receiver,
733 FixedArrayBase* elements) {
734 if (receiver->IsJSArray()) {
735 return static_cast<uint32_t>(
736 Smi::cast(JSArray::cast(receiver)->length())->value());
737 } else {
738 return ElementsAccessorSubclass::GetCapacityImpl(receiver, elements);
739 }
740 }
741
742 static Handle<FixedArrayBase> ConvertElementsWithCapacity( 733 static Handle<FixedArrayBase> ConvertElementsWithCapacity(
743 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, 734 Handle<JSObject> object, Handle<FixedArrayBase> old_elements,
744 ElementsKind from_kind, uint32_t capacity) { 735 ElementsKind from_kind, uint32_t capacity) {
745 return ConvertElementsWithCapacity( 736 return ConvertElementsWithCapacity(
746 object, old_elements, from_kind, capacity, 0, 0, 737 object, old_elements, from_kind, capacity, 0, 0,
747 ElementsAccessor::kCopyToEndAndInitializeToHole); 738 ElementsAccessor::kCopyToEndAndInitializeToHole);
748 } 739 }
749 740
750 static Handle<FixedArrayBase> ConvertElementsWithCapacity( 741 static Handle<FixedArrayBase> ConvertElementsWithCapacity(
751 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, 742 Handle<JSObject> object, Handle<FixedArrayBase> old_elements,
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 // intentionally to avoid ArrayConcat() builtin performance degradation. 839 // intentionally to avoid ArrayConcat() builtin performance degradation.
849 // 840 //
850 // Details: The idea is that allocations actually happen only in case of 841 // Details: The idea is that allocations actually happen only in case of
851 // copying from object with fast double elements to object with object 842 // copying from object with fast double elements to object with object
852 // elements. In all the other cases there are no allocations performed and 843 // elements. In all the other cases there are no allocations performed and
853 // handle creation causes noticeable performance degradation of the builtin. 844 // handle creation causes noticeable performance degradation of the builtin.
854 ElementsAccessorSubclass::CopyElementsImpl( 845 ElementsAccessorSubclass::CopyElementsImpl(
855 from, from_start, *to, from_kind, to_start, packed_size, copy_size); 846 from, from_start, *to, from_kind, to_start, packed_size, copy_size);
856 } 847 }
857 848
858 void CollectElementIndices(Handle<JSObject> object,
859 Handle<FixedArrayBase> backing_store,
860 KeyAccumulator* keys, uint32_t range,
861 PropertyFilter filter, uint32_t offset) final {
862 ElementsAccessorSubclass::CollectElementIndicesImpl(
863 object, backing_store, keys, range, filter, offset);
864 }
865
866 static void CollectElementIndicesImpl(Handle<JSObject> object, 849 static void CollectElementIndicesImpl(Handle<JSObject> object,
867 Handle<FixedArrayBase> backing_store, 850 Handle<FixedArrayBase> backing_store,
868 KeyAccumulator* keys, uint32_t range, 851 KeyAccumulator* keys, uint32_t range,
869 PropertyFilter filter, 852 PropertyFilter filter,
870 uint32_t offset) { 853 uint32_t offset) {
871 DCHECK_NE(DICTIONARY_ELEMENTS, kind()); 854 DCHECK_NE(DICTIONARY_ELEMENTS, kind());
872 if (filter & ONLY_ALL_CAN_READ) { 855 if (filter & ONLY_ALL_CAN_READ) {
873 // Non-dictionary elements can't have all-can-read accessors. 856 // Non-dictionary elements can't have all-can-read accessors.
874 return; 857 return;
875 } 858 }
876 uint32_t length = GetIterationLength(*object, *backing_store); 859 uint32_t length = 0;
860 if (object->IsJSArray()) {
861 length = Smi::cast(JSArray::cast(*object)->length())->value();
862 } else {
863 length =
864 ElementsAccessorSubclass::GetCapacityImpl(*object, *backing_store);
865 }
877 if (range < length) length = range; 866 if (range < length) length = range;
878 for (uint32_t i = offset; i < length; i++) { 867 for (uint32_t i = offset; i < length; i++) {
879 if (ElementsAccessorSubclass::HasElementImpl(object, i, backing_store, 868 if (!ElementsAccessorSubclass::HasElementImpl(object, i, backing_store,
880 filter)) { 869 filter)) {
881 keys->AddKey(i); 870 continue;
882 } 871 }
872 keys->AddKey(i);
883 } 873 }
884 } 874 }
885 875
886 static Handle<FixedArray> DirectCollectElementIndicesImpl( 876 void CollectElementIndices(Handle<JSObject> object,
887 Isolate* isolate, Handle<JSObject> object, 877 Handle<FixedArrayBase> backing_store,
888 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, 878 KeyAccumulator* keys, uint32_t range,
889 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices) { 879 PropertyFilter filter, uint32_t offset) final {
890 uint32_t length = 880 ElementsAccessorSubclass::CollectElementIndicesImpl(
891 ElementsAccessorSubclass::GetIterationLength(*object, *backing_store); 881 object, backing_store, keys, range, filter, offset);
892 uint32_t insertion_index = 0; 882 };
893 for (uint32_t i = 0; i < length; i++) {
894 if (ElementsAccessorSubclass::HasElementImpl(object, i, backing_store,
895 filter)) {
896 if (convert == CONVERT_TO_STRING) {
897 list->set(insertion_index++, *isolate->factory()->Uint32ToString(i));
898 } else {
899 list->set(insertion_index++, Smi::FromInt(i), SKIP_WRITE_BARRIER);
900 }
901 }
902 }
903 *nof_indices = insertion_index;
904 return list;
905 }
906
907 Handle<FixedArray> PrependElementIndices(Handle<JSObject> object,
908 Handle<FixedArrayBase> backing_store,
909 Handle<FixedArray> keys,
910 GetKeysConversion convert,
911 PropertyFilter filter) final {
912 return ElementsAccessorSubclass::PrependElementIndicesImpl(
913 object, backing_store, keys, convert, filter);
914 }
915
916 static Handle<FixedArray> PrependElementIndicesImpl(
917 Handle<JSObject> object, Handle<FixedArrayBase> backing_store,
918 Handle<FixedArray> keys, GetKeysConversion convert,
919 PropertyFilter filter) {
920 Isolate* isolate = object->GetIsolate();
921 uint32_t nof_property_keys = keys->length();
922 uint32_t initial_list_length =
923 ElementsAccessorSubclass::GetCapacityImpl(*object, *backing_store);
924 initial_list_length += nof_property_keys;
925
926 // Collect the element indices into a new list.
927 uint32_t nof_indices = 0;
928 Handle<FixedArray> combined_keys =
929 isolate->factory()->NewFixedArray(initial_list_length);
930 combined_keys = ElementsAccessorSubclass::DirectCollectElementIndicesImpl(
931 isolate, object, backing_store, convert, filter, combined_keys,
932 &nof_indices);
933
934 // Sort the indices list if necessary.
935 if (IsDictionaryElementsKind(kind())) {
936 struct {
937 bool operator()(Object* a, Object* b) {
938 if (!a->IsUndefined()) {
939 if (b->IsUndefined()) return true;
940 return a->Number() < b->Number();
941 }
942 return !b->IsUndefined();
943 }
944 } cmp;
945 Object** start =
946 reinterpret_cast<Object**>(combined_keys->GetFirstElementAddress());
947 std::sort(start, start + nof_indices, cmp);
948 // Indices from dictionary elements should only be converted after
949 // sorting.
950 if (convert == CONVERT_TO_STRING) {
951 for (uint32_t i = 0; i < nof_indices; i++) {
952 combined_keys->set(i, *isolate->factory()->Uint32ToString(
953 combined_keys->get(i)->Number()));
954 }
955 }
956 }
957
958 // Copy over the passed-in property keys.
959 CopyObjectToObjectElements(*keys, FAST_ELEMENTS, 0, *combined_keys,
960 FAST_ELEMENTS, nof_indices, nof_property_keys);
961
962 if (IsHoleyElementsKind(kind())) {
963 // Shrink combined_keys to the final size.
964 int final_size = nof_indices + nof_property_keys;
965 DCHECK_LE(final_size, combined_keys->length());
966 combined_keys->Shrink(final_size);
967 }
968
969 return combined_keys;
970 }
971 883
972 void AddElementsToKeyAccumulator(Handle<JSObject> receiver, 884 void AddElementsToKeyAccumulator(Handle<JSObject> receiver,
973 KeyAccumulator* accumulator, 885 KeyAccumulator* accumulator,
974 AddKeyConversion convert) final { 886 AddKeyConversion convert) final {
975 ElementsAccessorSubclass::AddElementsToKeyAccumulatorImpl( 887 ElementsAccessorSubclass::AddElementsToKeyAccumulatorImpl(
976 receiver, accumulator, convert); 888 receiver, accumulator, convert);
977 } 889 }
978 890
979 static uint32_t GetCapacityImpl(JSObject* holder, 891 static uint32_t GetCapacityImpl(JSObject* holder,
980 FixedArrayBase* backing_store) { 892 FixedArrayBase* backing_store) {
(...skipping 12 matching lines...) Expand all
993 static uint32_t GetEntryForIndexImpl(JSObject* holder, 905 static uint32_t GetEntryForIndexImpl(JSObject* holder,
994 FixedArrayBase* backing_store, 906 FixedArrayBase* backing_store,
995 uint32_t index, PropertyFilter filter) { 907 uint32_t index, PropertyFilter filter) {
996 if (IsHoleyElementsKind(kind())) { 908 if (IsHoleyElementsKind(kind())) {
997 return index < ElementsAccessorSubclass::GetCapacityImpl(holder, 909 return index < ElementsAccessorSubclass::GetCapacityImpl(holder,
998 backing_store) && 910 backing_store) &&
999 !BackingStore::cast(backing_store)->is_the_hole(index) 911 !BackingStore::cast(backing_store)->is_the_hole(index)
1000 ? index 912 ? index
1001 : kMaxUInt32; 913 : kMaxUInt32;
1002 } else { 914 } else {
1003 uint32_t length = GetIterationLength(holder, backing_store); 915 uint32_t length =
916 holder->IsJSArray()
917 ? static_cast<uint32_t>(
918 Smi::cast(JSArray::cast(holder)->length())->value())
919 : ElementsAccessorSubclass::GetCapacityImpl(holder,
920 backing_store);
1004 return index < length ? index : kMaxUInt32; 921 return index < length ? index : kMaxUInt32;
1005 } 922 }
1006 } 923 }
1007 924
1008 uint32_t GetEntryForIndex(JSObject* holder, FixedArrayBase* backing_store, 925 uint32_t GetEntryForIndex(JSObject* holder, FixedArrayBase* backing_store,
1009 uint32_t index) final { 926 uint32_t index) final {
1010 return ElementsAccessorSubclass::GetEntryForIndexImpl( 927 return ElementsAccessorSubclass::GetEntryForIndexImpl(
1011 holder, backing_store, index, ALL_PROPERTIES); 928 holder, backing_store, index, ALL_PROPERTIES);
1012 } 929 }
1013 930
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1195 1112
1196 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { 1113 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) {
1197 return GetDetailsImpl(holder->elements(), entry); 1114 return GetDetailsImpl(holder->elements(), entry);
1198 } 1115 }
1199 1116
1200 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 1117 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
1201 uint32_t entry) { 1118 uint32_t entry) {
1202 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry); 1119 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry);
1203 } 1120 }
1204 1121
1205 static uint32_t GetKeyForEntryImpl(Handle<SeededNumberDictionary> dictionary,
1206 int entry, PropertyFilter filter) {
1207 DisallowHeapAllocation no_gc;
1208 Object* raw_key = dictionary->KeyAt(entry);
1209 if (!dictionary->IsKey(raw_key)) return kMaxUInt32;
1210 if (raw_key->FilterKey(filter)) return kMaxUInt32;
1211 if (dictionary->IsDeleted(entry)) return kMaxUInt32;
1212 DCHECK(raw_key->IsNumber());
1213 DCHECK_LE(raw_key->Number(), kMaxUInt32);
1214 uint32_t key = static_cast<uint32_t>(raw_key->Number());
1215 PropertyDetails details = dictionary->DetailsAt(entry);
1216 if (filter & ONLY_ALL_CAN_READ) {
1217 if (details.kind() != kAccessor) return kMaxUInt32;
1218 Object* accessors = dictionary->ValueAt(entry);
1219 if (!accessors->IsAccessorInfo()) return kMaxUInt32;
1220 if (!AccessorInfo::cast(accessors)->all_can_read()) return kMaxUInt32;
1221 }
1222 PropertyAttributes attr = details.attributes();
1223 if ((attr & filter) != 0) return kMaxUInt32;
1224 return key;
1225 }
1226
1227 static void CollectElementIndicesImpl(Handle<JSObject> object, 1122 static void CollectElementIndicesImpl(Handle<JSObject> object,
1228 Handle<FixedArrayBase> backing_store, 1123 Handle<FixedArrayBase> backing_store,
1229 KeyAccumulator* keys, uint32_t range, 1124 KeyAccumulator* keys, uint32_t range,
1230 PropertyFilter filter, 1125 PropertyFilter filter,
1231 uint32_t offset) { 1126 uint32_t offset) {
1232 Handle<SeededNumberDictionary> dictionary = 1127 Handle<SeededNumberDictionary> dictionary =
1233 Handle<SeededNumberDictionary>::cast(backing_store); 1128 Handle<SeededNumberDictionary>::cast(backing_store);
1234 int capacity = dictionary->Capacity(); 1129 int capacity = dictionary->Capacity();
1235 for (int i = 0; i < capacity; i++) { 1130 for (int i = 0; i < capacity; i++) {
1236 uint32_t key = GetKeyForEntryImpl(dictionary, i, filter); 1131 Object* k = dictionary->KeyAt(i);
1237 if (key == kMaxUInt32) continue; 1132 if (!dictionary->IsKey(k)) continue;
1238 keys->AddKey(key); 1133 if (k->FilterKey(filter)) continue;
1134 if (dictionary->IsDeleted(i)) continue;
1135 DCHECK(k->IsNumber());
1136 DCHECK_LE(k->Number(), kMaxUInt32);
1137 uint32_t index = static_cast<uint32_t>(k->Number());
1138 if (index < offset) continue;
1139 PropertyDetails details = dictionary->DetailsAt(i);
1140 if (filter & ONLY_ALL_CAN_READ) {
1141 if (details.kind() != kAccessor) continue;
1142 Object* accessors = dictionary->ValueAt(i);
1143 if (!accessors->IsAccessorInfo()) continue;
1144 if (!AccessorInfo::cast(accessors)->all_can_read()) continue;
1145 }
1146 PropertyAttributes attr = details.attributes();
1147 if ((attr & filter) != 0) continue;
1148 keys->AddKey(index);
1239 } 1149 }
1240 1150
1241 keys->SortCurrentElementsList(); 1151 keys->SortCurrentElementsList();
1242 } 1152 }
1243 1153
1244 static Handle<FixedArray> DirectCollectElementIndicesImpl(
1245 Isolate* isolate, Handle<JSObject> object,
1246 Handle<FixedArrayBase> backing_store, GetKeysConversion convert,
1247 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices) {
1248 Handle<SeededNumberDictionary> dictionary =
1249 Handle<SeededNumberDictionary>::cast(backing_store);
1250 uint32_t capacity = dictionary->Capacity();
1251 uint32_t insertion_index = 0;
1252 for (uint32_t i = 0; i < capacity; i++) {
1253 uint32_t key = GetKeyForEntryImpl(dictionary, i, filter);
1254 if (key == kMaxUInt32) continue;
1255 list->set(insertion_index++, *isolate->factory()->NewNumberFromUint(key));
1256 }
1257 *nof_indices = insertion_index;
1258 return list;
1259 }
1260
1261 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, 1154 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
1262 KeyAccumulator* accumulator, 1155 KeyAccumulator* accumulator,
1263 AddKeyConversion convert) { 1156 AddKeyConversion convert) {
1264 SeededNumberDictionary* dictionary = 1157 SeededNumberDictionary* dictionary =
1265 SeededNumberDictionary::cast(receiver->elements()); 1158 SeededNumberDictionary::cast(receiver->elements());
1266 int capacity = dictionary->Capacity(); 1159 int capacity = dictionary->Capacity();
1267 for (int i = 0; i < capacity; i++) { 1160 for (int i = 0; i < capacity; i++) {
1268 Object* k = dictionary->KeyAt(i); 1161 Object* k = dictionary->KeyAt(i);
1269 if (!dictionary->IsKey(k)) continue; 1162 if (!dictionary->IsKey(k)) continue;
1270 if (dictionary->IsDeleted(i)) continue; 1163 if (dictionary->IsDeleted(i)) continue;
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1415 DeleteCommon(obj, entry, handle(obj->elements())); 1308 DeleteCommon(obj, entry, handle(obj->elements()));
1416 } 1309 }
1417 1310
1418 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) { 1311 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) {
1419 return !BackingStore::cast(backing_store)->is_the_hole(entry); 1312 return !BackingStore::cast(backing_store)->is_the_hole(entry);
1420 } 1313 }
1421 1314
1422 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, 1315 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
1423 KeyAccumulator* accumulator, 1316 KeyAccumulator* accumulator,
1424 AddKeyConversion convert) { 1317 AddKeyConversion convert) {
1318 uint32_t length = 0;
1425 Handle<FixedArrayBase> elements(receiver->elements(), 1319 Handle<FixedArrayBase> elements(receiver->elements(),
1426 receiver->GetIsolate()); 1320 receiver->GetIsolate());
1427 uint32_t length = 1321 if (receiver->IsJSArray()) {
1428 FastElementsAccessorSubclass::GetIterationLength(*receiver, *elements); 1322 length = Smi::cast(JSArray::cast(*receiver)->length())->value();
1323 } else {
1324 length =
1325 FastElementsAccessorSubclass::GetCapacityImpl(*receiver, *elements);
1326 }
1429 for (uint32_t i = 0; i < length; i++) { 1327 for (uint32_t i = 0; i < length; i++) {
1430 if (IsFastPackedElementsKind(KindTraits::Kind) || 1328 if (IsFastPackedElementsKind(KindTraits::Kind) ||
1431 HasEntryImpl(*elements, i)) { 1329 HasEntryImpl(*elements, i)) {
1432 accumulator->AddKey(FastElementsAccessorSubclass::GetImpl(*elements, i), 1330 accumulator->AddKey(FastElementsAccessorSubclass::GetImpl(*elements, i),
1433 convert); 1331 convert);
1434 } 1332 }
1435 } 1333 }
1436 } 1334 }
1437 1335
1438 static void ValidateContents(Handle<JSObject> holder, int length) { 1336 static void ValidateContents(Handle<JSObject> holder, int length) {
(...skipping 1343 matching lines...) Expand 10 before | Expand all | Expand 10 after
2782 } 2680 }
2783 } 2681 }
2784 2682
2785 DCHECK(j == result_len); 2683 DCHECK(j == result_len);
2786 return result_array; 2684 return result_array;
2787 } 2685 }
2788 2686
2789 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; 2687 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL;
2790 } // namespace internal 2688 } // namespace internal
2791 } // namespace v8 2689 } // namespace v8
OLDNEW
« no previous file with comments | « src/elements.h ('k') | src/key-accumulator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698