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