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
3 // found in the LICENSE file.
4
5 #ifndef V8_ELEMENTS_KIND_H_
6 #define V8_ELEMENTS_KIND_H_
7
8 #include "src/checks.h"
9
10 namespace v8 {
11 namespace internal {
12
13 enum ElementsKind {
14 // The "fast" kind for elements that only contain SMI values. Must be first
15 // to make it possible to efficiently check maps for this kind.
16 FAST_SMI_ELEMENTS,
17 FAST_HOLEY_SMI_ELEMENTS,
18
19 // The "fast" kind for tagged values. Must be second to make it possible to
20 // efficiently check maps for this and the FAST_SMI_ONLY_ELEMENTS kind
21 // together at once.
22 FAST_ELEMENTS,
23 FAST_HOLEY_ELEMENTS,
24
25 // The "fast" kind for unwrapped, non-tagged double values.
26 FAST_DOUBLE_ELEMENTS,
27 FAST_HOLEY_DOUBLE_ELEMENTS,
28
29 // The "slow" kind.
30 DICTIONARY_ELEMENTS,
31 SLOPPY_ARGUMENTS_ELEMENTS,
32 // The "fast" kind for external arrays
33 EXTERNAL_INT8_ELEMENTS,
34 EXTERNAL_UINT8_ELEMENTS,
35 EXTERNAL_INT16_ELEMENTS,
36 EXTERNAL_UINT16_ELEMENTS,
37 EXTERNAL_INT32_ELEMENTS,
38 EXTERNAL_UINT32_ELEMENTS,
39 EXTERNAL_FLOAT32_ELEMENTS,
40 EXTERNAL_FLOAT64_ELEMENTS,
41 EXTERNAL_UINT8_CLAMPED_ELEMENTS,
42
43 // Fixed typed arrays
44 UINT8_ELEMENTS,
45 INT8_ELEMENTS,
46 UINT16_ELEMENTS,
47 INT16_ELEMENTS,
48 UINT32_ELEMENTS,
49 INT32_ELEMENTS,
50 FLOAT32_ELEMENTS,
51 FLOAT64_ELEMENTS,
52 UINT8_CLAMPED_ELEMENTS,
53
54 // Derived constants from ElementsKind
55 FIRST_ELEMENTS_KIND = FAST_SMI_ELEMENTS,
56 LAST_ELEMENTS_KIND = UINT8_CLAMPED_ELEMENTS,
57 FIRST_FAST_ELEMENTS_KIND = FAST_SMI_ELEMENTS,
58 LAST_FAST_ELEMENTS_KIND = FAST_HOLEY_DOUBLE_ELEMENTS,
59 FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND = EXTERNAL_INT8_ELEMENTS,
60 LAST_EXTERNAL_ARRAY_ELEMENTS_KIND = EXTERNAL_UINT8_CLAMPED_ELEMENTS,
61 FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND = UINT8_ELEMENTS,
62 LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND = UINT8_CLAMPED_ELEMENTS,
63 TERMINAL_FAST_ELEMENTS_KIND = FAST_HOLEY_ELEMENTS
64 };
65
66 const int kElementsKindCount = LAST_ELEMENTS_KIND - FIRST_ELEMENTS_KIND + 1;
67 const int kFastElementsKindCount = LAST_FAST_ELEMENTS_KIND -
68 FIRST_FAST_ELEMENTS_KIND + 1;
69
70 // The number to add to a packed elements kind to reach a holey elements kind
71 const int kFastElementsKindPackedToHoley =
72 FAST_HOLEY_SMI_ELEMENTS - FAST_SMI_ELEMENTS;
73
74 int ElementsKindToShiftSize(ElementsKind elements_kind);
75 int GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind);
76 const char* ElementsKindToString(ElementsKind kind);
77
GetInitialFastElementsKind()78 inline ElementsKind GetInitialFastElementsKind() { return FAST_SMI_ELEMENTS; }
79
80 ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number);
81 int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind);
82
83 ElementsKind GetNextTransitionElementsKind(ElementsKind elements_kind);
84
IsDictionaryElementsKind(ElementsKind kind)85 inline bool IsDictionaryElementsKind(ElementsKind kind) {
86 return kind == DICTIONARY_ELEMENTS;
87 }
88
89
IsSloppyArgumentsElements(ElementsKind kind)90 inline bool IsSloppyArgumentsElements(ElementsKind kind) {
91 return kind == SLOPPY_ARGUMENTS_ELEMENTS;
92 }
93
94
IsExternalArrayElementsKind(ElementsKind kind)95 inline bool IsExternalArrayElementsKind(ElementsKind kind) {
96 return kind >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND &&
97 kind <= LAST_EXTERNAL_ARRAY_ELEMENTS_KIND;
98 }
99
100
IsTerminalElementsKind(ElementsKind kind)101 inline bool IsTerminalElementsKind(ElementsKind kind) {
102 return kind == TERMINAL_FAST_ELEMENTS_KIND ||
103 IsExternalArrayElementsKind(kind);
104 }
105
106
IsFixedTypedArrayElementsKind(ElementsKind kind)107 inline bool IsFixedTypedArrayElementsKind(ElementsKind kind) {
108 return kind >= FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND &&
109 kind <= LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND;
110 }
111
112
IsFastElementsKind(ElementsKind kind)113 inline bool IsFastElementsKind(ElementsKind kind) {
114 DCHECK(FIRST_FAST_ELEMENTS_KIND == 0);
115 return kind <= FAST_HOLEY_DOUBLE_ELEMENTS;
116 }
117
118
IsTransitionElementsKind(ElementsKind kind)119 inline bool IsTransitionElementsKind(ElementsKind kind) {
120 return IsFastElementsKind(kind) || IsFixedTypedArrayElementsKind(kind);
121 }
122
123
IsFastDoubleElementsKind(ElementsKind kind)124 inline bool IsFastDoubleElementsKind(ElementsKind kind) {
125 return kind == FAST_DOUBLE_ELEMENTS ||
126 kind == FAST_HOLEY_DOUBLE_ELEMENTS;
127 }
128
129
IsExternalFloatOrDoubleElementsKind(ElementsKind kind)130 inline bool IsExternalFloatOrDoubleElementsKind(ElementsKind kind) {
131 return kind == EXTERNAL_FLOAT64_ELEMENTS ||
132 kind == EXTERNAL_FLOAT32_ELEMENTS;
133 }
134
135
IsFixedFloatElementsKind(ElementsKind kind)136 inline bool IsFixedFloatElementsKind(ElementsKind kind) {
137 return kind == FLOAT32_ELEMENTS || kind == FLOAT64_ELEMENTS;
138 }
139
140
IsDoubleOrFloatElementsKind(ElementsKind kind)141 inline bool IsDoubleOrFloatElementsKind(ElementsKind kind) {
142 return IsFastDoubleElementsKind(kind) ||
143 IsExternalFloatOrDoubleElementsKind(kind) ||
144 IsFixedFloatElementsKind(kind);
145 }
146
147
IsFastSmiOrObjectElementsKind(ElementsKind kind)148 inline bool IsFastSmiOrObjectElementsKind(ElementsKind kind) {
149 return kind == FAST_SMI_ELEMENTS ||
150 kind == FAST_HOLEY_SMI_ELEMENTS ||
151 kind == FAST_ELEMENTS ||
152 kind == FAST_HOLEY_ELEMENTS;
153 }
154
155
IsFastSmiElementsKind(ElementsKind kind)156 inline bool IsFastSmiElementsKind(ElementsKind kind) {
157 return kind == FAST_SMI_ELEMENTS ||
158 kind == FAST_HOLEY_SMI_ELEMENTS;
159 }
160
161
IsFastObjectElementsKind(ElementsKind kind)162 inline bool IsFastObjectElementsKind(ElementsKind kind) {
163 return kind == FAST_ELEMENTS ||
164 kind == FAST_HOLEY_ELEMENTS;
165 }
166
167
IsFastHoleyElementsKind(ElementsKind kind)168 inline bool IsFastHoleyElementsKind(ElementsKind kind) {
169 return kind == FAST_HOLEY_SMI_ELEMENTS ||
170 kind == FAST_HOLEY_DOUBLE_ELEMENTS ||
171 kind == FAST_HOLEY_ELEMENTS;
172 }
173
174
IsHoleyElementsKind(ElementsKind kind)175 inline bool IsHoleyElementsKind(ElementsKind kind) {
176 return IsFastHoleyElementsKind(kind) ||
177 kind == DICTIONARY_ELEMENTS;
178 }
179
180
IsFastPackedElementsKind(ElementsKind kind)181 inline bool IsFastPackedElementsKind(ElementsKind kind) {
182 return kind == FAST_SMI_ELEMENTS ||
183 kind == FAST_DOUBLE_ELEMENTS ||
184 kind == FAST_ELEMENTS;
185 }
186
187
GetPackedElementsKind(ElementsKind holey_kind)188 inline ElementsKind GetPackedElementsKind(ElementsKind holey_kind) {
189 if (holey_kind == FAST_HOLEY_SMI_ELEMENTS) {
190 return FAST_SMI_ELEMENTS;
191 }
192 if (holey_kind == FAST_HOLEY_DOUBLE_ELEMENTS) {
193 return FAST_DOUBLE_ELEMENTS;
194 }
195 if (holey_kind == FAST_HOLEY_ELEMENTS) {
196 return FAST_ELEMENTS;
197 }
198 return holey_kind;
199 }
200
201
GetHoleyElementsKind(ElementsKind packed_kind)202 inline ElementsKind GetHoleyElementsKind(ElementsKind packed_kind) {
203 if (packed_kind == FAST_SMI_ELEMENTS) {
204 return FAST_HOLEY_SMI_ELEMENTS;
205 }
206 if (packed_kind == FAST_DOUBLE_ELEMENTS) {
207 return FAST_HOLEY_DOUBLE_ELEMENTS;
208 }
209 if (packed_kind == FAST_ELEMENTS) {
210 return FAST_HOLEY_ELEMENTS;
211 }
212 return packed_kind;
213 }
214
215
FastSmiToObjectElementsKind(ElementsKind from_kind)216 inline ElementsKind FastSmiToObjectElementsKind(ElementsKind from_kind) {
217 DCHECK(IsFastSmiElementsKind(from_kind));
218 return (from_kind == FAST_SMI_ELEMENTS)
219 ? FAST_ELEMENTS
220 : FAST_HOLEY_ELEMENTS;
221 }
222
223
IsSimpleMapChangeTransition(ElementsKind from_kind,ElementsKind to_kind)224 inline bool IsSimpleMapChangeTransition(ElementsKind from_kind,
225 ElementsKind to_kind) {
226 return (GetHoleyElementsKind(from_kind) == to_kind) ||
227 (IsFastSmiElementsKind(from_kind) &&
228 IsFastObjectElementsKind(to_kind));
229 }
230
231
232 bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
233 ElementsKind to_kind);
234
235
IsTransitionableFastElementsKind(ElementsKind from_kind)236 inline bool IsTransitionableFastElementsKind(ElementsKind from_kind) {
237 return IsFastElementsKind(from_kind) &&
238 from_kind != TERMINAL_FAST_ELEMENTS_KIND;
239 }
240
241
242 ElementsKind GetNextMoreGeneralFastElementsKind(ElementsKind elements_kind,
243 bool allow_only_packed);
244
245
CanTransitionToMoreGeneralFastElementsKind(ElementsKind elements_kind,bool allow_only_packed)246 inline bool CanTransitionToMoreGeneralFastElementsKind(
247 ElementsKind elements_kind,
248 bool allow_only_packed) {
249 return IsFastElementsKind(elements_kind) &&
250 (elements_kind != TERMINAL_FAST_ELEMENTS_KIND &&
251 (!allow_only_packed || elements_kind != FAST_ELEMENTS));
252 }
253
254
255 } } // namespace v8::internal
256
257 #endif // V8_ELEMENTS_KIND_H_
258