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 334071 : int ElementsKindToShiftSize(ElementsKind elements_kind) {
17 334071 : 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 14138 : return 1;
25 : case UINT32_ELEMENTS:
26 : case INT32_ELEMENTS:
27 : case FLOAT32_ELEMENTS:
28 3749 : 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 26981 : return 3;
35 : case PACKED_SMI_ELEMENTS:
36 : case PACKED_ELEMENTS:
37 : case PACKED_FROZEN_ELEMENTS:
38 : case PACKED_SEALED_ELEMENTS:
39 : case HOLEY_SMI_ELEMENTS:
40 : case HOLEY_ELEMENTS:
41 : case DICTIONARY_ELEMENTS:
42 : case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
43 : case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
44 : case FAST_STRING_WRAPPER_ELEMENTS:
45 : case SLOW_STRING_WRAPPER_ELEMENTS:
46 273698 : return kTaggedSizeLog2;
47 : case NO_ELEMENTS:
48 0 : UNREACHABLE();
49 : }
50 0 : UNREACHABLE();
51 : }
52 :
53 8397 : int ElementsKindToByteSize(ElementsKind elements_kind) {
54 8397 : return 1 << ElementsKindToShiftSize(elements_kind);
55 : }
56 :
57 0 : int GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind) {
58 : STATIC_ASSERT(FixedArray::kHeaderSize == FixedDoubleArray::kHeaderSize);
59 :
60 0 : if (IsFixedTypedArrayElementsKind(elements_kind)) {
61 : return 0;
62 : } else {
63 0 : return FixedArray::kHeaderSize - kHeapObjectTag;
64 : }
65 : }
66 :
67 :
68 18050 : const char* ElementsKindToString(ElementsKind kind) {
69 : ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
70 18050 : return accessor->name();
71 : }
72 :
73 : ElementsKind kFastElementsKindSequence[kFastElementsKindCount] = {
74 : PACKED_SMI_ELEMENTS, // 0
75 : HOLEY_SMI_ELEMENTS, // 1
76 : PACKED_DOUBLE_ELEMENTS, // 2
77 : HOLEY_DOUBLE_ELEMENTS, // 3
78 : PACKED_ELEMENTS, // 4
79 : HOLEY_ELEMENTS // 5
80 : };
81 : STATIC_ASSERT(PACKED_SMI_ELEMENTS == FIRST_FAST_ELEMENTS_KIND);
82 : // Verify that kFastElementsKindPackedToHoley is correct.
83 : STATIC_ASSERT(PACKED_SMI_ELEMENTS + kFastElementsKindPackedToHoley ==
84 : HOLEY_SMI_ELEMENTS);
85 : STATIC_ASSERT(PACKED_DOUBLE_ELEMENTS + kFastElementsKindPackedToHoley ==
86 : HOLEY_DOUBLE_ELEMENTS);
87 : STATIC_ASSERT(PACKED_ELEMENTS + kFastElementsKindPackedToHoley ==
88 : HOLEY_ELEMENTS);
89 :
90 1782 : ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number) {
91 : DCHECK(sequence_number >= 0 &&
92 : sequence_number < kFastElementsKindCount);
93 4778 : return kFastElementsKindSequence[sequence_number];
94 : }
95 :
96 334 : int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind) {
97 15992 : for (int i = 0; i < kFastElementsKindCount; ++i) {
98 9661 : if (kFastElementsKindSequence[i] == elements_kind) {
99 334 : return i;
100 : }
101 : }
102 0 : UNREACHABLE();
103 : }
104 :
105 :
106 2996 : ElementsKind GetNextTransitionElementsKind(ElementsKind kind) {
107 : int index = GetSequenceIndexFromFastElementsKind(kind);
108 5992 : return GetFastElementsKindFromSequenceIndex(index + 1);
109 : }
110 :
111 :
112 : static inline bool IsFastTransitionTarget(ElementsKind elements_kind) {
113 14330948 : return IsFastElementsKind(elements_kind) ||
114 : elements_kind == DICTIONARY_ELEMENTS;
115 : }
116 :
117 17040748 : bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
118 : ElementsKind to_kind) {
119 17040748 : if (!IsFastElementsKind(from_kind)) return false;
120 14330948 : if (!IsFastTransitionTarget(to_kind)) return false;
121 : DCHECK(!IsFixedTypedArrayElementsKind(from_kind));
122 : DCHECK(!IsFixedTypedArrayElementsKind(to_kind));
123 14325384 : switch (from_kind) {
124 : case PACKED_SMI_ELEMENTS:
125 8096303 : return to_kind != PACKED_SMI_ELEMENTS;
126 : case HOLEY_SMI_ELEMENTS:
127 1305157 : return to_kind != PACKED_SMI_ELEMENTS && to_kind != HOLEY_SMI_ELEMENTS;
128 : case PACKED_DOUBLE_ELEMENTS:
129 415736 : return to_kind != PACKED_SMI_ELEMENTS && to_kind != HOLEY_SMI_ELEMENTS &&
130 415736 : to_kind != PACKED_DOUBLE_ELEMENTS;
131 : case HOLEY_DOUBLE_ELEMENTS:
132 4231 : return to_kind == PACKED_ELEMENTS || to_kind == HOLEY_ELEMENTS;
133 : case PACKED_ELEMENTS:
134 1059308 : return to_kind == HOLEY_ELEMENTS;
135 : case HOLEY_ELEMENTS:
136 : return false;
137 : default:
138 : return false;
139 : }
140 : }
141 :
142 4304 : bool UnionElementsKindUptoSize(ElementsKind* a_out, ElementsKind b) {
143 : // Assert that the union of two ElementKinds can be computed via std::max.
144 : static_assert(PACKED_SMI_ELEMENTS < HOLEY_SMI_ELEMENTS,
145 : "ElementsKind union not computable via std::max.");
146 : static_assert(HOLEY_SMI_ELEMENTS < PACKED_ELEMENTS,
147 : "ElementsKind union not computable via std::max.");
148 : static_assert(PACKED_ELEMENTS < HOLEY_ELEMENTS,
149 : "ElementsKind union not computable via std::max.");
150 : static_assert(PACKED_DOUBLE_ELEMENTS < HOLEY_DOUBLE_ELEMENTS,
151 : "ElementsKind union not computable via std::max.");
152 4304 : ElementsKind a = *a_out;
153 4304 : switch (a) {
154 : case PACKED_SMI_ELEMENTS:
155 2527 : switch (b) {
156 : case PACKED_SMI_ELEMENTS:
157 : case HOLEY_SMI_ELEMENTS:
158 : case PACKED_ELEMENTS:
159 : case HOLEY_ELEMENTS:
160 2511 : *a_out = b;
161 2511 : return true;
162 : default:
163 : return false;
164 : }
165 : case HOLEY_SMI_ELEMENTS:
166 365 : switch (b) {
167 : case PACKED_SMI_ELEMENTS:
168 : case HOLEY_SMI_ELEMENTS:
169 333 : *a_out = HOLEY_SMI_ELEMENTS;
170 333 : return true;
171 : case PACKED_ELEMENTS:
172 : case HOLEY_ELEMENTS:
173 16 : *a_out = HOLEY_ELEMENTS;
174 16 : return true;
175 : default:
176 : return false;
177 : }
178 : case PACKED_ELEMENTS:
179 747 : switch (b) {
180 : case PACKED_SMI_ELEMENTS:
181 : case PACKED_ELEMENTS:
182 678 : *a_out = PACKED_ELEMENTS;
183 678 : return true;
184 : case HOLEY_SMI_ELEMENTS:
185 : case HOLEY_ELEMENTS:
186 20 : *a_out = HOLEY_ELEMENTS;
187 20 : return true;
188 : default:
189 : return false;
190 : }
191 : case HOLEY_ELEMENTS:
192 104 : switch (b) {
193 : case PACKED_SMI_ELEMENTS:
194 : case HOLEY_SMI_ELEMENTS:
195 : case PACKED_ELEMENTS:
196 : case HOLEY_ELEMENTS:
197 88 : *a_out = HOLEY_ELEMENTS;
198 88 : return true;
199 : default:
200 : return false;
201 : }
202 : break;
203 : case PACKED_DOUBLE_ELEMENTS:
204 463 : switch (b) {
205 : case PACKED_DOUBLE_ELEMENTS:
206 : case HOLEY_DOUBLE_ELEMENTS:
207 423 : *a_out = b;
208 423 : return true;
209 : default:
210 : return false;
211 : }
212 : case HOLEY_DOUBLE_ELEMENTS:
213 98 : switch (b) {
214 : case PACKED_DOUBLE_ELEMENTS:
215 : case HOLEY_DOUBLE_ELEMENTS:
216 98 : *a_out = HOLEY_DOUBLE_ELEMENTS;
217 98 : return true;
218 : default:
219 : return false;
220 : }
221 :
222 : break;
223 : default:
224 : break;
225 : }
226 : return false;
227 : }
228 :
229 : } // namespace internal
230 122004 : } // namespace v8
|