• 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/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   // Elements kind of the "arguments" object (only in sloppy mode).
34   FAST_SLOPPY_ARGUMENTS_ELEMENTS,
35   SLOW_SLOPPY_ARGUMENTS_ELEMENTS,
36 
37   // For string wrapper objects ("new String('...')"), the string's characters
38   // are overlaid onto a regular elements backing store.
39   FAST_STRING_WRAPPER_ELEMENTS,
40   SLOW_STRING_WRAPPER_ELEMENTS,
41 
42   // Fixed typed arrays.
43   UINT8_ELEMENTS,
44   INT8_ELEMENTS,
45   UINT16_ELEMENTS,
46   INT16_ELEMENTS,
47   UINT32_ELEMENTS,
48   INT32_ELEMENTS,
49   FLOAT32_ELEMENTS,
50   FLOAT64_ELEMENTS,
51   UINT8_CLAMPED_ELEMENTS,
52 
53   // Sentinel ElementsKind for objects with no elements.
54   NO_ELEMENTS,
55 
56   // Derived constants from ElementsKind.
57   FIRST_ELEMENTS_KIND = FAST_SMI_ELEMENTS,
58   LAST_ELEMENTS_KIND = UINT8_CLAMPED_ELEMENTS,
59   FIRST_FAST_ELEMENTS_KIND = FAST_SMI_ELEMENTS,
60   LAST_FAST_ELEMENTS_KIND = FAST_HOLEY_DOUBLE_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 == FAST_SLOPPY_ARGUMENTS_ELEMENTS ||
92          kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS;
93 }
94 
IsStringWrapperElementsKind(ElementsKind kind)95 inline bool IsStringWrapperElementsKind(ElementsKind kind) {
96   return kind == FAST_STRING_WRAPPER_ELEMENTS ||
97          kind == SLOW_STRING_WRAPPER_ELEMENTS;
98 }
99 
IsFixedTypedArrayElementsKind(ElementsKind kind)100 inline bool IsFixedTypedArrayElementsKind(ElementsKind kind) {
101   return kind >= FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND &&
102          kind <= LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND;
103 }
104 
105 
IsTerminalElementsKind(ElementsKind kind)106 inline bool IsTerminalElementsKind(ElementsKind kind) {
107   return kind == TERMINAL_FAST_ELEMENTS_KIND ||
108          IsFixedTypedArrayElementsKind(kind);
109 }
110 
111 
IsFastElementsKind(ElementsKind kind)112 inline bool IsFastElementsKind(ElementsKind kind) {
113   STATIC_ASSERT(FIRST_FAST_ELEMENTS_KIND == 0);
114   return kind <= FAST_HOLEY_DOUBLE_ELEMENTS;
115 }
116 
117 
IsTransitionElementsKind(ElementsKind kind)118 inline bool IsTransitionElementsKind(ElementsKind kind) {
119   return IsFastElementsKind(kind) || IsFixedTypedArrayElementsKind(kind) ||
120          kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS ||
121          kind == FAST_STRING_WRAPPER_ELEMENTS;
122 }
123 
124 
IsFastDoubleElementsKind(ElementsKind kind)125 inline bool IsFastDoubleElementsKind(ElementsKind kind) {
126   return kind == FAST_DOUBLE_ELEMENTS ||
127       kind == FAST_HOLEY_DOUBLE_ELEMENTS;
128 }
129 
130 
IsFixedFloatElementsKind(ElementsKind kind)131 inline bool IsFixedFloatElementsKind(ElementsKind kind) {
132   return kind == FLOAT32_ELEMENTS || kind == FLOAT64_ELEMENTS;
133 }
134 
135 
IsDoubleOrFloatElementsKind(ElementsKind kind)136 inline bool IsDoubleOrFloatElementsKind(ElementsKind kind) {
137   return IsFastDoubleElementsKind(kind) || IsFixedFloatElementsKind(kind);
138 }
139 
140 
IsFastSmiOrObjectElementsKind(ElementsKind kind)141 inline bool IsFastSmiOrObjectElementsKind(ElementsKind kind) {
142   return kind == FAST_SMI_ELEMENTS ||
143       kind == FAST_HOLEY_SMI_ELEMENTS ||
144       kind == FAST_ELEMENTS ||
145       kind == FAST_HOLEY_ELEMENTS;
146 }
147 
148 
IsFastSmiElementsKind(ElementsKind kind)149 inline bool IsFastSmiElementsKind(ElementsKind kind) {
150   return kind == FAST_SMI_ELEMENTS ||
151       kind == FAST_HOLEY_SMI_ELEMENTS;
152 }
153 
154 
IsFastObjectElementsKind(ElementsKind kind)155 inline bool IsFastObjectElementsKind(ElementsKind kind) {
156   return kind == FAST_ELEMENTS ||
157       kind == FAST_HOLEY_ELEMENTS;
158 }
159 
160 
IsFastHoleyElementsKind(ElementsKind kind)161 inline bool IsFastHoleyElementsKind(ElementsKind kind) {
162   return kind == FAST_HOLEY_SMI_ELEMENTS ||
163       kind == FAST_HOLEY_DOUBLE_ELEMENTS ||
164       kind == FAST_HOLEY_ELEMENTS;
165 }
166 
167 
IsHoleyElementsKind(ElementsKind kind)168 inline bool IsHoleyElementsKind(ElementsKind kind) {
169   return IsFastHoleyElementsKind(kind) ||
170       kind == DICTIONARY_ELEMENTS;
171 }
172 
173 
IsFastPackedElementsKind(ElementsKind kind)174 inline bool IsFastPackedElementsKind(ElementsKind kind) {
175   return kind == FAST_SMI_ELEMENTS || kind == FAST_DOUBLE_ELEMENTS ||
176          kind == FAST_ELEMENTS;
177 }
178 
179 
GetPackedElementsKind(ElementsKind holey_kind)180 inline ElementsKind GetPackedElementsKind(ElementsKind holey_kind) {
181   if (holey_kind == FAST_HOLEY_SMI_ELEMENTS) {
182     return FAST_SMI_ELEMENTS;
183   }
184   if (holey_kind == FAST_HOLEY_DOUBLE_ELEMENTS) {
185     return FAST_DOUBLE_ELEMENTS;
186   }
187   if (holey_kind == FAST_HOLEY_ELEMENTS) {
188     return FAST_ELEMENTS;
189   }
190   return holey_kind;
191 }
192 
193 
GetHoleyElementsKind(ElementsKind packed_kind)194 inline ElementsKind GetHoleyElementsKind(ElementsKind packed_kind) {
195   if (packed_kind == FAST_SMI_ELEMENTS) {
196     return FAST_HOLEY_SMI_ELEMENTS;
197   }
198   if (packed_kind == FAST_DOUBLE_ELEMENTS) {
199     return FAST_HOLEY_DOUBLE_ELEMENTS;
200   }
201   if (packed_kind == FAST_ELEMENTS) {
202     return FAST_HOLEY_ELEMENTS;
203   }
204   return packed_kind;
205 }
206 
207 
FastSmiToObjectElementsKind(ElementsKind from_kind)208 inline ElementsKind FastSmiToObjectElementsKind(ElementsKind from_kind) {
209   DCHECK(IsFastSmiElementsKind(from_kind));
210   return (from_kind == FAST_SMI_ELEMENTS)
211       ? FAST_ELEMENTS
212       : FAST_HOLEY_ELEMENTS;
213 }
214 
215 
IsSimpleMapChangeTransition(ElementsKind from_kind,ElementsKind to_kind)216 inline bool IsSimpleMapChangeTransition(ElementsKind from_kind,
217                                         ElementsKind to_kind) {
218   return (GetHoleyElementsKind(from_kind) == to_kind) ||
219       (IsFastSmiElementsKind(from_kind) &&
220        IsFastObjectElementsKind(to_kind));
221 }
222 
223 
224 bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
225                                          ElementsKind to_kind);
226 
227 
GetMoreGeneralElementsKind(ElementsKind from_kind,ElementsKind to_kind)228 inline ElementsKind GetMoreGeneralElementsKind(ElementsKind from_kind,
229                                                ElementsKind to_kind) {
230   if (IsMoreGeneralElementsKindTransition(from_kind, to_kind)) {
231     return to_kind;
232   }
233   return from_kind;
234 }
235 
236 
IsTransitionableFastElementsKind(ElementsKind from_kind)237 inline bool IsTransitionableFastElementsKind(ElementsKind from_kind) {
238   return IsFastElementsKind(from_kind) &&
239       from_kind != TERMINAL_FAST_ELEMENTS_KIND;
240 }
241 
242 
243 }  // namespace internal
244 }  // namespace v8
245 
246 #endif  // V8_ELEMENTS_KIND_H_
247