• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ElementsKindToShiftSize(ElementsKind elements_kind)17 int ElementsKindToShiftSize(ElementsKind elements_kind) {
18   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       return 1;
26     case UINT32_ELEMENTS:
27     case INT32_ELEMENTS:
28     case FLOAT32_ELEMENTS:
29       return 2;
30     case FAST_DOUBLE_ELEMENTS:
31     case FAST_HOLEY_DOUBLE_ELEMENTS:
32     case FLOAT64_ELEMENTS:
33       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       return kPointerSizeLog2;
44     case NO_ELEMENTS:
45       UNREACHABLE();
46       return 0;
47   }
48   UNREACHABLE();
49   return 0;
50 }
51 
52 
GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind)53 int GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind) {
54   STATIC_ASSERT(FixedArray::kHeaderSize == FixedDoubleArray::kHeaderSize);
55 
56   if (IsFixedTypedArrayElementsKind(elements_kind)) {
57     return 0;
58   } else {
59     return FixedArray::kHeaderSize - kHeapObjectTag;
60   }
61 }
62 
63 
ElementsKindToString(ElementsKind kind)64 const char* ElementsKindToString(ElementsKind kind) {
65   ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
66   return accessor->name();
67 }
68 
69 
70 struct InitializeFastElementsKindSequence {
Constructv8::internal::InitializeFastElementsKindSequence71   static void Construct(
72       ElementsKind** fast_elements_kind_sequence_ptr) {
73     ElementsKind* fast_elements_kind_sequence =
74         new ElementsKind[kFastElementsKindCount];
75     *fast_elements_kind_sequence_ptr = fast_elements_kind_sequence;
76     STATIC_ASSERT(FAST_SMI_ELEMENTS == FIRST_FAST_ELEMENTS_KIND);
77     fast_elements_kind_sequence[0] = FAST_SMI_ELEMENTS;
78     fast_elements_kind_sequence[1] = FAST_HOLEY_SMI_ELEMENTS;
79     fast_elements_kind_sequence[2] = FAST_DOUBLE_ELEMENTS;
80     fast_elements_kind_sequence[3] = FAST_HOLEY_DOUBLE_ELEMENTS;
81     fast_elements_kind_sequence[4] = FAST_ELEMENTS;
82     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   }
92 };
93 
94 
95 static base::LazyInstance<ElementsKind*,
96                           InitializeFastElementsKindSequence>::type
97     fast_elements_kind_sequence = LAZY_INSTANCE_INITIALIZER;
98 
99 
GetFastElementsKindFromSequenceIndex(int sequence_number)100 ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number) {
101   DCHECK(sequence_number >= 0 &&
102          sequence_number < kFastElementsKindCount);
103   return fast_elements_kind_sequence.Get()[sequence_number];
104 }
105 
106 
GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind)107 int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind) {
108   for (int i = 0; i < kFastElementsKindCount; ++i) {
109     if (fast_elements_kind_sequence.Get()[i] == elements_kind) {
110       return i;
111     }
112   }
113   UNREACHABLE();
114   return 0;
115 }
116 
117 
GetNextTransitionElementsKind(ElementsKind kind)118 ElementsKind GetNextTransitionElementsKind(ElementsKind kind) {
119   int index = GetSequenceIndexFromFastElementsKind(kind);
120   return GetFastElementsKindFromSequenceIndex(index + 1);
121 }
122 
123 
IsFastTransitionTarget(ElementsKind elements_kind)124 static inline bool IsFastTransitionTarget(ElementsKind elements_kind) {
125   return IsFastElementsKind(elements_kind) ||
126       elements_kind == DICTIONARY_ELEMENTS;
127 }
128 
IsMoreGeneralElementsKindTransition(ElementsKind from_kind,ElementsKind to_kind)129 bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
130                                          ElementsKind to_kind) {
131   if (IsFixedTypedArrayElementsKind(from_kind) ||
132       IsFixedTypedArrayElementsKind(to_kind)) {
133     return false;
134   }
135   if (IsFastElementsKind(from_kind) && IsFastTransitionTarget(to_kind)) {
136     switch (from_kind) {
137       case FAST_SMI_ELEMENTS:
138         return to_kind != FAST_SMI_ELEMENTS;
139       case FAST_HOLEY_SMI_ELEMENTS:
140         return to_kind != FAST_SMI_ELEMENTS &&
141             to_kind != FAST_HOLEY_SMI_ELEMENTS;
142       case FAST_DOUBLE_ELEMENTS:
143         return to_kind != FAST_SMI_ELEMENTS &&
144             to_kind != FAST_HOLEY_SMI_ELEMENTS &&
145             to_kind != FAST_DOUBLE_ELEMENTS;
146       case FAST_HOLEY_DOUBLE_ELEMENTS:
147         return to_kind == FAST_ELEMENTS ||
148             to_kind == FAST_HOLEY_ELEMENTS;
149       case FAST_ELEMENTS:
150         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
163