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 369803 : int ElementsKindToShiftSize(ElementsKind elements_kind) {
17 369803 : 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 11002 : return 1;
25 : case UINT32_ELEMENTS:
26 : case INT32_ELEMENTS:
27 : case FLOAT32_ELEMENTS:
28 4589 : 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 27597 : 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 313966 : return kTaggedSizeLog2;
45 : case NO_ELEMENTS:
46 0 : UNREACHABLE();
47 : }
48 0 : UNREACHABLE();
49 : }
50 :
51 8845 : int ElementsKindToByteSize(ElementsKind elements_kind) {
52 8845 : 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 17490 : const char* ElementsKindToString(ElementsKind kind) {
67 17490 : ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
68 17490 : 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 7710 : return kFastElementsKindSequence[sequence_number];
92 : }
93 :
94 6262 : int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind) {
95 17699 : for (int i = 0; i < kFastElementsKindCount; ++i) {
96 17699 : if (kFastElementsKindSequence[i] == elements_kind) {
97 6262 : return i;
98 : }
99 : }
100 0 : UNREACHABLE();
101 : }
102 :
103 :
104 5928 : ElementsKind GetNextTransitionElementsKind(ElementsKind kind) {
105 5928 : int index = GetSequenceIndexFromFastElementsKind(kind);
106 11856 : return GetFastElementsKindFromSequenceIndex(index + 1);
107 : }
108 :
109 :
110 : static inline bool IsFastTransitionTarget(ElementsKind elements_kind) {
111 16274805 : return IsFastElementsKind(elements_kind) ||
112 : elements_kind == DICTIONARY_ELEMENTS;
113 : }
114 :
115 18363969 : bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
116 : ElementsKind to_kind) {
117 18363969 : if (!IsFastElementsKind(from_kind)) return false;
118 16274805 : if (!IsFastTransitionTarget(to_kind)) return false;
119 : DCHECK(!IsFixedTypedArrayElementsKind(from_kind));
120 : DCHECK(!IsFixedTypedArrayElementsKind(to_kind));
121 16273896 : switch (from_kind) {
122 : case PACKED_SMI_ELEMENTS:
123 8879272 : return to_kind != PACKED_SMI_ELEMENTS;
124 : case HOLEY_SMI_ELEMENTS:
125 1303153 : return to_kind != PACKED_SMI_ELEMENTS && to_kind != HOLEY_SMI_ELEMENTS;
126 : case PACKED_DOUBLE_ELEMENTS:
127 415486 : return to_kind != PACKED_SMI_ELEMENTS && to_kind != HOLEY_SMI_ELEMENTS &&
128 415486 : to_kind != PACKED_DOUBLE_ELEMENTS;
129 : case HOLEY_DOUBLE_ELEMENTS:
130 4241 : return to_kind == PACKED_ELEMENTS || to_kind == HOLEY_ELEMENTS;
131 : case PACKED_ELEMENTS:
132 1062911 : return to_kind == HOLEY_ELEMENTS;
133 : case HOLEY_ELEMENTS:
134 : return false;
135 : default:
136 : return false;
137 : }
138 : }
139 :
140 4411 : 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 4411 : ElementsKind a = *a_out;
151 4411 : switch (a) {
152 : case PACKED_SMI_ELEMENTS:
153 2560 : switch (b) {
154 : case PACKED_SMI_ELEMENTS:
155 : case HOLEY_SMI_ELEMENTS:
156 : case PACKED_ELEMENTS:
157 : case HOLEY_ELEMENTS:
158 2544 : *a_out = b;
159 2544 : return true;
160 : default:
161 : return false;
162 : }
163 : case HOLEY_SMI_ELEMENTS:
164 380 : switch (b) {
165 : case PACKED_SMI_ELEMENTS:
166 : case HOLEY_SMI_ELEMENTS:
167 348 : *a_out = HOLEY_SMI_ELEMENTS;
168 348 : return true;
169 : case PACKED_ELEMENTS:
170 : case HOLEY_ELEMENTS:
171 16 : *a_out = HOLEY_ELEMENTS;
172 16 : return true;
173 : default:
174 : return false;
175 : }
176 : case PACKED_ELEMENTS:
177 791 : switch (b) {
178 : case PACKED_SMI_ELEMENTS:
179 : case PACKED_ELEMENTS:
180 722 : *a_out = PACKED_ELEMENTS;
181 722 : 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 104 : switch (b) {
191 : case PACKED_SMI_ELEMENTS:
192 : case HOLEY_SMI_ELEMENTS:
193 : case PACKED_ELEMENTS:
194 : case HOLEY_ELEMENTS:
195 88 : *a_out = HOLEY_ELEMENTS;
196 88 : return true;
197 : default:
198 : return false;
199 : }
200 : break;
201 : case PACKED_DOUBLE_ELEMENTS:
202 482 : switch (b) {
203 : case PACKED_DOUBLE_ELEMENTS:
204 : case HOLEY_DOUBLE_ELEMENTS:
205 442 : *a_out = b;
206 442 : return true;
207 : default:
208 : return false;
209 : }
210 : case HOLEY_DOUBLE_ELEMENTS:
211 94 : switch (b) {
212 : case PACKED_DOUBLE_ELEMENTS:
213 : case HOLEY_DOUBLE_ELEMENTS:
214 94 : *a_out = HOLEY_DOUBLE_ELEMENTS;
215 94 : 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 178779 : } // namespace v8
|