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