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 #ifndef V8_ELEMENTS_KIND_H_ 6 #define V8_ELEMENTS_KIND_H_ 7 8 #include "src/base/macros.h" 9 #include "src/checks.h" 10 11 namespace v8 { 12 namespace internal { 13 14 enum ElementsKind { 15 // The "fast" kind for elements that only contain SMI values. Must be first 16 // to make it possible to efficiently check maps for this kind. 17 FAST_SMI_ELEMENTS, 18 FAST_HOLEY_SMI_ELEMENTS, 19 20 // The "fast" kind for tagged values. Must be second to make it possible to 21 // efficiently check maps for this and the FAST_SMI_ONLY_ELEMENTS kind 22 // together at once. 23 FAST_ELEMENTS, 24 FAST_HOLEY_ELEMENTS, 25 26 // The "fast" kind for unwrapped, non-tagged double values. 27 FAST_DOUBLE_ELEMENTS, 28 FAST_HOLEY_DOUBLE_ELEMENTS, 29 30 // The "slow" kind. 31 DICTIONARY_ELEMENTS, 32 33 FAST_SLOPPY_ARGUMENTS_ELEMENTS, 34 SLOW_SLOPPY_ARGUMENTS_ELEMENTS, 35 36 // Fixed typed arrays 37 UINT8_ELEMENTS, 38 INT8_ELEMENTS, 39 UINT16_ELEMENTS, 40 INT16_ELEMENTS, 41 UINT32_ELEMENTS, 42 INT32_ELEMENTS, 43 FLOAT32_ELEMENTS, 44 FLOAT64_ELEMENTS, 45 UINT8_CLAMPED_ELEMENTS, 46 47 // Derived constants from ElementsKind 48 FIRST_ELEMENTS_KIND = FAST_SMI_ELEMENTS, 49 LAST_ELEMENTS_KIND = UINT8_CLAMPED_ELEMENTS, 50 FIRST_FAST_ELEMENTS_KIND = FAST_SMI_ELEMENTS, 51 LAST_FAST_ELEMENTS_KIND = FAST_HOLEY_DOUBLE_ELEMENTS, 52 FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND = UINT8_ELEMENTS, 53 LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND = UINT8_CLAMPED_ELEMENTS, 54 TERMINAL_FAST_ELEMENTS_KIND = FAST_HOLEY_ELEMENTS 55 }; 56 57 const int kElementsKindCount = LAST_ELEMENTS_KIND - FIRST_ELEMENTS_KIND + 1; 58 const int kFastElementsKindCount = LAST_FAST_ELEMENTS_KIND - 59 FIRST_FAST_ELEMENTS_KIND + 1; 60 61 // The number to add to a packed elements kind to reach a holey elements kind 62 const int kFastElementsKindPackedToHoley = 63 FAST_HOLEY_SMI_ELEMENTS - FAST_SMI_ELEMENTS; 64 65 int ElementsKindToShiftSize(ElementsKind elements_kind); 66 int GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind); 67 const char* ElementsKindToString(ElementsKind kind); 68 69 inline ElementsKind GetInitialFastElementsKind() { return FAST_SMI_ELEMENTS; } 70 71 ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number); 72 int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind); 73 74 ElementsKind GetNextTransitionElementsKind(ElementsKind elements_kind); 75 76 inline bool IsDictionaryElementsKind(ElementsKind kind) { 77 return kind == DICTIONARY_ELEMENTS; 78 } 79 80 81 inline bool IsSloppyArgumentsElements(ElementsKind kind) { 82 return kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS || 83 kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS; 84 } 85 86 87 inline bool IsFixedTypedArrayElementsKind(ElementsKind kind) { 88 return kind >= FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND && 89 kind <= LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND; 90 } 91 92 93 inline bool IsTerminalElementsKind(ElementsKind kind) { 94 return kind == TERMINAL_FAST_ELEMENTS_KIND || 95 IsFixedTypedArrayElementsKind(kind); 96 } 97 98 99 inline bool IsFastElementsKind(ElementsKind kind) { 100 STATIC_ASSERT(FIRST_FAST_ELEMENTS_KIND == 0); 101 return kind <= FAST_HOLEY_DOUBLE_ELEMENTS; 102 } 103 104 105 inline bool IsTransitionElementsKind(ElementsKind kind) { 106 return IsFastElementsKind(kind) || IsFixedTypedArrayElementsKind(kind) || 107 kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS; 108 } 109 110 111 inline bool IsFastDoubleElementsKind(ElementsKind kind) { 112 return kind == FAST_DOUBLE_ELEMENTS || 113 kind == FAST_HOLEY_DOUBLE_ELEMENTS; 114 } 115 116 117 inline bool IsFixedFloatElementsKind(ElementsKind kind) { 118 return kind == FLOAT32_ELEMENTS || kind == FLOAT64_ELEMENTS; 119 } 120 121 122 inline bool IsDoubleOrFloatElementsKind(ElementsKind kind) { 123 return IsFastDoubleElementsKind(kind) || IsFixedFloatElementsKind(kind); 124 } 125 126 127 inline bool IsFastSmiOrObjectElementsKind(ElementsKind kind) { 128 return kind == FAST_SMI_ELEMENTS || 129 kind == FAST_HOLEY_SMI_ELEMENTS || 130 kind == FAST_ELEMENTS || 131 kind == FAST_HOLEY_ELEMENTS; 132 } 133 134 135 inline bool IsFastSmiElementsKind(ElementsKind kind) { 136 return kind == FAST_SMI_ELEMENTS || 137 kind == FAST_HOLEY_SMI_ELEMENTS; 138 } 139 140 141 inline bool IsFastObjectElementsKind(ElementsKind kind) { 142 return kind == FAST_ELEMENTS || 143 kind == FAST_HOLEY_ELEMENTS; 144 } 145 146 147 inline bool IsFastHoleyElementsKind(ElementsKind kind) { 148 return kind == FAST_HOLEY_SMI_ELEMENTS || 149 kind == FAST_HOLEY_DOUBLE_ELEMENTS || 150 kind == FAST_HOLEY_ELEMENTS; 151 } 152 153 154 inline bool IsHoleyElementsKind(ElementsKind kind) { 155 return IsFastHoleyElementsKind(kind) || 156 kind == DICTIONARY_ELEMENTS; 157 } 158 159 160 inline bool IsFastPackedElementsKind(ElementsKind kind) { 161 return kind == FAST_SMI_ELEMENTS || kind == FAST_DOUBLE_ELEMENTS || 162 kind == FAST_ELEMENTS; 163 } 164 165 166 inline ElementsKind GetPackedElementsKind(ElementsKind holey_kind) { 167 if (holey_kind == FAST_HOLEY_SMI_ELEMENTS) { 168 return FAST_SMI_ELEMENTS; 169 } 170 if (holey_kind == FAST_HOLEY_DOUBLE_ELEMENTS) { 171 return FAST_DOUBLE_ELEMENTS; 172 } 173 if (holey_kind == FAST_HOLEY_ELEMENTS) { 174 return FAST_ELEMENTS; 175 } 176 return holey_kind; 177 } 178 179 180 inline ElementsKind GetHoleyElementsKind(ElementsKind packed_kind) { 181 if (packed_kind == FAST_SMI_ELEMENTS) { 182 return FAST_HOLEY_SMI_ELEMENTS; 183 } 184 if (packed_kind == FAST_DOUBLE_ELEMENTS) { 185 return FAST_HOLEY_DOUBLE_ELEMENTS; 186 } 187 if (packed_kind == FAST_ELEMENTS) { 188 return FAST_HOLEY_ELEMENTS; 189 } 190 return packed_kind; 191 } 192 193 194 inline ElementsKind FastSmiToObjectElementsKind(ElementsKind from_kind) { 195 DCHECK(IsFastSmiElementsKind(from_kind)); 196 return (from_kind == FAST_SMI_ELEMENTS) 197 ? FAST_ELEMENTS 198 : FAST_HOLEY_ELEMENTS; 199 } 200 201 202 inline bool IsSimpleMapChangeTransition(ElementsKind from_kind, 203 ElementsKind to_kind) { 204 return (GetHoleyElementsKind(from_kind) == to_kind) || 205 (IsFastSmiElementsKind(from_kind) && 206 IsFastObjectElementsKind(to_kind)); 207 } 208 209 210 bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind, 211 ElementsKind to_kind); 212 213 214 inline ElementsKind GetMoreGeneralElementsKind(ElementsKind from_kind, 215 ElementsKind to_kind) { 216 if (IsMoreGeneralElementsKindTransition(from_kind, to_kind)) { 217 return to_kind; 218 } 219 return from_kind; 220 } 221 222 223 inline bool IsTransitionableFastElementsKind(ElementsKind from_kind) { 224 return IsFastElementsKind(from_kind) && 225 from_kind != TERMINAL_FAST_ELEMENTS_KIND; 226 } 227 228 229 } // namespace internal 230 } // namespace v8 231 232 #endif // V8_ELEMENTS_KIND_H_ 233