Home | History | Annotate | Download | only in src
      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