• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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