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/checks.h" 9 10 namespace v8 { 11 namespace internal { 12 13 enum ElementsKind { 14 // The "fast" kind for elements that only contain SMI values. Must be first 15 // to make it possible to efficiently check maps for this kind. 16 FAST_SMI_ELEMENTS, 17 FAST_HOLEY_SMI_ELEMENTS, 18 19 // The "fast" kind for tagged values. Must be second to make it possible to 20 // efficiently check maps for this and the FAST_SMI_ONLY_ELEMENTS kind 21 // together at once. 22 FAST_ELEMENTS, 23 FAST_HOLEY_ELEMENTS, 24 25 // The "fast" kind for unwrapped, non-tagged double values. 26 FAST_DOUBLE_ELEMENTS, 27 FAST_HOLEY_DOUBLE_ELEMENTS, 28 29 // The "slow" kind. 30 DICTIONARY_ELEMENTS, 31 SLOPPY_ARGUMENTS_ELEMENTS, 32 // The "fast" kind for external arrays 33 EXTERNAL_INT8_ELEMENTS, 34 EXTERNAL_UINT8_ELEMENTS, 35 EXTERNAL_INT16_ELEMENTS, 36 EXTERNAL_UINT16_ELEMENTS, 37 EXTERNAL_INT32_ELEMENTS, 38 EXTERNAL_UINT32_ELEMENTS, 39 EXTERNAL_FLOAT32_ELEMENTS, 40 EXTERNAL_FLOAT64_ELEMENTS, 41 EXTERNAL_UINT8_CLAMPED_ELEMENTS, 42 43 // Fixed typed arrays 44 UINT8_ELEMENTS, 45 INT8_ELEMENTS, 46 UINT16_ELEMENTS, 47 INT16_ELEMENTS, 48 UINT32_ELEMENTS, 49 INT32_ELEMENTS, 50 FLOAT32_ELEMENTS, 51 FLOAT64_ELEMENTS, 52 UINT8_CLAMPED_ELEMENTS, 53 54 // Derived constants from ElementsKind 55 FIRST_ELEMENTS_KIND = FAST_SMI_ELEMENTS, 56 LAST_ELEMENTS_KIND = UINT8_CLAMPED_ELEMENTS, 57 FIRST_FAST_ELEMENTS_KIND = FAST_SMI_ELEMENTS, 58 LAST_FAST_ELEMENTS_KIND = FAST_HOLEY_DOUBLE_ELEMENTS, 59 FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND = EXTERNAL_INT8_ELEMENTS, 60 LAST_EXTERNAL_ARRAY_ELEMENTS_KIND = EXTERNAL_UINT8_CLAMPED_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 == SLOPPY_ARGUMENTS_ELEMENTS; 92 } 93 94 95 inline bool IsExternalArrayElementsKind(ElementsKind kind) { 96 return kind >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND && 97 kind <= LAST_EXTERNAL_ARRAY_ELEMENTS_KIND; 98 } 99 100 101 inline bool IsTerminalElementsKind(ElementsKind kind) { 102 return kind == TERMINAL_FAST_ELEMENTS_KIND || 103 IsExternalArrayElementsKind(kind); 104 } 105 106 107 inline bool IsFixedTypedArrayElementsKind(ElementsKind kind) { 108 return kind >= FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND && 109 kind <= LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND; 110 } 111 112 113 inline bool IsFastElementsKind(ElementsKind kind) { 114 DCHECK(FIRST_FAST_ELEMENTS_KIND == 0); 115 return kind <= FAST_HOLEY_DOUBLE_ELEMENTS; 116 } 117 118 119 inline bool IsTransitionElementsKind(ElementsKind kind) { 120 return IsFastElementsKind(kind) || IsFixedTypedArrayElementsKind(kind); 121 } 122 123 124 inline bool IsFastDoubleElementsKind(ElementsKind kind) { 125 return kind == FAST_DOUBLE_ELEMENTS || 126 kind == FAST_HOLEY_DOUBLE_ELEMENTS; 127 } 128 129 130 inline bool IsExternalFloatOrDoubleElementsKind(ElementsKind kind) { 131 return kind == EXTERNAL_FLOAT64_ELEMENTS || 132 kind == EXTERNAL_FLOAT32_ELEMENTS; 133 } 134 135 136 inline bool IsFixedFloatElementsKind(ElementsKind kind) { 137 return kind == FLOAT32_ELEMENTS || kind == FLOAT64_ELEMENTS; 138 } 139 140 141 inline bool IsDoubleOrFloatElementsKind(ElementsKind kind) { 142 return IsFastDoubleElementsKind(kind) || 143 IsExternalFloatOrDoubleElementsKind(kind) || 144 IsFixedFloatElementsKind(kind); 145 } 146 147 148 inline bool IsFastSmiOrObjectElementsKind(ElementsKind kind) { 149 return kind == FAST_SMI_ELEMENTS || 150 kind == FAST_HOLEY_SMI_ELEMENTS || 151 kind == FAST_ELEMENTS || 152 kind == FAST_HOLEY_ELEMENTS; 153 } 154 155 156 inline bool IsFastSmiElementsKind(ElementsKind kind) { 157 return kind == FAST_SMI_ELEMENTS || 158 kind == FAST_HOLEY_SMI_ELEMENTS; 159 } 160 161 162 inline bool IsFastObjectElementsKind(ElementsKind kind) { 163 return kind == FAST_ELEMENTS || 164 kind == FAST_HOLEY_ELEMENTS; 165 } 166 167 168 inline bool IsFastHoleyElementsKind(ElementsKind kind) { 169 return kind == FAST_HOLEY_SMI_ELEMENTS || 170 kind == FAST_HOLEY_DOUBLE_ELEMENTS || 171 kind == FAST_HOLEY_ELEMENTS; 172 } 173 174 175 inline bool IsHoleyElementsKind(ElementsKind kind) { 176 return IsFastHoleyElementsKind(kind) || 177 kind == DICTIONARY_ELEMENTS; 178 } 179 180 181 inline bool IsFastPackedElementsKind(ElementsKind kind) { 182 return kind == FAST_SMI_ELEMENTS || 183 kind == FAST_DOUBLE_ELEMENTS || 184 kind == FAST_ELEMENTS; 185 } 186 187 188 inline ElementsKind GetPackedElementsKind(ElementsKind holey_kind) { 189 if (holey_kind == FAST_HOLEY_SMI_ELEMENTS) { 190 return FAST_SMI_ELEMENTS; 191 } 192 if (holey_kind == FAST_HOLEY_DOUBLE_ELEMENTS) { 193 return FAST_DOUBLE_ELEMENTS; 194 } 195 if (holey_kind == FAST_HOLEY_ELEMENTS) { 196 return FAST_ELEMENTS; 197 } 198 return holey_kind; 199 } 200 201 202 inline ElementsKind GetHoleyElementsKind(ElementsKind packed_kind) { 203 if (packed_kind == FAST_SMI_ELEMENTS) { 204 return FAST_HOLEY_SMI_ELEMENTS; 205 } 206 if (packed_kind == FAST_DOUBLE_ELEMENTS) { 207 return FAST_HOLEY_DOUBLE_ELEMENTS; 208 } 209 if (packed_kind == FAST_ELEMENTS) { 210 return FAST_HOLEY_ELEMENTS; 211 } 212 return packed_kind; 213 } 214 215 216 inline ElementsKind FastSmiToObjectElementsKind(ElementsKind from_kind) { 217 DCHECK(IsFastSmiElementsKind(from_kind)); 218 return (from_kind == FAST_SMI_ELEMENTS) 219 ? FAST_ELEMENTS 220 : FAST_HOLEY_ELEMENTS; 221 } 222 223 224 inline bool IsSimpleMapChangeTransition(ElementsKind from_kind, 225 ElementsKind to_kind) { 226 return (GetHoleyElementsKind(from_kind) == to_kind) || 227 (IsFastSmiElementsKind(from_kind) && 228 IsFastObjectElementsKind(to_kind)); 229 } 230 231 232 bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind, 233 ElementsKind to_kind); 234 235 236 inline bool IsTransitionableFastElementsKind(ElementsKind from_kind) { 237 return IsFastElementsKind(from_kind) && 238 from_kind != TERMINAL_FAST_ELEMENTS_KIND; 239 } 240 241 242 ElementsKind GetNextMoreGeneralFastElementsKind(ElementsKind elements_kind, 243 bool allow_only_packed); 244 245 246 inline bool CanTransitionToMoreGeneralFastElementsKind( 247 ElementsKind elements_kind, 248 bool allow_only_packed) { 249 return IsFastElementsKind(elements_kind) && 250 (elements_kind != TERMINAL_FAST_ELEMENTS_KIND && 251 (!allow_only_packed || elements_kind != FAST_ELEMENTS)); 252 } 253 254 255 } } // namespace v8::internal 256 257 #endif // V8_ELEMENTS_KIND_H_ 258