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

Side by Side Diff: src/elements.cc

Issue 1397063002: [runtime] Fancify KeyAccumulator (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: nits Created 5 years, 2 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/objects.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 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 uint32_t end) final { 511 uint32_t end) final {
512 return ElementsAccessorSubclass::IsPackedImpl(holder, backing_store, start, 512 return ElementsAccessorSubclass::IsPackedImpl(holder, backing_store, start,
513 end); 513 end);
514 } 514 }
515 515
516 static bool IsPackedImpl(Handle<JSObject> holder, 516 static bool IsPackedImpl(Handle<JSObject> holder,
517 Handle<FixedArrayBase> backing_store, uint32_t start, 517 Handle<FixedArrayBase> backing_store, uint32_t start,
518 uint32_t end) { 518 uint32_t end) {
519 if (IsFastPackedElementsKind(kind())) return true; 519 if (IsFastPackedElementsKind(kind())) return true;
520 for (uint32_t i = start; i < end; i++) { 520 for (uint32_t i = start; i < end; i++) {
521 if (!ElementsAccessorSubclass::HasElementImpl(holder, i, backing_store)) { 521 if (!ElementsAccessorSubclass::HasElementImpl(holder, i, backing_store,
522 NONE)) {
522 return false; 523 return false;
523 } 524 }
524 } 525 }
525 return true; 526 return true;
526 } 527 }
527 528
528 static void TryTransitionResultArrayToPacked(Handle<JSArray> array) { 529 static void TryTransitionResultArrayToPacked(Handle<JSArray> array) {
529 if (!IsHoleyElementsKind(kind())) return; 530 if (!IsHoleyElementsKind(kind())) return;
530 int length = Smi::cast(array->length())->value(); 531 int length = Smi::cast(array->length())->value();
531 Handle<FixedArrayBase> backing_store(array->elements()); 532 Handle<FixedArrayBase> backing_store(array->elements());
532 if (!ElementsAccessorSubclass::IsPackedImpl(array, backing_store, 0, 533 if (!ElementsAccessorSubclass::IsPackedImpl(array, backing_store, 0,
533 length)) { 534 length)) {
534 return; 535 return;
535 } 536 }
536 ElementsKind packed_kind = GetPackedElementsKind(kind()); 537 ElementsKind packed_kind = GetPackedElementsKind(kind());
537 Handle<Map> new_map = 538 Handle<Map> new_map =
538 JSObject::GetElementsTransitionMap(array, packed_kind); 539 JSObject::GetElementsTransitionMap(array, packed_kind);
539 JSObject::MigrateToMap(array, new_map); 540 JSObject::MigrateToMap(array, new_map);
540 if (FLAG_trace_elements_transitions) { 541 if (FLAG_trace_elements_transitions) {
541 JSObject::PrintElementsTransition(stdout, array, kind(), backing_store, 542 JSObject::PrintElementsTransition(stdout, array, kind(), backing_store,
542 packed_kind, backing_store); 543 packed_kind, backing_store);
543 } 544 }
544 } 545 }
545 546
546 virtual bool HasElement(Handle<JSObject> holder, uint32_t index, 547 virtual bool HasElement(Handle<JSObject> holder, uint32_t index,
547 Handle<FixedArrayBase> backing_store) final { 548 Handle<FixedArrayBase> backing_store,
549 PropertyAttributes filter) final {
548 return ElementsAccessorSubclass::HasElementImpl(holder, index, 550 return ElementsAccessorSubclass::HasElementImpl(holder, index,
549 backing_store); 551 backing_store, filter);
550 } 552 }
551 553
552 static bool HasElementImpl(Handle<JSObject> holder, uint32_t index, 554 static bool HasElementImpl(Handle<JSObject> holder, uint32_t index,
553 Handle<FixedArrayBase> backing_store) { 555 Handle<FixedArrayBase> backing_store,
556 PropertyAttributes filter) {
554 return ElementsAccessorSubclass::GetEntryForIndexImpl( 557 return ElementsAccessorSubclass::GetEntryForIndexImpl(
555 *holder, *backing_store, index) != kMaxUInt32; 558 *holder, *backing_store, index, filter) != kMaxUInt32;
556 } 559 }
557 560
558 virtual Handle<Object> Get(Handle<FixedArrayBase> backing_store, 561 virtual Handle<Object> Get(Handle<FixedArrayBase> backing_store,
559 uint32_t entry) final { 562 uint32_t entry) final {
560 return ElementsAccessorSubclass::GetImpl(backing_store, entry); 563 return ElementsAccessorSubclass::GetImpl(backing_store, entry);
561 } 564 }
562 565
563 static Handle<Object> GetImpl(Handle<FixedArrayBase> backing_store, 566 static Handle<Object> GetImpl(Handle<FixedArrayBase> backing_store,
564 uint32_t entry) { 567 uint32_t entry) {
565 uint32_t index = GetIndexForEntryImpl(*backing_store, entry); 568 uint32_t index = GetIndexForEntryImpl(*backing_store, entry);
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
861 // intentionally to avoid ArrayConcat() builtin performance degradation. 864 // intentionally to avoid ArrayConcat() builtin performance degradation.
862 // 865 //
863 // Details: The idea is that allocations actually happen only in case of 866 // Details: The idea is that allocations actually happen only in case of
864 // copying from object with fast double elements to object with object 867 // copying from object with fast double elements to object with object
865 // elements. In all the other cases there are no allocations performed and 868 // elements. In all the other cases there are no allocations performed and
866 // handle creation causes noticeable performance degradation of the builtin. 869 // handle creation causes noticeable performance degradation of the builtin.
867 ElementsAccessorSubclass::CopyElementsImpl( 870 ElementsAccessorSubclass::CopyElementsImpl(
868 from, from_start, *to, from_kind, to_start, packed_size, copy_size); 871 from, from_start, *to, from_kind, to_start, packed_size, copy_size);
869 } 872 }
870 873
874 static void CollectElementIndicesImpl(Handle<JSObject> object,
875 Handle<FixedArrayBase> backing_store,
876 KeyAccumulator* keys, uint32_t range,
877 PropertyAttributes filter,
878 uint32_t offset) {
879 uint32_t length = 0;
880 if (object->IsJSArray()) {
881 length = Smi::cast(JSArray::cast(*object)->length())->value();
882 } else {
883 length =
884 ElementsAccessorSubclass::GetCapacityImpl(*object, *backing_store);
885 }
886 if (range < length) length = range;
887 for (uint32_t i = offset; i < length; i++) {
888 if (!ElementsAccessorSubclass::HasElementImpl(object, i, backing_store,
889 filter))
890 continue;
891 keys->AddKey(i);
892 }
893 }
894
895 virtual void CollectElementIndices(Handle<JSObject> object,
896 Handle<FixedArrayBase> backing_store,
897 KeyAccumulator* keys, uint32_t range,
898 PropertyAttributes filter,
899 uint32_t offset) final {
900 ElementsAccessorSubclass::CollectElementIndicesImpl(
901 object, backing_store, keys, range, filter, offset);
902 };
903
871 virtual void AddElementsToKeyAccumulator(Handle<JSObject> receiver, 904 virtual void AddElementsToKeyAccumulator(Handle<JSObject> receiver,
872 KeyAccumulator* accumulator, 905 KeyAccumulator* accumulator,
873 KeyFilter filter) final { 906 AddKeyConversion convert) final {
874 Handle<FixedArrayBase> from(receiver->elements()); 907 Handle<FixedArrayBase> from(receiver->elements());
875 uint32_t add_length = 908 uint32_t add_length =
876 ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from); 909 ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from);
877 if (add_length == 0) return; 910 if (add_length == 0) return;
878 accumulator->PrepareForComparisons(add_length); 911
879 int prev_key_count = accumulator->GetLength();
880 for (uint32_t i = 0; i < add_length; i++) { 912 for (uint32_t i = 0; i < add_length; i++) {
881 if (!ElementsAccessorSubclass::HasEntryImpl(*from, i)) continue; 913 if (!ElementsAccessorSubclass::HasEntryImpl(*from, i)) continue;
882 Handle<Object> value = ElementsAccessorSubclass::GetImpl(from, i); 914 Handle<Object> value = ElementsAccessorSubclass::GetImpl(from, i);
883 DCHECK(!value->IsTheHole()); 915 DCHECK(!value->IsTheHole());
884 DCHECK(!value->IsAccessorPair()); 916 DCHECK(!value->IsAccessorPair());
885 DCHECK(!value->IsExecutableAccessorInfo()); 917 DCHECK(!value->IsExecutableAccessorInfo());
886 if (filter == SKIP_SYMBOLS && value->IsSymbol()) { 918 accumulator->AddKey(value, convert);
887 continue;
888 }
889 accumulator->AddKey(value, prev_key_count);
890 } 919 }
891 } 920 }
892 921
893 static uint32_t GetCapacityImpl(JSObject* holder, 922 static uint32_t GetCapacityImpl(JSObject* holder,
894 FixedArrayBase* backing_store) { 923 FixedArrayBase* backing_store) {
895 return backing_store->length(); 924 return backing_store->length();
896 } 925 }
897 926
898 uint32_t GetCapacity(JSObject* holder, FixedArrayBase* backing_store) final { 927 virtual uint32_t GetCapacity(JSObject* holder,
928 FixedArrayBase* backing_store) final {
899 return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store); 929 return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store);
900 } 930 }
901 931
902 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) { 932 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) {
903 return true; 933 return true;
904 } 934 }
905 935
906 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, 936 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store,
907 uint32_t entry) { 937 uint32_t entry) {
908 return entry; 938 return entry;
909 } 939 }
910 940
911 static uint32_t GetEntryForIndexImpl(JSObject* holder, 941 static uint32_t GetEntryForIndexImpl(JSObject* holder,
912 FixedArrayBase* backing_store, 942 FixedArrayBase* backing_store,
913 uint32_t index) { 943 uint32_t index,
944 PropertyAttributes filter) {
914 if (IsHoleyElementsKind(kind())) { 945 if (IsHoleyElementsKind(kind())) {
915 return index < ElementsAccessorSubclass::GetCapacityImpl(holder, 946 return index < ElementsAccessorSubclass::GetCapacityImpl(holder,
916 backing_store) && 947 backing_store) &&
917 !BackingStore::cast(backing_store)->is_the_hole(index) 948 !BackingStore::cast(backing_store)->is_the_hole(index)
918 ? index 949 ? index
919 : kMaxUInt32; 950 : kMaxUInt32;
920 } else { 951 } else {
921 Smi* smi_length = Smi::cast(JSArray::cast(holder)->length()); 952 Smi* smi_length = Smi::cast(JSArray::cast(holder)->length());
922 uint32_t length = static_cast<uint32_t>(smi_length->value()); 953 uint32_t length = static_cast<uint32_t>(smi_length->value());
923 return index < length ? index : kMaxUInt32; 954 return index < length ? index : kMaxUInt32;
924 } 955 }
925 } 956 }
926 957
927 virtual uint32_t GetEntryForIndex(JSObject* holder, 958 virtual uint32_t GetEntryForIndex(JSObject* holder,
928 FixedArrayBase* backing_store, 959 FixedArrayBase* backing_store,
929 uint32_t index) final { 960 uint32_t index) final {
930 return ElementsAccessorSubclass::GetEntryForIndexImpl(holder, backing_store, 961 return ElementsAccessorSubclass::GetEntryForIndexImpl(holder, backing_store,
931 index); 962 index, NONE);
932 } 963 }
933 964
934 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 965 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
935 uint32_t entry) { 966 uint32_t entry) {
936 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); 967 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
937 } 968 }
938 969
939 virtual PropertyDetails GetDetails(FixedArrayBase* backing_store, 970 virtual PropertyDetails GetDetails(FixedArrayBase* backing_store,
940 uint32_t entry) final { 971 uint32_t entry) final {
941 return ElementsAccessorSubclass::GetDetailsImpl(backing_store, entry); 972 return ElementsAccessorSubclass::GetDetailsImpl(backing_store, entry);
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1083 1114
1084 static uint32_t GetIndexForEntryImpl(FixedArrayBase* store, uint32_t entry) { 1115 static uint32_t GetIndexForEntryImpl(FixedArrayBase* store, uint32_t entry) {
1085 DisallowHeapAllocation no_gc; 1116 DisallowHeapAllocation no_gc;
1086 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); 1117 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
1087 uint32_t result = 0; 1118 uint32_t result = 0;
1088 CHECK(dict->KeyAt(entry)->ToArrayIndex(&result)); 1119 CHECK(dict->KeyAt(entry)->ToArrayIndex(&result));
1089 return result; 1120 return result;
1090 } 1121 }
1091 1122
1092 static uint32_t GetEntryForIndexImpl(JSObject* holder, FixedArrayBase* store, 1123 static uint32_t GetEntryForIndexImpl(JSObject* holder, FixedArrayBase* store,
1093 uint32_t index) { 1124 uint32_t index,
1125 PropertyAttributes filter) {
1094 DisallowHeapAllocation no_gc; 1126 DisallowHeapAllocation no_gc;
1095 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); 1127 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store);
1096 int entry = dict->FindEntry(index); 1128 int entry = dictionary->FindEntry(index);
1097 return entry == SeededNumberDictionary::kNotFound 1129 if (entry == SeededNumberDictionary::kNotFound) return kMaxUInt32;
1098 ? kMaxUInt32 1130 if (filter != NONE) {
1099 : static_cast<uint32_t>(entry); 1131 PropertyDetails details = dictionary->DetailsAt(entry);
1132 PropertyAttributes attr = details.attributes();
1133 if ((attr & filter) != 0) return kMaxUInt32;
1134 }
1135 return static_cast<uint32_t>(entry);
1100 } 1136 }
1101 1137
1102 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 1138 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
1103 uint32_t entry) { 1139 uint32_t entry) {
1104 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry); 1140 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry);
1105 } 1141 }
1142
1143 static void CollectElementIndicesImpl(Handle<JSObject> object,
1144 Handle<FixedArrayBase> backing_store,
1145 KeyAccumulator* keys, uint32_t range,
1146 PropertyAttributes filter,
1147 uint32_t offset) {
1148 Handle<SeededNumberDictionary> dictionary =
1149 Handle<SeededNumberDictionary>::cast(backing_store);
1150 int capacity = dictionary->Capacity();
1151 for (int i = 0; i < capacity; i++) {
1152 Object* k = dictionary->KeyAt(i);
1153 if (!dictionary->IsKey(k)) continue;
1154 if (k->FilterKey(filter)) continue;
1155 if (dictionary->IsDeleted(i)) continue;
1156 DCHECK(k->IsNumber());
1157 DCHECK_LE(k->Number(), kMaxUInt32);
1158 uint32_t index = static_cast<uint32_t>(k->Number());
1159 if (index < offset) continue;
1160 PropertyDetails details = dictionary->DetailsAt(i);
1161 PropertyAttributes attr = details.attributes();
1162 if ((attr & filter) != 0) continue;
1163 keys->AddKey(index);
1164 }
1165
1166 keys->SortCurrentElementsList();
1167 }
1106 }; 1168 };
1107 1169
1108 1170
1109 // Super class for all fast element arrays. 1171 // Super class for all fast element arrays.
1110 template<typename FastElementsAccessorSubclass, 1172 template<typename FastElementsAccessorSubclass,
1111 typename KindTraits> 1173 typename KindTraits>
1112 class FastElementsAccessor 1174 class FastElementsAccessor
1113 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> { 1175 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> {
1114 public: 1176 public:
1115 explicit FastElementsAccessor(const char* name) 1177 explicit FastElementsAccessor(const char* name)
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after
1752 UNREACHABLE(); 1814 UNREACHABLE();
1753 } 1815 }
1754 1816
1755 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, 1817 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store,
1756 uint32_t entry) { 1818 uint32_t entry) {
1757 return entry; 1819 return entry;
1758 } 1820 }
1759 1821
1760 static uint32_t GetEntryForIndexImpl(JSObject* holder, 1822 static uint32_t GetEntryForIndexImpl(JSObject* holder,
1761 FixedArrayBase* backing_store, 1823 FixedArrayBase* backing_store,
1762 uint32_t index) { 1824 uint32_t index,
1825 PropertyAttributes filter) {
1763 return index < AccessorClass::GetCapacityImpl(holder, backing_store) 1826 return index < AccessorClass::GetCapacityImpl(holder, backing_store)
1764 ? index 1827 ? index
1765 : kMaxUInt32; 1828 : kMaxUInt32;
1766 } 1829 }
1767 1830
1768 static uint32_t GetCapacityImpl(JSObject* holder, 1831 static uint32_t GetCapacityImpl(JSObject* holder,
1769 FixedArrayBase* backing_store) { 1832 FixedArrayBase* backing_store) {
1770 JSArrayBufferView* view = JSArrayBufferView::cast(holder); 1833 JSArrayBufferView* view = JSArrayBufferView::cast(holder);
1771 if (view->WasNeutered()) return 0; 1834 if (view->WasNeutered()) return 0;
1772 return backing_store->length(); 1835 return backing_store->length();
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1886 FixedArray* parameter_map = FixedArray::cast(parameters); 1949 FixedArray* parameter_map = FixedArray::cast(parameters);
1887 uint32_t length = parameter_map->length() - 2; 1950 uint32_t length = parameter_map->length() - 2;
1888 if (entry < length) return entry; 1951 if (entry < length) return entry;
1889 1952
1890 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1953 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1891 return ArgumentsAccessor::GetIndexForEntryImpl(arguments, entry - length); 1954 return ArgumentsAccessor::GetIndexForEntryImpl(arguments, entry - length);
1892 } 1955 }
1893 1956
1894 static uint32_t GetEntryForIndexImpl(JSObject* holder, 1957 static uint32_t GetEntryForIndexImpl(JSObject* holder,
1895 FixedArrayBase* parameters, 1958 FixedArrayBase* parameters,
1896 uint32_t index) { 1959 uint32_t index,
1960 PropertyAttributes filter) {
1897 FixedArray* parameter_map = FixedArray::cast(parameters); 1961 FixedArray* parameter_map = FixedArray::cast(parameters);
1898 Object* probe = GetParameterMapArg(parameter_map, index); 1962 Object* probe = GetParameterMapArg(parameter_map, index);
1899 if (!probe->IsTheHole()) return index; 1963 if (!probe->IsTheHole()) return index;
1900 1964
1901 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1965 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1902 uint32_t entry = 1966 uint32_t entry = ArgumentsAccessor::GetEntryForIndexImpl(holder, arguments,
1903 ArgumentsAccessor::GetEntryForIndexImpl(holder, arguments, index); 1967 index, filter);
1904 if (entry == kMaxUInt32) return entry; 1968 if (entry == kMaxUInt32) return entry;
1905 return (parameter_map->length() - 2) + entry; 1969 return (parameter_map->length() - 2) + entry;
1906 } 1970 }
1907 1971
1908 static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters, 1972 static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters,
1909 uint32_t entry) { 1973 uint32_t entry) {
1910 FixedArray* parameter_map = FixedArray::cast(parameters); 1974 FixedArray* parameter_map = FixedArray::cast(parameters);
1911 uint32_t length = parameter_map->length() - 2; 1975 uint32_t length = parameter_map->length() - 2;
1912 if (entry < length) { 1976 if (entry < length) {
1913 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); 1977 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
2326 } 2390 }
2327 } 2391 }
2328 2392
2329 DCHECK(j == result_len); 2393 DCHECK(j == result_len);
2330 return result_array; 2394 return result_array;
2331 } 2395 }
2332 2396
2333 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; 2397 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL;
2334 } // namespace internal 2398 } // namespace internal
2335 } // namespace v8 2399 } // namespace v8
OLDNEW
« no previous file with comments | « src/elements.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698