0ebc6dc246b09e7dcb9296bfc138a5457210870f
[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 FAST_SMI_ELEMENTS:
43     case FAST_ELEMENTS:
44     case FAST_HOLEY_SMI_ELEMENTS:
45     case FAST_HOLEY_ELEMENTS:
46     case DICTIONARY_ELEMENTS:
47     case SLOPPY_ARGUMENTS_ELEMENTS:
48       return kPointerSizeLog2;
49   }
50   UNREACHABLE();
51   return 0;
52 }
53
54
55 int GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind) {
56   STATIC_ASSERT(FixedArray::kHeaderSize == FixedDoubleArray::kHeaderSize);
57   return IsExternalArrayElementsKind(elements_kind)
58       ? 0 : (FixedArray::kHeaderSize - kHeapObjectTag);
59 }
60
61
62 const char* ElementsKindToString(ElementsKind kind) {
63   ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
64   return accessor->name();
65 }
66
67
68 struct InitializeFastElementsKindSequence {
69   static void Construct(
70       ElementsKind** fast_elements_kind_sequence_ptr) {
71     ElementsKind* fast_elements_kind_sequence =
72         new ElementsKind[kFastElementsKindCount];
73     *fast_elements_kind_sequence_ptr = fast_elements_kind_sequence;
74     STATIC_ASSERT(FAST_SMI_ELEMENTS == FIRST_FAST_ELEMENTS_KIND);
75     fast_elements_kind_sequence[0] = FAST_SMI_ELEMENTS;
76     fast_elements_kind_sequence[1] = FAST_HOLEY_SMI_ELEMENTS;
77     fast_elements_kind_sequence[2] = FAST_DOUBLE_ELEMENTS;
78     fast_elements_kind_sequence[3] = FAST_HOLEY_DOUBLE_ELEMENTS;
79     fast_elements_kind_sequence[4] = FAST_ELEMENTS;
80     fast_elements_kind_sequence[5] = FAST_HOLEY_ELEMENTS;
81
82     // Verify that kFastElementsKindPackedToHoley is correct.
83     STATIC_ASSERT(FAST_SMI_ELEMENTS + kFastElementsKindPackedToHoley ==
84                   FAST_HOLEY_SMI_ELEMENTS);
85     STATIC_ASSERT(FAST_DOUBLE_ELEMENTS + kFastElementsKindPackedToHoley ==
86                   FAST_HOLEY_DOUBLE_ELEMENTS);
87     STATIC_ASSERT(FAST_ELEMENTS + kFastElementsKindPackedToHoley ==
88                   FAST_HOLEY_ELEMENTS);
89   }
90 };
91
92
93 static base::LazyInstance<ElementsKind*,
94                           InitializeFastElementsKindSequence>::type
95     fast_elements_kind_sequence = LAZY_INSTANCE_INITIALIZER;
96
97
98 ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number) {
99   DCHECK(sequence_number >= 0 &&
100          sequence_number < kFastElementsKindCount);
101   return fast_elements_kind_sequence.Get()[sequence_number];
102 }
103
104
105 int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind) {
106   for (int i = 0; i < kFastElementsKindCount; ++i) {
107     if (fast_elements_kind_sequence.Get()[i] == elements_kind) {
108       return i;
109     }
110   }
111   UNREACHABLE();
112   return 0;
113 }
114
115
116 ElementsKind GetNextTransitionElementsKind(ElementsKind kind) {
117   switch (kind) {
118 #define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
119     case TYPE##_ELEMENTS: return EXTERNAL_##TYPE##_ELEMENTS;
120
121     TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE)
122 #undef FIXED_TYPED_ARRAY_CASE
123     default: {
124       int index = GetSequenceIndexFromFastElementsKind(kind);
125       return GetFastElementsKindFromSequenceIndex(index + 1);
126     }
127   }
128 }
129
130
131 ElementsKind GetNextMoreGeneralFastElementsKind(ElementsKind elements_kind,
132                                                 bool allow_only_packed) {
133   DCHECK(IsFastElementsKind(elements_kind));
134   DCHECK(elements_kind != TERMINAL_FAST_ELEMENTS_KIND);
135   while (true) {
136     elements_kind = GetNextTransitionElementsKind(elements_kind);
137     if (!IsFastHoleyElementsKind(elements_kind) || !allow_only_packed) {
138       return elements_kind;
139     }
140   }
141   UNREACHABLE();
142   return TERMINAL_FAST_ELEMENTS_KIND;
143 }
144
145
146 static bool IsTypedArrayElementsKind(ElementsKind elements_kind) {
147   return IsFixedTypedArrayElementsKind(elements_kind) ||
148       IsExternalArrayElementsKind(elements_kind);
149 }
150
151
152 static inline bool IsFastTransitionTarget(ElementsKind elements_kind) {
153   return IsFastElementsKind(elements_kind) ||
154       elements_kind == DICTIONARY_ELEMENTS;
155 }
156
157 bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
158                                          ElementsKind to_kind) {
159   if (IsTypedArrayElementsKind(from_kind) ||
160       IsTypedArrayElementsKind(to_kind)) {
161     switch (from_kind) {
162 #define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
163       case TYPE##_ELEMENTS:                                   \
164         return to_kind == EXTERNAL_##TYPE##_ELEMENTS;
165
166       TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE);
167 #undef FIXED_TYPED_ARRAY_CASE
168       default:
169         return false;
170     }
171   }
172   if (IsFastElementsKind(from_kind) && IsFastTransitionTarget(to_kind)) {
173     switch (from_kind) {
174       case FAST_SMI_ELEMENTS:
175         return to_kind != FAST_SMI_ELEMENTS;
176       case FAST_HOLEY_SMI_ELEMENTS:
177         return to_kind != FAST_SMI_ELEMENTS &&
178             to_kind != FAST_HOLEY_SMI_ELEMENTS;
179       case FAST_DOUBLE_ELEMENTS:
180         return to_kind != FAST_SMI_ELEMENTS &&
181             to_kind != FAST_HOLEY_SMI_ELEMENTS &&
182             to_kind != FAST_DOUBLE_ELEMENTS;
183       case FAST_HOLEY_DOUBLE_ELEMENTS:
184         return to_kind == FAST_ELEMENTS ||
185             to_kind == FAST_HOLEY_ELEMENTS;
186       case FAST_ELEMENTS:
187         return to_kind == FAST_HOLEY_ELEMENTS;
188       case FAST_HOLEY_ELEMENTS:
189         return false;
190       default:
191         return false;
192     }
193   }
194   return false;
195 }
196
197
198 } }  // namespace v8::internal