LCOV - code coverage report
Current view: top level - src - elements-kind.h (source / functions) Hit Total Coverage
Test: app.info Lines: 44 47 93.6 %
Date: 2019-01-20 Functions: 5 7 71.4 %

          Line data    Source code
       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             : // V has parameters (Type, type, TYPE, C type)
      15             : #define TYPED_ARRAYS(V)                                  \
      16             :   V(Uint8, uint8, UINT8, uint8_t)                        \
      17             :   V(Int8, int8, INT8, int8_t)                            \
      18             :   V(Uint16, uint16, UINT16, uint16_t)                    \
      19             :   V(Int16, int16, INT16, int16_t)                        \
      20             :   V(Uint32, uint32, UINT32, uint32_t)                    \
      21             :   V(Int32, int32, INT32, int32_t)                        \
      22             :   V(Float32, float32, FLOAT32, float)                    \
      23             :   V(Float64, float64, FLOAT64, double)                   \
      24             :   V(Uint8Clamped, uint8_clamped, UINT8_CLAMPED, uint8_t) \
      25             :   V(BigUint64, biguint64, BIGUINT64, uint64_t)           \
      26             :   V(BigInt64, bigint64, BIGINT64, int64_t)
      27             : 
      28             : enum ElementsKind : uint8_t {
      29             :   // The "fast" kind for elements that only contain SMI values. Must be first
      30             :   // to make it possible to efficiently check maps for this kind.
      31             :   PACKED_SMI_ELEMENTS,
      32             :   HOLEY_SMI_ELEMENTS,
      33             : 
      34             :   // The "fast" kind for tagged values. Must be second to make it possible to
      35             :   // efficiently check maps for this and the PACKED_SMI_ELEMENTS kind
      36             :   // together at once.
      37             :   PACKED_ELEMENTS,
      38             :   HOLEY_ELEMENTS,
      39             : 
      40             :   // The "fast" kind for unwrapped, non-tagged double values.
      41             :   PACKED_DOUBLE_ELEMENTS,
      42             :   HOLEY_DOUBLE_ELEMENTS,
      43             : 
      44             :   // The "slow" kind.
      45             :   DICTIONARY_ELEMENTS,
      46             : 
      47             :   // Elements kind of the "arguments" object (only in sloppy mode).
      48             :   FAST_SLOPPY_ARGUMENTS_ELEMENTS,
      49             :   SLOW_SLOPPY_ARGUMENTS_ELEMENTS,
      50             : 
      51             :   // For string wrapper objects ("new String('...')"), the string's characters
      52             :   // are overlaid onto a regular elements backing store.
      53             :   FAST_STRING_WRAPPER_ELEMENTS,
      54             :   SLOW_STRING_WRAPPER_ELEMENTS,
      55             : 
      56             : // Fixed typed arrays.
      57             : #define TYPED_ARRAY_ELEMENTS_KIND(Type, type, TYPE, ctype) TYPE##_ELEMENTS,
      58             :   TYPED_ARRAYS(TYPED_ARRAY_ELEMENTS_KIND)
      59             : #undef TYPED_ARRAY_ELEMENTS_KIND
      60             : 
      61             :   // Sentinel ElementsKind for objects with no elements.
      62             :   NO_ELEMENTS,
      63             : 
      64             :   // Derived constants from ElementsKind.
      65             :   FIRST_ELEMENTS_KIND = PACKED_SMI_ELEMENTS,
      66             :   LAST_ELEMENTS_KIND = BIGINT64_ELEMENTS,
      67             :   FIRST_FAST_ELEMENTS_KIND = PACKED_SMI_ELEMENTS,
      68             :   LAST_FAST_ELEMENTS_KIND = HOLEY_DOUBLE_ELEMENTS,
      69             :   FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND = UINT8_ELEMENTS,
      70             :   LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND = BIGINT64_ELEMENTS,
      71             :   TERMINAL_FAST_ELEMENTS_KIND = HOLEY_ELEMENTS,
      72             : 
      73             : // Alias for kSystemPointerSize-sized elements
      74             : #ifdef V8_COMPRESS_POINTERS
      75             :   SYSTEM_POINTER_ELEMENTS = PACKED_DOUBLE_ELEMENTS,
      76             : #else
      77             :   SYSTEM_POINTER_ELEMENTS = PACKED_ELEMENTS,
      78             : #endif
      79             : };
      80             : 
      81             : constexpr int kElementsKindCount = LAST_ELEMENTS_KIND - FIRST_ELEMENTS_KIND + 1;
      82             : constexpr int kFastElementsKindCount =
      83             :     LAST_FAST_ELEMENTS_KIND - FIRST_FAST_ELEMENTS_KIND + 1;
      84             : 
      85             : // The number to add to a packed elements kind to reach a holey elements kind
      86             : constexpr int kFastElementsKindPackedToHoley =
      87             :     HOLEY_SMI_ELEMENTS - PACKED_SMI_ELEMENTS;
      88             : 
      89             : int ElementsKindToShiftSize(ElementsKind elements_kind);
      90             : int ElementsKindToByteSize(ElementsKind elements_kind);
      91             : int GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind);
      92             : const char* ElementsKindToString(ElementsKind kind);
      93             : 
      94             : inline ElementsKind GetInitialFastElementsKind() { return PACKED_SMI_ELEMENTS; }
      95             : 
      96             : ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number);
      97             : int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind);
      98             : 
      99             : ElementsKind GetNextTransitionElementsKind(ElementsKind elements_kind);
     100             : 
     101             : inline bool IsDictionaryElementsKind(ElementsKind kind) {
     102             :   return kind == DICTIONARY_ELEMENTS;
     103             : }
     104             : 
     105             : inline bool IsSloppyArgumentsElementsKind(ElementsKind kind) {
     106     7485861 :   return kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS ||
     107      291213 :          kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS;
     108             : }
     109             : 
     110             : inline bool IsStringWrapperElementsKind(ElementsKind kind) {
     111     6428947 :   return kind == FAST_STRING_WRAPPER_ELEMENTS ||
     112             :          kind == SLOW_STRING_WRAPPER_ELEMENTS;
     113             : }
     114             : 
     115           0 : inline bool IsFixedTypedArrayElementsKind(ElementsKind kind) {
     116     2224736 :   return kind >= FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND &&
     117     1571970 :          kind <= LAST_FIXED_TYPED_ARRAY_ELEMENTS_KIND;
     118             : }
     119             : 
     120             : inline bool IsTerminalElementsKind(ElementsKind kind) {
     121      175559 :   return kind == TERMINAL_FAST_ELEMENTS_KIND ||
     122             :          IsFixedTypedArrayElementsKind(kind);
     123             : }
     124             : 
     125           0 : inline bool IsFastElementsKind(ElementsKind kind) {
     126             :   STATIC_ASSERT(FIRST_FAST_ELEMENTS_KIND == 0);
     127       90768 :   return kind <= HOLEY_DOUBLE_ELEMENTS;
     128             : }
     129             : 
     130             : inline bool IsTransitionElementsKind(ElementsKind kind) {
     131         718 :   return IsFastElementsKind(kind) || IsFixedTypedArrayElementsKind(kind) ||
     132      296568 :          kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS ||
     133         718 :          kind == FAST_STRING_WRAPPER_ELEMENTS;
     134             : }
     135             : 
     136    22807790 : inline bool IsDoubleElementsKind(ElementsKind kind) {
     137    33832514 :   return kind == PACKED_DOUBLE_ELEMENTS || kind == HOLEY_DOUBLE_ELEMENTS;
     138             : }
     139             : 
     140             : 
     141             : inline bool IsFixedFloatElementsKind(ElementsKind kind) {
     142             :   return kind == FLOAT32_ELEMENTS || kind == FLOAT64_ELEMENTS;
     143             : }
     144             : 
     145             : 
     146             : inline bool IsDoubleOrFloatElementsKind(ElementsKind kind) {
     147             :   return IsDoubleElementsKind(kind) || IsFixedFloatElementsKind(kind);
     148             : }
     149             : 
     150             : inline bool IsSmiOrObjectElementsKind(ElementsKind kind) {
     151             :   return kind == PACKED_SMI_ELEMENTS || kind == HOLEY_SMI_ELEMENTS ||
     152     1350000 :          kind == PACKED_ELEMENTS || kind == HOLEY_ELEMENTS;
     153             : }
     154             : 
     155             : inline bool IsSmiElementsKind(ElementsKind kind) {
     156     1514198 :   return kind == PACKED_SMI_ELEMENTS || kind == HOLEY_SMI_ELEMENTS;
     157             : }
     158             : 
     159             : inline bool IsFastNumberElementsKind(ElementsKind kind) {
     160             :   return IsSmiElementsKind(kind) || IsDoubleElementsKind(kind);
     161             : }
     162             : 
     163             : inline bool IsObjectElementsKind(ElementsKind kind) {
     164    13763505 :   return kind == PACKED_ELEMENTS || kind == HOLEY_ELEMENTS;
     165             : }
     166             : 
     167        2603 : inline bool IsHoleyElementsKind(ElementsKind kind) {
     168    15641994 :   return kind == HOLEY_SMI_ELEMENTS || kind == HOLEY_DOUBLE_ELEMENTS ||
     169        2603 :          kind == HOLEY_ELEMENTS;
     170             : }
     171             : 
     172             : inline bool IsHoleyOrDictionaryElementsKind(ElementsKind kind) {
     173        5654 :   return IsHoleyElementsKind(kind) || kind == DICTIONARY_ELEMENTS;
     174             : }
     175             : 
     176             : 
     177          81 : inline bool IsFastPackedElementsKind(ElementsKind kind) {
     178     1893237 :   return kind == PACKED_SMI_ELEMENTS || kind == PACKED_DOUBLE_ELEMENTS ||
     179          81 :          kind == PACKED_ELEMENTS;
     180             : }
     181             : 
     182             : 
     183             : inline ElementsKind GetPackedElementsKind(ElementsKind holey_kind) {
     184      290175 :   if (holey_kind == HOLEY_SMI_ELEMENTS) {
     185             :     return PACKED_SMI_ELEMENTS;
     186             :   }
     187      288011 :   if (holey_kind == HOLEY_DOUBLE_ELEMENTS) {
     188             :     return PACKED_DOUBLE_ELEMENTS;
     189             :   }
     190      287829 :   if (holey_kind == HOLEY_ELEMENTS) {
     191             :     return PACKED_ELEMENTS;
     192             :   }
     193             :   return holey_kind;
     194             : }
     195             : 
     196             : 
     197        1225 : inline ElementsKind GetHoleyElementsKind(ElementsKind packed_kind) {
     198    15910194 :   if (packed_kind == PACKED_SMI_ELEMENTS) {
     199             :     return HOLEY_SMI_ELEMENTS;
     200             :   }
     201    11504537 :   if (packed_kind == PACKED_DOUBLE_ELEMENTS) {
     202             :     return HOLEY_DOUBLE_ELEMENTS;
     203             :   }
     204    11291060 :   if (packed_kind == PACKED_ELEMENTS) {
     205             :     return HOLEY_ELEMENTS;
     206             :   }
     207           0 :   return packed_kind;
     208             : }
     209             : 
     210        2364 : inline bool UnionElementsKindUptoPackedness(ElementsKind* a_out,
     211             :                                             ElementsKind b) {
     212             :   // Assert that the union of two ElementKinds can be computed via std::max.
     213             :   static_assert(PACKED_SMI_ELEMENTS < HOLEY_SMI_ELEMENTS,
     214             :                 "ElementsKind union not computable via std::max.");
     215             :   static_assert(PACKED_ELEMENTS < HOLEY_ELEMENTS,
     216             :                 "ElementsKind union not computable via std::max.");
     217             :   static_assert(PACKED_DOUBLE_ELEMENTS < HOLEY_DOUBLE_ELEMENTS,
     218             :                 "ElementsKind union not computable via std::max.");
     219        2364 :   ElementsKind a = *a_out;
     220             :   switch (a) {
     221             :     case HOLEY_SMI_ELEMENTS:
     222             :     case PACKED_SMI_ELEMENTS:
     223        1165 :       if (b == PACKED_SMI_ELEMENTS || b == HOLEY_SMI_ELEMENTS) {
     224        1125 :         *a_out = std::max(a, b);
     225        1125 :         return true;
     226             :       }
     227             :       break;
     228             :     case PACKED_ELEMENTS:
     229             :     case HOLEY_ELEMENTS:
     230         786 :       if (b == PACKED_ELEMENTS || b == HOLEY_ELEMENTS) {
     231         726 :         *a_out = std::max(a, b);
     232         726 :         return true;
     233             :       }
     234             :       break;
     235             :     case PACKED_DOUBLE_ELEMENTS:
     236             :     case HOLEY_DOUBLE_ELEMENTS:
     237         413 :       if (b == PACKED_DOUBLE_ELEMENTS || b == HOLEY_DOUBLE_ELEMENTS) {
     238         373 :         *a_out = std::max(a, b);
     239         373 :         return true;
     240             :       }
     241             :       break;
     242             :     default:
     243             :       break;
     244             :   }
     245             :   return false;
     246             : }
     247             : 
     248             : bool UnionElementsKindUptoSize(ElementsKind* a_out, ElementsKind b);
     249             : 
     250             : inline ElementsKind FastSmiToObjectElementsKind(ElementsKind from_kind) {
     251             :   DCHECK(IsSmiElementsKind(from_kind));
     252             :   return (from_kind == PACKED_SMI_ELEMENTS) ? PACKED_ELEMENTS : HOLEY_ELEMENTS;
     253             : }
     254             : 
     255             : 
     256             : inline bool IsSimpleMapChangeTransition(ElementsKind from_kind,
     257             :                                         ElementsKind to_kind) {
     258        3645 :   return (GetHoleyElementsKind(from_kind) == to_kind) ||
     259        2056 :          (IsSmiElementsKind(from_kind) && IsObjectElementsKind(to_kind));
     260             : }
     261             : 
     262             : 
     263             : bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
     264             :                                          ElementsKind to_kind);
     265             : 
     266             : 
     267             : inline ElementsKind GetMoreGeneralElementsKind(ElementsKind from_kind,
     268             :                                                ElementsKind to_kind) {
     269    14700296 :   if (IsMoreGeneralElementsKindTransition(from_kind, to_kind)) {
     270             :     return to_kind;
     271             :   }
     272             :   return from_kind;
     273             : }
     274             : 
     275             : 
     276             : inline bool IsTransitionableFastElementsKind(ElementsKind from_kind) {
     277      936650 :   return IsFastElementsKind(from_kind) &&
     278             :          from_kind != TERMINAL_FAST_ELEMENTS_KIND;
     279             : }
     280             : 
     281             : inline bool ElementsKindEqual(ElementsKind a, ElementsKind b) { return a == b; }
     282             : 
     283             : }  // namespace internal
     284             : }  // namespace v8
     285             : 
     286             : #endif  // V8_ELEMENTS_KIND_H_

Generated by: LCOV version 1.10