Line data Source code
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/api.h"
8 : #include "src/base/lazy-instance.h"
9 : #include "src/elements.h"
10 : #include "src/objects-inl.h"
11 : #include "src/objects.h"
12 :
13 : namespace v8 {
14 : namespace internal {
15 :
16 :
17 190179 : int ElementsKindToShiftSize(ElementsKind elements_kind) {
18 190179 : switch (elements_kind) {
19 : case UINT8_ELEMENTS:
20 : case INT8_ELEMENTS:
21 : case UINT8_CLAMPED_ELEMENTS:
22 : return 0;
23 : case UINT16_ELEMENTS:
24 : case INT16_ELEMENTS:
25 11935 : return 1;
26 : case UINT32_ELEMENTS:
27 : case INT32_ELEMENTS:
28 : case FLOAT32_ELEMENTS:
29 1704 : return 2;
30 : case PACKED_DOUBLE_ELEMENTS:
31 : case HOLEY_DOUBLE_ELEMENTS:
32 : case FLOAT64_ELEMENTS:
33 7761 : return 3;
34 : case PACKED_SMI_ELEMENTS:
35 : case PACKED_ELEMENTS:
36 : case HOLEY_SMI_ELEMENTS:
37 : case HOLEY_ELEMENTS:
38 : case DICTIONARY_ELEMENTS:
39 : case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
40 : case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
41 : case FAST_STRING_WRAPPER_ELEMENTS:
42 : case SLOW_STRING_WRAPPER_ELEMENTS:
43 154962 : return kPointerSizeLog2;
44 : case NO_ELEMENTS:
45 0 : UNREACHABLE();
46 : }
47 0 : UNREACHABLE();
48 : }
49 :
50 :
51 0 : int GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind) {
52 : STATIC_ASSERT(FixedArray::kHeaderSize == FixedDoubleArray::kHeaderSize);
53 :
54 0 : if (IsFixedTypedArrayElementsKind(elements_kind)) {
55 : return 0;
56 : } else {
57 0 : return FixedArray::kHeaderSize - kHeapObjectTag;
58 : }
59 : }
60 :
61 :
62 6087 : const char* ElementsKindToString(ElementsKind kind) {
63 6087 : ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
64 6087 : return accessor->name();
65 : }
66 :
67 :
68 : struct InitializeFastElementsKindSequence {
69 937 : static void Construct(void* fast_elements_kind_sequence_ptr_arg) {
70 : auto fast_elements_kind_sequence_ptr =
71 : reinterpret_cast<ElementsKind**>(fast_elements_kind_sequence_ptr_arg);
72 : ElementsKind* fast_elements_kind_sequence =
73 937 : new ElementsKind[kFastElementsKindCount];
74 937 : *fast_elements_kind_sequence_ptr = fast_elements_kind_sequence;
75 : STATIC_ASSERT(PACKED_SMI_ELEMENTS == FIRST_FAST_ELEMENTS_KIND);
76 937 : fast_elements_kind_sequence[0] = PACKED_SMI_ELEMENTS;
77 937 : fast_elements_kind_sequence[1] = HOLEY_SMI_ELEMENTS;
78 937 : fast_elements_kind_sequence[2] = PACKED_DOUBLE_ELEMENTS;
79 937 : fast_elements_kind_sequence[3] = HOLEY_DOUBLE_ELEMENTS;
80 937 : fast_elements_kind_sequence[4] = PACKED_ELEMENTS;
81 937 : fast_elements_kind_sequence[5] = HOLEY_ELEMENTS;
82 :
83 : // Verify that kFastElementsKindPackedToHoley is correct.
84 : STATIC_ASSERT(PACKED_SMI_ELEMENTS + kFastElementsKindPackedToHoley ==
85 : HOLEY_SMI_ELEMENTS);
86 : STATIC_ASSERT(PACKED_DOUBLE_ELEMENTS + kFastElementsKindPackedToHoley ==
87 : HOLEY_DOUBLE_ELEMENTS);
88 : STATIC_ASSERT(PACKED_ELEMENTS + kFastElementsKindPackedToHoley ==
89 : HOLEY_ELEMENTS);
90 937 : }
91 : };
92 :
93 :
94 : static base::LazyInstance<ElementsKind*,
95 : InitializeFastElementsKindSequence>::type
96 : fast_elements_kind_sequence = LAZY_INSTANCE_INITIALIZER;
97 :
98 :
99 1354 : ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number) {
100 : DCHECK(sequence_number >= 0 &&
101 : sequence_number < kFastElementsKindCount);
102 7442 : return fast_elements_kind_sequence.Get()[sequence_number];
103 : }
104 :
105 :
106 6334 : int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind) {
107 17795 : for (int i = 0; i < kFastElementsKindCount; ++i) {
108 17795 : if (fast_elements_kind_sequence.Get()[i] == elements_kind) {
109 6334 : return i;
110 : }
111 : }
112 0 : UNREACHABLE();
113 : }
114 :
115 :
116 6088 : ElementsKind GetNextTransitionElementsKind(ElementsKind kind) {
117 6088 : int index = GetSequenceIndexFromFastElementsKind(kind);
118 12176 : return GetFastElementsKindFromSequenceIndex(index + 1);
119 : }
120 :
121 :
122 : static inline bool IsFastTransitionTarget(ElementsKind elements_kind) {
123 14145079 : return IsFastElementsKind(elements_kind) ||
124 : elements_kind == DICTIONARY_ELEMENTS;
125 : }
126 :
127 16723619 : bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
128 : ElementsKind to_kind) {
129 32606663 : if (IsFixedTypedArrayElementsKind(from_kind) ||
130 : IsFixedTypedArrayElementsKind(to_kind)) {
131 : return false;
132 : }
133 30026892 : if (IsFastElementsKind(from_kind) && IsFastTransitionTarget(to_kind)) {
134 14144406 : switch (from_kind) {
135 : case PACKED_SMI_ELEMENTS:
136 6407579 : return to_kind != PACKED_SMI_ELEMENTS;
137 : case HOLEY_SMI_ELEMENTS:
138 1931974 : return to_kind != PACKED_SMI_ELEMENTS && to_kind != HOLEY_SMI_ELEMENTS;
139 : case PACKED_DOUBLE_ELEMENTS:
140 484563 : return to_kind != PACKED_SMI_ELEMENTS &&
141 : to_kind != HOLEY_SMI_ELEMENTS &&
142 484563 : to_kind != PACKED_DOUBLE_ELEMENTS;
143 : case HOLEY_DOUBLE_ELEMENTS:
144 97028 : return to_kind == PACKED_ELEMENTS || to_kind == HOLEY_ELEMENTS;
145 : case PACKED_ELEMENTS:
146 1504127 : return to_kind == HOLEY_ELEMENTS;
147 : case HOLEY_ELEMENTS:
148 : return false;
149 : default:
150 : return false;
151 : }
152 : }
153 : return false;
154 : }
155 :
156 :
157 : } // namespace internal
158 : } // namespace v8
|