• 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   FAST_SLOPPY_ARGUMENTS_ELEMENTS,
34   SLOW_SLOPPY_ARGUMENTS_ELEMENTS,
35 
36   // Fixed typed arrays
37   UINT8_ELEMENTS,
38   INT8_ELEMENTS,
39   UINT16_ELEMENTS,
40   INT16_ELEMENTS,
41   UINT32_ELEMENTS,
42   INT32_ELEMENTS,
43   FLOAT32_ELEMENTS,
44   FLOAT64_ELEMENTS,
45   UINT8_CLAMPED_ELEMENTS,
46 
47   // Derived constants from ElementsKind
48   FIRST_ELEMENTS_KIND = FAST_SMI_ELEMENTS,
49   LAST_ELEMENTS_KIND = UINT8_CLAMPED_ELEMENTS,
50   FIRST_FAST_ELEMENTS_KIND = FAST_SMI_ELEMENTS,
51   LAST_FAST_ELEMENTS_KIND = FAST_HOLEY_DOUBLE_ELEMENTS,
52   FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND = UINT8_ELEMENTS,
53   LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND = UINT8_CLAMPED_ELEMENTS,
54   TERMINAL_FAST_ELEMENTS_KIND = FAST_HOLEY_ELEMENTS
55 };
56 
57 const int kElementsKindCount = LAST_ELEMENTS_KIND - FIRST_ELEMENTS_KIND + 1;
58 const int kFastElementsKindCount = LAST_FAST_ELEMENTS_KIND -
59     FIRST_FAST_ELEMENTS_KIND + 1;
60 
61 // The number to add to a packed elements kind to reach a holey elements kind
62 const int kFastElementsKindPackedToHoley =
63     FAST_HOLEY_SMI_ELEMENTS - FAST_SMI_ELEMENTS;
64 
65 int ElementsKindToShiftSize(ElementsKind elements_kind);
66 int GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind);
67 const char* ElementsKindToString(ElementsKind kind);
68 
GetInitialFastElementsKind()69 inline ElementsKind GetInitialFastElementsKind() { return FAST_SMI_ELEMENTS; }
70 
71 ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number);
72 int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind);
73 
74 ElementsKind GetNextTransitionElementsKind(ElementsKind elements_kind);
75 
IsDictionaryElementsKind(ElementsKind kind)76 inline bool IsDictionaryElementsKind(ElementsKind kind) {
77   return kind == DICTIONARY_ELEMENTS;
78 }
79 
80 
IsSloppyArgumentsElements(ElementsKind kind)81 inline bool IsSloppyArgumentsElements(ElementsKind kind) {
82   return kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS ||
83          kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS;
84 }
85 
86 
IsFixedTypedArrayElementsKind(ElementsKind kind)87 inline bool IsFixedTypedArrayElementsKind(ElementsKind kind) {
88   return kind >= FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND &&
89          kind <= LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND;
90 }
91 
92 
IsTerminalElementsKind(ElementsKind kind)93 inline bool IsTerminalElementsKind(ElementsKind kind) {
94   return kind == TERMINAL_FAST_ELEMENTS_KIND ||
95          IsFixedTypedArrayElementsKind(kind);
96 }
97 
98 
IsFastElementsKind(ElementsKind kind)99 inline bool IsFastElementsKind(ElementsKind kind) {
100   STATIC_ASSERT(FIRST_FAST_ELEMENTS_KIND == 0);
101   return kind <= FAST_HOLEY_DOUBLE_ELEMENTS;
102 }
103 
104 
IsTransitionElementsKind(ElementsKind kind)105 inline bool IsTransitionElementsKind(ElementsKind kind) {
106   return IsFastElementsKind(kind) || IsFixedTypedArrayElementsKind(kind) ||
107          kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS;
108 }
109 
110 
IsFastDoubleElementsKind(ElementsKind kind)111 inline bool IsFastDoubleElementsKind(ElementsKind kind) {
112   return kind == FAST_DOUBLE_ELEMENTS ||
113       kind == FAST_HOLEY_DOUBLE_ELEMENTS;
114 }
115 
116 
IsFixedFloatElementsKind(ElementsKind kind)117 inline bool IsFixedFloatElementsKind(ElementsKind kind) {
118   return kind == FLOAT32_ELEMENTS || kind == FLOAT64_ELEMENTS;
119 }
120 
121 
IsDoubleOrFloatElementsKind(ElementsKind kind)122 inline bool IsDoubleOrFloatElementsKind(ElementsKind kind) {
123   return IsFastDoubleElementsKind(kind) || IsFixedFloatElementsKind(kind);
124 }
125 
126 
IsFastSmiOrObjectElementsKind(ElementsKind kind)127 inline bool IsFastSmiOrObjectElementsKind(ElementsKind kind) {
128   return kind == FAST_SMI_ELEMENTS ||
129       kind == FAST_HOLEY_SMI_ELEMENTS ||
130       kind == FAST_ELEMENTS ||
131       kind == FAST_HOLEY_ELEMENTS;
132 }
133 
134 
IsFastSmiElementsKind(ElementsKind kind)135 inline bool IsFastSmiElementsKind(ElementsKind kind) {
136   return kind == FAST_SMI_ELEMENTS ||
137       kind == FAST_HOLEY_SMI_ELEMENTS;
138 }
139 
140 
IsFastObjectElementsKind(ElementsKind kind)141 inline bool IsFastObjectElementsKind(ElementsKind kind) {
142   return kind == FAST_ELEMENTS ||
143       kind == FAST_HOLEY_ELEMENTS;
144 }
145 
146 
IsFastHoleyElementsKind(ElementsKind kind)147 inline bool IsFastHoleyElementsKind(ElementsKind kind) {
148   return kind == FAST_HOLEY_SMI_ELEMENTS ||
149       kind == FAST_HOLEY_DOUBLE_ELEMENTS ||
150       kind == FAST_HOLEY_ELEMENTS;
151 }
152 
153 
IsHoleyElementsKind(ElementsKind kind)154 inline bool IsHoleyElementsKind(ElementsKind kind) {
155   return IsFastHoleyElementsKind(kind) ||
156       kind == DICTIONARY_ELEMENTS;
157 }
158 
159 
IsFastPackedElementsKind(ElementsKind kind)160 inline bool IsFastPackedElementsKind(ElementsKind kind) {
161   return kind == FAST_SMI_ELEMENTS || kind == FAST_DOUBLE_ELEMENTS ||
162          kind == FAST_ELEMENTS;
163 }
164 
165 
GetPackedElementsKind(ElementsKind holey_kind)166 inline ElementsKind GetPackedElementsKind(ElementsKind holey_kind) {
167   if (holey_kind == FAST_HOLEY_SMI_ELEMENTS) {
168     return FAST_SMI_ELEMENTS;
169   }
170   if (holey_kind == FAST_HOLEY_DOUBLE_ELEMENTS) {
171     return FAST_DOUBLE_ELEMENTS;
172   }
173   if (holey_kind == FAST_HOLEY_ELEMENTS) {
174     return FAST_ELEMENTS;
175   }
176   return holey_kind;
177 }
178 
179 
GetHoleyElementsKind(ElementsKind packed_kind)180 inline ElementsKind GetHoleyElementsKind(ElementsKind packed_kind) {
181   if (packed_kind == FAST_SMI_ELEMENTS) {
182     return FAST_HOLEY_SMI_ELEMENTS;
183   }
184   if (packed_kind == FAST_DOUBLE_ELEMENTS) {
185     return FAST_HOLEY_DOUBLE_ELEMENTS;
186   }
187   if (packed_kind == FAST_ELEMENTS) {
188     return FAST_HOLEY_ELEMENTS;
189   }
190   return packed_kind;
191 }
192 
193 
FastSmiToObjectElementsKind(ElementsKind from_kind)194 inline ElementsKind FastSmiToObjectElementsKind(ElementsKind from_kind) {
195   DCHECK(IsFastSmiElementsKind(from_kind));
196   return (from_kind == FAST_SMI_ELEMENTS)
197       ? FAST_ELEMENTS
198       : FAST_HOLEY_ELEMENTS;
199 }
200 
201 
IsSimpleMapChangeTransition(ElementsKind from_kind,ElementsKind to_kind)202 inline bool IsSimpleMapChangeTransition(ElementsKind from_kind,
203                                         ElementsKind to_kind) {
204   return (GetHoleyElementsKind(from_kind) == to_kind) ||
205       (IsFastSmiElementsKind(from_kind) &&
206        IsFastObjectElementsKind(to_kind));
207 }
208 
209 
210 bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
211                                          ElementsKind to_kind);
212 
213 
GetMoreGeneralElementsKind(ElementsKind from_kind,ElementsKind to_kind)214 inline ElementsKind GetMoreGeneralElementsKind(ElementsKind from_kind,
215                                                ElementsKind to_kind) {
216   if (IsMoreGeneralElementsKindTransition(from_kind, to_kind)) {
217     return to_kind;
218   }
219   return from_kind;
220 }
221 
222 
IsTransitionableFastElementsKind(ElementsKind from_kind)223 inline bool IsTransitionableFastElementsKind(ElementsKind from_kind) {
224   return IsFastElementsKind(from_kind) &&
225       from_kind != TERMINAL_FAST_ELEMENTS_KIND;
226 }
227 
228 
229 }  // namespace internal
230 }  // namespace v8
231 
232 #endif  // V8_ELEMENTS_KIND_H_
233