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.
5 #include "src/elements-kind.h"
8 #include "src/base/lazy-instance.h"
9 #include "src/elements.h"
10 #include "src/objects.h"
16 int ElementsKindToShiftSize(ElementsKind elements_kind) {
17 switch (elements_kind) {
18 case EXTERNAL_INT8_ELEMENTS:
19 case EXTERNAL_UINT8_CLAMPED_ELEMENTS:
20 case EXTERNAL_UINT8_ELEMENTS:
23 case UINT8_CLAMPED_ELEMENTS:
25 case EXTERNAL_INT16_ELEMENTS:
26 case EXTERNAL_UINT16_ELEMENTS:
30 case EXTERNAL_INT32_ELEMENTS:
31 case EXTERNAL_UINT32_ELEMENTS:
32 case EXTERNAL_FLOAT32_ELEMENTS:
35 case FLOAT32_ELEMENTS:
37 case EXTERNAL_FLOAT64_ELEMENTS:
38 case FAST_DOUBLE_ELEMENTS:
39 case FAST_HOLEY_DOUBLE_ELEMENTS:
40 case FLOAT64_ELEMENTS:
42 case FAST_SMI_ELEMENTS:
44 case FAST_HOLEY_SMI_ELEMENTS:
45 case FAST_HOLEY_ELEMENTS:
46 case DICTIONARY_ELEMENTS:
47 case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
48 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
49 return kPointerSizeLog2;
56 static bool IsTypedArrayElementsKind(ElementsKind elements_kind) {
57 return IsFixedTypedArrayElementsKind(elements_kind) ||
58 IsExternalArrayElementsKind(elements_kind);
62 int GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind) {
63 STATIC_ASSERT(FixedArray::kHeaderSize == FixedDoubleArray::kHeaderSize);
65 if (IsTypedArrayElementsKind(elements_kind)) {
68 return FixedArray::kHeaderSize - kHeapObjectTag;
73 const char* ElementsKindToString(ElementsKind kind) {
74 ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
75 return accessor->name();
79 struct InitializeFastElementsKindSequence {
80 static void Construct(
81 ElementsKind** fast_elements_kind_sequence_ptr) {
82 ElementsKind* fast_elements_kind_sequence =
83 new ElementsKind[kFastElementsKindCount];
84 *fast_elements_kind_sequence_ptr = fast_elements_kind_sequence;
85 STATIC_ASSERT(FAST_SMI_ELEMENTS == FIRST_FAST_ELEMENTS_KIND);
86 fast_elements_kind_sequence[0] = FAST_SMI_ELEMENTS;
87 fast_elements_kind_sequence[1] = FAST_HOLEY_SMI_ELEMENTS;
88 fast_elements_kind_sequence[2] = FAST_DOUBLE_ELEMENTS;
89 fast_elements_kind_sequence[3] = FAST_HOLEY_DOUBLE_ELEMENTS;
90 fast_elements_kind_sequence[4] = FAST_ELEMENTS;
91 fast_elements_kind_sequence[5] = FAST_HOLEY_ELEMENTS;
93 // Verify that kFastElementsKindPackedToHoley is correct.
94 STATIC_ASSERT(FAST_SMI_ELEMENTS + kFastElementsKindPackedToHoley ==
95 FAST_HOLEY_SMI_ELEMENTS);
96 STATIC_ASSERT(FAST_DOUBLE_ELEMENTS + kFastElementsKindPackedToHoley ==
97 FAST_HOLEY_DOUBLE_ELEMENTS);
98 STATIC_ASSERT(FAST_ELEMENTS + kFastElementsKindPackedToHoley ==
104 static base::LazyInstance<ElementsKind*,
105 InitializeFastElementsKindSequence>::type
106 fast_elements_kind_sequence = LAZY_INSTANCE_INITIALIZER;
109 ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number) {
110 DCHECK(sequence_number >= 0 &&
111 sequence_number < kFastElementsKindCount);
112 return fast_elements_kind_sequence.Get()[sequence_number];
116 int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind) {
117 for (int i = 0; i < kFastElementsKindCount; ++i) {
118 if (fast_elements_kind_sequence.Get()[i] == elements_kind) {
127 ElementsKind GetNextTransitionElementsKind(ElementsKind kind) {
129 #define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
130 case TYPE##_ELEMENTS: return EXTERNAL_##TYPE##_ELEMENTS;
132 TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE)
133 #undef FIXED_TYPED_ARRAY_CASE
135 int index = GetSequenceIndexFromFastElementsKind(kind);
136 return GetFastElementsKindFromSequenceIndex(index + 1);
142 static inline bool IsFastTransitionTarget(ElementsKind elements_kind) {
143 return IsFastElementsKind(elements_kind) ||
144 elements_kind == DICTIONARY_ELEMENTS;
147 bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
148 ElementsKind to_kind) {
149 if (IsTypedArrayElementsKind(from_kind) ||
150 IsTypedArrayElementsKind(to_kind)) {
152 #define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
153 case TYPE##_ELEMENTS: \
154 return to_kind == EXTERNAL_##TYPE##_ELEMENTS;
156 TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE);
157 #undef FIXED_TYPED_ARRAY_CASE
162 if (IsFastElementsKind(from_kind) && IsFastTransitionTarget(to_kind)) {
164 case FAST_SMI_ELEMENTS:
165 return to_kind != FAST_SMI_ELEMENTS;
166 case FAST_HOLEY_SMI_ELEMENTS:
167 return to_kind != FAST_SMI_ELEMENTS &&
168 to_kind != FAST_HOLEY_SMI_ELEMENTS;
169 case FAST_DOUBLE_ELEMENTS:
170 return to_kind != FAST_SMI_ELEMENTS &&
171 to_kind != FAST_HOLEY_SMI_ELEMENTS &&
172 to_kind != FAST_DOUBLE_ELEMENTS;
173 case FAST_HOLEY_DOUBLE_ELEMENTS:
174 return to_kind == FAST_ELEMENTS ||
175 to_kind == FAST_HOLEY_ELEMENTS;
177 return to_kind == FAST_HOLEY_ELEMENTS;
178 case FAST_HOLEY_ELEMENTS:
188 } // namespace internal