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