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/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 383271 : int ElementsKindToShiftSize(ElementsKind elements_kind) {
17 383271 : 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 11009 : return 1;
25 : case UINT32_ELEMENTS:
26 : case INT32_ELEMENTS:
27 : case FLOAT32_ELEMENTS:
28 5541 : 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 27777 : 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 326282 : return kTaggedSizeLog2;
45 : case NO_ELEMENTS:
46 0 : UNREACHABLE();
47 : }
48 0 : UNREACHABLE();
49 : }
50 :
51 8871 : int ElementsKindToByteSize(ElementsKind elements_kind) {
52 8871 : return 1 << ElementsKindToShiftSize(elements_kind);
53 : }
54 :
55 0 : int GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind) {
56 : STATIC_ASSERT(FixedArray::kHeaderSize == FixedDoubleArray::kHeaderSize);
57 :
58 0 : if (IsFixedTypedArrayElementsKind(elements_kind)) {
59 : return 0;
60 : } else {
61 0 : return FixedArray::kHeaderSize - kHeapObjectTag;
62 : }
63 : }
64 :
65 :
66 18002 : const char* ElementsKindToString(ElementsKind kind) {
67 18002 : ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
68 18002 : return accessor->name();
69 : }
70 :
71 : ElementsKind kFastElementsKindSequence[kFastElementsKindCount] = {
72 : PACKED_SMI_ELEMENTS, // 0
73 : HOLEY_SMI_ELEMENTS, // 1
74 : PACKED_DOUBLE_ELEMENTS, // 2
75 : HOLEY_DOUBLE_ELEMENTS, // 3
76 : PACKED_ELEMENTS, // 4
77 : HOLEY_ELEMENTS // 5
78 : };
79 : STATIC_ASSERT(PACKED_SMI_ELEMENTS == FIRST_FAST_ELEMENTS_KIND);
80 : // Verify that kFastElementsKindPackedToHoley is correct.
81 : STATIC_ASSERT(PACKED_SMI_ELEMENTS + kFastElementsKindPackedToHoley ==
82 : HOLEY_SMI_ELEMENTS);
83 : STATIC_ASSERT(PACKED_DOUBLE_ELEMENTS + kFastElementsKindPackedToHoley ==
84 : HOLEY_DOUBLE_ELEMENTS);
85 : STATIC_ASSERT(PACKED_ELEMENTS + kFastElementsKindPackedToHoley ==
86 : HOLEY_ELEMENTS);
87 :
88 1782 : ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number) {
89 : DCHECK(sequence_number >= 0 &&
90 : sequence_number < kFastElementsKindCount);
91 7055 : return kFastElementsKindSequence[sequence_number];
92 : }
93 :
94 5607 : int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind) {
95 16043 : for (int i = 0; i < kFastElementsKindCount; ++i) {
96 16043 : if (kFastElementsKindSequence[i] == elements_kind) {
97 5607 : return i;
98 : }
99 : }
100 0 : UNREACHABLE();
101 : }
102 :
103 :
104 5273 : ElementsKind GetNextTransitionElementsKind(ElementsKind kind) {
105 5273 : int index = GetSequenceIndexFromFastElementsKind(kind);
106 10546 : return GetFastElementsKindFromSequenceIndex(index + 1);
107 : }
108 :
109 :
110 : static inline bool IsFastTransitionTarget(ElementsKind elements_kind) {
111 16358882 : return IsFastElementsKind(elements_kind) ||
112 : elements_kind == DICTIONARY_ELEMENTS;
113 : }
114 :
115 18444997 : bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
116 : ElementsKind to_kind) {
117 18444997 : if (!IsFastElementsKind(from_kind)) return false;
118 16358882 : if (!IsFastTransitionTarget(to_kind)) return false;
119 : DCHECK(!IsFixedTypedArrayElementsKind(from_kind));
120 : DCHECK(!IsFixedTypedArrayElementsKind(to_kind));
121 16357907 : switch (from_kind) {
122 : case PACKED_SMI_ELEMENTS:
123 8967584 : return to_kind != PACKED_SMI_ELEMENTS;
124 : case HOLEY_SMI_ELEMENTS:
125 1286612 : return to_kind != PACKED_SMI_ELEMENTS && to_kind != HOLEY_SMI_ELEMENTS;
126 : case PACKED_DOUBLE_ELEMENTS:
127 416594 : return to_kind != PACKED_SMI_ELEMENTS && to_kind != HOLEY_SMI_ELEMENTS &&
128 416594 : to_kind != PACKED_DOUBLE_ELEMENTS;
129 : case HOLEY_DOUBLE_ELEMENTS:
130 4415 : return to_kind == PACKED_ELEMENTS || to_kind == HOLEY_ELEMENTS;
131 : case PACKED_ELEMENTS:
132 1064009 : return to_kind == HOLEY_ELEMENTS;
133 : case HOLEY_ELEMENTS:
134 : return false;
135 : default:
136 : return false;
137 : }
138 : }
139 :
140 3803 : bool UnionElementsKindUptoSize(ElementsKind* a_out, ElementsKind b) {
141 : // Assert that the union of two ElementKinds can be computed via std::max.
142 : static_assert(PACKED_SMI_ELEMENTS < HOLEY_SMI_ELEMENTS,
143 : "ElementsKind union not computable via std::max.");
144 : static_assert(HOLEY_SMI_ELEMENTS < PACKED_ELEMENTS,
145 : "ElementsKind union not computable via std::max.");
146 : static_assert(PACKED_ELEMENTS < HOLEY_ELEMENTS,
147 : "ElementsKind union not computable via std::max.");
148 : static_assert(PACKED_DOUBLE_ELEMENTS < HOLEY_DOUBLE_ELEMENTS,
149 : "ElementsKind union not computable via std::max.");
150 3803 : ElementsKind a = *a_out;
151 3803 : switch (a) {
152 : case PACKED_SMI_ELEMENTS:
153 1875 : switch (b) {
154 : case PACKED_SMI_ELEMENTS:
155 : case HOLEY_SMI_ELEMENTS:
156 : case PACKED_ELEMENTS:
157 : case HOLEY_ELEMENTS:
158 1855 : *a_out = b;
159 1855 : return true;
160 : default:
161 : return false;
162 : }
163 : case HOLEY_SMI_ELEMENTS:
164 424 : switch (b) {
165 : case PACKED_SMI_ELEMENTS:
166 : case HOLEY_SMI_ELEMENTS:
167 384 : *a_out = HOLEY_SMI_ELEMENTS;
168 384 : return true;
169 : case PACKED_ELEMENTS:
170 : case HOLEY_ELEMENTS:
171 20 : *a_out = HOLEY_ELEMENTS;
172 20 : return true;
173 : default:
174 : return false;
175 : }
176 : case PACKED_ELEMENTS:
177 881 : switch (b) {
178 : case PACKED_SMI_ELEMENTS:
179 : case PACKED_ELEMENTS:
180 806 : *a_out = PACKED_ELEMENTS;
181 806 : return true;
182 : case HOLEY_SMI_ELEMENTS:
183 : case HOLEY_ELEMENTS:
184 20 : *a_out = HOLEY_ELEMENTS;
185 20 : return true;
186 : default:
187 : return false;
188 : }
189 : case HOLEY_ELEMENTS:
190 60 : switch (b) {
191 : case PACKED_SMI_ELEMENTS:
192 : case HOLEY_SMI_ELEMENTS:
193 : case PACKED_ELEMENTS:
194 : case HOLEY_ELEMENTS:
195 40 : *a_out = HOLEY_ELEMENTS;
196 40 : return true;
197 : default:
198 : return false;
199 : }
200 : break;
201 : case PACKED_DOUBLE_ELEMENTS:
202 495 : switch (b) {
203 : case PACKED_DOUBLE_ELEMENTS:
204 : case HOLEY_DOUBLE_ELEMENTS:
205 455 : *a_out = b;
206 455 : return true;
207 : default:
208 : return false;
209 : }
210 : case HOLEY_DOUBLE_ELEMENTS:
211 68 : switch (b) {
212 : case PACKED_DOUBLE_ELEMENTS:
213 : case HOLEY_DOUBLE_ELEMENTS:
214 68 : *a_out = HOLEY_DOUBLE_ELEMENTS;
215 68 : return true;
216 : default:
217 : return false;
218 : }
219 :
220 : break;
221 : default:
222 : break;
223 : }
224 : return false;
225 : }
226 :
227 : } // namespace internal
228 183867 : } // namespace v8
|