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 22 matching lines...) Expand all Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |