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   FAST_SLOPPY_ARGUMENTS_ELEMENTS,
     34   SLOW_SLOPPY_ARGUMENTS_ELEMENTS,
     35 
     36   // Fixed typed arrays
     37   UINT8_ELEMENTS,
     38   INT8_ELEMENTS,
     39   UINT16_ELEMENTS,
     40   INT16_ELEMENTS,
     41   UINT32_ELEMENTS,
     42   INT32_ELEMENTS,
     43   FLOAT32_ELEMENTS,
     44   FLOAT64_ELEMENTS,
     45   UINT8_CLAMPED_ELEMENTS,
     46 
     47   // Derived constants from ElementsKind
     48   FIRST_ELEMENTS_KIND = FAST_SMI_ELEMENTS,
     49   LAST_ELEMENTS_KIND = UINT8_CLAMPED_ELEMENTS,
     50   FIRST_FAST_ELEMENTS_KIND = FAST_SMI_ELEMENTS,
     51   LAST_FAST_ELEMENTS_KIND = FAST_HOLEY_DOUBLE_ELEMENTS,
     52   FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND = UINT8_ELEMENTS,
     53   LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND = UINT8_CLAMPED_ELEMENTS,
     54   TERMINAL_FAST_ELEMENTS_KIND = FAST_HOLEY_ELEMENTS
     55 };
     56 
     57 const int kElementsKindCount = LAST_ELEMENTS_KIND - FIRST_ELEMENTS_KIND + 1;
     58 const int kFastElementsKindCount = LAST_FAST_ELEMENTS_KIND -
     59     FIRST_FAST_ELEMENTS_KIND + 1;
     60 
     61 // The number to add to a packed elements kind to reach a holey elements kind
     62 const int kFastElementsKindPackedToHoley =
     63     FAST_HOLEY_SMI_ELEMENTS - FAST_SMI_ELEMENTS;
     64 
     65 int ElementsKindToShiftSize(ElementsKind elements_kind);
     66 int GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind);
     67 const char* ElementsKindToString(ElementsKind kind);
     68 
     69 inline ElementsKind GetInitialFastElementsKind() { return FAST_SMI_ELEMENTS; }
     70 
     71 ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number);
     72 int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind);
     73 
     74 ElementsKind GetNextTransitionElementsKind(ElementsKind elements_kind);
     75 
     76 inline bool IsDictionaryElementsKind(ElementsKind kind) {
     77   return kind == DICTIONARY_ELEMENTS;
     78 }
     79 
     80 
     81 inline bool IsSloppyArgumentsElements(ElementsKind kind) {
     82   return kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS ||
     83          kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS;
     84 }
     85 
     86 
     87 inline bool IsFixedTypedArrayElementsKind(ElementsKind kind) {
     88   return kind >= FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND &&
     89          kind <= LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND;
     90 }
     91 
     92 
     93 inline bool IsTerminalElementsKind(ElementsKind kind) {
     94   return kind == TERMINAL_FAST_ELEMENTS_KIND ||
     95          IsFixedTypedArrayElementsKind(kind);
     96 }
     97 
     98 
     99 inline bool IsFastElementsKind(ElementsKind kind) {
    100   STATIC_ASSERT(FIRST_FAST_ELEMENTS_KIND == 0);
    101   return kind <= FAST_HOLEY_DOUBLE_ELEMENTS;
    102 }
    103 
    104 
    105 inline bool IsTransitionElementsKind(ElementsKind kind) {
    106   return IsFastElementsKind(kind) || IsFixedTypedArrayElementsKind(kind) ||
    107          kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS;
    108 }
    109 
    110 
    111 inline bool IsFastDoubleElementsKind(ElementsKind kind) {
    112   return kind == FAST_DOUBLE_ELEMENTS ||
    113       kind == FAST_HOLEY_DOUBLE_ELEMENTS;
    114 }
    115 
    116 
    117 inline bool IsFixedFloatElementsKind(ElementsKind kind) {
    118   return kind == FLOAT32_ELEMENTS || kind == FLOAT64_ELEMENTS;
    119 }
    120 
    121 
    122 inline bool IsDoubleOrFloatElementsKind(ElementsKind kind) {
    123   return IsFastDoubleElementsKind(kind) || IsFixedFloatElementsKind(kind);
    124 }
    125 
    126 
    127 inline bool IsFastSmiOrObjectElementsKind(ElementsKind kind) {
    128   return kind == FAST_SMI_ELEMENTS ||
    129       kind == FAST_HOLEY_SMI_ELEMENTS ||
    130       kind == FAST_ELEMENTS ||
    131       kind == FAST_HOLEY_ELEMENTS;
    132 }
    133 
    134 
    135 inline bool IsFastSmiElementsKind(ElementsKind kind) {
    136   return kind == FAST_SMI_ELEMENTS ||
    137       kind == FAST_HOLEY_SMI_ELEMENTS;
    138 }
    139 
    140 
    141 inline bool IsFastObjectElementsKind(ElementsKind kind) {
    142   return kind == FAST_ELEMENTS ||
    143       kind == FAST_HOLEY_ELEMENTS;
    144 }
    145 
    146 
    147 inline bool IsFastHoleyElementsKind(ElementsKind kind) {
    148   return kind == FAST_HOLEY_SMI_ELEMENTS ||
    149       kind == FAST_HOLEY_DOUBLE_ELEMENTS ||
    150       kind == FAST_HOLEY_ELEMENTS;
    151 }
    152 
    153 
    154 inline bool IsHoleyElementsKind(ElementsKind kind) {
    155   return IsFastHoleyElementsKind(kind) ||
    156       kind == DICTIONARY_ELEMENTS;
    157 }
    158 
    159 
    160 inline bool IsFastPackedElementsKind(ElementsKind kind) {
    161   return kind == FAST_SMI_ELEMENTS || kind == FAST_DOUBLE_ELEMENTS ||
    162          kind == FAST_ELEMENTS;
    163 }
    164 
    165 
    166 inline ElementsKind GetPackedElementsKind(ElementsKind holey_kind) {
    167   if (holey_kind == FAST_HOLEY_SMI_ELEMENTS) {
    168     return FAST_SMI_ELEMENTS;
    169   }
    170   if (holey_kind == FAST_HOLEY_DOUBLE_ELEMENTS) {
    171     return FAST_DOUBLE_ELEMENTS;
    172   }
    173   if (holey_kind == FAST_HOLEY_ELEMENTS) {
    174     return FAST_ELEMENTS;
    175   }
    176   return holey_kind;
    177 }
    178 
    179 
    180 inline ElementsKind GetHoleyElementsKind(ElementsKind packed_kind) {
    181   if (packed_kind == FAST_SMI_ELEMENTS) {
    182     return FAST_HOLEY_SMI_ELEMENTS;
    183   }
    184   if (packed_kind == FAST_DOUBLE_ELEMENTS) {
    185     return FAST_HOLEY_DOUBLE_ELEMENTS;
    186   }
    187   if (packed_kind == FAST_ELEMENTS) {
    188     return FAST_HOLEY_ELEMENTS;
    189   }
    190   return packed_kind;
    191 }
    192 
    193 
    194 inline ElementsKind FastSmiToObjectElementsKind(ElementsKind from_kind) {
    195   DCHECK(IsFastSmiElementsKind(from_kind));
    196   return (from_kind == FAST_SMI_ELEMENTS)
    197       ? FAST_ELEMENTS
    198       : FAST_HOLEY_ELEMENTS;
    199 }
    200 
    201 
    202 inline bool IsSimpleMapChangeTransition(ElementsKind from_kind,
    203                                         ElementsKind to_kind) {
    204   return (GetHoleyElementsKind(from_kind) == to_kind) ||
    205       (IsFastSmiElementsKind(from_kind) &&
    206        IsFastObjectElementsKind(to_kind));
    207 }
    208 
    209 
    210 bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
    211                                          ElementsKind to_kind);
    212 
    213 
    214 inline ElementsKind GetMoreGeneralElementsKind(ElementsKind from_kind,
    215                                                ElementsKind to_kind) {
    216   if (IsMoreGeneralElementsKindTransition(from_kind, to_kind)) {
    217     return to_kind;
    218   }
    219   return from_kind;
    220 }
    221 
    222 
    223 inline bool IsTransitionableFastElementsKind(ElementsKind from_kind) {
    224   return IsFastElementsKind(from_kind) &&
    225       from_kind != TERMINAL_FAST_ELEMENTS_KIND;
    226 }
    227 
    228 
    229 }  // namespace internal
    230 }  // namespace v8
    231 
    232 #endif  // V8_ELEMENTS_KIND_H_
    233