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/messages.h" | 10 #include "src/messages.h" |
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
499 return ElementsAccessorSubclass::IsPackedImpl(holder, backing_store, start, | 499 return ElementsAccessorSubclass::IsPackedImpl(holder, backing_store, start, |
500 end); | 500 end); |
501 } | 501 } |
502 | 502 |
503 static bool IsPackedImpl(Handle<JSObject> holder, | 503 static bool IsPackedImpl(Handle<JSObject> holder, |
504 Handle<FixedArrayBase> backing_store, uint32_t start, | 504 Handle<FixedArrayBase> backing_store, uint32_t start, |
505 uint32_t end) { | 505 uint32_t end) { |
506 if (IsFastPackedElementsKind(kind())) return true; | 506 if (IsFastPackedElementsKind(kind())) return true; |
507 for (uint32_t i = start; i < end; i++) { | 507 for (uint32_t i = start; i < end; i++) { |
508 if (!ElementsAccessorSubclass::HasElementImpl(holder, i, backing_store, | 508 if (!ElementsAccessorSubclass::HasElementImpl(holder, i, backing_store, |
509 NONE)) { | 509 ALL_PROPERTIES)) { |
510 return false; | 510 return false; |
511 } | 511 } |
512 } | 512 } |
513 return true; | 513 return true; |
514 } | 514 } |
515 | 515 |
516 static void TryTransitionResultArrayToPacked(Handle<JSArray> array) { | 516 static void TryTransitionResultArrayToPacked(Handle<JSArray> array) { |
517 if (!IsHoleyElementsKind(kind())) return; | 517 if (!IsHoleyElementsKind(kind())) return; |
518 int length = Smi::cast(array->length())->value(); | 518 int length = Smi::cast(array->length())->value(); |
519 Handle<FixedArrayBase> backing_store(array->elements()); | 519 Handle<FixedArrayBase> backing_store(array->elements()); |
520 if (!ElementsAccessorSubclass::IsPackedImpl(array, backing_store, 0, | 520 if (!ElementsAccessorSubclass::IsPackedImpl(array, backing_store, 0, |
521 length)) { | 521 length)) { |
522 return; | 522 return; |
523 } | 523 } |
524 ElementsKind packed_kind = GetPackedElementsKind(kind()); | 524 ElementsKind packed_kind = GetPackedElementsKind(kind()); |
525 Handle<Map> new_map = | 525 Handle<Map> new_map = |
526 JSObject::GetElementsTransitionMap(array, packed_kind); | 526 JSObject::GetElementsTransitionMap(array, packed_kind); |
527 JSObject::MigrateToMap(array, new_map); | 527 JSObject::MigrateToMap(array, new_map); |
528 if (FLAG_trace_elements_transitions) { | 528 if (FLAG_trace_elements_transitions) { |
529 JSObject::PrintElementsTransition(stdout, array, kind(), backing_store, | 529 JSObject::PrintElementsTransition(stdout, array, kind(), backing_store, |
530 packed_kind, backing_store); | 530 packed_kind, backing_store); |
531 } | 531 } |
532 } | 532 } |
533 | 533 |
534 bool HasElement(Handle<JSObject> holder, uint32_t index, | 534 bool HasElement(Handle<JSObject> holder, uint32_t index, |
535 Handle<FixedArrayBase> backing_store, | 535 Handle<FixedArrayBase> backing_store, |
536 PropertyAttributes filter) final { | 536 PropertyFilter filter) final { |
537 return ElementsAccessorSubclass::HasElementImpl(holder, index, | 537 return ElementsAccessorSubclass::HasElementImpl(holder, index, |
538 backing_store, filter); | 538 backing_store, filter); |
539 } | 539 } |
540 | 540 |
541 static bool HasElementImpl(Handle<JSObject> holder, uint32_t index, | 541 static bool HasElementImpl(Handle<JSObject> holder, uint32_t index, |
542 Handle<FixedArrayBase> backing_store, | 542 Handle<FixedArrayBase> backing_store, |
543 PropertyAttributes filter) { | 543 PropertyFilter filter) { |
544 return ElementsAccessorSubclass::GetEntryForIndexImpl( | 544 return ElementsAccessorSubclass::GetEntryForIndexImpl( |
545 *holder, *backing_store, index, filter) != kMaxUInt32; | 545 *holder, *backing_store, index, filter) != kMaxUInt32; |
546 } | 546 } |
547 | 547 |
548 Handle<Object> Get(Handle<FixedArrayBase> backing_store, | 548 Handle<Object> Get(Handle<FixedArrayBase> backing_store, |
549 uint32_t entry) final { | 549 uint32_t entry) final { |
550 return ElementsAccessorSubclass::GetImpl(backing_store, entry); | 550 return ElementsAccessorSubclass::GetImpl(backing_store, entry); |
551 } | 551 } |
552 | 552 |
553 static Handle<Object> GetImpl(Handle<FixedArrayBase> backing_store, | 553 static Handle<Object> GetImpl(Handle<FixedArrayBase> backing_store, |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
850 // copying from object with fast double elements to object with object | 850 // copying from object with fast double elements to object with object |
851 // elements. In all the other cases there are no allocations performed and | 851 // elements. In all the other cases there are no allocations performed and |
852 // handle creation causes noticeable performance degradation of the builtin. | 852 // handle creation causes noticeable performance degradation of the builtin. |
853 ElementsAccessorSubclass::CopyElementsImpl( | 853 ElementsAccessorSubclass::CopyElementsImpl( |
854 from, from_start, *to, from_kind, to_start, packed_size, copy_size); | 854 from, from_start, *to, from_kind, to_start, packed_size, copy_size); |
855 } | 855 } |
856 | 856 |
857 static void CollectElementIndicesImpl(Handle<JSObject> object, | 857 static void CollectElementIndicesImpl(Handle<JSObject> object, |
858 Handle<FixedArrayBase> backing_store, | 858 Handle<FixedArrayBase> backing_store, |
859 KeyAccumulator* keys, uint32_t range, | 859 KeyAccumulator* keys, uint32_t range, |
860 PropertyAttributes filter, | 860 PropertyFilter filter, |
861 uint32_t offset) { | 861 uint32_t offset) { |
862 uint32_t length = 0; | 862 uint32_t length = 0; |
863 if (object->IsJSArray()) { | 863 if (object->IsJSArray()) { |
864 length = Smi::cast(JSArray::cast(*object)->length())->value(); | 864 length = Smi::cast(JSArray::cast(*object)->length())->value(); |
865 } else { | 865 } else { |
866 length = | 866 length = |
867 ElementsAccessorSubclass::GetCapacityImpl(*object, *backing_store); | 867 ElementsAccessorSubclass::GetCapacityImpl(*object, *backing_store); |
868 } | 868 } |
869 if (range < length) length = range; | 869 if (range < length) length = range; |
870 for (uint32_t i = offset; i < length; i++) { | 870 for (uint32_t i = offset; i < length; i++) { |
871 if (!ElementsAccessorSubclass::HasElementImpl(object, i, backing_store, | 871 if (!ElementsAccessorSubclass::HasElementImpl(object, i, backing_store, |
872 filter)) | 872 filter)) |
873 continue; | 873 continue; |
874 keys->AddKey(i); | 874 keys->AddKey(i); |
875 } | 875 } |
876 } | 876 } |
877 | 877 |
878 void CollectElementIndices(Handle<JSObject> object, | 878 void CollectElementIndices(Handle<JSObject> object, |
879 Handle<FixedArrayBase> backing_store, | 879 Handle<FixedArrayBase> backing_store, |
880 KeyAccumulator* keys, uint32_t range, | 880 KeyAccumulator* keys, uint32_t range, |
881 PropertyAttributes filter, uint32_t offset) final { | 881 PropertyFilter filter, uint32_t offset) final { |
882 ElementsAccessorSubclass::CollectElementIndicesImpl( | 882 ElementsAccessorSubclass::CollectElementIndicesImpl( |
883 object, backing_store, keys, range, filter, offset); | 883 object, backing_store, keys, range, filter, offset); |
884 }; | 884 }; |
885 | 885 |
886 void AddElementsToKeyAccumulator(Handle<JSObject> receiver, | 886 void AddElementsToKeyAccumulator(Handle<JSObject> receiver, |
887 KeyAccumulator* accumulator, | 887 KeyAccumulator* accumulator, |
888 AddKeyConversion convert) final { | 888 AddKeyConversion convert) final { |
889 Handle<FixedArrayBase> from(receiver->elements()); | 889 Handle<FixedArrayBase> from(receiver->elements()); |
890 uint32_t add_length = | 890 uint32_t add_length = |
891 ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from); | 891 ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from); |
(...skipping 22 matching lines...) Expand all Loading... |
914 return true; | 914 return true; |
915 } | 915 } |
916 | 916 |
917 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, | 917 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, |
918 uint32_t entry) { | 918 uint32_t entry) { |
919 return entry; | 919 return entry; |
920 } | 920 } |
921 | 921 |
922 static uint32_t GetEntryForIndexImpl(JSObject* holder, | 922 static uint32_t GetEntryForIndexImpl(JSObject* holder, |
923 FixedArrayBase* backing_store, | 923 FixedArrayBase* backing_store, |
924 uint32_t index, | 924 uint32_t index, PropertyFilter filter) { |
925 PropertyAttributes filter) { | |
926 if (IsHoleyElementsKind(kind())) { | 925 if (IsHoleyElementsKind(kind())) { |
927 return index < ElementsAccessorSubclass::GetCapacityImpl(holder, | 926 return index < ElementsAccessorSubclass::GetCapacityImpl(holder, |
928 backing_store) && | 927 backing_store) && |
929 !BackingStore::cast(backing_store)->is_the_hole(index) | 928 !BackingStore::cast(backing_store)->is_the_hole(index) |
930 ? index | 929 ? index |
931 : kMaxUInt32; | 930 : kMaxUInt32; |
932 } else { | 931 } else { |
933 uint32_t length = | 932 uint32_t length = |
934 holder->IsJSArray() | 933 holder->IsJSArray() |
935 ? static_cast<uint32_t>( | 934 ? static_cast<uint32_t>( |
936 Smi::cast(JSArray::cast(holder)->length())->value()) | 935 Smi::cast(JSArray::cast(holder)->length())->value()) |
937 : ElementsAccessorSubclass::GetCapacityImpl(holder, | 936 : ElementsAccessorSubclass::GetCapacityImpl(holder, |
938 backing_store); | 937 backing_store); |
939 return index < length ? index : kMaxUInt32; | 938 return index < length ? index : kMaxUInt32; |
940 } | 939 } |
941 } | 940 } |
942 | 941 |
943 uint32_t GetEntryForIndex(JSObject* holder, FixedArrayBase* backing_store, | 942 uint32_t GetEntryForIndex(JSObject* holder, FixedArrayBase* backing_store, |
944 uint32_t index) final { | 943 uint32_t index) final { |
945 return ElementsAccessorSubclass::GetEntryForIndexImpl(holder, backing_store, | 944 return ElementsAccessorSubclass::GetEntryForIndexImpl( |
946 index, NONE); | 945 holder, backing_store, index, ALL_PROPERTIES); |
947 } | 946 } |
948 | 947 |
949 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, | 948 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, |
950 uint32_t entry) { | 949 uint32_t entry) { |
951 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); | 950 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); |
952 } | 951 } |
953 | 952 |
954 PropertyDetails GetDetails(FixedArrayBase* backing_store, | 953 PropertyDetails GetDetails(FixedArrayBase* backing_store, |
955 uint32_t entry) final { | 954 uint32_t entry) final { |
956 return ElementsAccessorSubclass::GetDetailsImpl(backing_store, entry); | 955 return ElementsAccessorSubclass::GetDetailsImpl(backing_store, entry); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1098 | 1097 |
1099 static uint32_t GetIndexForEntryImpl(FixedArrayBase* store, uint32_t entry) { | 1098 static uint32_t GetIndexForEntryImpl(FixedArrayBase* store, uint32_t entry) { |
1100 DisallowHeapAllocation no_gc; | 1099 DisallowHeapAllocation no_gc; |
1101 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); | 1100 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); |
1102 uint32_t result = 0; | 1101 uint32_t result = 0; |
1103 CHECK(dict->KeyAt(entry)->ToArrayIndex(&result)); | 1102 CHECK(dict->KeyAt(entry)->ToArrayIndex(&result)); |
1104 return result; | 1103 return result; |
1105 } | 1104 } |
1106 | 1105 |
1107 static uint32_t GetEntryForIndexImpl(JSObject* holder, FixedArrayBase* store, | 1106 static uint32_t GetEntryForIndexImpl(JSObject* holder, FixedArrayBase* store, |
1108 uint32_t index, | 1107 uint32_t index, PropertyFilter filter) { |
1109 PropertyAttributes filter) { | |
1110 DisallowHeapAllocation no_gc; | 1108 DisallowHeapAllocation no_gc; |
1111 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store); | 1109 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store); |
1112 int entry = dictionary->FindEntry(index); | 1110 int entry = dictionary->FindEntry(index); |
1113 if (entry == SeededNumberDictionary::kNotFound) return kMaxUInt32; | 1111 if (entry == SeededNumberDictionary::kNotFound) return kMaxUInt32; |
1114 if (filter != NONE) { | 1112 if (filter != ALL_PROPERTIES) { |
1115 PropertyDetails details = dictionary->DetailsAt(entry); | 1113 PropertyDetails details = dictionary->DetailsAt(entry); |
1116 PropertyAttributes attr = details.attributes(); | 1114 PropertyAttributes attr = details.attributes(); |
1117 if ((attr & filter) != 0) return kMaxUInt32; | 1115 if ((attr & filter) != 0) return kMaxUInt32; |
1118 } | 1116 } |
1119 return static_cast<uint32_t>(entry); | 1117 return static_cast<uint32_t>(entry); |
1120 } | 1118 } |
1121 | 1119 |
1122 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, | 1120 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, |
1123 uint32_t entry) { | 1121 uint32_t entry) { |
1124 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry); | 1122 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry); |
1125 } | 1123 } |
1126 | 1124 |
1127 static void CollectElementIndicesImpl(Handle<JSObject> object, | 1125 static void CollectElementIndicesImpl(Handle<JSObject> object, |
1128 Handle<FixedArrayBase> backing_store, | 1126 Handle<FixedArrayBase> backing_store, |
1129 KeyAccumulator* keys, uint32_t range, | 1127 KeyAccumulator* keys, uint32_t range, |
1130 PropertyAttributes filter, | 1128 PropertyFilter filter, |
1131 uint32_t offset) { | 1129 uint32_t offset) { |
1132 Handle<SeededNumberDictionary> dictionary = | 1130 Handle<SeededNumberDictionary> dictionary = |
1133 Handle<SeededNumberDictionary>::cast(backing_store); | 1131 Handle<SeededNumberDictionary>::cast(backing_store); |
1134 int capacity = dictionary->Capacity(); | 1132 int capacity = dictionary->Capacity(); |
1135 for (int i = 0; i < capacity; i++) { | 1133 for (int i = 0; i < capacity; i++) { |
1136 Object* k = dictionary->KeyAt(i); | 1134 Object* k = dictionary->KeyAt(i); |
1137 if (!dictionary->IsKey(k)) continue; | 1135 if (!dictionary->IsKey(k)) continue; |
1138 if (k->FilterKey(filter)) continue; | 1136 if (k->FilterKey(filter)) continue; |
1139 if (dictionary->IsDeleted(i)) continue; | 1137 if (dictionary->IsDeleted(i)) continue; |
1140 DCHECK(k->IsNumber()); | 1138 DCHECK(k->IsNumber()); |
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1803 UNREACHABLE(); | 1801 UNREACHABLE(); |
1804 } | 1802 } |
1805 | 1803 |
1806 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, | 1804 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, |
1807 uint32_t entry) { | 1805 uint32_t entry) { |
1808 return entry; | 1806 return entry; |
1809 } | 1807 } |
1810 | 1808 |
1811 static uint32_t GetEntryForIndexImpl(JSObject* holder, | 1809 static uint32_t GetEntryForIndexImpl(JSObject* holder, |
1812 FixedArrayBase* backing_store, | 1810 FixedArrayBase* backing_store, |
1813 uint32_t index, | 1811 uint32_t index, PropertyFilter filter) { |
1814 PropertyAttributes filter) { | |
1815 return index < AccessorClass::GetCapacityImpl(holder, backing_store) | 1812 return index < AccessorClass::GetCapacityImpl(holder, backing_store) |
1816 ? index | 1813 ? index |
1817 : kMaxUInt32; | 1814 : kMaxUInt32; |
1818 } | 1815 } |
1819 | 1816 |
1820 static uint32_t GetCapacityImpl(JSObject* holder, | 1817 static uint32_t GetCapacityImpl(JSObject* holder, |
1821 FixedArrayBase* backing_store) { | 1818 FixedArrayBase* backing_store) { |
1822 JSArrayBufferView* view = JSArrayBufferView::cast(holder); | 1819 JSArrayBufferView* view = JSArrayBufferView::cast(holder); |
1823 if (view->WasNeutered()) return 0; | 1820 if (view->WasNeutered()) return 0; |
1824 return backing_store->length(); | 1821 return backing_store->length(); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1938 FixedArray* parameter_map = FixedArray::cast(parameters); | 1935 FixedArray* parameter_map = FixedArray::cast(parameters); |
1939 uint32_t length = parameter_map->length() - 2; | 1936 uint32_t length = parameter_map->length() - 2; |
1940 if (entry < length) return entry; | 1937 if (entry < length) return entry; |
1941 | 1938 |
1942 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 1939 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
1943 return ArgumentsAccessor::GetIndexForEntryImpl(arguments, entry - length); | 1940 return ArgumentsAccessor::GetIndexForEntryImpl(arguments, entry - length); |
1944 } | 1941 } |
1945 | 1942 |
1946 static uint32_t GetEntryForIndexImpl(JSObject* holder, | 1943 static uint32_t GetEntryForIndexImpl(JSObject* holder, |
1947 FixedArrayBase* parameters, | 1944 FixedArrayBase* parameters, |
1948 uint32_t index, | 1945 uint32_t index, PropertyFilter filter) { |
1949 PropertyAttributes filter) { | |
1950 FixedArray* parameter_map = FixedArray::cast(parameters); | 1946 FixedArray* parameter_map = FixedArray::cast(parameters); |
1951 Object* probe = GetParameterMapArg(parameter_map, index); | 1947 Object* probe = GetParameterMapArg(parameter_map, index); |
1952 if (!probe->IsTheHole()) return index; | 1948 if (!probe->IsTheHole()) return index; |
1953 | 1949 |
1954 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 1950 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
1955 uint32_t entry = ArgumentsAccessor::GetEntryForIndexImpl(holder, arguments, | 1951 uint32_t entry = ArgumentsAccessor::GetEntryForIndexImpl(holder, arguments, |
1956 index, filter); | 1952 index, filter); |
1957 if (entry == kMaxUInt32) return entry; | 1953 if (entry == kMaxUInt32) return entry; |
1958 return (parameter_map->length() - 2) + entry; | 1954 return (parameter_map->length() - 2) + entry; |
1959 } | 1955 } |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2379 } | 2375 } |
2380 } | 2376 } |
2381 | 2377 |
2382 DCHECK(j == result_len); | 2378 DCHECK(j == result_len); |
2383 return result_array; | 2379 return result_array; |
2384 } | 2380 } |
2385 | 2381 |
2386 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 2382 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
2387 } // namespace internal | 2383 } // namespace internal |
2388 } // namespace v8 | 2384 } // namespace v8 |
OLD | NEW |