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

Side by Side Diff: src/elements.cc

Issue 1612323003: Introduce {FAST,SLOW}_STRING_WRAPPER_ELEMENTS (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: one more DCHECK fix Created 4 years, 10 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/elements-kind.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 22 matching lines...) Expand all
33 // - FixedInt16ElementsAccessor 33 // - FixedInt16ElementsAccessor
34 // - FixedUint32ElementsAccessor 34 // - FixedUint32ElementsAccessor
35 // - FixedInt32ElementsAccessor 35 // - FixedInt32ElementsAccessor
36 // - FixedFloat32ElementsAccessor 36 // - FixedFloat32ElementsAccessor
37 // - FixedFloat64ElementsAccessor 37 // - FixedFloat64ElementsAccessor
38 // - FixedUint8ClampedElementsAccessor 38 // - FixedUint8ClampedElementsAccessor
39 // - DictionaryElementsAccessor 39 // - DictionaryElementsAccessor
40 // - SloppyArgumentsElementsAccessor 40 // - SloppyArgumentsElementsAccessor
41 // - FastSloppyArgumentsElementsAccessor 41 // - FastSloppyArgumentsElementsAccessor
42 // - SlowSloppyArgumentsElementsAccessor 42 // - SlowSloppyArgumentsElementsAccessor
43 43 // - StringWrapperElementsAccessor
44 // - FastStringWrapperElementsAccessor
45 // - SlowStringWrapperElementsAccessor
44 46
45 namespace v8 { 47 namespace v8 {
46 namespace internal { 48 namespace internal {
47 49
48 50
49 namespace { 51 namespace {
50 52
51 53
52 static const int kPackedSizeNotKnown = -1; 54 static const int kPackedSizeNotKnown = -1;
53 55
(...skipping 11 matching lines...) Expand all
65 V(FastPackedObjectElementsAccessor, FAST_ELEMENTS, FixedArray) \ 67 V(FastPackedObjectElementsAccessor, FAST_ELEMENTS, FixedArray) \
66 V(FastHoleyObjectElementsAccessor, FAST_HOLEY_ELEMENTS, FixedArray) \ 68 V(FastHoleyObjectElementsAccessor, FAST_HOLEY_ELEMENTS, FixedArray) \
67 V(FastPackedDoubleElementsAccessor, FAST_DOUBLE_ELEMENTS, FixedDoubleArray) \ 69 V(FastPackedDoubleElementsAccessor, FAST_DOUBLE_ELEMENTS, FixedDoubleArray) \
68 V(FastHoleyDoubleElementsAccessor, FAST_HOLEY_DOUBLE_ELEMENTS, \ 70 V(FastHoleyDoubleElementsAccessor, FAST_HOLEY_DOUBLE_ELEMENTS, \
69 FixedDoubleArray) \ 71 FixedDoubleArray) \
70 V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS, SeededNumberDictionary) \ 72 V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS, SeededNumberDictionary) \
71 V(FastSloppyArgumentsElementsAccessor, FAST_SLOPPY_ARGUMENTS_ELEMENTS, \ 73 V(FastSloppyArgumentsElementsAccessor, FAST_SLOPPY_ARGUMENTS_ELEMENTS, \
72 FixedArray) \ 74 FixedArray) \
73 V(SlowSloppyArgumentsElementsAccessor, SLOW_SLOPPY_ARGUMENTS_ELEMENTS, \ 75 V(SlowSloppyArgumentsElementsAccessor, SLOW_SLOPPY_ARGUMENTS_ELEMENTS, \
74 FixedArray) \ 76 FixedArray) \
77 V(FastStringWrapperElementsAccessor, FAST_STRING_WRAPPER_ELEMENTS, \
78 FixedArray) \
79 V(SlowStringWrapperElementsAccessor, SLOW_STRING_WRAPPER_ELEMENTS, \
80 FixedArray) \
75 V(FixedUint8ElementsAccessor, UINT8_ELEMENTS, FixedUint8Array) \ 81 V(FixedUint8ElementsAccessor, UINT8_ELEMENTS, FixedUint8Array) \
76 V(FixedInt8ElementsAccessor, INT8_ELEMENTS, FixedInt8Array) \ 82 V(FixedInt8ElementsAccessor, INT8_ELEMENTS, FixedInt8Array) \
77 V(FixedUint16ElementsAccessor, UINT16_ELEMENTS, FixedUint16Array) \ 83 V(FixedUint16ElementsAccessor, UINT16_ELEMENTS, FixedUint16Array) \
78 V(FixedInt16ElementsAccessor, INT16_ELEMENTS, FixedInt16Array) \ 84 V(FixedInt16ElementsAccessor, INT16_ELEMENTS, FixedInt16Array) \
79 V(FixedUint32ElementsAccessor, UINT32_ELEMENTS, FixedUint32Array) \ 85 V(FixedUint32ElementsAccessor, UINT32_ELEMENTS, FixedUint32Array) \
80 V(FixedInt32ElementsAccessor, INT32_ELEMENTS, FixedInt32Array) \ 86 V(FixedInt32ElementsAccessor, INT32_ELEMENTS, FixedInt32Array) \
81 V(FixedFloat32ElementsAccessor, FLOAT32_ELEMENTS, FixedFloat32Array) \ 87 V(FixedFloat32ElementsAccessor, FLOAT32_ELEMENTS, FixedFloat32Array) \
82 V(FixedFloat64ElementsAccessor, FLOAT64_ELEMENTS, FixedFloat64Array) \ 88 V(FixedFloat64ElementsAccessor, FLOAT64_ELEMENTS, FixedFloat64Array) \
83 V(FixedUint8ClampedElementsAccessor, UINT8_CLAMPED_ELEMENTS, \ 89 V(FixedUint8ClampedElementsAccessor, UINT8_CLAMPED_ELEMENTS, \
84 FixedUint8ClampedArray) 90 FixedUint8ClampedArray)
85 91
86
87 template<ElementsKind Kind> class ElementsKindTraits { 92 template<ElementsKind Kind> class ElementsKindTraits {
88 public: 93 public:
89 typedef FixedArrayBase BackingStore; 94 typedef FixedArrayBase BackingStore;
90 }; 95 };
91 96
92 #define ELEMENTS_TRAITS(Class, KindParam, Store) \ 97 #define ELEMENTS_TRAITS(Class, KindParam, Store) \
93 template<> class ElementsKindTraits<KindParam> { \ 98 template<> class ElementsKindTraits<KindParam> { \
94 public: /* NOLINT */ \ 99 public: /* NOLINT */ \
95 static const ElementsKind Kind = KindParam; \ 100 static const ElementsKind Kind = KindParam; \
96 typedef Store BackingStore; \ 101 typedef Store BackingStore; \
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 DCHECK((copy_size + static_cast<int>(to_start)) <= to_base->length() && 228 DCHECK((copy_size + static_cast<int>(to_start)) <= to_base->length() &&
224 (copy_size + static_cast<int>(from_start)) <= from_base->length()); 229 (copy_size + static_cast<int>(from_start)) <= from_base->length());
225 if (copy_size == 0) return; 230 if (copy_size == 0) return;
226 231
227 // From here on, the code below could actually allocate. Therefore the raw 232 // From here on, the code below could actually allocate. Therefore the raw
228 // values are wrapped into handles. 233 // values are wrapped into handles.
229 Isolate* isolate = from_base->GetIsolate(); 234 Isolate* isolate = from_base->GetIsolate();
230 Handle<FixedDoubleArray> from(FixedDoubleArray::cast(from_base), isolate); 235 Handle<FixedDoubleArray> from(FixedDoubleArray::cast(from_base), isolate);
231 Handle<FixedArray> to(FixedArray::cast(to_base), isolate); 236 Handle<FixedArray> to(FixedArray::cast(to_base), isolate);
232 237
233 // create an outer loop to not waste too much time on creating HandleScopes 238 // Use an outer loop to not waste too much time on creating HandleScopes.
234 // on the other hand we might overflow a single handle scope depending on 239 // On the other hand we might overflow a single handle scope depending on
235 // the copy_size 240 // the copy_size.
236 int offset = 0; 241 int offset = 0;
237 while (offset < copy_size) { 242 while (offset < copy_size) {
238 HandleScope scope(isolate); 243 HandleScope scope(isolate);
239 offset += 100; 244 offset += 100;
240 for (int i = offset - 100; i < offset && i < copy_size; ++i) { 245 for (int i = offset - 100; i < offset && i < copy_size; ++i) {
241 Handle<Object> value = FixedDoubleArray::get(from, i + from_start); 246 Handle<Object> value =
247 FixedDoubleArray::get(*from, i + from_start, isolate);
242 to->set(i + to_start, *value, UPDATE_WRITE_BARRIER); 248 to->set(i + to_start, *value, UPDATE_WRITE_BARRIER);
243 } 249 }
244 } 250 }
245 } 251 }
246 252
247 253
248 static void CopyDoubleToDoubleElements(FixedArrayBase* from_base, 254 static void CopyDoubleToDoubleElements(FixedArrayBase* from_base,
249 uint32_t from_start, 255 uint32_t from_start,
250 FixedArrayBase* to_base, 256 FixedArrayBase* to_base,
251 uint32_t to_start, int raw_copy_size) { 257 uint32_t to_start, int raw_copy_size) {
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 backing_store, filter); 544 backing_store, filter);
539 } 545 }
540 546
541 static bool HasElementImpl(Handle<JSObject> holder, uint32_t index, 547 static bool HasElementImpl(Handle<JSObject> holder, uint32_t index,
542 Handle<FixedArrayBase> backing_store, 548 Handle<FixedArrayBase> backing_store,
543 PropertyFilter filter) { 549 PropertyFilter filter) {
544 return ElementsAccessorSubclass::GetEntryForIndexImpl( 550 return ElementsAccessorSubclass::GetEntryForIndexImpl(
545 *holder, *backing_store, index, filter) != kMaxUInt32; 551 *holder, *backing_store, index, filter) != kMaxUInt32;
546 } 552 }
547 553
548 Handle<Object> Get(Handle<FixedArrayBase> backing_store, 554 Handle<Object> Get(Handle<JSObject> holder, uint32_t entry) final {
549 uint32_t entry) final { 555 return ElementsAccessorSubclass::GetImpl(holder, entry);
550 return ElementsAccessorSubclass::GetImpl(backing_store, entry);
551 } 556 }
552 557
553 static Handle<Object> GetImpl(Handle<FixedArrayBase> backing_store, 558 static Handle<Object> GetImpl(Handle<JSObject> holder, uint32_t entry) {
554 uint32_t entry) { 559 return ElementsAccessorSubclass::GetImpl(holder->elements(), entry);
555 uint32_t index = GetIndexForEntryImpl(*backing_store, entry);
556 return BackingStore::get(Handle<BackingStore>::cast(backing_store), index);
557 } 560 }
558 561
559 void Set(FixedArrayBase* backing_store, uint32_t entry, Object* value) final { 562 static Handle<Object> GetImpl(FixedArrayBase* backing_store, uint32_t entry) {
560 ElementsAccessorSubclass::SetImpl(backing_store, entry, value); 563 Isolate* isolate = backing_store->GetIsolate();
564 uint32_t index = GetIndexForEntryImpl(backing_store, entry);
565 return handle(BackingStore::cast(backing_store)->get(index), isolate);
561 } 566 }
562 567
563 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, 568 void Set(Handle<JSObject> holder, uint32_t entry, Object* value) final {
564 Object* value) { 569 ElementsAccessorSubclass::SetImpl(holder, entry, value);
565 UNREACHABLE();
566 }
567
568
569 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
570 Object* value, WriteBarrierMode mode) {
571 UNREACHABLE();
572 } 570 }
573 571
574 void Reconfigure(Handle<JSObject> object, Handle<FixedArrayBase> store, 572 void Reconfigure(Handle<JSObject> object, Handle<FixedArrayBase> store,
575 uint32_t entry, Handle<Object> value, 573 uint32_t entry, Handle<Object> value,
576 PropertyAttributes attributes) final { 574 PropertyAttributes attributes) final {
577 ElementsAccessorSubclass::ReconfigureImpl(object, store, entry, value, 575 ElementsAccessorSubclass::ReconfigureImpl(object, store, entry, value,
578 attributes); 576 attributes);
579 } 577 }
580 578
581 static void ReconfigureImpl(Handle<JSObject> object, 579 static void ReconfigureImpl(Handle<JSObject> object,
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 // always returning undefined. If there is a store to the initial 771 // always returning undefined. If there is a store to the initial
774 // prototype object, make sure all of these optimizations are invalidated. 772 // prototype object, make sure all of these optimizations are invalidated.
775 object->GetIsolate()->UpdateArrayProtectorOnSetLength(object); 773 object->GetIsolate()->UpdateArrayProtectorOnSetLength(object);
776 } 774 }
777 Handle<FixedArrayBase> old_elements(object->elements()); 775 Handle<FixedArrayBase> old_elements(object->elements());
778 // This method should only be called if there's a reason to update the 776 // This method should only be called if there's a reason to update the
779 // elements. 777 // elements.
780 DCHECK(IsFastDoubleElementsKind(from_kind) != 778 DCHECK(IsFastDoubleElementsKind(from_kind) !=
781 IsFastDoubleElementsKind(kind()) || 779 IsFastDoubleElementsKind(kind()) ||
782 IsDictionaryElementsKind(from_kind) || 780 IsDictionaryElementsKind(from_kind) ||
781 from_kind == SLOW_STRING_WRAPPER_ELEMENTS ||
783 static_cast<uint32_t>(old_elements->length()) < capacity); 782 static_cast<uint32_t>(old_elements->length()) < capacity);
784 Handle<FixedArrayBase> elements = 783 Handle<FixedArrayBase> elements =
785 ConvertElementsWithCapacity(object, old_elements, from_kind, capacity); 784 ConvertElementsWithCapacity(object, old_elements, from_kind, capacity);
786 785
787 ElementsKind to_kind = kind(); 786 ElementsKind to_kind = kind();
788 if (IsHoleyElementsKind(from_kind)) to_kind = GetHoleyElementsKind(to_kind); 787 if (IsHoleyElementsKind(from_kind)) to_kind = GetHoleyElementsKind(to_kind);
789 Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, to_kind); 788 Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, to_kind);
790 JSObject::SetMapAndElements(object, new_map, elements); 789 JSObject::SetMapAndElements(object, new_map, elements);
791 790
792 // Transition through the allocation site as well if present. 791 // Transition through the allocation site as well if present.
(...skipping 14 matching lines...) Expand all
807 ElementsAccessorSubclass::DeleteImpl(obj, entry); 806 ElementsAccessorSubclass::DeleteImpl(obj, entry);
808 } 807 }
809 808
810 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, 809 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
811 FixedArrayBase* to, ElementsKind from_kind, 810 FixedArrayBase* to, ElementsKind from_kind,
812 uint32_t to_start, int packed_size, 811 uint32_t to_start, int packed_size,
813 int copy_size) { 812 int copy_size) {
814 UNREACHABLE(); 813 UNREACHABLE();
815 } 814 }
816 815
817 void CopyElements(Handle<FixedArrayBase> from, uint32_t from_start,
818 ElementsKind from_kind, Handle<FixedArrayBase> to,
819 uint32_t to_start, int copy_size) final {
820 DCHECK(!from.is_null());
821 // NOTE: the ElementsAccessorSubclass::CopyElementsImpl() methods
822 // violate the handlified function signature convention:
823 // raw pointer parameters in the function that allocates. This is done
824 // intentionally to avoid ArrayConcat() builtin performance degradation.
825 // See the comment in another ElementsAccessorBase::CopyElements() for
826 // details.
827 ElementsAccessorSubclass::CopyElementsImpl(*from, from_start, *to,
828 from_kind, to_start,
829 kPackedSizeNotKnown, copy_size);
830 }
831
832 void CopyElements(JSObject* from_holder, uint32_t from_start, 816 void CopyElements(JSObject* from_holder, uint32_t from_start,
833 ElementsKind from_kind, Handle<FixedArrayBase> to, 817 ElementsKind from_kind, Handle<FixedArrayBase> to,
834 uint32_t to_start, int copy_size) final { 818 uint32_t to_start, int copy_size) final {
835 int packed_size = kPackedSizeNotKnown; 819 int packed_size = kPackedSizeNotKnown;
836 bool is_packed = IsFastPackedElementsKind(from_kind) && 820 bool is_packed = IsFastPackedElementsKind(from_kind) &&
837 from_holder->IsJSArray(); 821 from_holder->IsJSArray();
838 if (is_packed) { 822 if (is_packed) {
839 packed_size = 823 packed_size =
840 Smi::cast(JSArray::cast(from_holder)->length())->value(); 824 Smi::cast(JSArray::cast(from_holder)->length())->value();
841 if (copy_size >= 0 && packed_size > copy_size) { 825 if (copy_size >= 0 && packed_size > copy_size) {
(...skipping 12 matching lines...) Expand all
854 // handle creation causes noticeable performance degradation of the builtin. 838 // handle creation causes noticeable performance degradation of the builtin.
855 ElementsAccessorSubclass::CopyElementsImpl( 839 ElementsAccessorSubclass::CopyElementsImpl(
856 from, from_start, *to, from_kind, to_start, packed_size, copy_size); 840 from, from_start, *to, from_kind, to_start, packed_size, copy_size);
857 } 841 }
858 842
859 static void CollectElementIndicesImpl(Handle<JSObject> object, 843 static void CollectElementIndicesImpl(Handle<JSObject> object,
860 Handle<FixedArrayBase> backing_store, 844 Handle<FixedArrayBase> backing_store,
861 KeyAccumulator* keys, uint32_t range, 845 KeyAccumulator* keys, uint32_t range,
862 PropertyFilter filter, 846 PropertyFilter filter,
863 uint32_t offset) { 847 uint32_t offset) {
848 DCHECK_NE(DICTIONARY_ELEMENTS, kind());
864 if (filter & ONLY_ALL_CAN_READ) { 849 if (filter & ONLY_ALL_CAN_READ) {
865 // Non-dictionary elements can't have all-can-read accessors. 850 // Non-dictionary elements can't have all-can-read accessors.
866 return; 851 return;
867 } 852 }
868 uint32_t length = 0; 853 uint32_t length = 0;
869 if (object->IsJSArray()) { 854 if (object->IsJSArray()) {
870 length = Smi::cast(JSArray::cast(*object)->length())->value(); 855 length = Smi::cast(JSArray::cast(*object)->length())->value();
871 } else { 856 } else {
872 length = 857 length =
873 ElementsAccessorSubclass::GetCapacityImpl(*object, *backing_store); 858 ElementsAccessorSubclass::GetCapacityImpl(*object, *backing_store);
874 } 859 }
875 if (range < length) length = range; 860 if (range < length) length = range;
876 for (uint32_t i = offset; i < length; i++) { 861 for (uint32_t i = offset; i < length; i++) {
877 if (!ElementsAccessorSubclass::HasElementImpl(object, i, backing_store, 862 if (!ElementsAccessorSubclass::HasElementImpl(object, i, backing_store,
878 filter)) 863 filter)) {
879 continue; 864 continue;
865 }
880 keys->AddKey(i); 866 keys->AddKey(i);
881 } 867 }
882 } 868 }
883 869
884 void CollectElementIndices(Handle<JSObject> object, 870 void CollectElementIndices(Handle<JSObject> object,
885 Handle<FixedArrayBase> backing_store, 871 Handle<FixedArrayBase> backing_store,
886 KeyAccumulator* keys, uint32_t range, 872 KeyAccumulator* keys, uint32_t range,
887 PropertyFilter filter, uint32_t offset) final { 873 PropertyFilter filter, uint32_t offset) final {
888 ElementsAccessorSubclass::CollectElementIndicesImpl( 874 ElementsAccessorSubclass::CollectElementIndicesImpl(
889 object, backing_store, keys, range, filter, offset); 875 object, backing_store, keys, range, filter, offset);
890 }; 876 };
891 877
892 void AddElementsToKeyAccumulator(Handle<JSObject> receiver, 878 void AddElementsToKeyAccumulator(Handle<JSObject> receiver,
893 KeyAccumulator* accumulator, 879 KeyAccumulator* accumulator,
894 AddKeyConversion convert) final { 880 AddKeyConversion convert) final {
895 Handle<FixedArrayBase> from(receiver->elements()); 881 ElementsAccessorSubclass::AddElementsToKeyAccumulatorImpl(
896 uint32_t add_length = 882 receiver, accumulator, convert);
897 ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from);
898 if (add_length == 0) return;
899
900 for (uint32_t i = 0; i < add_length; i++) {
901 if (!ElementsAccessorSubclass::HasEntryImpl(*from, i)) continue;
902 Handle<Object> value = ElementsAccessorSubclass::GetImpl(from, i);
903 DCHECK(!value->IsTheHole());
904 DCHECK(!value->IsAccessorPair());
905 DCHECK(!value->IsAccessorInfo());
906 accumulator->AddKey(value, convert);
907 }
908 } 883 }
909 884
910 static uint32_t GetCapacityImpl(JSObject* holder, 885 static uint32_t GetCapacityImpl(JSObject* holder,
911 FixedArrayBase* backing_store) { 886 FixedArrayBase* backing_store) {
912 return backing_store->length(); 887 return backing_store->length();
913 } 888 }
914 889
915 uint32_t GetCapacity(JSObject* holder, FixedArrayBase* backing_store) final { 890 uint32_t GetCapacity(JSObject* holder, FixedArrayBase* backing_store) final {
916 return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store); 891 return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store);
917 } 892 }
918 893
919 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) {
920 return true;
921 }
922
923 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, 894 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store,
924 uint32_t entry) { 895 uint32_t entry) {
925 return entry; 896 return entry;
926 } 897 }
927 898
928 static uint32_t GetEntryForIndexImpl(JSObject* holder, 899 static uint32_t GetEntryForIndexImpl(JSObject* holder,
929 FixedArrayBase* backing_store, 900 FixedArrayBase* backing_store,
930 uint32_t index, PropertyFilter filter) { 901 uint32_t index, PropertyFilter filter) {
931 if (IsHoleyElementsKind(kind())) { 902 if (IsHoleyElementsKind(kind())) {
932 return index < ElementsAccessorSubclass::GetCapacityImpl(holder, 903 return index < ElementsAccessorSubclass::GetCapacityImpl(holder,
(...skipping 16 matching lines...) Expand all
949 uint32_t index) final { 920 uint32_t index) final {
950 return ElementsAccessorSubclass::GetEntryForIndexImpl( 921 return ElementsAccessorSubclass::GetEntryForIndexImpl(
951 holder, backing_store, index, ALL_PROPERTIES); 922 holder, backing_store, index, ALL_PROPERTIES);
952 } 923 }
953 924
954 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 925 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
955 uint32_t entry) { 926 uint32_t entry) {
956 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); 927 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
957 } 928 }
958 929
959 PropertyDetails GetDetails(FixedArrayBase* backing_store, 930 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) {
960 uint32_t entry) final { 931 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
961 return ElementsAccessorSubclass::GetDetailsImpl(backing_store, entry); 932 }
933
934 PropertyDetails GetDetails(JSObject* holder, uint32_t entry) final {
935 return ElementsAccessorSubclass::GetDetailsImpl(holder, entry);
962 } 936 }
963 937
964 private: 938 private:
965 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); 939 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase);
966 }; 940 };
967 941
968 942
969 class DictionaryElementsAccessor 943 class DictionaryElementsAccessor
970 : public ElementsAccessorBase<DictionaryElementsAccessor, 944 : public ElementsAccessorBase<DictionaryElementsAccessor,
971 ElementsKindTraits<DICTIONARY_ELEMENTS> > { 945 ElementsKindTraits<DICTIONARY_ELEMENTS> > {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1046 Handle<FixedArray> new_elements = 1020 Handle<FixedArray> new_elements =
1047 SeededNumberDictionary::Shrink(dict, index); 1021 SeededNumberDictionary::Shrink(dict, index);
1048 obj->set_elements(*new_elements); 1022 obj->set_elements(*new_elements);
1049 } 1023 }
1050 1024
1051 static Object* GetRaw(FixedArrayBase* store, uint32_t entry) { 1025 static Object* GetRaw(FixedArrayBase* store, uint32_t entry) {
1052 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store); 1026 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store);
1053 return backing_store->ValueAt(entry); 1027 return backing_store->ValueAt(entry);
1054 } 1028 }
1055 1029
1056 static Handle<Object> GetImpl(Handle<FixedArrayBase> store, uint32_t entry) { 1030 static Handle<Object> GetImpl(Handle<JSObject> holder, uint32_t entry) {
1057 Isolate* isolate = store->GetIsolate(); 1031 return GetImpl(holder->elements(), entry);
1058 return handle(GetRaw(*store, entry), isolate);
1059 } 1032 }
1060 1033
1061 static inline void SetImpl(FixedArrayBase* store, uint32_t entry, 1034 static Handle<Object> GetImpl(FixedArrayBase* backing_store, uint32_t entry) {
1035 return handle(GetRaw(backing_store, entry), backing_store->GetIsolate());
1036 }
1037
1038 static inline void SetImpl(Handle<JSObject> holder, uint32_t entry,
1062 Object* value) { 1039 Object* value) {
1063 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store); 1040 SetImpl(holder->elements(), entry, value);
1064 dictionary->ValueAtPut(entry, value); 1041 }
1042
1043 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
1044 Object* value) {
1045 SeededNumberDictionary::cast(backing_store)->ValueAtPut(entry, value);
1065 } 1046 }
1066 1047
1067 static void ReconfigureImpl(Handle<JSObject> object, 1048 static void ReconfigureImpl(Handle<JSObject> object,
1068 Handle<FixedArrayBase> store, uint32_t entry, 1049 Handle<FixedArrayBase> store, uint32_t entry,
1069 Handle<Object> value, 1050 Handle<Object> value,
1070 PropertyAttributes attributes) { 1051 PropertyAttributes attributes) {
1071 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(*store); 1052 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(*store);
1072 if (attributes != NONE) object->RequireSlowElements(dictionary); 1053 if (attributes != NONE) object->RequireSlowElements(dictionary);
1073 dictionary->ValueAtPut(entry, *value); 1054 dictionary->ValueAtPut(entry, *value);
1074 PropertyDetails details = dictionary->DetailsAt(entry); 1055 PropertyDetails details = dictionary->DetailsAt(entry);
1075 details = PropertyDetails(attributes, DATA, details.dictionary_index(), 1056 details = PropertyDetails(attributes, DATA, details.dictionary_index(),
1076 PropertyCellType::kNoCell); 1057 PropertyCellType::kNoCell);
1077 dictionary->DetailsAtPut(entry, details); 1058 dictionary->DetailsAtPut(entry, details);
1078 } 1059 }
1079 1060
1080 static void AddImpl(Handle<JSObject> object, uint32_t index, 1061 static void AddImpl(Handle<JSObject> object, uint32_t index,
1081 Handle<Object> value, PropertyAttributes attributes, 1062 Handle<Object> value, PropertyAttributes attributes,
1082 uint32_t new_capacity) { 1063 uint32_t new_capacity) {
1083 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); 1064 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
1084 Handle<SeededNumberDictionary> dictionary = 1065 Handle<SeededNumberDictionary> dictionary =
1085 object->HasFastElements() 1066 object->HasFastElements() || object->HasFastStringWrapperElements()
1086 ? JSObject::NormalizeElements(object) 1067 ? JSObject::NormalizeElements(object)
1087 : handle(SeededNumberDictionary::cast(object->elements())); 1068 : handle(SeededNumberDictionary::cast(object->elements()));
1088 Handle<SeededNumberDictionary> new_dictionary = 1069 Handle<SeededNumberDictionary> new_dictionary =
1089 SeededNumberDictionary::AddNumberEntry( 1070 SeededNumberDictionary::AddNumberEntry(
1090 dictionary, index, value, details, 1071 dictionary, index, value, details,
1091 object->map()->is_prototype_map()); 1072 object->map()->is_prototype_map());
1092 if (attributes != NONE) object->RequireSlowElements(*new_dictionary); 1073 if (attributes != NONE) object->RequireSlowElements(*new_dictionary);
1093 if (dictionary.is_identical_to(new_dictionary)) return; 1074 if (dictionary.is_identical_to(new_dictionary)) return;
1094 object->set_elements(*new_dictionary); 1075 object->set_elements(*new_dictionary);
1095 } 1076 }
(...skipping 20 matching lines...) Expand all
1116 int entry = dictionary->FindEntry(index); 1097 int entry = dictionary->FindEntry(index);
1117 if (entry == SeededNumberDictionary::kNotFound) return kMaxUInt32; 1098 if (entry == SeededNumberDictionary::kNotFound) return kMaxUInt32;
1118 if (filter != ALL_PROPERTIES) { 1099 if (filter != ALL_PROPERTIES) {
1119 PropertyDetails details = dictionary->DetailsAt(entry); 1100 PropertyDetails details = dictionary->DetailsAt(entry);
1120 PropertyAttributes attr = details.attributes(); 1101 PropertyAttributes attr = details.attributes();
1121 if ((attr & filter) != 0) return kMaxUInt32; 1102 if ((attr & filter) != 0) return kMaxUInt32;
1122 } 1103 }
1123 return static_cast<uint32_t>(entry); 1104 return static_cast<uint32_t>(entry);
1124 } 1105 }
1125 1106
1107 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) {
1108 return GetDetailsImpl(holder->elements(), entry);
1109 }
1110
1126 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 1111 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
1127 uint32_t entry) { 1112 uint32_t entry) {
1128 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry); 1113 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry);
1129 } 1114 }
1130 1115
1131 static void CollectElementIndicesImpl(Handle<JSObject> object, 1116 static void CollectElementIndicesImpl(Handle<JSObject> object,
1132 Handle<FixedArrayBase> backing_store, 1117 Handle<FixedArrayBase> backing_store,
1133 KeyAccumulator* keys, uint32_t range, 1118 KeyAccumulator* keys, uint32_t range,
1134 PropertyFilter filter, 1119 PropertyFilter filter,
1135 uint32_t offset) { 1120 uint32_t offset) {
(...skipping 16 matching lines...) Expand all
1152 if (!accessors->IsAccessorInfo()) continue; 1137 if (!accessors->IsAccessorInfo()) continue;
1153 if (!AccessorInfo::cast(accessors)->all_can_read()) continue; 1138 if (!AccessorInfo::cast(accessors)->all_can_read()) continue;
1154 } 1139 }
1155 PropertyAttributes attr = details.attributes(); 1140 PropertyAttributes attr = details.attributes();
1156 if ((attr & filter) != 0) continue; 1141 if ((attr & filter) != 0) continue;
1157 keys->AddKey(index); 1142 keys->AddKey(index);
1158 } 1143 }
1159 1144
1160 keys->SortCurrentElementsList(); 1145 keys->SortCurrentElementsList();
1161 } 1146 }
1147
1148 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
1149 KeyAccumulator* accumulator,
1150 AddKeyConversion convert) {
1151 SeededNumberDictionary* dictionary =
1152 SeededNumberDictionary::cast(receiver->elements());
1153 int capacity = dictionary->Capacity();
1154 for (int i = 0; i < capacity; i++) {
1155 Object* k = dictionary->KeyAt(i);
1156 if (!dictionary->IsKey(k)) continue;
1157 if (dictionary->IsDeleted(i)) continue;
1158 Object* value = dictionary->ValueAt(i);
1159 DCHECK(!value->IsTheHole());
1160 DCHECK(!value->IsAccessorPair());
1161 DCHECK(!value->IsAccessorInfo());
1162 accumulator->AddKey(value, convert);
1163 }
1164 }
1162 }; 1165 };
1163 1166
1164 1167
1165 // Super class for all fast element arrays. 1168 // Super class for all fast element arrays.
1166 template<typename FastElementsAccessorSubclass, 1169 template<typename FastElementsAccessorSubclass,
1167 typename KindTraits> 1170 typename KindTraits>
1168 class FastElementsAccessor 1171 class FastElementsAccessor
1169 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> { 1172 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> {
1170 public: 1173 public:
1171 explicit FastElementsAccessor(const char* name) 1174 explicit FastElementsAccessor(const char* name)
(...skipping 18 matching lines...) Expand all
1190 } 1193 }
1191 return; 1194 return;
1192 } 1195 }
1193 1196
1194 heap->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(*backing_store, 1197 heap->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(*backing_store,
1195 length - entry); 1198 length - entry);
1196 } 1199 }
1197 1200
1198 static void DeleteCommon(Handle<JSObject> obj, uint32_t entry, 1201 static void DeleteCommon(Handle<JSObject> obj, uint32_t entry,
1199 Handle<FixedArrayBase> store) { 1202 Handle<FixedArrayBase> store) {
1200 DCHECK(obj->HasFastSmiOrObjectElements() || 1203 DCHECK(obj->HasFastSmiOrObjectElements() || obj->HasFastDoubleElements() ||
1201 obj->HasFastDoubleElements() || 1204 obj->HasFastArgumentsElements() ||
1202 obj->HasFastArgumentsElements()); 1205 obj->HasFastStringWrapperElements());
1203 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(store); 1206 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(store);
1204 if (!obj->IsJSArray() && 1207 if (!obj->IsJSArray() &&
1205 entry == static_cast<uint32_t>(store->length()) - 1) { 1208 entry == static_cast<uint32_t>(store->length()) - 1) {
1206 DeleteAtEnd(obj, backing_store, entry); 1209 DeleteAtEnd(obj, backing_store, entry);
1207 return; 1210 return;
1208 } 1211 }
1209 1212
1210 backing_store->set_the_hole(entry); 1213 backing_store->set_the_hole(entry);
1211 1214
1212 // TODO(verwaest): Move this out of elements.cc. 1215 // TODO(verwaest): Move this out of elements.cc.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1270 ElementsKind from_kind = object->GetElementsKind(); 1273 ElementsKind from_kind = object->GetElementsKind();
1271 ElementsKind to_kind = FastElementsAccessorSubclass::kind(); 1274 ElementsKind to_kind = FastElementsAccessorSubclass::kind();
1272 if (IsDictionaryElementsKind(from_kind) || 1275 if (IsDictionaryElementsKind(from_kind) ||
1273 IsFastDoubleElementsKind(from_kind) != 1276 IsFastDoubleElementsKind(from_kind) !=
1274 IsFastDoubleElementsKind(to_kind) || 1277 IsFastDoubleElementsKind(to_kind) ||
1275 FastElementsAccessorSubclass::GetCapacityImpl( 1278 FastElementsAccessorSubclass::GetCapacityImpl(
1276 *object, object->elements()) != new_capacity) { 1279 *object, object->elements()) != new_capacity) {
1277 FastElementsAccessorSubclass::GrowCapacityAndConvertImpl(object, 1280 FastElementsAccessorSubclass::GrowCapacityAndConvertImpl(object,
1278 new_capacity); 1281 new_capacity);
1279 } else { 1282 } else {
1280 if (from_kind != to_kind) { 1283 if (IsFastElementsKind(from_kind) && from_kind != to_kind) {
1281 JSObject::TransitionElementsKind(object, to_kind); 1284 JSObject::TransitionElementsKind(object, to_kind);
1282 } 1285 }
1283 if (IsFastSmiOrObjectElementsKind(from_kind)) { 1286 if (IsFastSmiOrObjectElementsKind(from_kind)) {
1284 DCHECK(IsFastSmiOrObjectElementsKind(to_kind)); 1287 DCHECK(IsFastSmiOrObjectElementsKind(to_kind));
1285 JSObject::EnsureWritableFastElements(object); 1288 JSObject::EnsureWritableFastElements(object);
1286 } 1289 }
1287 } 1290 }
1288 FastElementsAccessorSubclass::SetImpl(object->elements(), index, *value); 1291 FastElementsAccessorSubclass::SetImpl(object, index, *value);
1289 } 1292 }
1290 1293
1291 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { 1294 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) {
1292 ElementsKind kind = KindTraits::Kind; 1295 ElementsKind kind = KindTraits::Kind;
1293 if (IsFastPackedElementsKind(kind)) { 1296 if (IsFastPackedElementsKind(kind)) {
1294 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind)); 1297 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind));
1295 } 1298 }
1296 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) { 1299 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) {
1297 JSObject::EnsureWritableFastElements(obj); 1300 JSObject::EnsureWritableFastElements(obj);
1298 } 1301 }
1299 DeleteCommon(obj, entry, handle(obj->elements())); 1302 DeleteCommon(obj, entry, handle(obj->elements()));
1300 } 1303 }
1301 1304
1302 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) { 1305 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) {
1303 return !BackingStore::cast(backing_store)->is_the_hole(entry); 1306 return !BackingStore::cast(backing_store)->is_the_hole(entry);
1304 } 1307 }
1305 1308
1309 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
1310 KeyAccumulator* accumulator,
1311 AddKeyConversion convert) {
1312 uint32_t length = 0;
1313 Handle<FixedArrayBase> elements(receiver->elements(),
1314 receiver->GetIsolate());
1315 if (receiver->IsJSArray()) {
1316 length = Smi::cast(JSArray::cast(*receiver)->length())->value();
1317 } else {
1318 length =
1319 FastElementsAccessorSubclass::GetCapacityImpl(*receiver, *elements);
1320 }
1321 for (uint32_t i = 0; i < length; i++) {
1322 if (IsFastPackedElementsKind(KindTraits::Kind) ||
1323 HasEntryImpl(*elements, i)) {
1324 accumulator->AddKey(FastElementsAccessorSubclass::GetImpl(*elements, i),
1325 convert);
1326 }
1327 }
1328 }
1329
1306 static void ValidateContents(Handle<JSObject> holder, int length) { 1330 static void ValidateContents(Handle<JSObject> holder, int length) {
1307 #if DEBUG 1331 #if DEBUG
1308 Isolate* isolate = holder->GetIsolate(); 1332 Isolate* isolate = holder->GetIsolate();
1309 HandleScope scope(isolate); 1333 HandleScope scope(isolate);
1310 Handle<FixedArrayBase> elements(holder->elements(), isolate); 1334 Handle<FixedArrayBase> elements(holder->elements(), isolate);
1311 Map* map = elements->map(); 1335 Map* map = elements->map();
1312 DCHECK((IsFastSmiOrObjectElementsKind(KindTraits::Kind) && 1336 DCHECK((IsFastSmiOrObjectElementsKind(KindTraits::Kind) &&
1313 (map == isolate->heap()->fixed_array_map() || 1337 (map == isolate->heap()->fixed_array_map() ||
1314 map == isolate->heap()->fixed_cow_array_map())) || 1338 map == isolate->heap()->fixed_cow_array_map())) ||
1315 (IsFastDoubleElementsKind(KindTraits::Kind) == 1339 (IsFastDoubleElementsKind(KindTraits::Kind) ==
1316 ((map == isolate->heap()->fixed_array_map() && length == 0) || 1340 ((map == isolate->heap()->fixed_array_map() && length == 0) ||
1317 map == isolate->heap()->fixed_double_array_map()))); 1341 map == isolate->heap()->fixed_double_array_map())));
1318 if (length == 0) return; // nothing to do! 1342 if (length == 0) return; // nothing to do!
1319 DisallowHeapAllocation no_gc; 1343 DisallowHeapAllocation no_gc;
1320 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); 1344 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements);
1321 if (IsFastSmiElementsKind(KindTraits::Kind)) { 1345 if (IsFastSmiElementsKind(KindTraits::Kind)) {
1322 for (int i = 0; i < length; i++) { 1346 for (int i = 0; i < length; i++) {
1323 DCHECK(BackingStore::get(backing_store, i)->IsSmi() || 1347 DCHECK(BackingStore::get(*backing_store, i, isolate)->IsSmi() ||
1324 (IsFastHoleyElementsKind(KindTraits::Kind) && 1348 (IsFastHoleyElementsKind(KindTraits::Kind) &&
1325 backing_store->is_the_hole(i))); 1349 backing_store->is_the_hole(i)));
1326 } 1350 }
1327 } 1351 }
1328 #endif 1352 #endif
1329 } 1353 }
1330 1354
1331 static Handle<Object> PopImpl(Handle<JSArray> receiver, 1355 static Handle<Object> PopImpl(Handle<JSArray> receiver,
1332 Handle<FixedArrayBase> backing_store) { 1356 Handle<FixedArrayBase> backing_store) {
1333 return FastElementsAccessorSubclass::RemoveElement(receiver, backing_store, 1357 return FastElementsAccessorSubclass::RemoveElement(receiver, backing_store,
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1473 static Handle<Object> RemoveElement(Handle<JSArray> receiver, 1497 static Handle<Object> RemoveElement(Handle<JSArray> receiver,
1474 Handle<FixedArrayBase> backing_store, 1498 Handle<FixedArrayBase> backing_store,
1475 Where remove_position) { 1499 Where remove_position) {
1476 Isolate* isolate = receiver->GetIsolate(); 1500 Isolate* isolate = receiver->GetIsolate();
1477 uint32_t length = 1501 uint32_t length =
1478 static_cast<uint32_t>(Smi::cast(receiver->length())->value()); 1502 static_cast<uint32_t>(Smi::cast(receiver->length())->value());
1479 DCHECK(length > 0); 1503 DCHECK(length > 0);
1480 int new_length = length - 1; 1504 int new_length = length - 1;
1481 int remove_index = remove_position == AT_START ? 0 : new_length; 1505 int remove_index = remove_position == AT_START ? 0 : new_length;
1482 Handle<Object> result = 1506 Handle<Object> result =
1483 FastElementsAccessorSubclass::GetImpl(backing_store, remove_index); 1507 FastElementsAccessorSubclass::GetImpl(*backing_store, remove_index);
1484 if (remove_position == AT_START) { 1508 if (remove_position == AT_START) {
1485 FastElementsAccessorSubclass::MoveElements( 1509 FastElementsAccessorSubclass::MoveElements(
1486 isolate, receiver, backing_store, 0, 1, new_length, 0, 0); 1510 isolate, receiver, backing_store, 0, 1, new_length, 0, 0);
1487 } 1511 }
1488 FastElementsAccessorSubclass::SetLengthImpl(isolate, receiver, new_length, 1512 FastElementsAccessorSubclass::SetLengthImpl(isolate, receiver, new_length,
1489 backing_store); 1513 backing_store);
1490 1514
1491 if (IsHoleyElementsKind(KindTraits::Kind) && result->IsTheHole()) { 1515 if (IsHoleyElementsKind(KindTraits::Kind) && result->IsTheHole()) {
1492 return receiver->GetIsolate()->factory()->undefined_value(); 1516 return receiver->GetIsolate()->factory()->undefined_value();
1493 } 1517 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1550 1574
1551 template<typename FastElementsAccessorSubclass, 1575 template<typename FastElementsAccessorSubclass,
1552 typename KindTraits> 1576 typename KindTraits>
1553 class FastSmiOrObjectElementsAccessor 1577 class FastSmiOrObjectElementsAccessor
1554 : public FastElementsAccessor<FastElementsAccessorSubclass, KindTraits> { 1578 : public FastElementsAccessor<FastElementsAccessorSubclass, KindTraits> {
1555 public: 1579 public:
1556 explicit FastSmiOrObjectElementsAccessor(const char* name) 1580 explicit FastSmiOrObjectElementsAccessor(const char* name)
1557 : FastElementsAccessor<FastElementsAccessorSubclass, 1581 : FastElementsAccessor<FastElementsAccessorSubclass,
1558 KindTraits>(name) {} 1582 KindTraits>(name) {}
1559 1583
1584 static inline void SetImpl(Handle<JSObject> holder, uint32_t entry,
1585 Object* value) {
1586 SetImpl(holder->elements(), entry, value);
1587 }
1588
1560 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, 1589 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
1561 Object* value) { 1590 Object* value) {
1562 FixedArray::cast(backing_store)->set(entry, value); 1591 FixedArray::cast(backing_store)->set(entry, value);
1563 } 1592 }
1564 1593
1565 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, 1594 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
1566 Object* value, WriteBarrierMode mode) { 1595 Object* value, WriteBarrierMode mode) {
1567 FixedArray::cast(backing_store)->set(entry, value, mode); 1596 FixedArray::cast(backing_store)->set(entry, value, mode);
1568 } 1597 }
1569 1598
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1606 FixedArrayBase* to, ElementsKind from_kind, 1635 FixedArrayBase* to, ElementsKind from_kind,
1607 uint32_t to_start, int packed_size, 1636 uint32_t to_start, int packed_size,
1608 int copy_size) { 1637 int copy_size) {
1609 DisallowHeapAllocation no_gc; 1638 DisallowHeapAllocation no_gc;
1610 ElementsKind to_kind = KindTraits::Kind; 1639 ElementsKind to_kind = KindTraits::Kind;
1611 switch (from_kind) { 1640 switch (from_kind) {
1612 case FAST_SMI_ELEMENTS: 1641 case FAST_SMI_ELEMENTS:
1613 case FAST_HOLEY_SMI_ELEMENTS: 1642 case FAST_HOLEY_SMI_ELEMENTS:
1614 case FAST_ELEMENTS: 1643 case FAST_ELEMENTS:
1615 case FAST_HOLEY_ELEMENTS: 1644 case FAST_HOLEY_ELEMENTS:
1645 case FAST_STRING_WRAPPER_ELEMENTS:
1616 CopyObjectToObjectElements(from, from_kind, from_start, to, to_kind, 1646 CopyObjectToObjectElements(from, from_kind, from_start, to, to_kind,
1617 to_start, copy_size); 1647 to_start, copy_size);
1618 break; 1648 break;
1619 case FAST_DOUBLE_ELEMENTS: 1649 case FAST_DOUBLE_ELEMENTS:
1620 case FAST_HOLEY_DOUBLE_ELEMENTS: { 1650 case FAST_HOLEY_DOUBLE_ELEMENTS: {
1621 AllowHeapAllocation allow_allocation; 1651 AllowHeapAllocation allow_allocation;
1622 DCHECK(IsFastObjectElementsKind(to_kind)); 1652 DCHECK(IsFastObjectElementsKind(to_kind));
1623 CopyDoubleToObjectElements(from, from_start, to, to_start, copy_size); 1653 CopyDoubleToObjectElements(from, from_start, to, to_start, copy_size);
1624 break; 1654 break;
1625 } 1655 }
1626 case DICTIONARY_ELEMENTS: 1656 case DICTIONARY_ELEMENTS:
1657 case SLOW_STRING_WRAPPER_ELEMENTS:
1627 CopyDictionaryToObjectElements(from, from_start, to, to_kind, to_start, 1658 CopyDictionaryToObjectElements(from, from_start, to, to_kind, to_start,
1628 copy_size); 1659 copy_size);
1629 break; 1660 break;
1630 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: 1661 case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
1631 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: 1662 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
1632 UNREACHABLE(); 1663 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) case TYPE##_ELEMENTS:
1633 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
1634 case TYPE##_ELEMENTS: \
1635 UNREACHABLE();
1636 TYPED_ARRAYS(TYPED_ARRAY_CASE) 1664 TYPED_ARRAYS(TYPED_ARRAY_CASE)
1637 #undef TYPED_ARRAY_CASE 1665 #undef TYPED_ARRAY_CASE
1666 // This function is currently only used for JSArrays with non-zero
1667 // length.
1668 UNREACHABLE();
1669 break;
1670 case NO_ELEMENTS:
1671 break; // Nothing to do.
1638 } 1672 }
1639 } 1673 }
1640 }; 1674 };
1641 1675
1642 1676
1643 class FastPackedSmiElementsAccessor 1677 class FastPackedSmiElementsAccessor
1644 : public FastSmiOrObjectElementsAccessor< 1678 : public FastSmiOrObjectElementsAccessor<
1645 FastPackedSmiElementsAccessor, 1679 FastPackedSmiElementsAccessor,
1646 ElementsKindTraits<FAST_SMI_ELEMENTS> > { 1680 ElementsKindTraits<FAST_SMI_ELEMENTS> > {
1647 public: 1681 public:
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1690 1724
1691 template<typename FastElementsAccessorSubclass, 1725 template<typename FastElementsAccessorSubclass,
1692 typename KindTraits> 1726 typename KindTraits>
1693 class FastDoubleElementsAccessor 1727 class FastDoubleElementsAccessor
1694 : public FastElementsAccessor<FastElementsAccessorSubclass, KindTraits> { 1728 : public FastElementsAccessor<FastElementsAccessorSubclass, KindTraits> {
1695 public: 1729 public:
1696 explicit FastDoubleElementsAccessor(const char* name) 1730 explicit FastDoubleElementsAccessor(const char* name)
1697 : FastElementsAccessor<FastElementsAccessorSubclass, 1731 : FastElementsAccessor<FastElementsAccessorSubclass,
1698 KindTraits>(name) {} 1732 KindTraits>(name) {}
1699 1733
1734 static Handle<Object> GetImpl(Handle<JSObject> holder, uint32_t entry) {
1735 return GetImpl(holder->elements(), entry);
1736 }
1737
1738 static Handle<Object> GetImpl(FixedArrayBase* backing_store, uint32_t entry) {
1739 Isolate* isolate = backing_store->GetIsolate();
1740 return FixedDoubleArray::get(FixedDoubleArray::cast(backing_store), entry,
1741 isolate);
1742 }
1743
1744 static inline void SetImpl(Handle<JSObject> holder, uint32_t entry,
1745 Object* value) {
1746 SetImpl(holder->elements(), entry, value);
1747 }
1748
1700 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, 1749 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
1701 Object* value) { 1750 Object* value) {
1702 FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); 1751 FixedDoubleArray::cast(backing_store)->set(entry, value->Number());
1703 } 1752 }
1704 1753
1705 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, 1754 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
1706 Object* value, WriteBarrierMode mode) { 1755 Object* value, WriteBarrierMode mode) {
1707 FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); 1756 FixedDoubleArray::cast(backing_store)->set(entry, value->Number());
1708 } 1757 }
1709 1758
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1752 case FAST_ELEMENTS: 1801 case FAST_ELEMENTS:
1753 case FAST_HOLEY_ELEMENTS: 1802 case FAST_HOLEY_ELEMENTS:
1754 CopyObjectToDoubleElements(from, from_start, to, to_start, copy_size); 1803 CopyObjectToDoubleElements(from, from_start, to, to_start, copy_size);
1755 break; 1804 break;
1756 case DICTIONARY_ELEMENTS: 1805 case DICTIONARY_ELEMENTS:
1757 CopyDictionaryToDoubleElements(from, from_start, to, to_start, 1806 CopyDictionaryToDoubleElements(from, from_start, to, to_start,
1758 copy_size); 1807 copy_size);
1759 break; 1808 break;
1760 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: 1809 case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
1761 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: 1810 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
1762 UNREACHABLE(); 1811 case FAST_STRING_WRAPPER_ELEMENTS:
1763 1812 case SLOW_STRING_WRAPPER_ELEMENTS:
1764 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 1813 case NO_ELEMENTS:
1765 case TYPE##_ELEMENTS: \ 1814 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) case TYPE##_ELEMENTS:
1766 UNREACHABLE();
1767 TYPED_ARRAYS(TYPED_ARRAY_CASE) 1815 TYPED_ARRAYS(TYPED_ARRAY_CASE)
1768 #undef TYPED_ARRAY_CASE 1816 #undef TYPED_ARRAY_CASE
1817 // This function is currently only used for JSArrays with non-zero
1818 // length.
1819 UNREACHABLE();
1820 break;
1769 } 1821 }
1770 } 1822 }
1771 }; 1823 };
1772 1824
1773 1825
1774 class FastPackedDoubleElementsAccessor 1826 class FastPackedDoubleElementsAccessor
1775 : public FastDoubleElementsAccessor< 1827 : public FastDoubleElementsAccessor<
1776 FastPackedDoubleElementsAccessor, 1828 FastPackedDoubleElementsAccessor,
1777 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> > { 1829 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> > {
1778 public: 1830 public:
(...skipping 22 matching lines...) Expand all
1801 : public ElementsAccessorBase<TypedElementsAccessor<Kind>, 1853 : public ElementsAccessorBase<TypedElementsAccessor<Kind>,
1802 ElementsKindTraits<Kind> > { 1854 ElementsKindTraits<Kind> > {
1803 public: 1855 public:
1804 explicit TypedElementsAccessor(const char* name) 1856 explicit TypedElementsAccessor(const char* name)
1805 : ElementsAccessorBase<AccessorClass, 1857 : ElementsAccessorBase<AccessorClass,
1806 ElementsKindTraits<Kind> >(name) {} 1858 ElementsKindTraits<Kind> >(name) {}
1807 1859
1808 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; 1860 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore;
1809 typedef TypedElementsAccessor<Kind> AccessorClass; 1861 typedef TypedElementsAccessor<Kind> AccessorClass;
1810 1862
1863 static inline void SetImpl(Handle<JSObject> holder, uint32_t entry,
1864 Object* value) {
1865 SetImpl(holder->elements(), entry, value);
1866 }
1867
1811 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, 1868 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
1812 Object* value) { 1869 Object* value) {
1813 BackingStore::cast(backing_store)->SetValue(entry, value); 1870 BackingStore::cast(backing_store)->SetValue(entry, value);
1814 } 1871 }
1815 1872
1816 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, 1873 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
1817 Object* value, WriteBarrierMode mode) { 1874 Object* value, WriteBarrierMode mode) {
1818 BackingStore::cast(backing_store)->SetValue(entry, value); 1875 BackingStore::cast(backing_store)->SetValue(entry, value);
1819 } 1876 }
1820 1877
1821 static Handle<Object> GetImpl(Handle<FixedArrayBase> backing_store, 1878 static Handle<Object> GetImpl(Handle<JSObject> holder, uint32_t entry) {
1822 uint32_t entry) { 1879 return GetImpl(holder->elements(), entry);
1823 uint32_t index = GetIndexForEntryImpl(*backing_store, entry); 1880 }
1824 return BackingStore::get(Handle<BackingStore>::cast(backing_store), index); 1881
1882 static Handle<Object> GetImpl(FixedArrayBase* backing_store, uint32_t entry) {
1883 return BackingStore::get(BackingStore::cast(backing_store), entry);
1884 }
1885
1886 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) {
1887 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell);
1825 } 1888 }
1826 1889
1827 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 1890 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
1828 uint32_t entry) { 1891 uint32_t entry) {
1829 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell); 1892 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell);
1830 } 1893 }
1831 1894
1895 static bool HasElementImpl(Handle<JSObject> holder, uint32_t index,
1896 Handle<FixedArrayBase> backing_store,
1897 PropertyFilter filter) {
1898 return index < AccessorClass::GetCapacityImpl(*holder, *backing_store);
1899 }
1900
1832 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, 1901 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array,
1833 uint32_t length, 1902 uint32_t length,
1834 Handle<FixedArrayBase> backing_store) { 1903 Handle<FixedArrayBase> backing_store) {
1835 // External arrays do not support changing their length. 1904 // External arrays do not support changing their length.
1836 UNREACHABLE(); 1905 UNREACHABLE();
1837 } 1906 }
1838 1907
1839 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { 1908 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) {
1840 UNREACHABLE(); 1909 UNREACHABLE();
1841 } 1910 }
(...skipping 10 matching lines...) Expand all
1852 ? index 1921 ? index
1853 : kMaxUInt32; 1922 : kMaxUInt32;
1854 } 1923 }
1855 1924
1856 static uint32_t GetCapacityImpl(JSObject* holder, 1925 static uint32_t GetCapacityImpl(JSObject* holder,
1857 FixedArrayBase* backing_store) { 1926 FixedArrayBase* backing_store) {
1858 JSArrayBufferView* view = JSArrayBufferView::cast(holder); 1927 JSArrayBufferView* view = JSArrayBufferView::cast(holder);
1859 if (view->WasNeutered()) return 0; 1928 if (view->WasNeutered()) return 0;
1860 return backing_store->length(); 1929 return backing_store->length();
1861 } 1930 }
1931
1932 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
1933 KeyAccumulator* accumulator,
1934 AddKeyConversion convert) {
1935 Handle<FixedArrayBase> elements(receiver->elements(),
1936 receiver->GetIsolate());
1937 uint32_t length = AccessorClass::GetCapacityImpl(*receiver, *elements);
1938 for (uint32_t i = 0; i < length; i++) {
1939 Handle<Object> value = AccessorClass::GetImpl(*elements, i);
1940 accumulator->AddKey(value, convert);
1941 }
1942 }
1862 }; 1943 };
1863 1944
1864 1945
1865 1946
1866 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ 1947 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \
1867 typedef TypedElementsAccessor<TYPE##_ELEMENTS > \ 1948 typedef TypedElementsAccessor<TYPE##_ELEMENTS > \
1868 Fixed##Type##ElementsAccessor; 1949 Fixed##Type##ElementsAccessor;
1869 1950
1870 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) 1951 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR)
1871 #undef FIXED_ELEMENTS_ACCESSOR 1952 #undef FIXED_ELEMENTS_ACCESSOR
1872 1953
1873 1954
1874 template <typename SloppyArgumentsElementsAccessorSubclass, 1955 template <typename SloppyArgumentsElementsAccessorSubclass,
1875 typename ArgumentsAccessor, typename KindTraits> 1956 typename ArgumentsAccessor, typename KindTraits>
1876 class SloppyArgumentsElementsAccessor 1957 class SloppyArgumentsElementsAccessor
1877 : public ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass, 1958 : public ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
1878 KindTraits> { 1959 KindTraits> {
1879 public: 1960 public:
1880 explicit SloppyArgumentsElementsAccessor(const char* name) 1961 explicit SloppyArgumentsElementsAccessor(const char* name)
1881 : ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass, 1962 : ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
1882 KindTraits>(name) { 1963 KindTraits>(name) {
1883 USE(KindTraits::Kind); 1964 USE(KindTraits::Kind);
1884 } 1965 }
1885 1966
1886 static Handle<Object> GetImpl(Handle<FixedArrayBase> parameters, 1967 static Handle<Object> GetImpl(Handle<JSObject> holder, uint32_t entry) {
1887 uint32_t entry) { 1968 return GetImpl(holder->elements(), entry);
1969 }
1970
1971 static Handle<Object> GetImpl(FixedArrayBase* parameters, uint32_t entry) {
1888 Isolate* isolate = parameters->GetIsolate(); 1972 Isolate* isolate = parameters->GetIsolate();
1889 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); 1973 Handle<FixedArray> parameter_map(FixedArray::cast(parameters), isolate);
1890 uint32_t length = parameter_map->length() - 2; 1974 uint32_t length = parameter_map->length() - 2;
1891 if (entry < length) { 1975 if (entry < length) {
1892 DisallowHeapAllocation no_gc; 1976 DisallowHeapAllocation no_gc;
1893 Object* probe = parameter_map->get(entry + 2); 1977 Object* probe = parameter_map->get(entry + 2);
1894 Context* context = Context::cast(parameter_map->get(0)); 1978 Context* context = Context::cast(parameter_map->get(0));
1895 int context_entry = Smi::cast(probe)->value(); 1979 int context_entry = Smi::cast(probe)->value();
1896 DCHECK(!context->get(context_entry)->IsTheHole()); 1980 DCHECK(!context->get(context_entry)->IsTheHole());
1897 return handle(context->get(context_entry), isolate); 1981 return handle(context->get(context_entry), isolate);
1898 } else { 1982 } else {
1899 // Object is not mapped, defer to the arguments. 1983 // Object is not mapped, defer to the arguments.
1900 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)), 1984 Handle<Object> result = ArgumentsAccessor::GetImpl(
1901 isolate); 1985 FixedArray::cast(parameter_map->get(1)), entry - length);
1902 Handle<Object> result =
1903 ArgumentsAccessor::GetImpl(arguments, entry - length);
1904 // Elements of the arguments object in slow mode might be slow aliases. 1986 // Elements of the arguments object in slow mode might be slow aliases.
1905 if (result->IsAliasedArgumentsEntry()) { 1987 if (result->IsAliasedArgumentsEntry()) {
1906 DisallowHeapAllocation no_gc; 1988 DisallowHeapAllocation no_gc;
1907 AliasedArgumentsEntry* alias = AliasedArgumentsEntry::cast(*result); 1989 AliasedArgumentsEntry* alias = AliasedArgumentsEntry::cast(*result);
1908 Context* context = Context::cast(parameter_map->get(0)); 1990 Context* context = Context::cast(parameter_map->get(0));
1909 int context_entry = alias->aliased_context_slot(); 1991 int context_entry = alias->aliased_context_slot();
1910 DCHECK(!context->get(context_entry)->IsTheHole()); 1992 DCHECK(!context->get(context_entry)->IsTheHole());
1911 return handle(context->get(context_entry), isolate); 1993 return handle(context->get(context_entry), isolate);
1912 } 1994 }
1913 return result; 1995 return result;
1914 } 1996 }
1915 } 1997 }
1916 1998
1917 static void GrowCapacityAndConvertImpl(Handle<JSObject> object, 1999 static void GrowCapacityAndConvertImpl(Handle<JSObject> object,
1918 uint32_t capacity) { 2000 uint32_t capacity) {
1919 UNREACHABLE(); 2001 UNREACHABLE();
1920 } 2002 }
1921 2003
2004 static inline void SetImpl(Handle<JSObject> holder, uint32_t entry,
2005 Object* value) {
2006 SetImpl(holder->elements(), entry, value);
2007 }
2008
1922 static inline void SetImpl(FixedArrayBase* store, uint32_t entry, 2009 static inline void SetImpl(FixedArrayBase* store, uint32_t entry,
1923 Object* value) { 2010 Object* value) {
1924 FixedArray* parameter_map = FixedArray::cast(store); 2011 FixedArray* parameter_map = FixedArray::cast(store);
1925 uint32_t length = parameter_map->length() - 2; 2012 uint32_t length = parameter_map->length() - 2;
1926 if (entry < length) { 2013 if (entry < length) {
1927 Object* probe = parameter_map->get(entry + 2); 2014 Object* probe = parameter_map->get(entry + 2);
1928 Context* context = Context::cast(parameter_map->get(0)); 2015 Context* context = Context::cast(parameter_map->get(0));
1929 int context_entry = Smi::cast(probe)->value(); 2016 int context_entry = Smi::cast(probe)->value();
1930 DCHECK(!context->get(context_entry)->IsTheHole()); 2017 DCHECK(!context->get(context_entry)->IsTheHole());
1931 context->set(context_entry, value); 2018 context->set(context_entry, value);
(...skipping 20 matching lines...) Expand all
1952 } 2039 }
1953 2040
1954 static uint32_t GetCapacityImpl(JSObject* holder, 2041 static uint32_t GetCapacityImpl(JSObject* holder,
1955 FixedArrayBase* backing_store) { 2042 FixedArrayBase* backing_store) {
1956 FixedArray* parameter_map = FixedArray::cast(backing_store); 2043 FixedArray* parameter_map = FixedArray::cast(backing_store);
1957 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 2044 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
1958 return parameter_map->length() - 2 + 2045 return parameter_map->length() - 2 +
1959 ArgumentsAccessor::GetCapacityImpl(holder, arguments); 2046 ArgumentsAccessor::GetCapacityImpl(holder, arguments);
1960 } 2047 }
1961 2048
2049 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
2050 KeyAccumulator* accumulator,
2051 AddKeyConversion convert) {
2052 FixedArrayBase* elements = receiver->elements();
2053 uint32_t length = GetCapacityImpl(*receiver, elements);
2054 for (uint32_t entry = 0; entry < length; entry++) {
2055 if (!HasEntryImpl(elements, entry)) continue;
2056 Handle<Object> value = GetImpl(elements, entry);
2057 accumulator->AddKey(value, convert);
2058 }
2059 }
2060
1962 static bool HasEntryImpl(FixedArrayBase* parameters, uint32_t entry) { 2061 static bool HasEntryImpl(FixedArrayBase* parameters, uint32_t entry) {
1963 FixedArray* parameter_map = FixedArray::cast(parameters); 2062 FixedArray* parameter_map = FixedArray::cast(parameters);
1964 uint32_t length = parameter_map->length() - 2; 2063 uint32_t length = parameter_map->length() - 2;
1965 if (entry < length) { 2064 if (entry < length) {
1966 return !GetParameterMapArg(parameter_map, entry)->IsTheHole(); 2065 return !GetParameterMapArg(parameter_map, entry)->IsTheHole();
1967 } 2066 }
1968 2067
1969 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 2068 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
1970 return ArgumentsAccessor::HasEntryImpl(arguments, entry - length); 2069 return ArgumentsAccessor::HasEntryImpl(arguments, entry - length);
1971 } 2070 }
(...skipping 15 matching lines...) Expand all
1987 Object* probe = GetParameterMapArg(parameter_map, index); 2086 Object* probe = GetParameterMapArg(parameter_map, index);
1988 if (!probe->IsTheHole()) return index; 2087 if (!probe->IsTheHole()) return index;
1989 2088
1990 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 2089 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1991 uint32_t entry = ArgumentsAccessor::GetEntryForIndexImpl(holder, arguments, 2090 uint32_t entry = ArgumentsAccessor::GetEntryForIndexImpl(holder, arguments,
1992 index, filter); 2091 index, filter);
1993 if (entry == kMaxUInt32) return entry; 2092 if (entry == kMaxUInt32) return entry;
1994 return (parameter_map->length() - 2) + entry; 2093 return (parameter_map->length() - 2) + entry;
1995 } 2094 }
1996 2095
1997 static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters, 2096 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) {
1998 uint32_t entry) { 2097 FixedArray* parameter_map = FixedArray::cast(holder->elements());
1999 FixedArray* parameter_map = FixedArray::cast(parameters);
2000 uint32_t length = parameter_map->length() - 2; 2098 uint32_t length = parameter_map->length() - 2;
2001 if (entry < length) { 2099 if (entry < length) {
2002 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); 2100 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
2003 } 2101 }
2004 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 2102 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
2005 return ArgumentsAccessor::GetDetailsImpl(arguments, entry - length); 2103 return ArgumentsAccessor::GetDetailsImpl(arguments, entry - length);
2006 } 2104 }
2007 2105
2008 static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t index) { 2106 static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t index) {
2009 uint32_t length = parameter_map->length() - 2; 2107 uint32_t length = parameter_map->length() - 2;
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
2194 Handle<FixedArrayBase> elements = 2292 Handle<FixedArrayBase> elements =
2195 ConvertElementsWithCapacity(object, old_elements, from_kind, capacity); 2293 ConvertElementsWithCapacity(object, old_elements, from_kind, capacity);
2196 Handle<Map> new_map = JSObject::GetElementsTransitionMap( 2294 Handle<Map> new_map = JSObject::GetElementsTransitionMap(
2197 object, FAST_SLOPPY_ARGUMENTS_ELEMENTS); 2295 object, FAST_SLOPPY_ARGUMENTS_ELEMENTS);
2198 JSObject::MigrateToMap(object, new_map); 2296 JSObject::MigrateToMap(object, new_map);
2199 parameter_map->set(1, *elements); 2297 parameter_map->set(1, *elements);
2200 JSObject::ValidateElements(object); 2298 JSObject::ValidateElements(object);
2201 } 2299 }
2202 }; 2300 };
2203 2301
2302 template <typename StringWrapperElementsAccessorSubclass,
2303 typename BackingStoreAccessor, typename KindTraits>
2304 class StringWrapperElementsAccessor
2305 : public ElementsAccessorBase<StringWrapperElementsAccessorSubclass,
2306 KindTraits> {
2307 public:
2308 explicit StringWrapperElementsAccessor(const char* name)
2309 : ElementsAccessorBase<StringWrapperElementsAccessorSubclass, KindTraits>(
2310 name) {
2311 USE(KindTraits::Kind);
2312 }
2313
2314 static Handle<Object> GetImpl(Handle<JSObject> holder, uint32_t entry) {
2315 Isolate* isolate = holder->GetIsolate();
2316 Handle<String> string(GetString(*holder), isolate);
2317 uint32_t length = static_cast<uint32_t>(string->length());
2318 if (entry < length) {
2319 return isolate->factory()->LookupSingleCharacterStringFromCode(
2320 String::Flatten(string)->Get(entry));
2321 }
2322 return BackingStoreAccessor::GetImpl(holder, entry - length);
2323 }
2324
2325 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) {
2326 uint32_t length = static_cast<uint32_t>(GetString(holder)->length());
2327 if (entry < length) {
2328 PropertyAttributes attributes =
2329 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
2330 return PropertyDetails(attributes, v8::internal::DATA, 0,
2331 PropertyCellType::kNoCell);
2332 }
2333 return BackingStoreAccessor::GetDetailsImpl(holder, entry - length);
2334 }
2335
2336 static uint32_t GetEntryForIndexImpl(JSObject* holder,
2337 FixedArrayBase* backing_store,
2338 uint32_t index, PropertyFilter filter) {
2339 uint32_t length = static_cast<uint32_t>(GetString(holder)->length());
2340 if (index < length) return index;
2341 uint32_t backing_store_entry = BackingStoreAccessor::GetEntryForIndexImpl(
2342 holder, backing_store, index, filter);
2343 if (backing_store_entry == kMaxUInt32) return kMaxUInt32;
2344 DCHECK(backing_store_entry < kMaxUInt32 - length);
2345 return backing_store_entry + length;
2346 }
2347
2348 static void DeleteImpl(Handle<JSObject> holder, uint32_t entry) {
2349 uint32_t length = static_cast<uint32_t>(GetString(*holder)->length());
2350 if (entry < length) {
2351 return; // String contents can't be deleted.
2352 }
2353 BackingStoreAccessor::DeleteImpl(holder, entry - length);
2354 }
2355
2356 static void SetImpl(Handle<JSObject> holder, uint32_t entry, Object* value) {
2357 uint32_t length = static_cast<uint32_t>(GetString(*holder)->length());
2358 if (entry < length) {
2359 return; // String contents are read-only.
2360 }
2361 BackingStoreAccessor::SetImpl(holder->elements(), entry - length, value);
2362 }
2363
2364 static void AddImpl(Handle<JSObject> object, uint32_t index,
2365 Handle<Object> value, PropertyAttributes attributes,
2366 uint32_t new_capacity) {
2367 DCHECK(index >= static_cast<uint32_t>(GetString(*object)->length()));
2368 if ((KindTraits::Kind == FAST_STRING_WRAPPER_ELEMENTS &&
2369 object->GetElementsKind() == SLOW_STRING_WRAPPER_ELEMENTS) ||
2370 BackingStoreAccessor::GetCapacityImpl(*object, object->elements()) !=
2371 new_capacity) {
2372 StringWrapperElementsAccessorSubclass::GrowCapacityAndConvertImpl(
2373 object, new_capacity);
2374 }
2375 BackingStoreAccessor::AddImpl(object, index, value, attributes,
2376 new_capacity);
2377 }
2378
2379 static void ReconfigureImpl(Handle<JSObject> object,
2380 Handle<FixedArrayBase> store, uint32_t entry,
2381 Handle<Object> value,
2382 PropertyAttributes attributes) {
2383 uint32_t length = static_cast<uint32_t>(GetString(*object)->length());
2384 if (entry < length) {
2385 return; // String contents can't be reconfigured.
2386 }
2387 BackingStoreAccessor::ReconfigureImpl(object, store, entry - length, value,
2388 attributes);
2389 }
2390
2391 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
2392 KeyAccumulator* accumulator,
2393 AddKeyConversion convert) {
2394 Isolate* isolate = receiver->GetIsolate();
2395 Handle<String> string(GetString(*receiver), isolate);
2396 string = String::Flatten(string);
2397 uint32_t length = static_cast<uint32_t>(string->length());
2398 for (uint32_t i = 0; i < length; i++) {
2399 accumulator->AddKey(
2400 isolate->factory()->LookupSingleCharacterStringFromCode(
2401 string->Get(i)),
2402 convert);
2403 }
2404 BackingStoreAccessor::AddElementsToKeyAccumulatorImpl(receiver, accumulator,
2405 convert);
2406 }
2407
2408 static void CollectElementIndicesImpl(Handle<JSObject> object,
2409 Handle<FixedArrayBase> backing_store,
2410 KeyAccumulator* keys, uint32_t range,
2411 PropertyFilter filter,
2412 uint32_t offset) {
2413 if ((filter & ONLY_ALL_CAN_READ) == 0) {
2414 uint32_t length = GetString(*object)->length();
2415 for (uint32_t i = 0; i < length; i++) {
2416 keys->AddKey(i);
2417 }
2418 }
2419 BackingStoreAccessor::CollectElementIndicesImpl(object, backing_store, keys,
2420 range, filter, offset);
2421 }
2422
2423 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
2424 FixedArrayBase* to, ElementsKind from_kind,
2425 uint32_t to_start, int packed_size,
2426 int copy_size) {
2427 BackingStoreAccessor::CopyElementsImpl(from, from_start, to, from_kind,
2428 to_start, packed_size, copy_size);
2429 }
2430
2431 private:
2432 static String* GetString(JSObject* holder) {
2433 DCHECK(holder->IsJSValue());
2434 JSValue* js_value = JSValue::cast(holder);
2435 DCHECK(js_value->value()->IsString());
2436 return String::cast(js_value->value());
2437 }
2438 };
2439
2440 class FastStringWrapperElementsAccessor
2441 : public StringWrapperElementsAccessor<
2442 FastStringWrapperElementsAccessor, FastHoleyObjectElementsAccessor,
2443 ElementsKindTraits<FAST_STRING_WRAPPER_ELEMENTS>> {
2444 public:
2445 explicit FastStringWrapperElementsAccessor(const char* name)
2446 : StringWrapperElementsAccessor<
2447 FastStringWrapperElementsAccessor, FastHoleyObjectElementsAccessor,
2448 ElementsKindTraits<FAST_STRING_WRAPPER_ELEMENTS>>(name) {}
2449 };
2450
2451 class SlowStringWrapperElementsAccessor
2452 : public StringWrapperElementsAccessor<
2453 SlowStringWrapperElementsAccessor, DictionaryElementsAccessor,
2454 ElementsKindTraits<SLOW_STRING_WRAPPER_ELEMENTS>> {
2455 public:
2456 explicit SlowStringWrapperElementsAccessor(const char* name)
2457 : StringWrapperElementsAccessor<
2458 SlowStringWrapperElementsAccessor, DictionaryElementsAccessor,
2459 ElementsKindTraits<SLOW_STRING_WRAPPER_ELEMENTS>>(name) {}
2460 };
2204 2461
2205 } // namespace 2462 } // namespace
2206 2463
2207 2464
2208 void CheckArrayAbuse(Handle<JSObject> obj, const char* op, uint32_t index, 2465 void CheckArrayAbuse(Handle<JSObject> obj, const char* op, uint32_t index,
2209 bool allow_appending) { 2466 bool allow_appending) {
2210 DisallowHeapAllocation no_allocation; 2467 DisallowHeapAllocation no_allocation;
2211 Object* raw_length = NULL; 2468 Object* raw_length = NULL;
2212 const char* elements_type = "array"; 2469 const char* elements_type = "array";
2213 if (obj->IsJSArray()) { 2470 if (obj->IsJSArray()) {
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
2415 } 2672 }
2416 } 2673 }
2417 2674
2418 DCHECK(j == result_len); 2675 DCHECK(j == result_len);
2419 return result_array; 2676 return result_array;
2420 } 2677 }
2421 2678
2422 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; 2679 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL;
2423 } // namespace internal 2680 } // namespace internal
2424 } // namespace v8 2681 } // namespace v8
OLDNEW
« no previous file with comments | « src/elements.h ('k') | src/elements-kind.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698