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

Side by Side Diff: src/elements.cc

Issue 1221713003: Distinguish slow from fast sloppy arguments (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 5 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/v8.h" 5 #include "src/v8.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/elements.h" 9 #include "src/elements.h"
10 #include "src/messages.h" 10 #include "src/messages.h"
(...skipping 29 matching lines...) Expand all
40 // - FixedInt8ElementsAccessor 40 // - FixedInt8ElementsAccessor
41 // - FixedUint16ElementsAccessor 41 // - FixedUint16ElementsAccessor
42 // - FixedInt16ElementsAccessor 42 // - FixedInt16ElementsAccessor
43 // - FixedUint32ElementsAccessor 43 // - FixedUint32ElementsAccessor
44 // - FixedInt32ElementsAccessor 44 // - FixedInt32ElementsAccessor
45 // - FixedFloat32ElementsAccessor 45 // - FixedFloat32ElementsAccessor
46 // - FixedFloat64ElementsAccessor 46 // - FixedFloat64ElementsAccessor
47 // - FixedUint8ClampedElementsAccessor 47 // - FixedUint8ClampedElementsAccessor
48 // - DictionaryElementsAccessor 48 // - DictionaryElementsAccessor
49 // - SloppyArgumentsElementsAccessor 49 // - SloppyArgumentsElementsAccessor
50 // - FastSloppyArgumentsElementsAccessor
51 // - SlowSloppyArgumentsElementsAccessor
50 52
51 53
52 namespace v8 { 54 namespace v8 {
53 namespace internal { 55 namespace internal {
54 56
55 57
56 static const int kPackedSizeNotKnown = -1; 58 static const int kPackedSizeNotKnown = -1;
57 59
58 60
59 // First argument in list is the accessor class, the second argument is the 61 // First argument in list is the accessor class, the second argument is the
60 // accessor ElementsKind, and the third is the backing store class. Use the 62 // accessor ElementsKind, and the third is the backing store class. Use the
61 // fast element handler for smi-only arrays. The implementation is currently 63 // fast element handler for smi-only arrays. The implementation is currently
62 // identical. Note that the order must match that of the ElementsKind enum for 64 // identical. Note that the order must match that of the ElementsKind enum for
63 // the |accessor_array[]| below to work. 65 // the |accessor_array[]| below to work.
64 #define ELEMENTS_LIST(V) \ 66 #define ELEMENTS_LIST(V) \
65 V(FastPackedSmiElementsAccessor, FAST_SMI_ELEMENTS, FixedArray) \ 67 V(FastPackedSmiElementsAccessor, FAST_SMI_ELEMENTS, FixedArray) \
66 V(FastHoleySmiElementsAccessor, FAST_HOLEY_SMI_ELEMENTS, \ 68 V(FastHoleySmiElementsAccessor, FAST_HOLEY_SMI_ELEMENTS, FixedArray) \
67 FixedArray) \ 69 V(FastPackedObjectElementsAccessor, FAST_ELEMENTS, FixedArray) \
68 V(FastPackedObjectElementsAccessor, FAST_ELEMENTS, FixedArray) \ 70 V(FastHoleyObjectElementsAccessor, FAST_HOLEY_ELEMENTS, FixedArray) \
69 V(FastHoleyObjectElementsAccessor, FAST_HOLEY_ELEMENTS, FixedArray) \ 71 V(FastPackedDoubleElementsAccessor, FAST_DOUBLE_ELEMENTS, FixedDoubleArray) \
70 V(FastPackedDoubleElementsAccessor, FAST_DOUBLE_ELEMENTS, \ 72 V(FastHoleyDoubleElementsAccessor, FAST_HOLEY_DOUBLE_ELEMENTS, \
71 FixedDoubleArray) \ 73 FixedDoubleArray) \
72 V(FastHoleyDoubleElementsAccessor, FAST_HOLEY_DOUBLE_ELEMENTS, \ 74 V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS, SeededNumberDictionary) \
73 FixedDoubleArray) \ 75 V(FastSloppyArgumentsElementsAccessor, FAST_SLOPPY_ARGUMENTS_ELEMENTS, \
74 V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS, \ 76 FixedArray) \
75 SeededNumberDictionary) \ 77 V(SlowSloppyArgumentsElementsAccessor, SLOW_SLOPPY_ARGUMENTS_ELEMENTS, \
76 V(SloppyArgumentsElementsAccessor, SLOPPY_ARGUMENTS_ELEMENTS, \ 78 FixedArray) \
77 FixedArray) \ 79 V(ExternalInt8ElementsAccessor, EXTERNAL_INT8_ELEMENTS, ExternalInt8Array) \
78 V(ExternalInt8ElementsAccessor, EXTERNAL_INT8_ELEMENTS, \ 80 V(ExternalUint8ElementsAccessor, EXTERNAL_UINT8_ELEMENTS, \
79 ExternalInt8Array) \ 81 ExternalUint8Array) \
80 V(ExternalUint8ElementsAccessor, \ 82 V(ExternalInt16ElementsAccessor, EXTERNAL_INT16_ELEMENTS, \
81 EXTERNAL_UINT8_ELEMENTS, ExternalUint8Array) \ 83 ExternalInt16Array) \
82 V(ExternalInt16ElementsAccessor, EXTERNAL_INT16_ELEMENTS, \ 84 V(ExternalUint16ElementsAccessor, EXTERNAL_UINT16_ELEMENTS, \
83 ExternalInt16Array) \ 85 ExternalUint16Array) \
84 V(ExternalUint16ElementsAccessor, \ 86 V(ExternalInt32ElementsAccessor, EXTERNAL_INT32_ELEMENTS, \
85 EXTERNAL_UINT16_ELEMENTS, ExternalUint16Array) \ 87 ExternalInt32Array) \
86 V(ExternalInt32ElementsAccessor, EXTERNAL_INT32_ELEMENTS, \ 88 V(ExternalUint32ElementsAccessor, EXTERNAL_UINT32_ELEMENTS, \
87 ExternalInt32Array) \ 89 ExternalUint32Array) \
88 V(ExternalUint32ElementsAccessor, \ 90 V(ExternalFloat32ElementsAccessor, EXTERNAL_FLOAT32_ELEMENTS, \
89 EXTERNAL_UINT32_ELEMENTS, ExternalUint32Array) \ 91 ExternalFloat32Array) \
90 V(ExternalFloat32ElementsAccessor, \ 92 V(ExternalFloat64ElementsAccessor, EXTERNAL_FLOAT64_ELEMENTS, \
91 EXTERNAL_FLOAT32_ELEMENTS, ExternalFloat32Array) \ 93 ExternalFloat64Array) \
92 V(ExternalFloat64ElementsAccessor, \ 94 V(ExternalUint8ClampedElementsAccessor, EXTERNAL_UINT8_CLAMPED_ELEMENTS, \
93 EXTERNAL_FLOAT64_ELEMENTS, ExternalFloat64Array) \ 95 ExternalUint8ClampedArray) \
94 V(ExternalUint8ClampedElementsAccessor, \ 96 V(FixedUint8ElementsAccessor, UINT8_ELEMENTS, FixedUint8Array) \
95 EXTERNAL_UINT8_CLAMPED_ELEMENTS, \ 97 V(FixedInt8ElementsAccessor, INT8_ELEMENTS, FixedInt8Array) \
96 ExternalUint8ClampedArray) \ 98 V(FixedUint16ElementsAccessor, UINT16_ELEMENTS, FixedUint16Array) \
97 V(FixedUint8ElementsAccessor, UINT8_ELEMENTS, FixedUint8Array) \ 99 V(FixedInt16ElementsAccessor, INT16_ELEMENTS, FixedInt16Array) \
98 V(FixedInt8ElementsAccessor, INT8_ELEMENTS, FixedInt8Array) \ 100 V(FixedUint32ElementsAccessor, UINT32_ELEMENTS, FixedUint32Array) \
99 V(FixedUint16ElementsAccessor, UINT16_ELEMENTS, FixedUint16Array) \ 101 V(FixedInt32ElementsAccessor, INT32_ELEMENTS, FixedInt32Array) \
100 V(FixedInt16ElementsAccessor, INT16_ELEMENTS, FixedInt16Array) \ 102 V(FixedFloat32ElementsAccessor, FLOAT32_ELEMENTS, FixedFloat32Array) \
101 V(FixedUint32ElementsAccessor, UINT32_ELEMENTS, FixedUint32Array) \ 103 V(FixedFloat64ElementsAccessor, FLOAT64_ELEMENTS, FixedFloat64Array) \
102 V(FixedInt32ElementsAccessor, INT32_ELEMENTS, FixedInt32Array) \ 104 V(FixedUint8ClampedElementsAccessor, UINT8_CLAMPED_ELEMENTS, \
103 V(FixedFloat32ElementsAccessor, FLOAT32_ELEMENTS, FixedFloat32Array) \
104 V(FixedFloat64ElementsAccessor, FLOAT64_ELEMENTS, FixedFloat64Array) \
105 V(FixedUint8ClampedElementsAccessor, UINT8_CLAMPED_ELEMENTS, \
106 FixedUint8ClampedArray) 105 FixedUint8ClampedArray)
107 106
108 107
109 template<ElementsKind Kind> class ElementsKindTraits { 108 template<ElementsKind Kind> class ElementsKindTraits {
110 public: 109 public:
111 typedef FixedArrayBase BackingStore; 110 typedef FixedArrayBase BackingStore;
112 }; 111 };
113 112
114 #define ELEMENTS_TRAITS(Class, KindParam, Store) \ 113 #define ELEMENTS_TRAITS(Class, KindParam, Store) \
115 template<> class ElementsKindTraits<KindParam> { \ 114 template<> class ElementsKindTraits<KindParam> { \
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 // } 542 // }
544 // 543 //
545 // This is an example of the Curiously Recurring Template Pattern (see 544 // This is an example of the Curiously Recurring Template Pattern (see
546 // http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). We use 545 // http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). We use
547 // CRTP to guarantee aggressive compile time optimizations (i.e. inlining and 546 // CRTP to guarantee aggressive compile time optimizations (i.e. inlining and
548 // specialization of SomeElementsAccessor methods). 547 // specialization of SomeElementsAccessor methods).
549 template <typename ElementsAccessorSubclass, 548 template <typename ElementsAccessorSubclass,
550 typename ElementsTraitsParam> 549 typename ElementsTraitsParam>
551 class ElementsAccessorBase : public ElementsAccessor { 550 class ElementsAccessorBase : public ElementsAccessor {
552 protected: 551 protected:
552 template <typename SloppyArgumentsElementsAccessorSubclass,
553 typename ArgumentsAccessor, typename KindTraits>
554 friend class SloppyArgumentsElementsAccessor;
553 explicit ElementsAccessorBase(const char* name) 555 explicit ElementsAccessorBase(const char* name)
554 : ElementsAccessor(name) { } 556 : ElementsAccessor(name) { }
555 557
556 typedef ElementsTraitsParam ElementsTraits; 558 typedef ElementsTraitsParam ElementsTraits;
557 typedef typename ElementsTraitsParam::BackingStore BackingStore; 559 typedef typename ElementsTraitsParam::BackingStore BackingStore;
558 560
559 static ElementsKind kind() { return ElementsTraits::Kind; } 561 static ElementsKind kind() { return ElementsTraits::Kind; }
560 562
561 static void ValidateContents(Handle<JSObject> holder, int length) { 563 static void ValidateContents(Handle<JSObject> holder, int length) {
562 } 564 }
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
915 virtual PropertyDetails GetDetails(FixedArrayBase* backing_store, 917 virtual PropertyDetails GetDetails(FixedArrayBase* backing_store,
916 uint32_t index) final { 918 uint32_t index) final {
917 return ElementsAccessorSubclass::GetDetailsImpl(backing_store, index); 919 return ElementsAccessorSubclass::GetDetailsImpl(backing_store, index);
918 } 920 }
919 921
920 private: 922 private:
921 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); 923 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase);
922 }; 924 };
923 925
924 926
927 class FastSloppyArgumentsElementsAccessor;
928 class FastHoleyObjectElementsAccessor;
929 template <typename SloppyArgumentsElementsAccessorSubclass,
930 typename ArgumentsAccessor, typename KindTraits>
931 class SloppyArgumentsElementsAccessor;
932
925 // Super class for all fast element arrays. 933 // Super class for all fast element arrays.
926 template<typename FastElementsAccessorSubclass, 934 template<typename FastElementsAccessorSubclass,
927 typename KindTraits> 935 typename KindTraits>
928 class FastElementsAccessor 936 class FastElementsAccessor
929 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> { 937 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> {
930 public: 938 public:
931 explicit FastElementsAccessor(const char* name) 939 explicit FastElementsAccessor(const char* name)
932 : ElementsAccessorBase<FastElementsAccessorSubclass, 940 : ElementsAccessorBase<FastElementsAccessorSubclass,
933 KindTraits>(name) {} 941 KindTraits>(name) {}
934 942
935 protected: 943 protected:
936 friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>; 944 friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>;
937 friend class SloppyArgumentsElementsAccessor; 945 friend class SloppyArgumentsElementsAccessor<
946 FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor,
947 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >;
938 948
939 typedef typename KindTraits::BackingStore BackingStore; 949 typedef typename KindTraits::BackingStore BackingStore;
940 950
941 static void DeleteCommon(Handle<JSObject> obj, uint32_t key, 951 static void DeleteCommon(Handle<JSObject> obj, uint32_t key,
942 LanguageMode language_mode) { 952 LanguageMode language_mode) {
943 DCHECK(obj->HasFastSmiOrObjectElements() || 953 DCHECK(obj->HasFastSmiOrObjectElements() ||
944 obj->HasFastDoubleElements() || 954 obj->HasFastDoubleElements() ||
945 obj->HasFastArgumentsElements()); 955 obj->HasFastArgumentsElements());
946 Isolate* isolate = obj->GetIsolate(); 956 Isolate* isolate = obj->GetIsolate();
947 Heap* heap = obj->GetHeap(); 957 Heap* heap = obj->GetHeap();
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 DCHECK(BackingStore::get(backing_store, i)->IsSmi() || 1069 DCHECK(BackingStore::get(backing_store, i)->IsSmi() ||
1060 (IsFastHoleyElementsKind(KindTraits::Kind) && 1070 (IsFastHoleyElementsKind(KindTraits::Kind) &&
1061 backing_store->is_the_hole(i))); 1071 backing_store->is_the_hole(i)));
1062 } 1072 }
1063 } 1073 }
1064 #endif 1074 #endif
1065 } 1075 }
1066 }; 1076 };
1067 1077
1068 1078
1069 static inline ElementsKind ElementsKindForArray(FixedArrayBase* array) {
1070 switch (array->map()->instance_type()) {
1071 case FIXED_ARRAY_TYPE:
1072 if (array->IsDictionary()) {
1073 return DICTIONARY_ELEMENTS;
1074 } else {
1075 return FAST_HOLEY_ELEMENTS;
1076 }
1077 case FIXED_DOUBLE_ARRAY_TYPE:
1078 return FAST_HOLEY_DOUBLE_ELEMENTS;
1079
1080 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
1081 case EXTERNAL_##TYPE##_ARRAY_TYPE: \
1082 return EXTERNAL_##TYPE##_ELEMENTS; \
1083 case FIXED_##TYPE##_ARRAY_TYPE: \
1084 return TYPE##_ELEMENTS;
1085
1086 TYPED_ARRAYS(TYPED_ARRAY_CASE)
1087 #undef TYPED_ARRAY_CASE
1088
1089 default:
1090 UNREACHABLE();
1091 }
1092 return FAST_HOLEY_ELEMENTS;
1093 }
1094
1095
1096 template<typename FastElementsAccessorSubclass, 1079 template<typename FastElementsAccessorSubclass,
1097 typename KindTraits> 1080 typename KindTraits>
1098 class FastSmiOrObjectElementsAccessor 1081 class FastSmiOrObjectElementsAccessor
1099 : public FastElementsAccessor<FastElementsAccessorSubclass, KindTraits> { 1082 : public FastElementsAccessor<FastElementsAccessorSubclass, KindTraits> {
1100 public: 1083 public:
1101 explicit FastSmiOrObjectElementsAccessor(const char* name) 1084 explicit FastSmiOrObjectElementsAccessor(const char* name)
1102 : FastElementsAccessor<FastElementsAccessorSubclass, 1085 : FastElementsAccessor<FastElementsAccessorSubclass,
1103 KindTraits>(name) {} 1086 KindTraits>(name) {}
1104 1087
1105 // NOTE: this method violates the handlified function signature convention: 1088 // NOTE: this method violates the handlified function signature convention:
(...skipping 19 matching lines...) Expand all
1125 case FAST_HOLEY_DOUBLE_ELEMENTS: { 1108 case FAST_HOLEY_DOUBLE_ELEMENTS: {
1126 AllowHeapAllocation allow_allocation; 1109 AllowHeapAllocation allow_allocation;
1127 CopyDoubleToObjectElements( 1110 CopyDoubleToObjectElements(
1128 from, from_start, to, to_kind, to_start, copy_size); 1111 from, from_start, to, to_kind, to_start, copy_size);
1129 break; 1112 break;
1130 } 1113 }
1131 case DICTIONARY_ELEMENTS: 1114 case DICTIONARY_ELEMENTS:
1132 CopyDictionaryToObjectElements(from, from_start, to, to_kind, to_start, 1115 CopyDictionaryToObjectElements(from, from_start, to, to_kind, to_start,
1133 copy_size); 1116 copy_size);
1134 break; 1117 break;
1135 case SLOPPY_ARGUMENTS_ELEMENTS: { 1118 case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
1136 // TODO(verwaest): This is a temporary hack to support extending 1119 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
1137 // SLOPPY_ARGUMENTS_ELEMENTS in GrowCapacityAndConvert. 1120 UNREACHABLE();
1138 // This case should be UNREACHABLE().
1139 FixedArray* parameter_map = FixedArray::cast(from);
1140 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
1141 ElementsKind from_kind = ElementsKindForArray(arguments);
1142 CopyElementsImpl(arguments, from_start, to, from_kind,
1143 to_start, packed_size, copy_size);
1144 break;
1145 }
1146 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 1121 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
1147 case EXTERNAL_##TYPE##_ELEMENTS: \ 1122 case EXTERNAL_##TYPE##_ELEMENTS: \
1148 case TYPE##_ELEMENTS: \ 1123 case TYPE##_ELEMENTS: \
1149 UNREACHABLE(); 1124 UNREACHABLE();
1150 TYPED_ARRAYS(TYPED_ARRAY_CASE) 1125 TYPED_ARRAYS(TYPED_ARRAY_CASE)
1151 #undef TYPED_ARRAY_CASE 1126 #undef TYPED_ARRAY_CASE
1152 } 1127 }
1153 } 1128 }
1154 }; 1129 };
1155 1130
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 CopyDoubleToDoubleElements(from, from_start, to, to_start, copy_size); 1205 CopyDoubleToDoubleElements(from, from_start, to, to_start, copy_size);
1231 break; 1206 break;
1232 case FAST_ELEMENTS: 1207 case FAST_ELEMENTS:
1233 case FAST_HOLEY_ELEMENTS: 1208 case FAST_HOLEY_ELEMENTS:
1234 CopyObjectToDoubleElements(from, from_start, to, to_start, copy_size); 1209 CopyObjectToDoubleElements(from, from_start, to, to_start, copy_size);
1235 break; 1210 break;
1236 case DICTIONARY_ELEMENTS: 1211 case DICTIONARY_ELEMENTS:
1237 CopyDictionaryToDoubleElements(from, from_start, to, to_start, 1212 CopyDictionaryToDoubleElements(from, from_start, to, to_start,
1238 copy_size); 1213 copy_size);
1239 break; 1214 break;
1240 case SLOPPY_ARGUMENTS_ELEMENTS: 1215 case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
1216 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
1241 UNREACHABLE(); 1217 UNREACHABLE();
1242 1218
1243 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 1219 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
1244 case EXTERNAL_##TYPE##_ELEMENTS: \ 1220 case EXTERNAL_##TYPE##_ELEMENTS: \
1245 case TYPE##_ELEMENTS: \ 1221 case TYPE##_ELEMENTS: \
1246 UNREACHABLE(); 1222 UNREACHABLE();
1247 TYPED_ARRAYS(TYPED_ARRAY_CASE) 1223 TYPED_ARRAYS(TYPED_ARRAY_CASE)
1248 #undef TYPED_ARRAY_CASE 1224 #undef TYPED_ARRAY_CASE
1249 } 1225 }
1250 } 1226 }
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1348 #undef EXTERNAL_ELEMENTS_ACCESSOR 1324 #undef EXTERNAL_ELEMENTS_ACCESSOR
1349 1325
1350 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ 1326 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \
1351 typedef TypedElementsAccessor<TYPE##_ELEMENTS > \ 1327 typedef TypedElementsAccessor<TYPE##_ELEMENTS > \
1352 Fixed##Type##ElementsAccessor; 1328 Fixed##Type##ElementsAccessor;
1353 1329
1354 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) 1330 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR)
1355 #undef FIXED_ELEMENTS_ACCESSOR 1331 #undef FIXED_ELEMENTS_ACCESSOR
1356 1332
1357 1333
1334 class SlowSloppyArgumentsElementsAccessor;
1335
1358 1336
1359 class DictionaryElementsAccessor 1337 class DictionaryElementsAccessor
1360 : public ElementsAccessorBase<DictionaryElementsAccessor, 1338 : public ElementsAccessorBase<DictionaryElementsAccessor,
1361 ElementsKindTraits<DICTIONARY_ELEMENTS> > { 1339 ElementsKindTraits<DICTIONARY_ELEMENTS> > {
1362 public: 1340 public:
1363 explicit DictionaryElementsAccessor(const char* name) 1341 explicit DictionaryElementsAccessor(const char* name)
1364 : ElementsAccessorBase<DictionaryElementsAccessor, 1342 : ElementsAccessorBase<DictionaryElementsAccessor,
1365 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} 1343 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {}
1366 1344
1367 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, 1345 static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1410 1388
1411 // Update the number of elements. 1389 // Update the number of elements.
1412 dict->ElementsRemoved(removed_entries); 1390 dict->ElementsRemoved(removed_entries);
1413 } 1391 }
1414 } 1392 }
1415 1393
1416 Handle<Object> length_obj = isolate->factory()->NewNumberFromUint(length); 1394 Handle<Object> length_obj = isolate->factory()->NewNumberFromUint(length);
1417 array->set_length(*length_obj); 1395 array->set_length(*length_obj);
1418 } 1396 }
1419 1397
1398 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
1399 FixedArrayBase* to, ElementsKind from_kind,
1400 uint32_t to_start, int packed_size,
1401 int copy_size) {
1402 UNREACHABLE();
1403 }
1404
1405
1406 protected:
1407 friend class ElementsAccessorBase<DictionaryElementsAccessor,
1408 ElementsKindTraits<DICTIONARY_ELEMENTS> >;
1409 friend class SlowSloppyArgumentsElementsAccessor;
1410 friend class SloppyArgumentsElementsAccessor<
1411 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
1412 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >;
1413
1420 static void DeleteCommon(Handle<JSObject> obj, uint32_t key, 1414 static void DeleteCommon(Handle<JSObject> obj, uint32_t key,
1421 LanguageMode language_mode) { 1415 LanguageMode language_mode) {
1422 Isolate* isolate = obj->GetIsolate(); 1416 Isolate* isolate = obj->GetIsolate();
1423 Handle<FixedArray> backing_store(FixedArray::cast(obj->elements()), 1417 Handle<FixedArray> backing_store(FixedArray::cast(obj->elements()),
1424 isolate); 1418 isolate);
1425 bool is_arguments = 1419 bool is_arguments = obj->HasSloppyArgumentsElements();
1426 (obj->GetElementsKind() == SLOPPY_ARGUMENTS_ELEMENTS);
1427 if (is_arguments) { 1420 if (is_arguments) {
1428 backing_store = handle(FixedArray::cast(backing_store->get(1)), isolate); 1421 backing_store = handle(FixedArray::cast(backing_store->get(1)), isolate);
1429 } 1422 }
1430 Handle<SeededNumberDictionary> dictionary = 1423 Handle<SeededNumberDictionary> dictionary =
1431 Handle<SeededNumberDictionary>::cast(backing_store); 1424 Handle<SeededNumberDictionary>::cast(backing_store);
1432 int entry = dictionary->FindEntry(key); 1425 int entry = dictionary->FindEntry(key);
1433 if (entry != SeededNumberDictionary::kNotFound) { 1426 if (entry != SeededNumberDictionary::kNotFound) {
1434 Handle<Object> result = 1427 Handle<Object> result =
1435 SeededNumberDictionary::DeleteProperty(dictionary, entry); 1428 SeededNumberDictionary::DeleteProperty(dictionary, entry);
1436 USE(result); 1429 USE(result);
1437 DCHECK(result->IsTrue()); 1430 DCHECK(result->IsTrue());
1438 Handle<FixedArray> new_elements = 1431 Handle<FixedArray> new_elements =
1439 SeededNumberDictionary::Shrink(dictionary, key); 1432 SeededNumberDictionary::Shrink(dictionary, key);
1440 1433
1441 if (is_arguments) { 1434 if (is_arguments) {
1442 FixedArray::cast(obj->elements())->set(1, *new_elements); 1435 FixedArray::cast(obj->elements())->set(1, *new_elements);
1443 } else { 1436 } else {
1444 obj->set_elements(*new_elements); 1437 obj->set_elements(*new_elements);
1445 } 1438 }
1446 } 1439 }
1447 } 1440 }
1448 1441
1449 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
1450 FixedArrayBase* to, ElementsKind from_kind,
1451 uint32_t to_start, int packed_size,
1452 int copy_size) {
1453 UNREACHABLE();
1454 }
1455
1456
1457 protected:
1458 friend class ElementsAccessorBase<DictionaryElementsAccessor,
1459 ElementsKindTraits<DICTIONARY_ELEMENTS> >;
1460
1461 virtual void Delete(Handle<JSObject> obj, uint32_t key, 1442 virtual void Delete(Handle<JSObject> obj, uint32_t key,
1462 LanguageMode language_mode) final { 1443 LanguageMode language_mode) final {
1463 DeleteCommon(obj, key, language_mode); 1444 DeleteCommon(obj, key, language_mode);
1464 } 1445 }
1465 1446
1466 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, 1447 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
1467 Handle<FixedArrayBase> store) { 1448 Handle<FixedArrayBase> store) {
1468 Handle<SeededNumberDictionary> backing_store = 1449 Handle<SeededNumberDictionary> backing_store =
1469 Handle<SeededNumberDictionary>::cast(store); 1450 Handle<SeededNumberDictionary>::cast(store);
1470 Isolate* isolate = backing_store->GetIsolate(); 1451 Isolate* isolate = backing_store->GetIsolate();
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1549 : static_cast<uint32_t>(entry); 1530 : static_cast<uint32_t>(entry);
1550 } 1531 }
1551 1532
1552 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 1533 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
1553 uint32_t index) { 1534 uint32_t index) {
1554 return SeededNumberDictionary::cast(backing_store)->DetailsAt(index); 1535 return SeededNumberDictionary::cast(backing_store)->DetailsAt(index);
1555 } 1536 }
1556 }; 1537 };
1557 1538
1558 1539
1559 class SloppyArgumentsElementsAccessor : public ElementsAccessorBase< 1540 template <typename SloppyArgumentsElementsAccessorSubclass,
1560 SloppyArgumentsElementsAccessor, 1541 typename ArgumentsAccessor, typename KindTraits>
1561 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> > { 1542 class SloppyArgumentsElementsAccessor
1543 : public ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
1544 KindTraits> {
1562 public: 1545 public:
1563 explicit SloppyArgumentsElementsAccessor(const char* name) 1546 explicit SloppyArgumentsElementsAccessor(const char* name)
1564 : ElementsAccessorBase< 1547 : ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
1565 SloppyArgumentsElementsAccessor, 1548 KindTraits>(name) {}
1566 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} 1549
1567 protected: 1550 protected:
1568 friend class ElementsAccessorBase< 1551 friend class ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
1569 SloppyArgumentsElementsAccessor, 1552 KindTraits>;
1570 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >;
1571 1553
1572 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, 1554 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
1573 Handle<FixedArrayBase> parameters) { 1555 Handle<FixedArrayBase> parameters) {
1574 Isolate* isolate = obj->GetIsolate(); 1556 Isolate* isolate = obj->GetIsolate();
1575 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); 1557 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
1576 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate); 1558 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate);
1577 if (!probe->IsTheHole()) { 1559 if (!probe->IsTheHole()) {
1578 DisallowHeapAllocation no_gc; 1560 DisallowHeapAllocation no_gc;
1579 Context* context = Context::cast(parameter_map->get(0)); 1561 Context* context = Context::cast(parameter_map->get(0));
1580 int context_index = Handle<Smi>::cast(probe)->value(); 1562 int context_index = Handle<Smi>::cast(probe)->value();
1581 DCHECK(!context->get(context_index)->IsTheHole()); 1563 DCHECK(!context->get(context_index)->IsTheHole());
1582 return handle(context->get(context_index), isolate); 1564 return handle(context->get(context_index), isolate);
1583 } else { 1565 } else {
1584 // Object is not mapped, defer to the arguments. 1566 // Object is not mapped, defer to the arguments.
1585 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)), 1567 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)),
1586 isolate); 1568 isolate);
1587 Handle<Object> result = 1569 Handle<Object> result = ArgumentsAccessor::GetImpl(obj, key, arguments);
1588 ElementsAccessor::ForArray(arguments)->Get(obj, key, arguments);
1589 // Elements of the arguments object in slow mode might be slow aliases. 1570 // Elements of the arguments object in slow mode might be slow aliases.
1590 if (result->IsAliasedArgumentsEntry()) { 1571 if (result->IsAliasedArgumentsEntry()) {
1591 DisallowHeapAllocation no_gc; 1572 DisallowHeapAllocation no_gc;
1592 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result); 1573 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result);
1593 Context* context = Context::cast(parameter_map->get(0)); 1574 Context* context = Context::cast(parameter_map->get(0));
1594 int context_index = entry->aliased_context_slot(); 1575 int context_index = entry->aliased_context_slot();
1595 DCHECK(!context->get(context_index)->IsTheHole()); 1576 DCHECK(!context->get(context_index)->IsTheHole());
1596 return handle(context->get(context_index), isolate); 1577 return handle(context->get(context_index), isolate);
1597 } else { 1578 } else {
1598 return result; 1579 return result;
1599 } 1580 }
1600 } 1581 }
1601 } 1582 }
1602 1583
1584 virtual void Delete(Handle<JSObject> obj, uint32_t key,
1585 LanguageMode language_mode) final {
1586 FixedArray* parameter_map = FixedArray::cast(obj->elements());
1587 if (!GetParameterMapArg(parameter_map, key)->IsTheHole()) {
1588 // TODO(kmillikin): We could check if this was the last aliased
1589 // parameter, and revert to normal elements in that case. That
1590 // would enable GC of the context.
1591 parameter_map->set_the_hole(key + 2);
1592 } else {
1593 ArgumentsAccessor::DeleteCommon(obj, key, language_mode);
1594 }
1595 }
1596
1603 static void GrowCapacityAndConvertImpl(Handle<JSObject> object, 1597 static void GrowCapacityAndConvertImpl(Handle<JSObject> object,
1604 uint32_t capacity) { 1598 uint32_t capacity) {
1605 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); 1599 UNREACHABLE();
1606 Handle<FixedArray> old_elements(FixedArray::cast(parameter_map->get(1)));
1607 ElementsKind from_kind = old_elements->IsDictionary() ? DICTIONARY_ELEMENTS
1608 : FAST_HOLEY_ELEMENTS;
1609 // This method should only be called if there's a reason to update the
1610 // elements.
1611 DCHECK(IsDictionaryElementsKind(from_kind) ||
1612 static_cast<uint32_t>(old_elements->length()) < capacity);
1613 Handle<FixedArrayBase> elements =
1614 ConvertElementsWithCapacity(object, old_elements, from_kind, capacity);
1615 parameter_map->set(1, *elements);
1616 JSObject::ValidateElements(object);
1617 } 1600 }
1618 1601
1619 static void SetImpl(FixedArrayBase* store, uint32_t key, Object* value) { 1602 static void SetImpl(FixedArrayBase* store, uint32_t key, Object* value) {
1620 FixedArray* parameter_map = FixedArray::cast(store); 1603 FixedArray* parameter_map = FixedArray::cast(store);
1621 Object* probe = GetParameterMapArg(parameter_map, key); 1604 Object* probe = GetParameterMapArg(parameter_map, key);
1622 if (!probe->IsTheHole()) { 1605 if (!probe->IsTheHole()) {
1623 Context* context = Context::cast(parameter_map->get(0)); 1606 Context* context = Context::cast(parameter_map->get(0));
1624 int context_index = Smi::cast(probe)->value(); 1607 int context_index = Smi::cast(probe)->value();
1625 DCHECK(!context->get(context_index)->IsTheHole()); 1608 DCHECK(!context->get(context_index)->IsTheHole());
1626 context->set(context_index, value); 1609 context->set(context_index, value);
1627 } else { 1610 } else {
1628 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1611 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1629 ElementsAccessor::ForArray(arguments)->Set(arguments, key, value); 1612 ArgumentsAccessor::SetImpl(arguments, key, value);
1630 } 1613 }
1631 } 1614 }
1632 1615
1633 static void ReconfigureImpl(Handle<JSObject> object,
1634 Handle<FixedArrayBase> store, uint32_t index,
1635 Handle<Object> value,
1636 PropertyAttributes attributes) {
1637 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(store);
1638 uint32_t length = parameter_map->length() - 2;
1639 if (index < length) {
1640 Object* probe = parameter_map->get(index + 2);
1641 DCHECK(!probe->IsTheHole());
1642 Context* context = Context::cast(parameter_map->get(0));
1643 int context_index = Smi::cast(probe)->value();
1644 DCHECK(!context->get(context_index)->IsTheHole());
1645 context->set(context_index, *value);
1646
1647 // Redefining attributes of an aliased element destroys fast aliasing.
1648 parameter_map->set_the_hole(index + 2);
1649 // For elements that are still writable we re-establish slow aliasing.
1650 if ((attributes & READ_ONLY) == 0) {
1651 Isolate* isolate = store->GetIsolate();
1652 value = isolate->factory()->NewAliasedArgumentsEntry(context_index);
1653 }
1654
1655 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
1656 Handle<SeededNumberDictionary> arguments =
1657 parameter_map->get(1)->IsSeededNumberDictionary()
1658 ? handle(SeededNumberDictionary::cast(parameter_map->get(1)))
1659 : JSObject::NormalizeElements(object);
1660 arguments = SeededNumberDictionary::AddNumberEntry(arguments, index,
1661 value, details);
1662 parameter_map->set(1, *arguments);
1663 } else {
1664 Handle<FixedArrayBase> arguments(
1665 FixedArrayBase::cast(parameter_map->get(1)));
1666 ElementsAccessor::ForArray(arguments)
1667 ->Reconfigure(object, arguments, index - length, value, attributes);
1668 }
1669 }
1670
1671 static void AddImpl(Handle<JSObject> object, uint32_t key,
1672 Handle<Object> value, PropertyAttributes attributes,
1673 uint32_t new_capacity) {
1674 DCHECK_EQ(NONE, attributes);
1675 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
1676 Handle<FixedArrayBase> old_elements(
1677 FixedArrayBase::cast(parameter_map->get(1)));
1678 if (old_elements->IsSeededNumberDictionary() ||
1679 static_cast<uint32_t>(old_elements->length()) < new_capacity) {
1680 GrowCapacityAndConvertImpl(object, new_capacity);
1681 }
1682 SetImpl(object->elements(), key, *value);
1683 }
1684
1685 static MaybeHandle<AccessorPair> GetAccessorPairImpl( 1616 static MaybeHandle<AccessorPair> GetAccessorPairImpl(
1686 Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> parameters) { 1617 Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> parameters) {
1687 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); 1618 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
1688 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), 1619 Handle<Object> probe(GetParameterMapArg(*parameter_map, key),
1689 obj->GetIsolate()); 1620 obj->GetIsolate());
1690 if (!probe->IsTheHole()) { 1621 if (!probe->IsTheHole()) {
1691 return MaybeHandle<AccessorPair>(); 1622 return MaybeHandle<AccessorPair>();
1692 } else { 1623 } else {
1693 // If not aliased, check the arguments. 1624 // If not aliased, check the arguments.
1694 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); 1625 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
1695 return ElementsAccessor::ForArray(arguments) 1626 return ArgumentsAccessor::GetAccessorPairImpl(obj, key, arguments);
1696 ->GetAccessorPair(obj, key, arguments);
1697 } 1627 }
1698 } 1628 }
1699 1629
1700 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, 1630 static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
1701 Handle<FixedArrayBase> parameter_map) { 1631 Handle<FixedArrayBase> parameter_map) {
1702 // Sloppy arguments objects are not arrays. 1632 // Sloppy arguments objects are not arrays.
1703 UNREACHABLE(); 1633 UNREACHABLE();
1704 } 1634 }
1705 1635
1706 virtual void Delete(Handle<JSObject> obj, uint32_t key,
1707 LanguageMode language_mode) final {
1708 Isolate* isolate = obj->GetIsolate();
1709 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements()));
1710 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate);
1711 if (!probe->IsTheHole()) {
1712 // TODO(kmillikin): We could check if this was the last aliased
1713 // parameter, and revert to normal elements in that case. That
1714 // would enable GC of the context.
1715 parameter_map->set_the_hole(key + 2);
1716 } else {
1717 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
1718 if (arguments->IsDictionary()) {
1719 DictionaryElementsAccessor::DeleteCommon(obj, key, language_mode);
1720 } else {
1721 // It's difficult to access the version of DeleteCommon that is declared
1722 // in the templatized super class, call the concrete implementation in
1723 // the class for the most generalized ElementsKind subclass.
1724 FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, language_mode);
1725 }
1726 }
1727 }
1728
1729 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
1730 FixedArrayBase* to, ElementsKind from_kind,
1731 uint32_t to_start, int packed_size,
1732 int copy_size) {
1733 DCHECK(!to->IsDictionary());
1734 if (from_kind == DICTIONARY_ELEMENTS) {
1735 CopyDictionaryToObjectElements(from, from_start, to, FAST_HOLEY_ELEMENTS,
1736 to_start, copy_size);
1737 } else {
1738 DCHECK_EQ(FAST_HOLEY_ELEMENTS, from_kind);
1739 CopyObjectToObjectElements(from, from_kind, from_start, to,
1740 FAST_HOLEY_ELEMENTS, to_start, copy_size);
1741 }
1742 }
1743
1744 static uint32_t GetCapacityImpl(JSObject* holder, 1636 static uint32_t GetCapacityImpl(JSObject* holder,
1745 FixedArrayBase* backing_store) { 1637 FixedArrayBase* backing_store) {
1746 FixedArray* parameter_map = FixedArray::cast(backing_store); 1638 FixedArray* parameter_map = FixedArray::cast(backing_store);
1747 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 1639 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
1748 return parameter_map->length() - 2 + 1640 return parameter_map->length() - 2 +
1749 ForArray(arguments)->GetCapacity(holder, arguments); 1641 ArgumentsAccessor::GetCapacityImpl(holder, arguments);
1750 } 1642 }
1751 1643
1752 static bool HasIndexImpl(FixedArrayBase* parameters, uint32_t index) { 1644 static bool HasIndexImpl(FixedArrayBase* parameters, uint32_t index) {
1753 FixedArray* parameter_map = FixedArray::cast(parameters); 1645 FixedArray* parameter_map = FixedArray::cast(parameters);
1754 uint32_t length = parameter_map->length() - 2; 1646 uint32_t length = parameter_map->length() - 2;
1755 if (index < length) { 1647 if (index < length) {
1756 return !GetParameterMapArg(parameter_map, index)->IsTheHole(); 1648 return !GetParameterMapArg(parameter_map, index)->IsTheHole();
1757 } 1649 }
1758 1650
1759 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 1651 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
1760 return ForArray(arguments)->HasIndex(arguments, index - length); 1652 return ArgumentsAccessor::HasIndexImpl(arguments, index - length);
1761 } 1653 }
1762 1654
1763 static uint32_t GetKeyForIndexImpl(FixedArrayBase* parameters, 1655 static uint32_t GetKeyForIndexImpl(FixedArrayBase* parameters,
1764 uint32_t index) { 1656 uint32_t index) {
1765 FixedArray* parameter_map = FixedArray::cast(parameters); 1657 FixedArray* parameter_map = FixedArray::cast(parameters);
1766 uint32_t length = parameter_map->length() - 2; 1658 uint32_t length = parameter_map->length() - 2;
1767 if (index < length) return index; 1659 if (index < length) return index;
1768 1660
1769 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1661 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1770 return ForArray(arguments)->GetKeyForIndex(arguments, index - length); 1662 return ArgumentsAccessor::GetKeyForIndexImpl(arguments, index - length);
1771 } 1663 }
1772 1664
1773 static uint32_t GetIndexForKeyImpl(JSObject* holder, 1665 static uint32_t GetIndexForKeyImpl(JSObject* holder,
1774 FixedArrayBase* parameters, uint32_t key) { 1666 FixedArrayBase* parameters, uint32_t key) {
1775 FixedArray* parameter_map = FixedArray::cast(parameters); 1667 FixedArray* parameter_map = FixedArray::cast(parameters);
1776 Object* probe = GetParameterMapArg(parameter_map, key); 1668 Object* probe = GetParameterMapArg(parameter_map, key);
1777 if (!probe->IsTheHole()) return key; 1669 if (!probe->IsTheHole()) return key;
1778 1670
1779 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1671 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1780 uint32_t index = ElementsAccessor::ForArray(arguments) 1672 uint32_t index =
1781 ->GetIndexForKey(holder, arguments, key); 1673 ArgumentsAccessor::GetIndexForKeyImpl(holder, arguments, key);
1782 if (index == kMaxUInt32) return index; 1674 if (index == kMaxUInt32) return index;
1783 return (parameter_map->length() - 2) + index; 1675 return (parameter_map->length() - 2) + index;
1784 } 1676 }
1785 1677
1786 static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters, 1678 static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters,
1787 uint32_t index) { 1679 uint32_t index) {
1788 FixedArray* parameter_map = FixedArray::cast(parameters); 1680 FixedArray* parameter_map = FixedArray::cast(parameters);
1789 uint32_t length = parameter_map->length() - 2; 1681 uint32_t length = parameter_map->length() - 2;
1790 if (index < length) { 1682 if (index < length) {
1791 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); 1683 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
1792 } 1684 }
1793 index -= length; 1685 index -= length;
1794 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1686 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1795 return ElementsAccessor::ForArray(arguments)->GetDetails(arguments, index); 1687 return ArgumentsAccessor::GetDetailsImpl(arguments, index);
1796 } 1688 }
1797 1689
1798 private:
1799 static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t key) { 1690 static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t key) {
1800 uint32_t length = parameter_map->length() - 2; 1691 uint32_t length = parameter_map->length() - 2;
1801 return key < length 1692 return key < length
1802 ? parameter_map->get(key + 2) 1693 ? parameter_map->get(key + 2)
1803 : Object::cast(parameter_map->GetHeap()->the_hole_value()); 1694 : Object::cast(parameter_map->GetHeap()->the_hole_value());
1804 } 1695 }
1805 }; 1696 };
1806 1697
1807 1698
1808 ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) { 1699 class FastSloppyArgumentsElementsAccessor
1809 return elements_accessors_[ElementsKindForArray(array)]; 1700 : public SloppyArgumentsElementsAccessor<
1810 } 1701 FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor,
1702 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> > {
1703 public:
1704 friend class SloppyArgumentsElementsAccessor<
1705 FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor,
1706 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >;
1707 friend class ElementsAccessorBase<
1708 FastSloppyArgumentsElementsAccessor,
1709 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >;
1710 explicit FastSloppyArgumentsElementsAccessor(const char* name)
1711 : SloppyArgumentsElementsAccessor<
1712 FastSloppyArgumentsElementsAccessor,
1713 FastHoleyObjectElementsAccessor,
1714 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
1715
1716 protected:
1717 static void AddImpl(Handle<JSObject> object, uint32_t key,
1718 Handle<Object> value, PropertyAttributes attributes,
1719 uint32_t new_capacity) {
1720 DCHECK_EQ(NONE, attributes);
1721 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
1722 Handle<FixedArrayBase> old_elements(
1723 FixedArrayBase::cast(parameter_map->get(1)));
1724 if (old_elements->IsSeededNumberDictionary() ||
1725 static_cast<uint32_t>(old_elements->length()) < new_capacity) {
1726 GrowCapacityAndConvertImpl(object, new_capacity);
1727 }
1728 SetImpl(object->elements(), key, *value);
1729 }
1730
1731 static void ReconfigureImpl(Handle<JSObject> object,
1732 Handle<FixedArrayBase> store, uint32_t index,
1733 Handle<Object> value,
1734 PropertyAttributes attributes) {
1735 Handle<SeededNumberDictionary> dictionary =
1736 JSObject::NormalizeElements(object);
1737 FixedArray::cast(*store)->set(1, *dictionary);
1738 uint32_t length = static_cast<uint32_t>(store->length()) - 2;
1739 if (index >= length) {
1740 index = dictionary->FindEntry(index - length) + length;
1741 }
1742 object->GetElementsAccessor()->Reconfigure(object, store, index, value,
1743 attributes);
1744 }
1745
1746 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
1747 FixedArrayBase* to, ElementsKind from_kind,
1748 uint32_t to_start, int packed_size,
1749 int copy_size) {
1750 DCHECK(!to->IsDictionary());
1751 if (from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS) {
1752 CopyDictionaryToObjectElements(from, from_start, to, FAST_HOLEY_ELEMENTS,
1753 to_start, copy_size);
1754 } else {
1755 DCHECK_EQ(FAST_SLOPPY_ARGUMENTS_ELEMENTS, from_kind);
1756 CopyObjectToObjectElements(from, FAST_HOLEY_ELEMENTS, from_start, to,
1757 FAST_HOLEY_ELEMENTS, to_start, copy_size);
1758 }
1759 }
1760
1761 static void GrowCapacityAndConvertImpl(Handle<JSObject> object,
1762 uint32_t capacity) {
1763 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
1764 Handle<FixedArray> old_elements(FixedArray::cast(parameter_map->get(1)));
1765 ElementsKind from_kind = object->GetElementsKind();
1766 // This method should only be called if there's a reason to update the
1767 // elements.
1768 DCHECK(from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS ||
1769 static_cast<uint32_t>(old_elements->length()) < capacity);
1770 Handle<FixedArrayBase> elements =
1771 ConvertElementsWithCapacity(object, old_elements, from_kind, capacity);
1772 Handle<Map> new_map = JSObject::GetElementsTransitionMap(
1773 object, FAST_SLOPPY_ARGUMENTS_ELEMENTS);
1774 JSObject::MigrateToMap(object, new_map);
1775 parameter_map->set(1, *elements);
1776 JSObject::ValidateElements(object);
1777 }
1778 };
1811 1779
1812 1780
1813 ElementsAccessor* ElementsAccessor::ForArray(Handle<FixedArrayBase> array) { 1781 class SlowSloppyArgumentsElementsAccessor
1814 return ForArray(*array); 1782 : public SloppyArgumentsElementsAccessor<
1815 } 1783 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
1784 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > {
1785 public:
1786 friend class ElementsAccessorBase<
1787 SlowSloppyArgumentsElementsAccessor,
1788 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >;
1789 friend class SloppyArgumentsElementsAccessor<
1790 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
1791 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >;
1792 explicit SlowSloppyArgumentsElementsAccessor(const char* name)
1793 : SloppyArgumentsElementsAccessor<
1794 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
1795 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
1796
1797 protected:
1798 static void AddImpl(Handle<JSObject> object, uint32_t key,
1799 Handle<Object> value, PropertyAttributes attributes,
1800 uint32_t new_capacity) {
1801 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
1802 Handle<FixedArrayBase> old_elements(
1803 FixedArrayBase::cast(parameter_map->get(1)));
1804 Handle<SeededNumberDictionary> dictionary =
1805 old_elements->IsSeededNumberDictionary()
1806 ? Handle<SeededNumberDictionary>::cast(old_elements)
1807 : JSObject::NormalizeElements(object);
1808 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
1809 Handle<SeededNumberDictionary> new_dictionary =
1810 SeededNumberDictionary::AddNumberEntry(dictionary, key, value, details);
1811 if (attributes != NONE) new_dictionary->set_requires_slow_elements();
1812 if (*dictionary != *new_dictionary) {
1813 FixedArray::cast(object->elements())->set(1, *new_dictionary);
1814 }
1815 }
1816
1817 static void ReconfigureImpl(Handle<JSObject> object,
1818 Handle<FixedArrayBase> store, uint32_t index,
1819 Handle<Object> value,
1820 PropertyAttributes attributes) {
1821 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(store);
1822 uint32_t length = parameter_map->length() - 2;
1823 if (index < length) {
1824 Object* probe = parameter_map->get(index + 2);
1825 DCHECK(!probe->IsTheHole());
1826 Context* context = Context::cast(parameter_map->get(0));
1827 int context_index = Smi::cast(probe)->value();
1828 DCHECK(!context->get(context_index)->IsTheHole());
1829 context->set(context_index, *value);
1830
1831 // Redefining attributes of an aliased element destroys fast aliasing.
1832 parameter_map->set_the_hole(index + 2);
1833 // For elements that are still writable we re-establish slow aliasing.
1834 if ((attributes & READ_ONLY) == 0) {
1835 Isolate* isolate = store->GetIsolate();
1836 value = isolate->factory()->NewAliasedArgumentsEntry(context_index);
1837 }
1838
1839 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
1840 Handle<SeededNumberDictionary> arguments(
1841 SeededNumberDictionary::cast(parameter_map->get(1)));
1842 arguments = SeededNumberDictionary::AddNumberEntry(arguments, index,
1843 value, details);
1844 parameter_map->set(1, *arguments);
1845 } else {
1846 Handle<FixedArrayBase> arguments(
1847 FixedArrayBase::cast(parameter_map->get(1)));
1848 DictionaryElementsAccessor::ReconfigureImpl(
1849 object, arguments, index - length, value, attributes);
1850 }
1851 }
1852 };
1816 1853
1817 1854
1818 void ElementsAccessor::InitializeOncePerProcess() { 1855 void ElementsAccessor::InitializeOncePerProcess() {
1819 static ElementsAccessor* accessor_array[] = { 1856 static ElementsAccessor* accessor_array[] = {
1820 #define ACCESSOR_ARRAY(Class, Kind, Store) new Class(#Kind), 1857 #define ACCESSOR_ARRAY(Class, Kind, Store) new Class(#Kind),
1821 ELEMENTS_LIST(ACCESSOR_ARRAY) 1858 ELEMENTS_LIST(ACCESSOR_ARRAY)
1822 #undef ACCESSOR_ARRAY 1859 #undef ACCESSOR_ARRAY
1823 }; 1860 };
1824 1861
1825 STATIC_ASSERT((sizeof(accessor_array) / sizeof(*accessor_array)) == 1862 STATIC_ASSERT((sizeof(accessor_array) / sizeof(*accessor_array)) ==
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1969 break; 2006 break;
1970 } 2007 }
1971 2008
1972 array->set_elements(*elms); 2009 array->set_elements(*elms);
1973 array->set_length(Smi::FromInt(number_of_elements)); 2010 array->set_length(Smi::FromInt(number_of_elements));
1974 return array; 2011 return array;
1975 } 2012 }
1976 2013
1977 } // namespace internal 2014 } // namespace internal
1978 } // namespace v8 2015 } // 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