1// Copyright 2012 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6//     * Redistributions of source code must retain the above copyright
7//       notice, this list of conditions and the following disclaimer.
8//     * Redistributions in binary form must reproduce the above
9//       copyright notice, this list of conditions and the following
10//       disclaimer in the documentation and/or other materials provided
11//       with the distribution.
12//     * Neither the name of Google Inc. nor the names of its
13//       contributors may be used to endorse or promote products derived
14//       from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_ELEMENTS_KIND_H_
29#define V8_ELEMENTS_KIND_H_
30
31#include "v8checks.h"
32
33namespace v8 {
34namespace internal {
35
36enum ElementsKind {
37  // The "fast" kind for elements that only contain SMI values. Must be first
38  // to make it possible to efficiently check maps for this kind.
39  FAST_SMI_ELEMENTS,
40  FAST_HOLEY_SMI_ELEMENTS,
41
42  // The "fast" kind for tagged values. Must be second to make it possible to
43  // efficiently check maps for this and the FAST_SMI_ONLY_ELEMENTS kind
44  // together at once.
45  FAST_ELEMENTS,
46  FAST_HOLEY_ELEMENTS,
47
48  // The "fast" kind for unwrapped, non-tagged double values.
49  FAST_DOUBLE_ELEMENTS,
50  FAST_HOLEY_DOUBLE_ELEMENTS,
51
52  // The "slow" kind.
53  DICTIONARY_ELEMENTS,
54  NON_STRICT_ARGUMENTS_ELEMENTS,
55  // The "fast" kind for external arrays
56  EXTERNAL_BYTE_ELEMENTS,
57  EXTERNAL_UNSIGNED_BYTE_ELEMENTS,
58  EXTERNAL_SHORT_ELEMENTS,
59  EXTERNAL_UNSIGNED_SHORT_ELEMENTS,
60  EXTERNAL_INT_ELEMENTS,
61  EXTERNAL_UNSIGNED_INT_ELEMENTS,
62  EXTERNAL_FLOAT_ELEMENTS,
63  EXTERNAL_DOUBLE_ELEMENTS,
64  EXTERNAL_PIXEL_ELEMENTS,
65
66  // Derived constants from ElementsKind
67  FIRST_ELEMENTS_KIND = FAST_SMI_ELEMENTS,
68  LAST_ELEMENTS_KIND = EXTERNAL_PIXEL_ELEMENTS,
69  FIRST_FAST_ELEMENTS_KIND = FAST_SMI_ELEMENTS,
70  LAST_FAST_ELEMENTS_KIND = FAST_HOLEY_DOUBLE_ELEMENTS,
71  FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND = EXTERNAL_BYTE_ELEMENTS,
72  LAST_EXTERNAL_ARRAY_ELEMENTS_KIND = EXTERNAL_PIXEL_ELEMENTS,
73  TERMINAL_FAST_ELEMENTS_KIND = FAST_HOLEY_ELEMENTS
74};
75
76const int kElementsKindCount = LAST_ELEMENTS_KIND - FIRST_ELEMENTS_KIND + 1;
77const int kFastElementsKindCount = LAST_FAST_ELEMENTS_KIND -
78    FIRST_FAST_ELEMENTS_KIND + 1;
79
80// The number to add to a packed elements kind to reach a holey elements kind
81const int kFastElementsKindPackedToHoley =
82    FAST_HOLEY_SMI_ELEMENTS - FAST_SMI_ELEMENTS;
83
84int ElementsKindToShiftSize(ElementsKind elements_kind);
85const char* ElementsKindToString(ElementsKind kind);
86void PrintElementsKind(FILE* out, ElementsKind kind);
87
88ElementsKind GetInitialFastElementsKind();
89
90ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_index);
91
92int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind);
93
94
95inline bool IsDictionaryElementsKind(ElementsKind kind) {
96  return kind == DICTIONARY_ELEMENTS;
97}
98
99
100inline bool IsExternalArrayElementsKind(ElementsKind kind) {
101  return kind >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND &&
102      kind <= LAST_EXTERNAL_ARRAY_ELEMENTS_KIND;
103}
104
105
106inline bool IsFastElementsKind(ElementsKind kind) {
107  ASSERT(FIRST_FAST_ELEMENTS_KIND == 0);
108  return kind <= FAST_HOLEY_DOUBLE_ELEMENTS;
109}
110
111
112inline bool IsFastDoubleElementsKind(ElementsKind kind) {
113  return kind == FAST_DOUBLE_ELEMENTS ||
114      kind == FAST_HOLEY_DOUBLE_ELEMENTS;
115}
116
117
118inline bool IsExternalFloatOrDoubleElementsKind(ElementsKind kind) {
119  return kind == EXTERNAL_DOUBLE_ELEMENTS ||
120      kind == EXTERNAL_FLOAT_ELEMENTS;
121}
122
123
124inline bool IsDoubleOrFloatElementsKind(ElementsKind kind) {
125  return IsFastDoubleElementsKind(kind) ||
126      IsExternalFloatOrDoubleElementsKind(kind);
127}
128
129
130inline bool IsFastSmiOrObjectElementsKind(ElementsKind kind) {
131  return kind == FAST_SMI_ELEMENTS ||
132      kind == FAST_HOLEY_SMI_ELEMENTS ||
133      kind == FAST_ELEMENTS ||
134      kind == FAST_HOLEY_ELEMENTS;
135}
136
137
138inline bool IsFastSmiElementsKind(ElementsKind kind) {
139  return kind == FAST_SMI_ELEMENTS ||
140      kind == FAST_HOLEY_SMI_ELEMENTS;
141}
142
143
144inline bool IsFastObjectElementsKind(ElementsKind kind) {
145  return kind == FAST_ELEMENTS ||
146      kind == FAST_HOLEY_ELEMENTS;
147}
148
149
150inline bool IsFastHoleyElementsKind(ElementsKind kind) {
151  return kind == FAST_HOLEY_SMI_ELEMENTS ||
152      kind == FAST_HOLEY_DOUBLE_ELEMENTS ||
153      kind == FAST_HOLEY_ELEMENTS;
154}
155
156
157inline bool IsHoleyElementsKind(ElementsKind kind) {
158  return IsFastHoleyElementsKind(kind) ||
159      kind == DICTIONARY_ELEMENTS;
160}
161
162
163inline bool IsFastPackedElementsKind(ElementsKind kind) {
164  return kind == FAST_SMI_ELEMENTS ||
165      kind == FAST_DOUBLE_ELEMENTS ||
166      kind == FAST_ELEMENTS;
167}
168
169
170inline ElementsKind GetPackedElementsKind(ElementsKind holey_kind) {
171  if (holey_kind == FAST_HOLEY_SMI_ELEMENTS) {
172    return FAST_SMI_ELEMENTS;
173  }
174  if (holey_kind == FAST_HOLEY_DOUBLE_ELEMENTS) {
175    return FAST_DOUBLE_ELEMENTS;
176  }
177  if (holey_kind == FAST_HOLEY_ELEMENTS) {
178    return FAST_ELEMENTS;
179  }
180  return holey_kind;
181}
182
183
184inline ElementsKind GetHoleyElementsKind(ElementsKind packed_kind) {
185  if (packed_kind == FAST_SMI_ELEMENTS) {
186    return FAST_HOLEY_SMI_ELEMENTS;
187  }
188  if (packed_kind == FAST_DOUBLE_ELEMENTS) {
189    return FAST_HOLEY_DOUBLE_ELEMENTS;
190  }
191  if (packed_kind == FAST_ELEMENTS) {
192    return FAST_HOLEY_ELEMENTS;
193  }
194  return packed_kind;
195}
196
197
198inline ElementsKind FastSmiToObjectElementsKind(ElementsKind from_kind) {
199  ASSERT(IsFastSmiElementsKind(from_kind));
200  return (from_kind == FAST_SMI_ELEMENTS)
201      ? FAST_ELEMENTS
202      : FAST_HOLEY_ELEMENTS;
203}
204
205
206inline bool IsSimpleMapChangeTransition(ElementsKind from_kind,
207                                        ElementsKind to_kind) {
208  return (GetHoleyElementsKind(from_kind) == to_kind) ||
209      (IsFastSmiElementsKind(from_kind) &&
210       IsFastObjectElementsKind(to_kind));
211}
212
213
214bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
215                                         ElementsKind to_kind);
216
217
218inline bool IsTransitionableFastElementsKind(ElementsKind from_kind) {
219  return IsFastElementsKind(from_kind) &&
220      from_kind != TERMINAL_FAST_ELEMENTS_KIND;
221}
222
223
224ElementsKind GetNextMoreGeneralFastElementsKind(ElementsKind elements_kind,
225                                                bool allow_only_packed);
226
227
228inline bool CanTransitionToMoreGeneralFastElementsKind(
229    ElementsKind elements_kind,
230    bool allow_only_packed) {
231  return IsFastElementsKind(elements_kind) &&
232      (elements_kind != TERMINAL_FAST_ELEMENTS_KIND &&
233       (!allow_only_packed || elements_kind != FAST_ELEMENTS));
234}
235
236
237} }  // namespace v8::internal
238
239#endif  // V8_ELEMENTS_KIND_H_
240