V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
elements-kind.cc
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 #include "src/elements-kind.h"
6 
7 #include "src/base/lazy-instance.h"
8 #include "src/elements.h"
9 #include "src/objects-inl.h"
10 #include "src/objects.h"
11 
12 namespace v8 {
13 namespace internal {
14 
15 
16 int ElementsKindToShiftSize(ElementsKind elements_kind) {
17  switch (elements_kind) {
18  case UINT8_ELEMENTS:
19  case INT8_ELEMENTS:
20  case UINT8_CLAMPED_ELEMENTS:
21  return 0;
22  case UINT16_ELEMENTS:
23  case INT16_ELEMENTS:
24  return 1;
25  case UINT32_ELEMENTS:
26  case INT32_ELEMENTS:
27  case FLOAT32_ELEMENTS:
28  return 2;
29  case PACKED_DOUBLE_ELEMENTS:
30  case HOLEY_DOUBLE_ELEMENTS:
31  case FLOAT64_ELEMENTS:
32  case BIGINT64_ELEMENTS:
33  case BIGUINT64_ELEMENTS:
34  return 3;
35  case PACKED_SMI_ELEMENTS:
36  case PACKED_ELEMENTS:
37  case HOLEY_SMI_ELEMENTS:
38  case HOLEY_ELEMENTS:
39  case DICTIONARY_ELEMENTS:
40  case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
41  case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
42  case FAST_STRING_WRAPPER_ELEMENTS:
43  case SLOW_STRING_WRAPPER_ELEMENTS:
44  return kPointerSizeLog2;
45  case NO_ELEMENTS:
46  UNREACHABLE();
47  }
48  UNREACHABLE();
49 }
50 
51 int ElementsKindToByteSize(ElementsKind elements_kind) {
52  return 1 << ElementsKindToShiftSize(elements_kind);
53 }
54 
55 int GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind) {
56  STATIC_ASSERT(FixedArray::kHeaderSize == FixedDoubleArray::kHeaderSize);
57 
58  if (IsFixedTypedArrayElementsKind(elements_kind)) {
59  return 0;
60  } else {
61  return FixedArray::kHeaderSize - kHeapObjectTag;
62  }
63 }
64 
65 
66 const char* ElementsKindToString(ElementsKind kind) {
67  ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
68  return accessor->name();
69 }
70 
71 
73  static void Construct(void* fast_elements_kind_sequence_ptr_arg) {
74  auto fast_elements_kind_sequence_ptr =
75  reinterpret_cast<ElementsKind**>(fast_elements_kind_sequence_ptr_arg);
76  ElementsKind* fast_elements_kind_sequence =
77  new ElementsKind[kFastElementsKindCount];
78  *fast_elements_kind_sequence_ptr = fast_elements_kind_sequence;
79  STATIC_ASSERT(PACKED_SMI_ELEMENTS == FIRST_FAST_ELEMENTS_KIND);
80  fast_elements_kind_sequence[0] = PACKED_SMI_ELEMENTS;
81  fast_elements_kind_sequence[1] = HOLEY_SMI_ELEMENTS;
82  fast_elements_kind_sequence[2] = PACKED_DOUBLE_ELEMENTS;
83  fast_elements_kind_sequence[3] = HOLEY_DOUBLE_ELEMENTS;
84  fast_elements_kind_sequence[4] = PACKED_ELEMENTS;
85  fast_elements_kind_sequence[5] = HOLEY_ELEMENTS;
86 
87  // Verify that kFastElementsKindPackedToHoley is correct.
88  STATIC_ASSERT(PACKED_SMI_ELEMENTS + kFastElementsKindPackedToHoley ==
89  HOLEY_SMI_ELEMENTS);
90  STATIC_ASSERT(PACKED_DOUBLE_ELEMENTS + kFastElementsKindPackedToHoley ==
91  HOLEY_DOUBLE_ELEMENTS);
92  STATIC_ASSERT(PACKED_ELEMENTS + kFastElementsKindPackedToHoley ==
93  HOLEY_ELEMENTS);
94  }
95 };
96 
97 
98 static base::LazyInstance<ElementsKind*,
100  fast_elements_kind_sequence = LAZY_INSTANCE_INITIALIZER;
101 
102 
103 ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number) {
104  DCHECK(sequence_number >= 0 &&
105  sequence_number < kFastElementsKindCount);
106  return fast_elements_kind_sequence.Get()[sequence_number];
107 }
108 
109 
110 int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind) {
111  for (int i = 0; i < kFastElementsKindCount; ++i) {
112  if (fast_elements_kind_sequence.Get()[i] == elements_kind) {
113  return i;
114  }
115  }
116  UNREACHABLE();
117 }
118 
119 
120 ElementsKind GetNextTransitionElementsKind(ElementsKind kind) {
121  int index = GetSequenceIndexFromFastElementsKind(kind);
122  return GetFastElementsKindFromSequenceIndex(index + 1);
123 }
124 
125 
126 static inline bool IsFastTransitionTarget(ElementsKind elements_kind) {
127  return IsFastElementsKind(elements_kind) ||
128  elements_kind == DICTIONARY_ELEMENTS;
129 }
130 
131 bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
132  ElementsKind to_kind) {
133  if (!IsFastElementsKind(from_kind)) return false;
134  if (!IsFastTransitionTarget(to_kind)) return false;
135  DCHECK(!IsFixedTypedArrayElementsKind(from_kind));
136  DCHECK(!IsFixedTypedArrayElementsKind(to_kind));
137  switch (from_kind) {
138  case PACKED_SMI_ELEMENTS:
139  return to_kind != PACKED_SMI_ELEMENTS;
140  case HOLEY_SMI_ELEMENTS:
141  return to_kind != PACKED_SMI_ELEMENTS && to_kind != HOLEY_SMI_ELEMENTS;
142  case PACKED_DOUBLE_ELEMENTS:
143  return to_kind != PACKED_SMI_ELEMENTS && to_kind != HOLEY_SMI_ELEMENTS &&
144  to_kind != PACKED_DOUBLE_ELEMENTS;
145  case HOLEY_DOUBLE_ELEMENTS:
146  return to_kind == PACKED_ELEMENTS || to_kind == HOLEY_ELEMENTS;
147  case PACKED_ELEMENTS:
148  return to_kind == HOLEY_ELEMENTS;
149  case HOLEY_ELEMENTS:
150  return false;
151  default:
152  return false;
153  }
154 }
155 
156 bool UnionElementsKindUptoSize(ElementsKind* a_out, ElementsKind b) {
157  // Assert that the union of two ElementKinds can be computed via std::max.
158  static_assert(PACKED_SMI_ELEMENTS < HOLEY_SMI_ELEMENTS,
159  "ElementsKind union not computable via std::max.");
160  static_assert(HOLEY_SMI_ELEMENTS < PACKED_ELEMENTS,
161  "ElementsKind union not computable via std::max.");
162  static_assert(PACKED_ELEMENTS < HOLEY_ELEMENTS,
163  "ElementsKind union not computable via std::max.");
164  static_assert(PACKED_DOUBLE_ELEMENTS < HOLEY_DOUBLE_ELEMENTS,
165  "ElementsKind union not computable via std::max.");
166  ElementsKind a = *a_out;
167  switch (a) {
168  case PACKED_SMI_ELEMENTS:
169  switch (b) {
170  case PACKED_SMI_ELEMENTS:
171  case HOLEY_SMI_ELEMENTS:
172  case PACKED_ELEMENTS:
173  case HOLEY_ELEMENTS:
174  *a_out = b;
175  return true;
176  default:
177  return false;
178  }
179  case HOLEY_SMI_ELEMENTS:
180  switch (b) {
181  case PACKED_SMI_ELEMENTS:
182  case HOLEY_SMI_ELEMENTS:
183  *a_out = HOLEY_SMI_ELEMENTS;
184  return true;
185  case PACKED_ELEMENTS:
186  case HOLEY_ELEMENTS:
187  *a_out = HOLEY_ELEMENTS;
188  return true;
189  default:
190  return false;
191  }
192  case PACKED_ELEMENTS:
193  switch (b) {
194  case PACKED_SMI_ELEMENTS:
195  case PACKED_ELEMENTS:
196  *a_out = PACKED_ELEMENTS;
197  return true;
198  case HOLEY_SMI_ELEMENTS:
199  case HOLEY_ELEMENTS:
200  *a_out = HOLEY_ELEMENTS;
201  return true;
202  default:
203  return false;
204  }
205  case HOLEY_ELEMENTS:
206  switch (b) {
207  case PACKED_SMI_ELEMENTS:
208  case HOLEY_SMI_ELEMENTS:
209  case PACKED_ELEMENTS:
210  case HOLEY_ELEMENTS:
211  *a_out = HOLEY_ELEMENTS;
212  return true;
213  default:
214  return false;
215  }
216  break;
217  case PACKED_DOUBLE_ELEMENTS:
218  switch (b) {
219  case PACKED_DOUBLE_ELEMENTS:
220  case HOLEY_DOUBLE_ELEMENTS:
221  *a_out = b;
222  return true;
223  default:
224  return false;
225  }
226  case HOLEY_DOUBLE_ELEMENTS:
227  switch (b) {
228  case PACKED_DOUBLE_ELEMENTS:
229  case HOLEY_DOUBLE_ELEMENTS:
230  *a_out = HOLEY_DOUBLE_ELEMENTS;
231  return true;
232  default:
233  return false;
234  }
235 
236  break;
237  default:
238  break;
239  }
240  return false;
241 }
242 
243 } // namespace internal
244 } // namespace v8
Definition: libplatform.h:13