LCOV - code coverage report
Current view: top level - src/compiler - types.h (source / functions) Hit Total Coverage
Test: app.info Lines: 51 51 100.0 %
Date: 2019-04-17 Functions: 9 9 100.0 %

          Line data    Source code
       1             : // Copyright 2014 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_COMPILER_TYPES_H_
       6             : #define V8_COMPILER_TYPES_H_
       7             : 
       8             : #include "src/base/compiler-specific.h"
       9             : #include "src/compiler/js-heap-broker.h"
      10             : #include "src/conversions.h"
      11             : #include "src/globals.h"
      12             : #include "src/handles.h"
      13             : #include "src/objects.h"
      14             : #include "src/ostreams.h"
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : namespace compiler {
      19             : 
      20             : // SUMMARY
      21             : //
      22             : // A simple type system for compiler-internal use. It is based entirely on
      23             : // union types, and all subtyping hence amounts to set inclusion. Besides the
      24             : // obvious primitive types and some predefined unions, the type language also
      25             : // can express class types (a.k.a. specific maps) and singleton types (i.e.,
      26             : // concrete constants).
      27             : //
      28             : // The following equations and inequations hold:
      29             : //
      30             : //   None <= T
      31             : //   T <= Any
      32             : //
      33             : //   Number = Signed32 \/ Unsigned32 \/ Double
      34             : //   Smi <= Signed32
      35             : //   Name = String \/ Symbol
      36             : //   UniqueName = InternalizedString \/ Symbol
      37             : //   InternalizedString < String
      38             : //
      39             : //   Receiver = Object \/ Proxy
      40             : //   OtherUndetectable < Object
      41             : //   DetectableReceiver = Receiver - OtherUndetectable
      42             : //
      43             : //   Constant(x) < T  iff instance_type(map(x)) < T
      44             : //
      45             : //
      46             : // RANGE TYPES
      47             : //
      48             : // A range type represents a continuous integer interval by its minimum and
      49             : // maximum value.  Either value may be an infinity, in which case that infinity
      50             : // itself is also included in the range.   A range never contains NaN or -0.
      51             : //
      52             : // If a value v happens to be an integer n, then Constant(v) is considered a
      53             : // subtype of Range(n, n) (and therefore also a subtype of any larger range).
      54             : // In order to avoid large unions, however, it is usually a good idea to use
      55             : // Range rather than Constant.
      56             : //
      57             : //
      58             : // PREDICATES
      59             : //
      60             : // There are two main functions for testing types:
      61             : //
      62             : //   T1.Is(T2)     -- tests whether T1 is included in T2 (i.e., T1 <= T2)
      63             : //   T1.Maybe(T2)  -- tests whether T1 and T2 overlap (i.e., T1 /\ T2 =/= 0)
      64             : //
      65             : // Typically, the former is to be used to select representations (e.g., via
      66             : // T.Is(SignedSmall())), and the latter to check whether a specific case needs
      67             : // handling (e.g., via T.Maybe(Number())).
      68             : //
      69             : // There is no functionality to discover whether a type is a leaf in the
      70             : // lattice. That is intentional. It should always be possible to refine the
      71             : // lattice (e.g., splitting up number types further) without invalidating any
      72             : // existing assumptions or tests.
      73             : // Consequently, do not normally use Equals for type tests, always use Is!
      74             : //
      75             : // The NowIs operator implements state-sensitive subtying, as described above.
      76             : // Any compilation decision based on such temporary properties requires runtime
      77             : // guarding!
      78             : //
      79             : //
      80             : // PROPERTIES
      81             : //
      82             : // Various formal properties hold for constructors, operators, and predicates
      83             : // over types. For example, constructors are injective and subtyping is a
      84             : // complete partial order.
      85             : //
      86             : // See test/cctest/test-types.cc for a comprehensive executable specification,
      87             : // especially with respect to the properties of the more exotic 'temporal'
      88             : // constructors and predicates (those prefixed 'Now').
      89             : //
      90             : //
      91             : // IMPLEMENTATION
      92             : //
      93             : // Internally, all 'primitive' types, and their unions, are represented as
      94             : // bitsets. Bit 0 is reserved for tagging. Only structured types require
      95             : // allocation.
      96             : 
      97             : // -----------------------------------------------------------------------------
      98             : // Values for bitset types
      99             : 
     100             : // clang-format off
     101             : 
     102             : #define INTERNAL_BITSET_TYPE_LIST(V)                                      \
     103             :   V(OtherUnsigned31,    1u << 1)  \
     104             :   V(OtherUnsigned32,    1u << 2)  \
     105             :   V(OtherSigned32,      1u << 3)  \
     106             :   V(OtherNumber,        1u << 4)  \
     107             :   V(OtherOneByteString, 1u << 5)  \
     108             :   V(OtherTwoByteString, 1u << 6)  \
     109             : 
     110             : #define PROPER_BITSET_TYPE_LIST(V) \
     111             :   V(None,                              0u)        \
     112             :   V(Negative31,                        1u << 7)   \
     113             :   V(Null,                              1u << 8)   \
     114             :   V(Undefined,                         1u << 9)   \
     115             :   V(Boolean,                           1u << 10)  \
     116             :   V(Unsigned30,                        1u << 11)  \
     117             :   V(MinusZero,                         1u << 12)  \
     118             :   V(NaN,                               1u << 13)  \
     119             :   V(Symbol,                            1u << 14)  \
     120             :   V(EmptyString,                       1u << 15)  \
     121             :   V(NonEmptyInternalizedOneByteString, 1u << 16)  \
     122             :   V(NonEmptyInternalizedTwoByteString, 1u << 17)  \
     123             :   V(OtherCallable,                     1u << 18)  \
     124             :   V(OtherObject,                       1u << 19)  \
     125             :   V(OtherUndetectable,                 1u << 20)  \
     126             :   V(CallableProxy,                     1u << 21)  \
     127             :   V(OtherProxy,                        1u << 22)  \
     128             :   V(Function,                          1u << 23)  \
     129             :   V(BoundFunction,                     1u << 24)  \
     130             :   V(Hole,                              1u << 25)  \
     131             :   V(OtherInternal,                     1u << 26)  \
     132             :   V(ExternalPointer,                   1u << 27)  \
     133             :   V(Array,                             1u << 28)  \
     134             :   V(BigInt,                            1u << 29)  \
     135             :   \
     136             :   V(Signed31,                     kUnsigned30 | kNegative31) \
     137             :   V(Signed32,                     kSigned31 | kOtherUnsigned31 | \
     138             :                                   kOtherSigned32) \
     139             :   V(Signed32OrMinusZero,          kSigned32 | kMinusZero) \
     140             :   V(Signed32OrMinusZeroOrNaN,     kSigned32 | kMinusZero | kNaN) \
     141             :   V(Negative32,                   kNegative31 | kOtherSigned32) \
     142             :   V(Unsigned31,                   kUnsigned30 | kOtherUnsigned31) \
     143             :   V(Unsigned32,                   kUnsigned30 | kOtherUnsigned31 | \
     144             :                                   kOtherUnsigned32) \
     145             :   V(Unsigned32OrMinusZero,        kUnsigned32 | kMinusZero) \
     146             :   V(Unsigned32OrMinusZeroOrNaN,   kUnsigned32 | kMinusZero | kNaN) \
     147             :   V(Integral32,                   kSigned32 | kUnsigned32) \
     148             :   V(Integral32OrMinusZero,        kIntegral32 | kMinusZero) \
     149             :   V(Integral32OrMinusZeroOrNaN,   kIntegral32OrMinusZero | kNaN) \
     150             :   V(PlainNumber,                  kIntegral32 | kOtherNumber) \
     151             :   V(OrderedNumber,                kPlainNumber | kMinusZero) \
     152             :   V(MinusZeroOrNaN,               kMinusZero | kNaN) \
     153             :   V(Number,                       kOrderedNumber | kNaN) \
     154             :   V(Numeric,                      kNumber | kBigInt) \
     155             :   V(InternalizedOneByteString,    kEmptyString | \
     156             :                                   kNonEmptyInternalizedOneByteString) \
     157             :   V(OneByteString,                kInternalizedOneByteString | \
     158             :                                   kOtherOneByteString) \
     159             :   V(InternalizedString,           kInternalizedOneByteString | \
     160             :                                   kNonEmptyInternalizedTwoByteString) \
     161             :   V(NonEmptyOneByteString,        kNonEmptyInternalizedOneByteString | \
     162             :                                   kOtherOneByteString) \
     163             :   V(NonEmptyTwoByteString,        kNonEmptyInternalizedTwoByteString | \
     164             :                                   kOtherTwoByteString) \
     165             :   V(NonEmptyString,               kNonEmptyOneByteString | \
     166             :                                   kNonEmptyTwoByteString) \
     167             :   V(String,                       kEmptyString | kNonEmptyString) \
     168             :   V(UniqueName,                   kSymbol | kInternalizedString) \
     169             :   V(Name,                         kSymbol | kString) \
     170             :   V(InternalizedStringOrNull,     kInternalizedString | kNull) \
     171             :   V(BooleanOrNumber,              kBoolean | kNumber) \
     172             :   V(BooleanOrNullOrNumber,        kBooleanOrNumber | kNull) \
     173             :   V(BooleanOrNullOrUndefined,     kBoolean | kNull | kUndefined) \
     174             :   V(Oddball,                      kBooleanOrNullOrUndefined | kHole) \
     175             :   V(NullOrNumber,                 kNull | kNumber) \
     176             :   V(NullOrUndefined,              kNull | kUndefined) \
     177             :   V(Undetectable,                 kNullOrUndefined | kOtherUndetectable) \
     178             :   V(NumberOrHole,                 kNumber | kHole) \
     179             :   V(NumberOrOddball,              kNumber | kNullOrUndefined | kBoolean | \
     180             :                                   kHole) \
     181             :   V(NumericOrString,              kNumeric | kString) \
     182             :   V(NumberOrUndefined,            kNumber | kUndefined) \
     183             :   V(NumberOrUndefinedOrNullOrBoolean,  \
     184             :                                   kNumber | kNullOrUndefined | kBoolean) \
     185             :   V(PlainPrimitive,               kNumber | kString | kBoolean | \
     186             :                                   kNullOrUndefined) \
     187             :   V(NonBigIntPrimitive,           kSymbol | kPlainPrimitive) \
     188             :   V(Primitive,                    kBigInt | kNonBigIntPrimitive) \
     189             :   V(OtherUndetectableOrUndefined, kOtherUndetectable | kUndefined) \
     190             :   V(Proxy,                        kCallableProxy | kOtherProxy) \
     191             :   V(ArrayOrOtherObject,           kArray | kOtherObject) \
     192             :   V(ArrayOrProxy,                 kArray | kProxy) \
     193             :   V(DetectableCallable,           kFunction | kBoundFunction | \
     194             :                                   kOtherCallable | kCallableProxy) \
     195             :   V(Callable,                     kDetectableCallable | kOtherUndetectable) \
     196             :   V(NonCallable,                  kArray | kOtherObject | kOtherProxy) \
     197             :   V(NonCallableOrNull,            kNonCallable | kNull) \
     198             :   V(DetectableObject,             kArray | kFunction | kBoundFunction | \
     199             :                                   kOtherCallable | kOtherObject) \
     200             :   V(DetectableReceiver,           kDetectableObject | kProxy) \
     201             :   V(DetectableReceiverOrNull,     kDetectableReceiver | kNull) \
     202             :   V(Object,                       kDetectableObject | kOtherUndetectable) \
     203             :   V(Receiver,                     kObject | kProxy) \
     204             :   V(ReceiverOrUndefined,          kReceiver | kUndefined) \
     205             :   V(ReceiverOrNullOrUndefined,    kReceiver | kNull | kUndefined) \
     206             :   V(SymbolOrReceiver,             kSymbol | kReceiver) \
     207             :   V(StringOrReceiver,             kString | kReceiver) \
     208             :   V(Unique,                       kBoolean | kUniqueName | kNull | \
     209             :                                   kUndefined | kReceiver) \
     210             :   V(Internal,                     kHole | kExternalPointer | kOtherInternal) \
     211             :   V(NonInternal,                  kPrimitive | kReceiver) \
     212             :   V(NonBigInt,                    kNonBigIntPrimitive | kReceiver) \
     213             :   V(NonNumber,                    kBigInt | kUnique | kString | kInternal) \
     214             :   V(Any,                          0xfffffffeu)
     215             : 
     216             : // clang-format on
     217             : 
     218             : /*
     219             :  * The following diagrams show how integers (in the mathematical sense) are
     220             :  * divided among the different atomic numerical types.
     221             :  *
     222             :  *   ON    OS32     N31     U30     OU31    OU32     ON
     223             :  * ______[_______[_______[_______[_______[_______[_______
     224             :  *     -2^31   -2^30     0      2^30    2^31    2^32
     225             :  *
     226             :  * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1.
     227             :  *
     228             :  * Some of the atomic numerical bitsets are internal only (see
     229             :  * INTERNAL_BITSET_TYPE_LIST).  To a types user, they should only occur in
     230             :  * union with certain other bitsets.  For instance, OtherNumber should only
     231             :  * occur as part of PlainNumber.
     232             :  */
     233             : 
     234             : #define BITSET_TYPE_LIST(V)    \
     235             :   INTERNAL_BITSET_TYPE_LIST(V) \
     236             :   PROPER_BITSET_TYPE_LIST(V)
     237             : 
     238             : class HeapConstantType;
     239             : class OtherNumberConstantType;
     240             : class TupleType;
     241             : class Type;
     242             : class UnionType;
     243             : 
     244             : // -----------------------------------------------------------------------------
     245             : // Bitset types (internal).
     246             : 
     247             : class V8_EXPORT_PRIVATE BitsetType {
     248             :  public:
     249             :   using bitset = uint32_t;  // Internal
     250             : 
     251             :   enum : uint32_t {
     252             : #define DECLARE_TYPE(type, value) k##type = (value),
     253             :     BITSET_TYPE_LIST(DECLARE_TYPE)
     254             : #undef DECLARE_TYPE
     255             :         kUnusedEOL = 0
     256             :   };
     257             : 
     258             :   static bitset SignedSmall();
     259             :   static bitset UnsignedSmall();
     260             : 
     261             :   static bool IsNone(bitset bits) { return bits == kNone; }
     262             : 
     263             :   static bool Is(bitset bits1, bitset bits2) {
     264   351128304 :     return (bits1 | bits2) == bits2;
     265             :   }
     266             : 
     267             :   static double Min(bitset);
     268             :   static double Max(bitset);
     269             : 
     270             :   static bitset Glb(double min, double max);
     271             :   static bitset Lub(HeapObjectType const& type) {
     272    18423328 :     return Lub<HeapObjectType>(type);
     273             :   }
     274       12596 :   static bitset Lub(MapRef const& map) { return Lub<MapRef>(map); }
     275             :   static bitset Lub(double value);
     276             :   static bitset Lub(double min, double max);
     277             :   static bitset ExpandInternals(bitset bits);
     278             : 
     279             :   static const char* Name(bitset);
     280             :   static void Print(std::ostream& os, bitset);  // NOLINT
     281             : #ifdef DEBUG
     282             :   static void Print(bitset);
     283             : #endif
     284             : 
     285             :   static bitset NumberBits(bitset bits);
     286             : 
     287             :  private:
     288             :   struct Boundary {
     289             :     bitset internal;
     290             :     bitset external;
     291             :     double min;
     292             :   };
     293             :   static const Boundary BoundariesArray[];
     294             :   static inline const Boundary* Boundaries();
     295             :   static inline size_t BoundariesSize();
     296             : 
     297             :   template <typename MapRefLike>
     298             :   static bitset Lub(MapRefLike const& map);
     299             : };
     300             : 
     301             : // -----------------------------------------------------------------------------
     302             : // Superclass for non-bitset types (internal).
     303             : class TypeBase {
     304             :  protected:
     305             :   friend class Type;
     306             : 
     307             :   enum Kind { kHeapConstant, kOtherNumberConstant, kTuple, kUnion, kRange };
     308             : 
     309  1141125093 :   Kind kind() const { return kind_; }
     310    61804428 :   explicit TypeBase(Kind kind) : kind_(kind) {}
     311             : 
     312             :   static bool IsKind(Type type, Kind kind);
     313             : 
     314             :  private:
     315             :   Kind kind_;
     316             : };
     317             : 
     318             : // -----------------------------------------------------------------------------
     319             : // Range types.
     320             : 
     321             : class RangeType : public TypeBase {
     322             :  public:
     323             :   struct Limits {
     324             :     double min;
     325             :     double max;
     326    17437907 :     Limits(double min, double max) : min(min), max(max) {}
     327             :     explicit Limits(const RangeType* range)
     328             :         : min(range->Min()), max(range->Max()) {}
     329             :     bool IsEmpty();
     330             :     static Limits Empty() { return Limits(1, 0); }
     331             :     static Limits Intersect(Limits lhs, Limits rhs);
     332             :     static Limits Union(Limits lhs, Limits rhs);
     333             :   };
     334             : 
     335             :   double Min() const { return limits_.min; }
     336             :   double Max() const { return limits_.max; }
     337             : 
     338             :   static bool IsInteger(double x) {
     339     9558656 :     return nearbyint(x) == x && !IsMinusZero(x);  // Allows for infinities.
     340             :   }
     341             : 
     342             :  private:
     343             :   friend class Type;
     344             :   friend class BitsetType;
     345             :   friend class UnionType;
     346             : 
     347             :   static RangeType* New(double min, double max, Zone* zone) {
     348    17437907 :     return New(Limits(min, max), zone);
     349             :   }
     350             : 
     351    21395117 :   static RangeType* New(Limits lim, Zone* zone) {
     352             :     DCHECK(IsInteger(lim.min) && IsInteger(lim.max));
     353             :     DCHECK(lim.min <= lim.max);
     354             :     BitsetType::bitset bits = BitsetType::Lub(lim.min, lim.max);
     355             : 
     356    42790168 :     return new (zone->New(sizeof(RangeType))) RangeType(bits, lim);
     357             :   }
     358             : 
     359             :   RangeType(BitsetType::bitset bitset, Limits limits)
     360    21395084 :       : TypeBase(kRange), bitset_(bitset), limits_(limits) {}
     361             : 
     362             :   BitsetType::bitset Lub() const { return bitset_; }
     363             : 
     364             :   BitsetType::bitset bitset_;
     365             :   Limits limits_;
     366             : };
     367             : 
     368             : // -----------------------------------------------------------------------------
     369             : // The actual type.
     370             : 
     371             : class V8_EXPORT_PRIVATE Type {
     372             :  public:
     373             :   using bitset = BitsetType::bitset;  // Internal
     374             : 
     375             : // Constructors.
     376             : #define DEFINE_TYPE_CONSTRUCTOR(type, value) \
     377             :   static Type type() { return NewBitset(BitsetType::k##type); }
     378             :   PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
     379             : #undef DEFINE_TYPE_CONSTRUCTOR
     380             : 
     381   201405832 :   Type() : payload_(0) {}
     382             : 
     383     6829755 :   static Type SignedSmall() { return NewBitset(BitsetType::SignedSmall()); }
     384      231968 :   static Type UnsignedSmall() { return NewBitset(BitsetType::UnsignedSmall()); }
     385             : 
     386             :   static Type OtherNumberConstant(double value, Zone* zone);
     387             :   static Type HeapConstant(JSHeapBroker* broker, Handle<i::Object> value,
     388             :                            Zone* zone);
     389             :   static Type HeapConstant(const HeapObjectRef& value, Zone* zone);
     390             :   static Type Range(double min, double max, Zone* zone);
     391             :   static Type Range(RangeType::Limits lims, Zone* zone);
     392             :   static Type Tuple(Type first, Type second, Type third, Zone* zone);
     393             :   static Type Union(int length, Zone* zone);
     394             : 
     395             :   // NewConstant is a factory that returns Constant, Range or Number.
     396             :   static Type NewConstant(JSHeapBroker* broker, Handle<i::Object> value,
     397             :                           Zone* zone);
     398             :   static Type NewConstant(double value, Zone* zone);
     399             : 
     400             :   static Type Union(Type type1, Type type2, Zone* zone);
     401             :   static Type Intersect(Type type1, Type type2, Zone* zone);
     402             : 
     403             :   static Type For(HeapObjectType const& type) {
     404             :     return NewBitset(BitsetType::ExpandInternals(BitsetType::Lub(type)));
     405             :   }
     406       12596 :   static Type For(MapRef const& type) {
     407       24853 :     return NewBitset(BitsetType::ExpandInternals(BitsetType::Lub(type)));
     408             :   }
     409             : 
     410             :   // Predicates.
     411   838791579 :   bool IsNone() const { return payload_ == None().payload_; }
     412      389402 :   bool IsInvalid() const { return payload_ == 0u; }
     413             : 
     414    46559377 :   bool Is(Type that) const {
     415   411150845 :     return payload_ == that.payload_ || this->SlowIs(that);
     416             :   }
     417             :   bool Maybe(Type that) const;
     418      363114 :   bool Equals(Type that) const { return this->Is(that) && that.Is(*this); }
     419             : 
     420             :   // Inspection.
     421  1438710529 :   bool IsBitset() const { return payload_ & 1; }
     422             :   bool IsRange() const { return IsKind(TypeBase::kRange); }
     423             :   bool IsHeapConstant() const { return IsKind(TypeBase::kHeapConstant); }
     424             :   bool IsOtherNumberConstant() const {
     425             :     return IsKind(TypeBase::kOtherNumberConstant);
     426             :   }
     427             :   bool IsTuple() const { return IsKind(TypeBase::kTuple); }
     428             : 
     429             :   const HeapConstantType* AsHeapConstant() const;
     430             :   const OtherNumberConstantType* AsOtherNumberConstant() const;
     431             :   const RangeType* AsRange() const;
     432             :   const TupleType* AsTuple() const;
     433             : 
     434             :   // Minimum and maximum of a numeric type.
     435             :   // These functions do not distinguish between -0 and +0.  NaN is ignored.
     436             :   // Only call them on subtypes of Number whose intersection with OrderedNumber
     437             :   // is not empty.
     438             :   double Min() const;
     439             :   double Max() const;
     440             : 
     441             :   // Extracts a range from the type: if the type is a range or a union
     442             :   // containing a range, that range is returned; otherwise, nullptr is returned.
     443             :   Type GetRange() const;
     444             : 
     445             :   int NumConstants() const;
     446             : 
     447             :   static Type Invalid() { return Type(); }
     448             : 
     449        4085 :   bool operator==(Type other) const { return payload_ == other.payload_; }
     450             :   bool operator!=(Type other) const { return payload_ != other.payload_; }
     451             : 
     452             :   // Printing.
     453             : 
     454             :   void PrintTo(std::ostream& os) const;
     455             : 
     456             : #ifdef DEBUG
     457             :   void Print() const;
     458             : #endif
     459             : 
     460             :   // Helpers for testing.
     461             :   bool IsUnionForTesting() { return IsUnion(); }
     462             :   bitset AsBitsetForTesting() { return AsBitset(); }
     463        3516 :   const UnionType* AsUnionForTesting() { return AsUnion(); }
     464       50052 :   Type BitsetGlbForTesting() { return NewBitset(BitsetGlb()); }
     465       50068 :   Type BitsetLubForTesting() { return NewBitset(BitsetLub()); }
     466             : 
     467             :  private:
     468             :   // Friends.
     469             :   template <class>
     470             :   friend class Iterator;
     471             :   friend BitsetType;
     472             :   friend UnionType;
     473             :   friend size_t hash_value(Type type);
     474             : 
     475    59725962 :   explicit Type(bitset bits) : payload_(bits | 1u) {}
     476             :   Type(TypeBase* type_base)  // NOLINT(runtime/explicit)
     477    58178480 :       : payload_(reinterpret_cast<uintptr_t>(type_base)) {}
     478             : 
     479             :   // Internal inspection.
     480             :   bool IsKind(TypeBase::Kind kind) const {
     481  1222750066 :     if (IsBitset()) return false;
     482             :     const TypeBase* base = ToTypeBase();
     483  1141125093 :     return base->kind() == kind;
     484             :   }
     485             : 
     486             :   const TypeBase* ToTypeBase() const {
     487  1647120939 :     return reinterpret_cast<TypeBase*>(payload_);
     488             :   }
     489             :   static Type FromTypeBase(TypeBase* type) { return Type(type); }
     490             : 
     491    42475824 :   bool IsAny() const { return payload_ == Any().payload_; }
     492             :   bool IsUnion() const { return IsKind(TypeBase::kUnion); }
     493             : 
     494             :   bitset AsBitset() const {
     495             :     DCHECK(IsBitset());
     496   642825279 :     return static_cast<bitset>(payload_) ^ 1u;
     497             :   }
     498             : 
     499             :   const UnionType* AsUnion() const;
     500             : 
     501             :   bitset BitsetGlb() const;  // greatest lower bound that's a bitset
     502             :   bitset BitsetLub() const;  // least upper bound that's a bitset
     503             : 
     504             :   bool SlowIs(Type that) const;
     505             : 
     506             :   static Type NewBitset(bitset bits) { return Type(bits); }
     507             : 
     508             :   static bool Overlap(const RangeType* lhs, const RangeType* rhs);
     509             :   static bool Contains(const RangeType* lhs, const RangeType* rhs);
     510             : 
     511             :   static int UpdateRange(Type type, UnionType* result, int size, Zone* zone);
     512             : 
     513             :   static RangeType::Limits IntersectRangeAndBitset(Type range, Type bits,
     514             :                                                    Zone* zone);
     515             :   static RangeType::Limits ToLimits(bitset bits, Zone* zone);
     516             : 
     517             :   bool SimplyEquals(Type that) const;
     518             : 
     519             :   static int AddToUnion(Type type, UnionType* result, int size, Zone* zone);
     520             :   static int IntersectAux(Type type, Type other, UnionType* result, int size,
     521             :                           RangeType::Limits* limits, Zone* zone);
     522             :   static Type NormalizeUnion(UnionType* unioned, int size, Zone* zone);
     523             :   static Type NormalizeRangeAndBitset(Type range, bitset* bits, Zone* zone);
     524             : 
     525             :   // If LSB is set, the payload is a bitset; if LSB is clear, the payload is
     526             :   // a pointer to a subtype of the TypeBase class.
     527             :   uintptr_t payload_;
     528             : };
     529             : 
     530             : inline size_t hash_value(Type type) { return type.payload_; }
     531             : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, Type type);
     532             : 
     533             : // -----------------------------------------------------------------------------
     534             : // Constant types.
     535             : 
     536             : class OtherNumberConstantType : public TypeBase {
     537             :  public:
     538             :   double Value() const { return value_; }
     539             : 
     540             :   static bool IsOtherNumberConstant(double value);
     541             : 
     542             :  private:
     543             :   friend class Type;
     544             :   friend class BitsetType;
     545             : 
     546     1640802 :   static OtherNumberConstantType* New(double value, Zone* zone) {
     547             :     return new (zone->New(sizeof(OtherNumberConstantType)))
     548     1640802 :         OtherNumberConstantType(value);  // NOLINT
     549             :   }
     550             : 
     551     1640802 :   explicit OtherNumberConstantType(double value)
     552     1640802 :       : TypeBase(kOtherNumberConstant), value_(value) {
     553     1640802 :     CHECK(IsOtherNumberConstant(value));
     554     1640802 :   }
     555             : 
     556             :   BitsetType::bitset Lub() const { return BitsetType::kOtherNumber; }
     557             : 
     558             :   double value_;
     559             : };
     560             : 
     561             : class V8_EXPORT_PRIVATE HeapConstantType : public NON_EXPORTED_BASE(TypeBase) {
     562             :  public:
     563             :   Handle<HeapObject> Value() const;
     564             :   const HeapObjectRef& Ref() const { return heap_ref_; }
     565             : 
     566             :  private:
     567             :   friend class Type;
     568             :   friend class BitsetType;
     569             : 
     570    18423320 :   static HeapConstantType* New(const HeapObjectRef& heap_ref, Zone* zone) {
     571             :     DCHECK(!heap_ref.IsHeapNumber());
     572             :     DCHECK_IMPLIES(heap_ref.IsString(), heap_ref.IsInternalizedString());
     573    36846638 :     BitsetType::bitset bitset = BitsetType::Lub(heap_ref.GetHeapObjectType());
     574             :     return new (zone->New(sizeof(HeapConstantType)))
     575    36846620 :         HeapConstantType(bitset, heap_ref);
     576             :   }
     577             : 
     578             :   HeapConstantType(BitsetType::bitset bitset, const HeapObjectRef& heap_ref);
     579             : 
     580             :   BitsetType::bitset Lub() const { return bitset_; }
     581             : 
     582             :   BitsetType::bitset bitset_;
     583             :   HeapObjectRef heap_ref_;
     584             : };
     585             : 
     586             : // -----------------------------------------------------------------------------
     587             : // Superclass for types with variable number of type fields.
     588             : class StructuralType : public TypeBase {
     589             :  public:
     590             :   int LengthForTesting() const { return Length(); }
     591             : 
     592             :  protected:
     593             :   friend class Type;
     594             : 
     595             :   int Length() const { return length_; }
     596             : 
     597             :   Type Get(int i) const {
     598             :     DCHECK(0 <= i && i < this->Length());
     599   256324461 :     return elements_[i];
     600             :   }
     601             : 
     602             :   void Set(int i, Type type) {
     603             :     DCHECK(0 <= i && i < this->Length());
     604    54733222 :     elements_[i] = type;
     605             :   }
     606             : 
     607             :   void Shrink(int length) {
     608             :     DCHECK(2 <= length && length <= this->Length());
     609    16716659 :     length_ = length;
     610             :   }
     611             : 
     612             :   StructuralType(Kind kind, int length, Zone* zone)
     613    20345232 :       : TypeBase(kind), length_(length) {
     614    20345232 :     elements_ = reinterpret_cast<Type*>(zone->New(sizeof(Type) * length));
     615             :   }
     616             : 
     617             :  private:
     618             :   int length_;
     619             :   Type* elements_;
     620             : };
     621             : 
     622             : // -----------------------------------------------------------------------------
     623             : // Tuple types.
     624             : 
     625             : class TupleType : public StructuralType {
     626             :  public:
     627             :   int Arity() const { return this->Length(); }
     628             :   Type Element(int i) const { return this->Get(i); }
     629             : 
     630             :   void InitElement(int i, Type type) { this->Set(i, type); }
     631             : 
     632             :  private:
     633             :   friend class Type;
     634             : 
     635             :   TupleType(int length, Zone* zone) : StructuralType(kTuple, length, zone) {}
     636             : 
     637        1386 :   static TupleType* New(int length, Zone* zone) {
     638        2772 :     return new (zone->New(sizeof(TupleType))) TupleType(length, zone);
     639             :   }
     640             : };
     641             : 
     642             : // -----------------------------------------------------------------------------
     643             : // Union types (internal).
     644             : // A union is a structured type with the following invariants:
     645             : // - its length is at least 2
     646             : // - at most one field is a bitset, and it must go into index 0
     647             : // - no field is a union
     648             : // - no field is a subtype of any other field
     649             : class UnionType : public StructuralType {
     650             :  private:
     651             :   friend Type;
     652             :   friend BitsetType;
     653             : 
     654             :   UnionType(int length, Zone* zone) : StructuralType(kUnion, length, zone) {}
     655             : 
     656    20343849 :   static UnionType* New(int length, Zone* zone) {
     657    40687676 :     return new (zone->New(sizeof(UnionType))) UnionType(length, zone);
     658             :   }
     659             : 
     660             :   bool Wellformed() const;
     661             : };
     662             : 
     663             : }  // namespace compiler
     664             : }  // namespace internal
     665             : }  // namespace v8
     666             : 
     667             : #endif  // V8_COMPILER_TYPES_H_

Generated by: LCOV version 1.10