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