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/v8checks.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 void PrintElementsKind(FILE* out, ElementsKind kind);
78
79 ElementsKind GetInitialFastElementsKind();
80
81 ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number);
82 int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind);
83
84 ElementsKind GetNextTransitionElementsKind(ElementsKind elements_kind);
85
IsDictionaryElementsKind(ElementsKind kind)86 inline bool IsDictionaryElementsKind(ElementsKind kind) {
87 return kind == DICTIONARY_ELEMENTS;
88 }
89
90
IsExternalArrayElementsKind(ElementsKind kind)91 inline bool IsExternalArrayElementsKind(ElementsKind kind) {
92 return kind >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND &&
93 kind <= LAST_EXTERNAL_ARRAY_ELEMENTS_KIND;
94 }
95
96
IsTerminalElementsKind(ElementsKind kind)97 inline bool IsTerminalElementsKind(ElementsKind kind) {
98 return kind == TERMINAL_FAST_ELEMENTS_KIND ||
99 IsExternalArrayElementsKind(kind);
100 }
101
102
IsFixedTypedArrayElementsKind(ElementsKind kind)103 inline bool IsFixedTypedArrayElementsKind(ElementsKind kind) {
104 return kind >= FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND &&
105 kind <= LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND;
106 }
107
108
IsFastElementsKind(ElementsKind kind)109 inline bool IsFastElementsKind(ElementsKind kind) {
110 ASSERT(FIRST_FAST_ELEMENTS_KIND == 0);
111 return kind <= FAST_HOLEY_DOUBLE_ELEMENTS;
112 }
113
114
IsTransitionElementsKind(ElementsKind kind)115 inline bool IsTransitionElementsKind(ElementsKind kind) {
116 return IsFastElementsKind(kind) || IsFixedTypedArrayElementsKind(kind);
117 }
118
119
IsFastDoubleElementsKind(ElementsKind kind)120 inline bool IsFastDoubleElementsKind(ElementsKind kind) {
121 return kind == FAST_DOUBLE_ELEMENTS ||
122 kind == FAST_HOLEY_DOUBLE_ELEMENTS;
123 }
124
125
IsExternalFloatOrDoubleElementsKind(ElementsKind kind)126 inline bool IsExternalFloatOrDoubleElementsKind(ElementsKind kind) {
127 return kind == EXTERNAL_FLOAT64_ELEMENTS ||
128 kind == EXTERNAL_FLOAT32_ELEMENTS;
129 }
130
131
IsFixedFloatElementsKind(ElementsKind kind)132 inline bool IsFixedFloatElementsKind(ElementsKind kind) {
133 return kind == FLOAT32_ELEMENTS || kind == FLOAT64_ELEMENTS;
134 }
135
136
IsDoubleOrFloatElementsKind(ElementsKind kind)137 inline bool IsDoubleOrFloatElementsKind(ElementsKind kind) {
138 return IsFastDoubleElementsKind(kind) ||
139 IsExternalFloatOrDoubleElementsKind(kind) ||
140 IsFixedFloatElementsKind(kind);
141 }
142
143
IsFastSmiOrObjectElementsKind(ElementsKind kind)144 inline bool IsFastSmiOrObjectElementsKind(ElementsKind kind) {
145 return kind == FAST_SMI_ELEMENTS ||
146 kind == FAST_HOLEY_SMI_ELEMENTS ||
147 kind == FAST_ELEMENTS ||
148 kind == FAST_HOLEY_ELEMENTS;
149 }
150
151
IsFastSmiElementsKind(ElementsKind kind)152 inline bool IsFastSmiElementsKind(ElementsKind kind) {
153 return kind == FAST_SMI_ELEMENTS ||
154 kind == FAST_HOLEY_SMI_ELEMENTS;
155 }
156
157
IsFastObjectElementsKind(ElementsKind kind)158 inline bool IsFastObjectElementsKind(ElementsKind kind) {
159 return kind == FAST_ELEMENTS ||
160 kind == FAST_HOLEY_ELEMENTS;
161 }
162
163
IsFastHoleyElementsKind(ElementsKind kind)164 inline bool IsFastHoleyElementsKind(ElementsKind kind) {
165 return kind == FAST_HOLEY_SMI_ELEMENTS ||
166 kind == FAST_HOLEY_DOUBLE_ELEMENTS ||
167 kind == FAST_HOLEY_ELEMENTS;
168 }
169
170
IsHoleyElementsKind(ElementsKind kind)171 inline bool IsHoleyElementsKind(ElementsKind kind) {
172 return IsFastHoleyElementsKind(kind) ||
173 kind == DICTIONARY_ELEMENTS;
174 }
175
176
IsFastPackedElementsKind(ElementsKind kind)177 inline bool IsFastPackedElementsKind(ElementsKind kind) {
178 return kind == FAST_SMI_ELEMENTS ||
179 kind == FAST_DOUBLE_ELEMENTS ||
180 kind == FAST_ELEMENTS;
181 }
182
183
GetPackedElementsKind(ElementsKind holey_kind)184 inline ElementsKind GetPackedElementsKind(ElementsKind holey_kind) {
185 if (holey_kind == FAST_HOLEY_SMI_ELEMENTS) {
186 return FAST_SMI_ELEMENTS;
187 }
188 if (holey_kind == FAST_HOLEY_DOUBLE_ELEMENTS) {
189 return FAST_DOUBLE_ELEMENTS;
190 }
191 if (holey_kind == FAST_HOLEY_ELEMENTS) {
192 return FAST_ELEMENTS;
193 }
194 return holey_kind;
195 }
196
197
GetHoleyElementsKind(ElementsKind packed_kind)198 inline ElementsKind GetHoleyElementsKind(ElementsKind packed_kind) {
199 if (packed_kind == FAST_SMI_ELEMENTS) {
200 return FAST_HOLEY_SMI_ELEMENTS;
201 }
202 if (packed_kind == FAST_DOUBLE_ELEMENTS) {
203 return FAST_HOLEY_DOUBLE_ELEMENTS;
204 }
205 if (packed_kind == FAST_ELEMENTS) {
206 return FAST_HOLEY_ELEMENTS;
207 }
208 return packed_kind;
209 }
210
211
FastSmiToObjectElementsKind(ElementsKind from_kind)212 inline ElementsKind FastSmiToObjectElementsKind(ElementsKind from_kind) {
213 ASSERT(IsFastSmiElementsKind(from_kind));
214 return (from_kind == FAST_SMI_ELEMENTS)
215 ? FAST_ELEMENTS
216 : FAST_HOLEY_ELEMENTS;
217 }
218
219
IsSimpleMapChangeTransition(ElementsKind from_kind,ElementsKind to_kind)220 inline bool IsSimpleMapChangeTransition(ElementsKind from_kind,
221 ElementsKind to_kind) {
222 return (GetHoleyElementsKind(from_kind) == to_kind) ||
223 (IsFastSmiElementsKind(from_kind) &&
224 IsFastObjectElementsKind(to_kind));
225 }
226
227
228 bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
229 ElementsKind to_kind);
230
231
IsTransitionableFastElementsKind(ElementsKind from_kind)232 inline bool IsTransitionableFastElementsKind(ElementsKind from_kind) {
233 return IsFastElementsKind(from_kind) &&
234 from_kind != TERMINAL_FAST_ELEMENTS_KIND;
235 }
236
237
238 ElementsKind GetNextMoreGeneralFastElementsKind(ElementsKind elements_kind,
239 bool allow_only_packed);
240
241
CanTransitionToMoreGeneralFastElementsKind(ElementsKind elements_kind,bool allow_only_packed)242 inline bool CanTransitionToMoreGeneralFastElementsKind(
243 ElementsKind elements_kind,
244 bool allow_only_packed) {
245 return IsFastElementsKind(elements_kind) &&
246 (elements_kind != TERMINAL_FAST_ELEMENTS_KIND &&
247 (!allow_only_packed || elements_kind != FAST_ELEMENTS));
248 }
249
250
251 } } // namespace v8::internal
252
253 #endif // V8_ELEMENTS_KIND_H_
254