1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #ifndef V8_ELEMENTS_KIND_H_ 29 #define V8_ELEMENTS_KIND_H_ 30 31 #include "v8checks.h" 32 33 namespace v8 { 34 namespace internal { 35 36 enum ElementsKind { 37 // The "fast" kind for elements that only contain SMI values. Must be first 38 // to make it possible to efficiently check maps for this kind. 39 FAST_SMI_ELEMENTS, 40 FAST_HOLEY_SMI_ELEMENTS, 41 42 // The "fast" kind for tagged values. Must be second to make it possible to 43 // efficiently check maps for this and the FAST_SMI_ONLY_ELEMENTS kind 44 // together at once. 45 FAST_ELEMENTS, 46 FAST_HOLEY_ELEMENTS, 47 48 // The "fast" kind for unwrapped, non-tagged double values. 49 FAST_DOUBLE_ELEMENTS, 50 FAST_HOLEY_DOUBLE_ELEMENTS, 51 52 // The "slow" kind. 53 DICTIONARY_ELEMENTS, 54 NON_STRICT_ARGUMENTS_ELEMENTS, 55 // The "fast" kind for external arrays 56 EXTERNAL_BYTE_ELEMENTS, 57 EXTERNAL_UNSIGNED_BYTE_ELEMENTS, 58 EXTERNAL_SHORT_ELEMENTS, 59 EXTERNAL_UNSIGNED_SHORT_ELEMENTS, 60 EXTERNAL_INT_ELEMENTS, 61 EXTERNAL_UNSIGNED_INT_ELEMENTS, 62 EXTERNAL_FLOAT_ELEMENTS, 63 EXTERNAL_DOUBLE_ELEMENTS, 64 EXTERNAL_PIXEL_ELEMENTS, 65 66 // Derived constants from ElementsKind 67 FIRST_ELEMENTS_KIND = FAST_SMI_ELEMENTS, 68 LAST_ELEMENTS_KIND = EXTERNAL_PIXEL_ELEMENTS, 69 FIRST_FAST_ELEMENTS_KIND = FAST_SMI_ELEMENTS, 70 LAST_FAST_ELEMENTS_KIND = FAST_HOLEY_DOUBLE_ELEMENTS, 71 FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND = EXTERNAL_BYTE_ELEMENTS, 72 LAST_EXTERNAL_ARRAY_ELEMENTS_KIND = EXTERNAL_PIXEL_ELEMENTS, 73 TERMINAL_FAST_ELEMENTS_KIND = FAST_HOLEY_ELEMENTS 74 }; 75 76 const int kElementsKindCount = LAST_ELEMENTS_KIND - FIRST_ELEMENTS_KIND + 1; 77 const int kFastElementsKindCount = LAST_FAST_ELEMENTS_KIND - 78 FIRST_FAST_ELEMENTS_KIND + 1; 79 80 const char* ElementsKindToString(ElementsKind kind); 81 void PrintElementsKind(FILE* out, ElementsKind kind); 82 83 ElementsKind GetInitialFastElementsKind(); 84 85 ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_index); 86 87 int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind); 88 89 90 inline bool IsDictionaryElementsKind(ElementsKind kind) { 91 return kind == DICTIONARY_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 IsFastElementsKind(ElementsKind kind) { 102 ASSERT(FIRST_FAST_ELEMENTS_KIND == 0); 103 return kind <= FAST_HOLEY_DOUBLE_ELEMENTS; 104 } 105 106 107 inline bool IsFastDoubleElementsKind(ElementsKind kind) { 108 return kind == FAST_DOUBLE_ELEMENTS || 109 kind == FAST_HOLEY_DOUBLE_ELEMENTS; 110 } 111 112 113 inline bool IsExternalFloatOrDoubleElementsKind(ElementsKind kind) { 114 return kind == EXTERNAL_DOUBLE_ELEMENTS || 115 kind == EXTERNAL_FLOAT_ELEMENTS; 116 } 117 118 119 inline bool IsDoubleOrFloatElementsKind(ElementsKind kind) { 120 return IsFastDoubleElementsKind(kind) || 121 IsExternalFloatOrDoubleElementsKind(kind); 122 } 123 124 125 inline bool IsFastSmiOrObjectElementsKind(ElementsKind kind) { 126 return kind == FAST_SMI_ELEMENTS || 127 kind == FAST_HOLEY_SMI_ELEMENTS || 128 kind == FAST_ELEMENTS || 129 kind == FAST_HOLEY_ELEMENTS; 130 } 131 132 133 inline bool IsFastSmiElementsKind(ElementsKind kind) { 134 return kind == FAST_SMI_ELEMENTS || 135 kind == FAST_HOLEY_SMI_ELEMENTS; 136 } 137 138 139 inline bool IsFastObjectElementsKind(ElementsKind kind) { 140 return kind == FAST_ELEMENTS || 141 kind == FAST_HOLEY_ELEMENTS; 142 } 143 144 145 inline bool IsFastHoleyElementsKind(ElementsKind kind) { 146 return kind == FAST_HOLEY_SMI_ELEMENTS || 147 kind == FAST_HOLEY_DOUBLE_ELEMENTS || 148 kind == FAST_HOLEY_ELEMENTS; 149 } 150 151 152 inline bool IsHoleyElementsKind(ElementsKind kind) { 153 return IsFastHoleyElementsKind(kind) || 154 kind == DICTIONARY_ELEMENTS; 155 } 156 157 158 inline bool IsFastPackedElementsKind(ElementsKind kind) { 159 return kind == FAST_SMI_ELEMENTS || 160 kind == FAST_DOUBLE_ELEMENTS || 161 kind == FAST_ELEMENTS; 162 } 163 164 165 inline ElementsKind GetPackedElementsKind(ElementsKind holey_kind) { 166 if (holey_kind == FAST_HOLEY_SMI_ELEMENTS) { 167 return FAST_SMI_ELEMENTS; 168 } 169 if (holey_kind == FAST_HOLEY_DOUBLE_ELEMENTS) { 170 return FAST_DOUBLE_ELEMENTS; 171 } 172 if (holey_kind == FAST_HOLEY_ELEMENTS) { 173 return FAST_ELEMENTS; 174 } 175 return holey_kind; 176 } 177 178 179 inline ElementsKind GetHoleyElementsKind(ElementsKind packed_kind) { 180 if (packed_kind == FAST_SMI_ELEMENTS) { 181 return FAST_HOLEY_SMI_ELEMENTS; 182 } 183 if (packed_kind == FAST_DOUBLE_ELEMENTS) { 184 return FAST_HOLEY_DOUBLE_ELEMENTS; 185 } 186 if (packed_kind == FAST_ELEMENTS) { 187 return FAST_HOLEY_ELEMENTS; 188 } 189 return packed_kind; 190 } 191 192 193 inline ElementsKind FastSmiToObjectElementsKind(ElementsKind from_kind) { 194 ASSERT(IsFastSmiElementsKind(from_kind)); 195 return (from_kind == FAST_SMI_ELEMENTS) 196 ? FAST_ELEMENTS 197 : FAST_HOLEY_ELEMENTS; 198 } 199 200 201 inline bool IsSimpleMapChangeTransition(ElementsKind from_kind, 202 ElementsKind to_kind) { 203 return (GetHoleyElementsKind(from_kind) == to_kind) || 204 (IsFastSmiElementsKind(from_kind) && 205 IsFastObjectElementsKind(to_kind)); 206 } 207 208 209 bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind, 210 ElementsKind to_kind); 211 212 213 inline bool IsTransitionableFastElementsKind(ElementsKind from_kind) { 214 return IsFastElementsKind(from_kind) && 215 from_kind != TERMINAL_FAST_ELEMENTS_KIND; 216 } 217 218 219 ElementsKind GetNextMoreGeneralFastElementsKind(ElementsKind elements_kind, 220 bool allow_only_packed); 221 222 223 inline bool CanTransitionToMoreGeneralFastElementsKind( 224 ElementsKind elements_kind, 225 bool allow_only_packed) { 226 return IsFastElementsKind(elements_kind) && 227 (elements_kind != TERMINAL_FAST_ELEMENTS_KIND && 228 (!allow_only_packed || elements_kind != FAST_ELEMENTS)); 229 } 230 231 232 } } // namespace v8::internal 233 234 #endif // V8_ELEMENTS_KIND_H_ 235