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 475459 : int ElementsKindToShiftSize(ElementsKind elements_kind) {
18 475459 : 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 14403 : return 1;
26 : case UINT32_ELEMENTS:
27 : case INT32_ELEMENTS:
28 : case FLOAT32_ELEMENTS:
29 3728 : return 2;
30 : case FAST_DOUBLE_ELEMENTS:
31 : case FAST_HOLEY_DOUBLE_ELEMENTS:
32 : case FLOAT64_ELEMENTS:
33 21990 : return 3;
34 : case FAST_SMI_ELEMENTS:
35 : case FAST_ELEMENTS:
36 : case FAST_HOLEY_SMI_ELEMENTS:
37 : case FAST_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 418681 : return kPointerSizeLog2;
44 : case NO_ELEMENTS:
45 0 : UNREACHABLE();
46 : return 0;
47 : }
48 0 : UNREACHABLE();
49 : return 0;
50 : }
51 :
52 :
53 80309 : int GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind) {
54 : STATIC_ASSERT(FixedArray::kHeaderSize == FixedDoubleArray::kHeaderSize);
55 :
56 80309 : if (IsFixedTypedArrayElementsKind(elements_kind)) {
57 : return 0;
58 : } else {
59 76412 : return FixedArray::kHeaderSize - kHeapObjectTag;
60 : }
61 : }
62 :
63 :
64 8699 : const char* ElementsKindToString(ElementsKind kind) {
65 8699 : ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
66 8699 : return accessor->name();
67 : }
68 :
69 :
70 : struct InitializeFastElementsKindSequence {
71 1026 : static void Construct(
72 : ElementsKind** fast_elements_kind_sequence_ptr) {
73 : ElementsKind* fast_elements_kind_sequence =
74 1026 : new ElementsKind[kFastElementsKindCount];
75 1026 : *fast_elements_kind_sequence_ptr = fast_elements_kind_sequence;
76 : STATIC_ASSERT(FAST_SMI_ELEMENTS == FIRST_FAST_ELEMENTS_KIND);
77 1026 : fast_elements_kind_sequence[0] = FAST_SMI_ELEMENTS;
78 1026 : fast_elements_kind_sequence[1] = FAST_HOLEY_SMI_ELEMENTS;
79 1026 : fast_elements_kind_sequence[2] = FAST_DOUBLE_ELEMENTS;
80 1026 : fast_elements_kind_sequence[3] = FAST_HOLEY_DOUBLE_ELEMENTS;
81 1026 : fast_elements_kind_sequence[4] = FAST_ELEMENTS;
82 1026 : fast_elements_kind_sequence[5] = FAST_HOLEY_ELEMENTS;
83 :
84 : // Verify that kFastElementsKindPackedToHoley is correct.
85 : STATIC_ASSERT(FAST_SMI_ELEMENTS + kFastElementsKindPackedToHoley ==
86 : FAST_HOLEY_SMI_ELEMENTS);
87 : STATIC_ASSERT(FAST_DOUBLE_ELEMENTS + kFastElementsKindPackedToHoley ==
88 : FAST_HOLEY_DOUBLE_ELEMENTS);
89 : STATIC_ASSERT(FAST_ELEMENTS + kFastElementsKindPackedToHoley ==
90 : FAST_HOLEY_ELEMENTS);
91 1026 : }
92 : };
93 :
94 :
95 : static base::LazyInstance<ElementsKind*,
96 : InitializeFastElementsKindSequence>::type
97 : fast_elements_kind_sequence = LAZY_INSTANCE_INITIALIZER;
98 :
99 :
100 1822 : ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number) {
101 : DCHECK(sequence_number >= 0 &&
102 : sequence_number < kFastElementsKindCount);
103 12281 : return fast_elements_kind_sequence.Get()[sequence_number];
104 : }
105 :
106 :
107 10789 : int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind) {
108 29993 : for (int i = 0; i < kFastElementsKindCount; ++i) {
109 29993 : if (fast_elements_kind_sequence.Get()[i] == elements_kind) {
110 : return i;
111 : }
112 : }
113 0 : UNREACHABLE();
114 : return 0;
115 : }
116 :
117 :
118 10459 : ElementsKind GetNextTransitionElementsKind(ElementsKind kind) {
119 10459 : int index = GetSequenceIndexFromFastElementsKind(kind);
120 20918 : return GetFastElementsKindFromSequenceIndex(index + 1);
121 : }
122 :
123 :
124 : static inline bool IsFastTransitionTarget(ElementsKind elements_kind) {
125 16191133 : return IsFastElementsKind(elements_kind) ||
126 : elements_kind == DICTIONARY_ELEMENTS;
127 : }
128 :
129 20042042 : bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
130 : ElementsKind to_kind) {
131 38773633 : if (IsFixedTypedArrayElementsKind(from_kind) ||
132 : IsFixedTypedArrayElementsKind(to_kind)) {
133 : return false;
134 : }
135 34920848 : if (IsFastElementsKind(from_kind) && IsFastTransitionTarget(to_kind)) {
136 16190157 : switch (from_kind) {
137 : case FAST_SMI_ELEMENTS:
138 9408860 : return to_kind != FAST_SMI_ELEMENTS;
139 : case FAST_HOLEY_SMI_ELEMENTS:
140 : return to_kind != FAST_SMI_ELEMENTS &&
141 1262968 : to_kind != FAST_HOLEY_SMI_ELEMENTS;
142 : case FAST_DOUBLE_ELEMENTS:
143 1020869 : return to_kind != FAST_SMI_ELEMENTS &&
144 : to_kind != FAST_HOLEY_SMI_ELEMENTS &&
145 1020869 : to_kind != FAST_DOUBLE_ELEMENTS;
146 : case FAST_HOLEY_DOUBLE_ELEMENTS:
147 144192 : return to_kind == FAST_ELEMENTS ||
148 144192 : to_kind == FAST_HOLEY_ELEMENTS;
149 : case FAST_ELEMENTS:
150 2226788 : return to_kind == FAST_HOLEY_ELEMENTS;
151 : case FAST_HOLEY_ELEMENTS:
152 : return false;
153 : default:
154 : return false;
155 : }
156 : }
157 : return false;
158 : }
159 :
160 :
161 : } // namespace internal
162 : } // namespace v8
|