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/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