Home | History | Annotate | Download | only in src
      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 // The number to add to a packed elements kind to reach a holey elements kind
     81 const int kFastElementsKindPackedToHoley =
     82     FAST_HOLEY_SMI_ELEMENTS - FAST_SMI_ELEMENTS;
     83 
     84 int ElementsKindToShiftSize(ElementsKind elements_kind);
     85 const char* ElementsKindToString(ElementsKind kind);
     86 void PrintElementsKind(FILE* out, ElementsKind kind);
     87 
     88 ElementsKind GetInitialFastElementsKind();
     89 
     90 ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_index);
     91 
     92 int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind);
     93 
     94 
     95 inline bool IsDictionaryElementsKind(ElementsKind kind) {
     96   return kind == DICTIONARY_ELEMENTS;
     97 }
     98 
     99 
    100 inline bool IsExternalArrayElementsKind(ElementsKind kind) {
    101   return kind >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND &&
    102       kind <= LAST_EXTERNAL_ARRAY_ELEMENTS_KIND;
    103 }
    104 
    105 
    106 inline bool IsFastElementsKind(ElementsKind kind) {
    107   ASSERT(FIRST_FAST_ELEMENTS_KIND == 0);
    108   return kind <= FAST_HOLEY_DOUBLE_ELEMENTS;
    109 }
    110 
    111 
    112 inline bool IsFastDoubleElementsKind(ElementsKind kind) {
    113   return kind == FAST_DOUBLE_ELEMENTS ||
    114       kind == FAST_HOLEY_DOUBLE_ELEMENTS;
    115 }
    116 
    117 
    118 inline bool IsExternalFloatOrDoubleElementsKind(ElementsKind kind) {
    119   return kind == EXTERNAL_DOUBLE_ELEMENTS ||
    120       kind == EXTERNAL_FLOAT_ELEMENTS;
    121 }
    122 
    123 
    124 inline bool IsDoubleOrFloatElementsKind(ElementsKind kind) {
    125   return IsFastDoubleElementsKind(kind) ||
    126       IsExternalFloatOrDoubleElementsKind(kind);
    127 }
    128 
    129 
    130 inline bool IsFastSmiOrObjectElementsKind(ElementsKind kind) {
    131   return kind == FAST_SMI_ELEMENTS ||
    132       kind == FAST_HOLEY_SMI_ELEMENTS ||
    133       kind == FAST_ELEMENTS ||
    134       kind == FAST_HOLEY_ELEMENTS;
    135 }
    136 
    137 
    138 inline bool IsFastSmiElementsKind(ElementsKind kind) {
    139   return kind == FAST_SMI_ELEMENTS ||
    140       kind == FAST_HOLEY_SMI_ELEMENTS;
    141 }
    142 
    143 
    144 inline bool IsFastObjectElementsKind(ElementsKind kind) {
    145   return kind == FAST_ELEMENTS ||
    146       kind == FAST_HOLEY_ELEMENTS;
    147 }
    148 
    149 
    150 inline bool IsFastHoleyElementsKind(ElementsKind kind) {
    151   return kind == FAST_HOLEY_SMI_ELEMENTS ||
    152       kind == FAST_HOLEY_DOUBLE_ELEMENTS ||
    153       kind == FAST_HOLEY_ELEMENTS;
    154 }
    155 
    156 
    157 inline bool IsHoleyElementsKind(ElementsKind kind) {
    158   return IsFastHoleyElementsKind(kind) ||
    159       kind == DICTIONARY_ELEMENTS;
    160 }
    161 
    162 
    163 inline bool IsFastPackedElementsKind(ElementsKind kind) {
    164   return kind == FAST_SMI_ELEMENTS ||
    165       kind == FAST_DOUBLE_ELEMENTS ||
    166       kind == FAST_ELEMENTS;
    167 }
    168 
    169 
    170 inline ElementsKind GetPackedElementsKind(ElementsKind holey_kind) {
    171   if (holey_kind == FAST_HOLEY_SMI_ELEMENTS) {
    172     return FAST_SMI_ELEMENTS;
    173   }
    174   if (holey_kind == FAST_HOLEY_DOUBLE_ELEMENTS) {
    175     return FAST_DOUBLE_ELEMENTS;
    176   }
    177   if (holey_kind == FAST_HOLEY_ELEMENTS) {
    178     return FAST_ELEMENTS;
    179   }
    180   return holey_kind;
    181 }
    182 
    183 
    184 inline ElementsKind GetHoleyElementsKind(ElementsKind packed_kind) {
    185   if (packed_kind == FAST_SMI_ELEMENTS) {
    186     return FAST_HOLEY_SMI_ELEMENTS;
    187   }
    188   if (packed_kind == FAST_DOUBLE_ELEMENTS) {
    189     return FAST_HOLEY_DOUBLE_ELEMENTS;
    190   }
    191   if (packed_kind == FAST_ELEMENTS) {
    192     return FAST_HOLEY_ELEMENTS;
    193   }
    194   return packed_kind;
    195 }
    196 
    197 
    198 inline ElementsKind FastSmiToObjectElementsKind(ElementsKind from_kind) {
    199   ASSERT(IsFastSmiElementsKind(from_kind));
    200   return (from_kind == FAST_SMI_ELEMENTS)
    201       ? FAST_ELEMENTS
    202       : FAST_HOLEY_ELEMENTS;
    203 }
    204 
    205 
    206 inline bool IsSimpleMapChangeTransition(ElementsKind from_kind,
    207                                         ElementsKind to_kind) {
    208   return (GetHoleyElementsKind(from_kind) == to_kind) ||
    209       (IsFastSmiElementsKind(from_kind) &&
    210        IsFastObjectElementsKind(to_kind));
    211 }
    212 
    213 
    214 bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
    215                                          ElementsKind to_kind);
    216 
    217 
    218 inline bool IsTransitionableFastElementsKind(ElementsKind from_kind) {
    219   return IsFastElementsKind(from_kind) &&
    220       from_kind != TERMINAL_FAST_ELEMENTS_KIND;
    221 }
    222 
    223 
    224 ElementsKind GetNextMoreGeneralFastElementsKind(ElementsKind elements_kind,
    225                                                 bool allow_only_packed);
    226 
    227 
    228 inline bool CanTransitionToMoreGeneralFastElementsKind(
    229     ElementsKind elements_kind,
    230     bool allow_only_packed) {
    231   return IsFastElementsKind(elements_kind) &&
    232       (elements_kind != TERMINAL_FAST_ELEMENTS_KIND &&
    233        (!allow_only_packed || elements_kind != FAST_ELEMENTS));
    234 }
    235 
    236 
    237 } }  // namespace v8::internal
    238 
    239 #endif  // V8_ELEMENTS_KIND_H_
    240