Upstream version 8.37.186.0
[platform/framework/web/crosswalk.git] / src / v8 / src / elements-kind.cc
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.h"
11
12 namespace v8 {
13 namespace internal {
14
15
16 int ElementsKindToShiftSize(ElementsKind elements_kind) {
17   switch (elements_kind) {
18     case EXTERNAL_INT8_ELEMENTS:
19     case EXTERNAL_UINT8_CLAMPED_ELEMENTS:
20     case EXTERNAL_UINT8_ELEMENTS:
21     case UINT8_ELEMENTS:
22     case INT8_ELEMENTS:
23     case UINT8_CLAMPED_ELEMENTS:
24       return 0;
25     case EXTERNAL_INT16_ELEMENTS:
26     case EXTERNAL_UINT16_ELEMENTS:
27     case UINT16_ELEMENTS:
28     case INT16_ELEMENTS:
29       return 1;
30     case EXTERNAL_INT32_ELEMENTS:
31     case EXTERNAL_UINT32_ELEMENTS:
32     case EXTERNAL_FLOAT32_ELEMENTS:
33     case UINT32_ELEMENTS:
34     case INT32_ELEMENTS:
35     case FLOAT32_ELEMENTS:
36       return 2;
37     case EXTERNAL_FLOAT64_ELEMENTS:
38     case FAST_DOUBLE_ELEMENTS:
39     case FAST_HOLEY_DOUBLE_ELEMENTS:
40     case FLOAT64_ELEMENTS:
41       return 3;
42     case EXTERNAL_FLOAT32x4_ELEMENTS:
43     case EXTERNAL_FLOAT64x2_ELEMENTS:
44     case EXTERNAL_INT32x4_ELEMENTS:
45     case FLOAT32x4_ELEMENTS:
46     case FLOAT64x2_ELEMENTS:
47     case INT32x4_ELEMENTS:
48       return 4;
49     case FAST_SMI_ELEMENTS:
50     case FAST_ELEMENTS:
51     case FAST_HOLEY_SMI_ELEMENTS:
52     case FAST_HOLEY_ELEMENTS:
53     case DICTIONARY_ELEMENTS:
54     case SLOPPY_ARGUMENTS_ELEMENTS:
55       return kPointerSizeLog2;
56   }
57   UNREACHABLE();
58   return 0;
59 }
60
61
62 int GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind) {
63   STATIC_ASSERT(FixedArray::kHeaderSize == FixedDoubleArray::kHeaderSize);
64   return IsExternalArrayElementsKind(elements_kind)
65       ? 0 : (FixedArray::kHeaderSize - kHeapObjectTag);
66 }
67
68
69 const char* ElementsKindToString(ElementsKind kind) {
70   ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
71   return accessor->name();
72 }
73
74
75 void PrintElementsKind(FILE* out, ElementsKind kind) {
76   PrintF(out, "%s", ElementsKindToString(kind));
77 }
78
79
80 ElementsKind GetInitialFastElementsKind() {
81   if (FLAG_packed_arrays) {
82     return FAST_SMI_ELEMENTS;
83   } else {
84     return FAST_HOLEY_SMI_ELEMENTS;
85   }
86 }
87
88
89 struct InitializeFastElementsKindSequence {
90   static void Construct(
91       ElementsKind** fast_elements_kind_sequence_ptr) {
92     ElementsKind* fast_elements_kind_sequence =
93         new ElementsKind[kFastElementsKindCount];
94     *fast_elements_kind_sequence_ptr = fast_elements_kind_sequence;
95     STATIC_ASSERT(FAST_SMI_ELEMENTS == FIRST_FAST_ELEMENTS_KIND);
96     fast_elements_kind_sequence[0] = FAST_SMI_ELEMENTS;
97     fast_elements_kind_sequence[1] = FAST_HOLEY_SMI_ELEMENTS;
98     fast_elements_kind_sequence[2] = FAST_DOUBLE_ELEMENTS;
99     fast_elements_kind_sequence[3] = FAST_HOLEY_DOUBLE_ELEMENTS;
100     fast_elements_kind_sequence[4] = FAST_ELEMENTS;
101     fast_elements_kind_sequence[5] = FAST_HOLEY_ELEMENTS;
102
103     // Verify that kFastElementsKindPackedToHoley is correct.
104     STATIC_ASSERT(FAST_SMI_ELEMENTS + kFastElementsKindPackedToHoley ==
105                   FAST_HOLEY_SMI_ELEMENTS);
106     STATIC_ASSERT(FAST_DOUBLE_ELEMENTS + kFastElementsKindPackedToHoley ==
107                   FAST_HOLEY_DOUBLE_ELEMENTS);
108     STATIC_ASSERT(FAST_ELEMENTS + kFastElementsKindPackedToHoley ==
109                   FAST_HOLEY_ELEMENTS);
110   }
111 };
112
113
114 static base::LazyInstance<ElementsKind*,
115                           InitializeFastElementsKindSequence>::type
116     fast_elements_kind_sequence = LAZY_INSTANCE_INITIALIZER;
117
118
119 ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number) {
120   ASSERT(sequence_number >= 0 &&
121          sequence_number < kFastElementsKindCount);
122   return fast_elements_kind_sequence.Get()[sequence_number];
123 }
124
125
126 int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind) {
127   for (int i = 0; i < kFastElementsKindCount; ++i) {
128     if (fast_elements_kind_sequence.Get()[i] == elements_kind) {
129       return i;
130     }
131   }
132   UNREACHABLE();
133   return 0;
134 }
135
136
137 ElementsKind GetNextTransitionElementsKind(ElementsKind kind) {
138   switch (kind) {
139 #define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
140     case TYPE##_ELEMENTS: return EXTERNAL_##TYPE##_ELEMENTS;
141
142     TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE)
143 #undef FIXED_TYPED_ARRAY_CASE
144     default: {
145       int index = GetSequenceIndexFromFastElementsKind(kind);
146       return GetFastElementsKindFromSequenceIndex(index + 1);
147     }
148   }
149 }
150
151
152 ElementsKind GetNextMoreGeneralFastElementsKind(ElementsKind elements_kind,
153                                                 bool allow_only_packed) {
154   ASSERT(IsFastElementsKind(elements_kind));
155   ASSERT(elements_kind != TERMINAL_FAST_ELEMENTS_KIND);
156   while (true) {
157     elements_kind = GetNextTransitionElementsKind(elements_kind);
158     if (!IsFastHoleyElementsKind(elements_kind) || !allow_only_packed) {
159       return elements_kind;
160     }
161   }
162   UNREACHABLE();
163   return TERMINAL_FAST_ELEMENTS_KIND;
164 }
165
166
167 static bool IsTypedArrayElementsKind(ElementsKind elements_kind) {
168   return IsFixedTypedArrayElementsKind(elements_kind) ||
169       IsExternalArrayElementsKind(elements_kind);
170 }
171
172
173 static inline bool IsFastTransitionTarget(ElementsKind elements_kind) {
174   return IsFastElementsKind(elements_kind) ||
175       elements_kind == DICTIONARY_ELEMENTS;
176 }
177
178 bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
179                                          ElementsKind to_kind) {
180   if (IsTypedArrayElementsKind(from_kind) ||
181       IsTypedArrayElementsKind(to_kind)) {
182     switch (from_kind) {
183 #define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
184       case TYPE##_ELEMENTS:                                   \
185         return to_kind == EXTERNAL_##TYPE##_ELEMENTS;
186
187       TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE);
188 #undef FIXED_TYPED_ARRAY_CASE
189       default:
190         return false;
191     }
192   }
193   if (IsFastElementsKind(from_kind) && IsFastTransitionTarget(to_kind)) {
194     switch (from_kind) {
195       case FAST_SMI_ELEMENTS:
196         return to_kind != FAST_SMI_ELEMENTS;
197       case FAST_HOLEY_SMI_ELEMENTS:
198         return to_kind != FAST_SMI_ELEMENTS &&
199             to_kind != FAST_HOLEY_SMI_ELEMENTS;
200       case FAST_DOUBLE_ELEMENTS:
201         return to_kind != FAST_SMI_ELEMENTS &&
202             to_kind != FAST_HOLEY_SMI_ELEMENTS &&
203             to_kind != FAST_DOUBLE_ELEMENTS;
204       case FAST_HOLEY_DOUBLE_ELEMENTS:
205         return to_kind == FAST_ELEMENTS ||
206             to_kind == FAST_HOLEY_ELEMENTS;
207       case FAST_ELEMENTS:
208         return to_kind == FAST_HOLEY_ELEMENTS;
209       case FAST_HOLEY_ELEMENTS:
210         return false;
211       default:
212         return false;
213     }
214   }
215   return false;
216 }
217
218
219 } }  // namespace v8::internal