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/v8checks.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 void PrintElementsKind(FILE* out, ElementsKind kind); 78 79 ElementsKind GetInitialFastElementsKind(); 80 81 ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number); 82 int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind); 83 84 ElementsKind GetNextTransitionElementsKind(ElementsKind elements_kind); 85 86 inline bool IsDictionaryElementsKind(ElementsKind kind) { 87 return kind == DICTIONARY_ELEMENTS; 88 } 89 90 91 inline bool IsExternalArrayElementsKind(ElementsKind kind) { 92 return kind >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND && 93 kind <= LAST_EXTERNAL_ARRAY_ELEMENTS_KIND; 94 } 95 96 97 inline bool IsTerminalElementsKind(ElementsKind kind) { 98 return kind == TERMINAL_FAST_ELEMENTS_KIND || 99 IsExternalArrayElementsKind(kind); 100 } 101 102 103 inline bool IsFixedTypedArrayElementsKind(ElementsKind kind) { 104 return kind >= FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND && 105 kind <= LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND; 106 } 107 108 109 inline bool IsFastElementsKind(ElementsKind kind) { 110 ASSERT(FIRST_FAST_ELEMENTS_KIND == 0); 111 return kind <= FAST_HOLEY_DOUBLE_ELEMENTS; 112 } 113 114 115 inline bool IsTransitionElementsKind(ElementsKind kind) { 116 return IsFastElementsKind(kind) || IsFixedTypedArrayElementsKind(kind); 117 } 118 119 120 inline bool IsFastDoubleElementsKind(ElementsKind kind) { 121 return kind == FAST_DOUBLE_ELEMENTS || 122 kind == FAST_HOLEY_DOUBLE_ELEMENTS; 123 } 124 125 126 inline bool IsExternalFloatOrDoubleElementsKind(ElementsKind kind) { 127 return kind == EXTERNAL_FLOAT64_ELEMENTS || 128 kind == EXTERNAL_FLOAT32_ELEMENTS; 129 } 130 131 132 inline bool IsFixedFloatElementsKind(ElementsKind kind) { 133 return kind == FLOAT32_ELEMENTS || kind == FLOAT64_ELEMENTS; 134 } 135 136 137 inline bool IsDoubleOrFloatElementsKind(ElementsKind kind) { 138 return IsFastDoubleElementsKind(kind) || 139 IsExternalFloatOrDoubleElementsKind(kind) || 140 IsFixedFloatElementsKind(kind); 141 } 142 143 144 inline bool IsFastSmiOrObjectElementsKind(ElementsKind kind) { 145 return kind == FAST_SMI_ELEMENTS || 146 kind == FAST_HOLEY_SMI_ELEMENTS || 147 kind == FAST_ELEMENTS || 148 kind == FAST_HOLEY_ELEMENTS; 149 } 150 151 152 inline bool IsFastSmiElementsKind(ElementsKind kind) { 153 return kind == FAST_SMI_ELEMENTS || 154 kind == FAST_HOLEY_SMI_ELEMENTS; 155 } 156 157 158 inline bool IsFastObjectElementsKind(ElementsKind kind) { 159 return kind == FAST_ELEMENTS || 160 kind == FAST_HOLEY_ELEMENTS; 161 } 162 163 164 inline bool IsFastHoleyElementsKind(ElementsKind kind) { 165 return kind == FAST_HOLEY_SMI_ELEMENTS || 166 kind == FAST_HOLEY_DOUBLE_ELEMENTS || 167 kind == FAST_HOLEY_ELEMENTS; 168 } 169 170 171 inline bool IsHoleyElementsKind(ElementsKind kind) { 172 return IsFastHoleyElementsKind(kind) || 173 kind == DICTIONARY_ELEMENTS; 174 } 175 176 177 inline bool IsFastPackedElementsKind(ElementsKind kind) { 178 return kind == FAST_SMI_ELEMENTS || 179 kind == FAST_DOUBLE_ELEMENTS || 180 kind == FAST_ELEMENTS; 181 } 182 183 184 inline ElementsKind GetPackedElementsKind(ElementsKind holey_kind) { 185 if (holey_kind == FAST_HOLEY_SMI_ELEMENTS) { 186 return FAST_SMI_ELEMENTS; 187 } 188 if (holey_kind == FAST_HOLEY_DOUBLE_ELEMENTS) { 189 return FAST_DOUBLE_ELEMENTS; 190 } 191 if (holey_kind == FAST_HOLEY_ELEMENTS) { 192 return FAST_ELEMENTS; 193 } 194 return holey_kind; 195 } 196 197 198 inline ElementsKind GetHoleyElementsKind(ElementsKind packed_kind) { 199 if (packed_kind == FAST_SMI_ELEMENTS) { 200 return FAST_HOLEY_SMI_ELEMENTS; 201 } 202 if (packed_kind == FAST_DOUBLE_ELEMENTS) { 203 return FAST_HOLEY_DOUBLE_ELEMENTS; 204 } 205 if (packed_kind == FAST_ELEMENTS) { 206 return FAST_HOLEY_ELEMENTS; 207 } 208 return packed_kind; 209 } 210 211 212 inline ElementsKind FastSmiToObjectElementsKind(ElementsKind from_kind) { 213 ASSERT(IsFastSmiElementsKind(from_kind)); 214 return (from_kind == FAST_SMI_ELEMENTS) 215 ? FAST_ELEMENTS 216 : FAST_HOLEY_ELEMENTS; 217 } 218 219 220 inline bool IsSimpleMapChangeTransition(ElementsKind from_kind, 221 ElementsKind to_kind) { 222 return (GetHoleyElementsKind(from_kind) == to_kind) || 223 (IsFastSmiElementsKind(from_kind) && 224 IsFastObjectElementsKind(to_kind)); 225 } 226 227 228 bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind, 229 ElementsKind to_kind); 230 231 232 inline bool IsTransitionableFastElementsKind(ElementsKind from_kind) { 233 return IsFastElementsKind(from_kind) && 234 from_kind != TERMINAL_FAST_ELEMENTS_KIND; 235 } 236 237 238 ElementsKind GetNextMoreGeneralFastElementsKind(ElementsKind elements_kind, 239 bool allow_only_packed); 240 241 242 inline bool CanTransitionToMoreGeneralFastElementsKind( 243 ElementsKind elements_kind, 244 bool allow_only_packed) { 245 return IsFastElementsKind(elements_kind) && 246 (elements_kind != TERMINAL_FAST_ELEMENTS_KIND && 247 (!allow_only_packed || elements_kind != FAST_ELEMENTS)); 248 } 249 250 251 } } // namespace v8::internal 252 253 #endif // V8_ELEMENTS_KIND_H_ 254