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 // Elements kind of the "arguments" object (only in sloppy mode). 34 FAST_SLOPPY_ARGUMENTS_ELEMENTS, 35 SLOW_SLOPPY_ARGUMENTS_ELEMENTS, 36 37 // For string wrapper objects ("new String('...')"), the string's characters 38 // are overlaid onto a regular elements backing store. 39 FAST_STRING_WRAPPER_ELEMENTS, 40 SLOW_STRING_WRAPPER_ELEMENTS, 41 42 // Fixed typed arrays. 43 UINT8_ELEMENTS, 44 INT8_ELEMENTS, 45 UINT16_ELEMENTS, 46 INT16_ELEMENTS, 47 UINT32_ELEMENTS, 48 INT32_ELEMENTS, 49 FLOAT32_ELEMENTS, 50 FLOAT64_ELEMENTS, 51 UINT8_CLAMPED_ELEMENTS, 52 53 // Sentinel ElementsKind for objects with no elements. 54 NO_ELEMENTS, 55 56 // Derived constants from ElementsKind. 57 FIRST_ELEMENTS_KIND = FAST_SMI_ELEMENTS, 58 LAST_ELEMENTS_KIND = UINT8_CLAMPED_ELEMENTS, 59 FIRST_FAST_ELEMENTS_KIND = FAST_SMI_ELEMENTS, 60 LAST_FAST_ELEMENTS_KIND = FAST_HOLEY_DOUBLE_ELEMENTS, 61 FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND = UINT8_ELEMENTS, 62 LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND = UINT8_CLAMPED_ELEMENTS, 63 TERMINAL_FAST_ELEMENTS_KIND = FAST_HOLEY_ELEMENTS 64 }; 65 66 const int kElementsKindCount = LAST_ELEMENTS_KIND - FIRST_ELEMENTS_KIND + 1; 67 const int kFastElementsKindCount = LAST_FAST_ELEMENTS_KIND - 68 FIRST_FAST_ELEMENTS_KIND + 1; 69 70 // The number to add to a packed elements kind to reach a holey elements kind 71 const int kFastElementsKindPackedToHoley = 72 FAST_HOLEY_SMI_ELEMENTS - FAST_SMI_ELEMENTS; 73 74 int ElementsKindToShiftSize(ElementsKind elements_kind); 75 int GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind); 76 const char* ElementsKindToString(ElementsKind kind); 77 78 inline ElementsKind GetInitialFastElementsKind() { return FAST_SMI_ELEMENTS; } 79 80 ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number); 81 int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind); 82 83 ElementsKind GetNextTransitionElementsKind(ElementsKind elements_kind); 84 85 inline bool IsDictionaryElementsKind(ElementsKind kind) { 86 return kind == DICTIONARY_ELEMENTS; 87 } 88 89 90 inline bool IsSloppyArgumentsElements(ElementsKind kind) { 91 return kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS || 92 kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS; 93 } 94 95 inline bool IsStringWrapperElementsKind(ElementsKind kind) { 96 return kind == FAST_STRING_WRAPPER_ELEMENTS || 97 kind == SLOW_STRING_WRAPPER_ELEMENTS; 98 } 99 100 inline bool IsFixedTypedArrayElementsKind(ElementsKind kind) { 101 return kind >= FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND && 102 kind <= LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND; 103 } 104 105 106 inline bool IsTerminalElementsKind(ElementsKind kind) { 107 return kind == TERMINAL_FAST_ELEMENTS_KIND || 108 IsFixedTypedArrayElementsKind(kind); 109 } 110 111 112 inline bool IsFastElementsKind(ElementsKind kind) { 113 STATIC_ASSERT(FIRST_FAST_ELEMENTS_KIND == 0); 114 return kind <= FAST_HOLEY_DOUBLE_ELEMENTS; 115 } 116 117 118 inline bool IsTransitionElementsKind(ElementsKind kind) { 119 return IsFastElementsKind(kind) || IsFixedTypedArrayElementsKind(kind) || 120 kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS || 121 kind == FAST_STRING_WRAPPER_ELEMENTS; 122 } 123 124 125 inline bool IsFastDoubleElementsKind(ElementsKind kind) { 126 return kind == FAST_DOUBLE_ELEMENTS || 127 kind == FAST_HOLEY_DOUBLE_ELEMENTS; 128 } 129 130 131 inline bool IsFixedFloatElementsKind(ElementsKind kind) { 132 return kind == FLOAT32_ELEMENTS || kind == FLOAT64_ELEMENTS; 133 } 134 135 136 inline bool IsDoubleOrFloatElementsKind(ElementsKind kind) { 137 return IsFastDoubleElementsKind(kind) || IsFixedFloatElementsKind(kind); 138 } 139 140 141 inline bool IsFastSmiOrObjectElementsKind(ElementsKind kind) { 142 return kind == FAST_SMI_ELEMENTS || 143 kind == FAST_HOLEY_SMI_ELEMENTS || 144 kind == FAST_ELEMENTS || 145 kind == FAST_HOLEY_ELEMENTS; 146 } 147 148 149 inline bool IsFastSmiElementsKind(ElementsKind kind) { 150 return kind == FAST_SMI_ELEMENTS || 151 kind == FAST_HOLEY_SMI_ELEMENTS; 152 } 153 154 155 inline bool IsFastObjectElementsKind(ElementsKind kind) { 156 return kind == FAST_ELEMENTS || 157 kind == FAST_HOLEY_ELEMENTS; 158 } 159 160 161 inline bool IsFastHoleyElementsKind(ElementsKind kind) { 162 return kind == FAST_HOLEY_SMI_ELEMENTS || 163 kind == FAST_HOLEY_DOUBLE_ELEMENTS || 164 kind == FAST_HOLEY_ELEMENTS; 165 } 166 167 168 inline bool IsHoleyElementsKind(ElementsKind kind) { 169 return IsFastHoleyElementsKind(kind) || 170 kind == DICTIONARY_ELEMENTS; 171 } 172 173 174 inline bool IsFastPackedElementsKind(ElementsKind kind) { 175 return kind == FAST_SMI_ELEMENTS || kind == FAST_DOUBLE_ELEMENTS || 176 kind == FAST_ELEMENTS; 177 } 178 179 180 inline ElementsKind GetPackedElementsKind(ElementsKind holey_kind) { 181 if (holey_kind == FAST_HOLEY_SMI_ELEMENTS) { 182 return FAST_SMI_ELEMENTS; 183 } 184 if (holey_kind == FAST_HOLEY_DOUBLE_ELEMENTS) { 185 return FAST_DOUBLE_ELEMENTS; 186 } 187 if (holey_kind == FAST_HOLEY_ELEMENTS) { 188 return FAST_ELEMENTS; 189 } 190 return holey_kind; 191 } 192 193 194 inline ElementsKind GetHoleyElementsKind(ElementsKind packed_kind) { 195 if (packed_kind == FAST_SMI_ELEMENTS) { 196 return FAST_HOLEY_SMI_ELEMENTS; 197 } 198 if (packed_kind == FAST_DOUBLE_ELEMENTS) { 199 return FAST_HOLEY_DOUBLE_ELEMENTS; 200 } 201 if (packed_kind == FAST_ELEMENTS) { 202 return FAST_HOLEY_ELEMENTS; 203 } 204 return packed_kind; 205 } 206 207 208 inline ElementsKind FastSmiToObjectElementsKind(ElementsKind from_kind) { 209 DCHECK(IsFastSmiElementsKind(from_kind)); 210 return (from_kind == FAST_SMI_ELEMENTS) 211 ? FAST_ELEMENTS 212 : FAST_HOLEY_ELEMENTS; 213 } 214 215 216 inline bool IsSimpleMapChangeTransition(ElementsKind from_kind, 217 ElementsKind to_kind) { 218 return (GetHoleyElementsKind(from_kind) == to_kind) || 219 (IsFastSmiElementsKind(from_kind) && 220 IsFastObjectElementsKind(to_kind)); 221 } 222 223 224 bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind, 225 ElementsKind to_kind); 226 227 228 inline ElementsKind GetMoreGeneralElementsKind(ElementsKind from_kind, 229 ElementsKind to_kind) { 230 if (IsMoreGeneralElementsKindTransition(from_kind, to_kind)) { 231 return to_kind; 232 } 233 return from_kind; 234 } 235 236 237 inline bool IsTransitionableFastElementsKind(ElementsKind from_kind) { 238 return IsFastElementsKind(from_kind) && 239 from_kind != TERMINAL_FAST_ELEMENTS_KIND; 240 } 241 242 243 } // namespace internal 244 } // namespace v8 245 246 #endif // V8_ELEMENTS_KIND_H_ 247