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-19 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(OtherString,     1u << 5)  \
     108             : 
     109             : #define PROPER_BITSET_TYPE_LIST(V) \
     110             :   V(None,                     0u)        \
     111             :   V(Negative31,               1u << 6)   \
     112             :   V(Null,                     1u << 7)   \
     113             :   V(Undefined,                1u << 8)   \
     114             :   V(Boolean,                  1u << 9)   \
     115             :   V(Unsigned30,               1u << 10)   \
     116             :   V(MinusZero,                1u << 11)  \
     117             :   V(NaN,                      1u << 12)  \
     118             :   V(Symbol,                   1u << 13)  \
     119             :   V(InternalizedString,       1u << 14)  \
     120             :   V(OtherCallable,            1u << 16)  \
     121             :   V(OtherObject,              1u << 17)  \
     122             :   V(OtherUndetectable,        1u << 18)  \
     123             :   V(CallableProxy,            1u << 19)  \
     124             :   V(OtherProxy,               1u << 20)  \
     125             :   V(Function,                 1u << 21)  \
     126             :   V(BoundFunction,            1u << 22)  \
     127             :   V(Hole,                     1u << 23)  \
     128             :   V(OtherInternal,            1u << 24)  \
     129             :   V(ExternalPointer,          1u << 25)  \
     130             :   V(Array,                    1u << 26)  \
     131             :   V(BigInt,                   1u << 27)  \
     132             :   \
     133             :   V(Signed31,                     kUnsigned30 | kNegative31) \
     134             :   V(Signed32,                     kSigned31 | kOtherUnsigned31 | \
     135             :                                   kOtherSigned32) \
     136             :   V(Signed32OrMinusZero,          kSigned32 | kMinusZero) \
     137             :   V(Signed32OrMinusZeroOrNaN,     kSigned32 | kMinusZero | kNaN) \
     138             :   V(Negative32,                   kNegative31 | kOtherSigned32) \
     139             :   V(Unsigned31,                   kUnsigned30 | kOtherUnsigned31) \
     140             :   V(Unsigned32,                   kUnsigned30 | kOtherUnsigned31 | \
     141             :                                   kOtherUnsigned32) \
     142             :   V(Unsigned32OrMinusZero,        kUnsigned32 | kMinusZero) \
     143             :   V(Unsigned32OrMinusZeroOrNaN,   kUnsigned32 | kMinusZero | kNaN) \
     144             :   V(Integral32,                   kSigned32 | kUnsigned32) \
     145             :   V(Integral32OrMinusZero,        kIntegral32 | kMinusZero) \
     146             :   V(Integral32OrMinusZeroOrNaN,   kIntegral32OrMinusZero | kNaN) \
     147             :   V(PlainNumber,                  kIntegral32 | kOtherNumber) \
     148             :   V(OrderedNumber,                kPlainNumber | kMinusZero) \
     149             :   V(MinusZeroOrNaN,               kMinusZero | kNaN) \
     150             :   V(Number,                       kOrderedNumber | kNaN) \
     151             :   V(Numeric,                      kNumber | kBigInt) \
     152             :   V(String,                       kInternalizedString | kOtherString) \
     153             :   V(UniqueName,                   kSymbol | kInternalizedString) \
     154             :   V(Name,                         kSymbol | kString) \
     155             :   V(InternalizedStringOrNull,     kInternalizedString | kNull) \
     156             :   V(BooleanOrNumber,              kBoolean | kNumber) \
     157             :   V(BooleanOrNullOrNumber,        kBooleanOrNumber | kNull) \
     158             :   V(BooleanOrNullOrUndefined,     kBoolean | kNull | kUndefined) \
     159             :   V(Oddball,                      kBooleanOrNullOrUndefined | kHole) \
     160             :   V(NullOrNumber,                 kNull | kNumber) \
     161             :   V(NullOrUndefined,              kNull | kUndefined) \
     162             :   V(Undetectable,                 kNullOrUndefined | kOtherUndetectable) \
     163             :   V(NumberOrHole,                 kNumber | kHole) \
     164             :   V(NumberOrOddball,              kNumber | kNullOrUndefined | kBoolean | \
     165             :                                   kHole) \
     166             :   V(NumericOrString,              kNumeric | kString) \
     167             :   V(NumberOrUndefined,            kNumber | kUndefined) \
     168             :   V(NumberOrUndefinedOrNullOrBoolean,  \
     169             :                                   kNumber | kNullOrUndefined | kBoolean) \
     170             :   V(PlainPrimitive,               kNumber | kString | kBoolean | \
     171             :                                   kNullOrUndefined) \
     172             :   V(NonBigIntPrimitive,           kSymbol | kPlainPrimitive) \
     173             :   V(Primitive,                    kBigInt | kNonBigIntPrimitive) \
     174             :   V(OtherUndetectableOrUndefined, kOtherUndetectable | kUndefined) \
     175             :   V(Proxy,                        kCallableProxy | kOtherProxy) \
     176             :   V(ArrayOrOtherObject,           kArray | kOtherObject) \
     177             :   V(ArrayOrProxy,                 kArray | kProxy) \
     178             :   V(DetectableCallable,           kFunction | kBoundFunction | \
     179             :                                   kOtherCallable | kCallableProxy) \
     180             :   V(Callable,                     kDetectableCallable | kOtherUndetectable) \
     181             :   V(NonCallable,                  kArray | kOtherObject | kOtherProxy) \
     182             :   V(NonCallableOrNull,            kNonCallable | kNull) \
     183             :   V(DetectableObject,             kArray | kFunction | kBoundFunction | \
     184             :                                   kOtherCallable | kOtherObject) \
     185             :   V(DetectableReceiver,           kDetectableObject | kProxy) \
     186             :   V(DetectableReceiverOrNull,     kDetectableReceiver | kNull) \
     187             :   V(Object,                       kDetectableObject | kOtherUndetectable) \
     188             :   V(Receiver,                     kObject | kProxy) \
     189             :   V(ReceiverOrUndefined,          kReceiver | kUndefined) \
     190             :   V(ReceiverOrNullOrUndefined,    kReceiver | kNull | kUndefined) \
     191             :   V(SymbolOrReceiver,             kSymbol | kReceiver) \
     192             :   V(StringOrReceiver,             kString | kReceiver) \
     193             :   V(Unique,                       kBoolean | kUniqueName | kNull | \
     194             :                                   kUndefined | kReceiver) \
     195             :   V(Internal,                     kHole | kExternalPointer | kOtherInternal) \
     196             :   V(NonInternal,                  kPrimitive | kReceiver) \
     197             :   V(NonBigInt,                    kNonBigIntPrimitive | kReceiver) \
     198             :   V(NonNumber,                    kBigInt | kUnique | kString | kInternal) \
     199             :   V(Any,                          0xfffffffeu)
     200             : 
     201             : // clang-format on
     202             : 
     203             : /*
     204             :  * The following diagrams show how integers (in the mathematical sense) are
     205             :  * divided among the different atomic numerical types.
     206             :  *
     207             :  *   ON    OS32     N31     U30     OU31    OU32     ON
     208             :  * ______[_______[_______[_______[_______[_______[_______
     209             :  *     -2^31   -2^30     0      2^30    2^31    2^32
     210             :  *
     211             :  * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1.
     212             :  *
     213             :  * Some of the atomic numerical bitsets are internal only (see
     214             :  * INTERNAL_BITSET_TYPE_LIST).  To a types user, they should only occur in
     215             :  * union with certain other bitsets.  For instance, OtherNumber should only
     216             :  * occur as part of PlainNumber.
     217             :  */
     218             : 
     219             : #define BITSET_TYPE_LIST(V)    \
     220             :   INTERNAL_BITSET_TYPE_LIST(V) \
     221             :   PROPER_BITSET_TYPE_LIST(V)
     222             : 
     223             : class HeapConstantType;
     224             : class OtherNumberConstantType;
     225             : class TupleType;
     226             : class Type;
     227             : class UnionType;
     228             : 
     229             : // -----------------------------------------------------------------------------
     230             : // Bitset types (internal).
     231             : 
     232             : class V8_EXPORT_PRIVATE BitsetType {
     233             :  public:
     234             :   using bitset = uint32_t;  // Internal
     235             : 
     236             :   enum : uint32_t {
     237             : #define DECLARE_TYPE(type, value) k##type = (value),
     238             :     BITSET_TYPE_LIST(DECLARE_TYPE)
     239             : #undef DECLARE_TYPE
     240             :         kUnusedEOL = 0
     241             :   };
     242             : 
     243             :   static bitset SignedSmall();
     244             :   static bitset UnsignedSmall();
     245             : 
     246             :   static bool IsNone(bitset bits) { return bits == kNone; }
     247             : 
     248             :   static bool Is(bitset bits1, bitset bits2) {
     249   353731398 :     return (bits1 | bits2) == bits2;
     250             :   }
     251             : 
     252             :   static double Min(bitset);
     253             :   static double Max(bitset);
     254             : 
     255             :   static bitset Glb(double min, double max);
     256             :   static bitset Lub(HeapObjectType const& type) {
     257    18989893 :     return Lub<HeapObjectType>(type);
     258             :   }
     259       12193 :   static bitset Lub(MapRef const& map) { return Lub<MapRef>(map); }
     260             :   static bitset Lub(double value);
     261             :   static bitset Lub(double min, double max);
     262             :   static bitset ExpandInternals(bitset bits);
     263             : 
     264             :   static const char* Name(bitset);
     265             :   static void Print(std::ostream& os, bitset);  // NOLINT
     266             : #ifdef DEBUG
     267             :   static void Print(bitset);
     268             : #endif
     269             : 
     270             :   static bitset NumberBits(bitset bits);
     271             : 
     272             :  private:
     273             :   struct Boundary {
     274             :     bitset internal;
     275             :     bitset external;
     276             :     double min;
     277             :   };
     278             :   static const Boundary BoundariesArray[];
     279             :   static inline const Boundary* Boundaries();
     280             :   static inline size_t BoundariesSize();
     281             : 
     282             :   template <typename MapRefLike>
     283             :   static bitset Lub(MapRefLike const& map);
     284             : };
     285             : 
     286             : // -----------------------------------------------------------------------------
     287             : // Superclass for non-bitset types (internal).
     288             : class TypeBase {
     289             :  protected:
     290             :   friend class Type;
     291             : 
     292             :   enum Kind { kHeapConstant, kOtherNumberConstant, kTuple, kUnion, kRange };
     293             : 
     294  1151431675 :   Kind kind() const { return kind_; }
     295    63590230 :   explicit TypeBase(Kind kind) : kind_(kind) {}
     296             : 
     297             :   static bool IsKind(Type type, Kind kind);
     298             : 
     299             :  private:
     300             :   Kind kind_;
     301             : };
     302             : 
     303             : // -----------------------------------------------------------------------------
     304             : // Range types.
     305             : 
     306             : class RangeType : public TypeBase {
     307             :  public:
     308             :   struct Limits {
     309             :     double min;
     310             :     double max;
     311    17767148 :     Limits(double min, double max) : min(min), max(max) {}
     312             :     explicit Limits(const RangeType* range)
     313             :         : min(range->Min()), max(range->Max()) {}
     314             :     bool IsEmpty();
     315             :     static Limits Empty() { return Limits(1, 0); }
     316             :     static Limits Intersect(Limits lhs, Limits rhs);
     317             :     static Limits Union(Limits lhs, Limits rhs);
     318             :   };
     319             : 
     320             :   double Min() const { return limits_.min; }
     321             :   double Max() const { return limits_.max; }
     322             : 
     323             :   static bool IsInteger(double x) {
     324     9811803 :     return nearbyint(x) == x && !IsMinusZero(x);  // Allows for infinities.
     325             :   }
     326             : 
     327             :  private:
     328             :   friend class Type;
     329             :   friend class BitsetType;
     330             :   friend class UnionType;
     331             : 
     332             :   static RangeType* New(double min, double max, Zone* zone) {
     333    17767148 :     return New(Limits(min, max), zone);
     334             :   }
     335             : 
     336    21657020 :   static RangeType* New(Limits lim, Zone* zone) {
     337             :     DCHECK(IsInteger(lim.min) && IsInteger(lim.max));
     338             :     DCHECK(lim.min <= lim.max);
     339             :     BitsetType::bitset bits = BitsetType::Lub(lim.min, lim.max);
     340             : 
     341    43313982 :     return new (zone->New(sizeof(RangeType))) RangeType(bits, lim);
     342             :   }
     343             : 
     344             :   RangeType(BitsetType::bitset bitset, Limits limits)
     345    21656991 :       : TypeBase(kRange), bitset_(bitset), limits_(limits) {}
     346             : 
     347             :   BitsetType::bitset Lub() const { return bitset_; }
     348             : 
     349             :   BitsetType::bitset bitset_;
     350             :   Limits limits_;
     351             : };
     352             : 
     353             : // -----------------------------------------------------------------------------
     354             : // The actual type.
     355             : 
     356             : class V8_EXPORT_PRIVATE Type {
     357             :  public:
     358             :   using bitset = BitsetType::bitset;  // Internal
     359             : 
     360             : // Constructors.
     361             : #define DEFINE_TYPE_CONSTRUCTOR(type, value) \
     362             :   static Type type() { return NewBitset(BitsetType::k##type); }
     363             :   PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
     364             : #undef DEFINE_TYPE_CONSTRUCTOR
     365             : 
     366   201490984 :   Type() : payload_(0) {}
     367             : 
     368     6849140 :   static Type SignedSmall() { return NewBitset(BitsetType::SignedSmall()); }
     369      233109 :   static Type UnsignedSmall() { return NewBitset(BitsetType::UnsignedSmall()); }
     370             : 
     371             :   static Type OtherNumberConstant(double value, Zone* zone);
     372             :   static Type HeapConstant(JSHeapBroker* broker, Handle<i::Object> value,
     373             :                            Zone* zone);
     374             :   static Type HeapConstant(const HeapObjectRef& value, Zone* zone);
     375             :   static Type Range(double min, double max, Zone* zone);
     376             :   static Type Range(RangeType::Limits lims, Zone* zone);
     377             :   static Type Tuple(Type first, Type second, Type third, Zone* zone);
     378             :   static Type Union(int length, Zone* zone);
     379             : 
     380             :   // NewConstant is a factory that returns Constant, Range or Number.
     381             :   static Type NewConstant(JSHeapBroker* broker, Handle<i::Object> value,
     382             :                           Zone* zone);
     383             :   static Type NewConstant(double value, Zone* zone);
     384             : 
     385             :   static Type Union(Type type1, Type type2, Zone* zone);
     386             :   static Type Intersect(Type type1, Type type2, Zone* zone);
     387             : 
     388             :   static Type For(HeapObjectType const& type) {
     389             :     return NewBitset(BitsetType::ExpandInternals(BitsetType::Lub(type)));
     390             :   }
     391       12193 :   static Type For(MapRef const& type) {
     392       24386 :     return NewBitset(BitsetType::ExpandInternals(BitsetType::Lub(type)));
     393             :   }
     394             : 
     395             :   // Predicates.
     396   840599712 :   bool IsNone() const { return payload_ == None().payload_; }
     397      391239 :   bool IsInvalid() const { return payload_ == 0u; }
     398             : 
     399    46810532 :   bool Is(Type that) const {
     400   412798747 :     return payload_ == that.payload_ || this->SlowIs(that);
     401             :   }
     402             :   bool Maybe(Type that) const;
     403      344670 :   bool Equals(Type that) const { return this->Is(that) && that.Is(*this); }
     404             : 
     405             :   // Inspection.
     406  1455281434 :   bool IsBitset() const { return payload_ & 1; }
     407             :   bool IsRange() const { return IsKind(TypeBase::kRange); }
     408             :   bool IsHeapConstant() const { return IsKind(TypeBase::kHeapConstant); }
     409             :   bool IsOtherNumberConstant() const {
     410             :     return IsKind(TypeBase::kOtherNumberConstant);
     411             :   }
     412             :   bool IsTuple() const { return IsKind(TypeBase::kTuple); }
     413             : 
     414             :   const HeapConstantType* AsHeapConstant() const;
     415             :   const OtherNumberConstantType* AsOtherNumberConstant() const;
     416             :   const RangeType* AsRange() const;
     417             :   const TupleType* AsTuple() const;
     418             : 
     419             :   // Minimum and maximum of a numeric type.
     420             :   // These functions do not distinguish between -0 and +0.  NaN is ignored.
     421             :   // Only call them on subtypes of Number whose intersection with OrderedNumber
     422             :   // is not empty.
     423             :   double Min() const;
     424             :   double Max() const;
     425             : 
     426             :   // Extracts a range from the type: if the type is a range or a union
     427             :   // containing a range, that range is returned; otherwise, nullptr is returned.
     428             :   Type GetRange() const;
     429             : 
     430             :   int NumConstants() const;
     431             : 
     432             :   static Type Invalid() { return Type(); }
     433             : 
     434        3020 :   bool operator==(Type other) const { return payload_ == other.payload_; }
     435             :   bool operator!=(Type other) const { return payload_ != other.payload_; }
     436             : 
     437             :   // Printing.
     438             : 
     439             :   void PrintTo(std::ostream& os) const;
     440             : 
     441             : #ifdef DEBUG
     442             :   void Print() const;
     443             : #endif
     444             : 
     445             :   // Helpers for testing.
     446             :   bool IsUnionForTesting() { return IsUnion(); }
     447             :   bitset AsBitsetForTesting() { return AsBitset(); }
     448        2504 :   const UnionType* AsUnionForTesting() { return AsUnion(); }
     449       44044 :   Type BitsetGlbForTesting() { return NewBitset(BitsetGlb()); }
     450       44052 :   Type BitsetLubForTesting() { return NewBitset(BitsetLub()); }
     451             : 
     452             :  private:
     453             :   // Friends.
     454             :   template <class>
     455             :   friend class Iterator;
     456             :   friend BitsetType;
     457             :   friend UnionType;
     458             :   friend size_t hash_value(Type type);
     459             : 
     460    60136941 :   explicit Type(bitset bits) : payload_(bits | 1u) {}
     461             :   Type(TypeBase* type_base)  // NOLINT(runtime/explicit)
     462    60014764 :       : payload_(reinterpret_cast<uintptr_t>(type_base)) {}
     463             : 
     464             :   // Internal inspection.
     465             :   bool IsKind(TypeBase::Kind kind) const {
     466  1235859764 :     if (IsBitset()) return false;
     467             :     const TypeBase* base = ToTypeBase();
     468  1151431675 :     return base->kind() == kind;
     469             :   }
     470             : 
     471             :   const TypeBase* ToTypeBase() const {
     472  1664418903 :     return reinterpret_cast<TypeBase*>(payload_);
     473             :   }
     474             :   static Type FromTypeBase(TypeBase* type) { return Type(type); }
     475             : 
     476    43748853 :   bool IsAny() const { return payload_ == Any().payload_; }
     477             :   bool IsUnion() const { return IsKind(TypeBase::kUnion); }
     478             : 
     479             :   bitset AsBitset() const {
     480             :     DCHECK(IsBitset());
     481   647853511 :     return static_cast<bitset>(payload_) ^ 1u;
     482             :   }
     483             : 
     484             :   const UnionType* AsUnion() const;
     485             : 
     486             :   bitset BitsetGlb() const;  // greatest lower bound that's a bitset
     487             :   bitset BitsetLub() const;  // least upper bound that's a bitset
     488             : 
     489             :   bool SlowIs(Type that) const;
     490             : 
     491             :   static Type NewBitset(bitset bits) { return Type(bits); }
     492             : 
     493             :   static bool Overlap(const RangeType* lhs, const RangeType* rhs);
     494             :   static bool Contains(const RangeType* lhs, const RangeType* rhs);
     495             : 
     496             :   static int UpdateRange(Type type, UnionType* result, int size, Zone* zone);
     497             : 
     498             :   static RangeType::Limits IntersectRangeAndBitset(Type range, Type bits,
     499             :                                                    Zone* zone);
     500             :   static RangeType::Limits ToLimits(bitset bits, Zone* zone);
     501             : 
     502             :   bool SimplyEquals(Type that) const;
     503             : 
     504             :   static int AddToUnion(Type type, UnionType* result, int size, Zone* zone);
     505             :   static int IntersectAux(Type type, Type other, UnionType* result, int size,
     506             :                           RangeType::Limits* limits, Zone* zone);
     507             :   static Type NormalizeUnion(UnionType* unioned, int size, Zone* zone);
     508             :   static Type NormalizeRangeAndBitset(Type range, bitset* bits, Zone* zone);
     509             : 
     510             :   // If LSB is set, the payload is a bitset; if LSB is clear, the payload is
     511             :   // a pointer to a subtype of the TypeBase class.
     512             :   uintptr_t payload_;
     513             : };
     514             : 
     515             : inline size_t hash_value(Type type) { return type.payload_; }
     516             : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, Type type);
     517             : 
     518             : // -----------------------------------------------------------------------------
     519             : // Constant types.
     520             : 
     521             : class OtherNumberConstantType : public TypeBase {
     522             :  public:
     523             :   double Value() const { return value_; }
     524             : 
     525             :   static bool IsOtherNumberConstant(double value);
     526             : 
     527             :  private:
     528             :   friend class Type;
     529             :   friend class BitsetType;
     530             : 
     531     1735499 :   static OtherNumberConstantType* New(double value, Zone* zone) {
     532             :     return new (zone->New(sizeof(OtherNumberConstantType)))
     533     1735499 :         OtherNumberConstantType(value);  // NOLINT
     534             :   }
     535             : 
     536     1735499 :   explicit OtherNumberConstantType(double value)
     537     1735499 :       : TypeBase(kOtherNumberConstant), value_(value) {
     538     1735499 :     CHECK(IsOtherNumberConstant(value));
     539     1735499 :   }
     540             : 
     541             :   BitsetType::bitset Lub() const { return BitsetType::kOtherNumber; }
     542             : 
     543             :   double value_;
     544             : };
     545             : 
     546             : class V8_EXPORT_PRIVATE HeapConstantType : public NON_EXPORTED_BASE(TypeBase) {
     547             :  public:
     548             :   Handle<HeapObject> Value() const;
     549             :   const HeapObjectRef& Ref() const { return heap_ref_; }
     550             : 
     551             :  private:
     552             :   friend class Type;
     553             :   friend class BitsetType;
     554             : 
     555    18989884 :   static HeapConstantType* New(const HeapObjectRef& heap_ref, Zone* zone) {
     556             :     DCHECK(!heap_ref.IsHeapNumber());
     557             :     DCHECK_IMPLIES(heap_ref.IsString(), heap_ref.IsInternalizedString());
     558    37979760 :     BitsetType::bitset bitset = BitsetType::Lub(heap_ref.GetHeapObjectType());
     559             :     return new (zone->New(sizeof(HeapConstantType)))
     560    37979730 :         HeapConstantType(bitset, heap_ref);
     561             :   }
     562             : 
     563             :   HeapConstantType(BitsetType::bitset bitset, const HeapObjectRef& heap_ref);
     564             : 
     565             :   BitsetType::bitset Lub() const { return bitset_; }
     566             : 
     567             :   BitsetType::bitset bitset_;
     568             :   HeapObjectRef heap_ref_;
     569             : };
     570             : 
     571             : // -----------------------------------------------------------------------------
     572             : // Superclass for types with variable number of type fields.
     573             : class StructuralType : public TypeBase {
     574             :  public:
     575             :   int LengthForTesting() const { return Length(); }
     576             : 
     577             :  protected:
     578             :   friend class Type;
     579             : 
     580             :   int Length() const { return length_; }
     581             : 
     582             :   Type Get(int i) const {
     583             :     DCHECK(0 <= i && i < this->Length());
     584   261153377 :     return elements_[i];
     585             :   }
     586             : 
     587             :   void Set(int i, Type type) {
     588             :     DCHECK(0 <= i && i < this->Length());
     589    56283339 :     elements_[i] = type;
     590             :   }
     591             : 
     592             :   void Shrink(int length) {
     593             :     DCHECK(2 <= length && length <= this->Length());
     594    17629694 :     length_ = length;
     595             :   }
     596             : 
     597             :   StructuralType(Kind kind, int length, Zone* zone)
     598    21207875 :       : TypeBase(kind), length_(length) {
     599    21207875 :     elements_ = reinterpret_cast<Type*>(zone->New(sizeof(Type) * length));
     600             :   }
     601             : 
     602             :  private:
     603             :   int length_;
     604             :   Type* elements_;
     605             : };
     606             : 
     607             : // -----------------------------------------------------------------------------
     608             : // Tuple types.
     609             : 
     610             : class TupleType : public StructuralType {
     611             :  public:
     612             :   int Arity() const { return this->Length(); }
     613             :   Type Element(int i) const { return this->Get(i); }
     614             : 
     615             :   void InitElement(int i, Type type) { this->Set(i, type); }
     616             : 
     617             :  private:
     618             :   friend class Type;
     619             : 
     620             :   TupleType(int length, Zone* zone) : StructuralType(kTuple, length, zone) {}
     621             : 
     622        1380 :   static TupleType* New(int length, Zone* zone) {
     623        2760 :     return new (zone->New(sizeof(TupleType))) TupleType(length, zone);
     624             :   }
     625             : };
     626             : 
     627             : // -----------------------------------------------------------------------------
     628             : // Union types (internal).
     629             : // A union is a structured type with the following invariants:
     630             : // - its length is at least 2
     631             : // - at most one field is a bitset, and it must go into index 0
     632             : // - no field is a union
     633             : // - no field is a subtype of any other field
     634             : class UnionType : public StructuralType {
     635             :  private:
     636             :   friend Type;
     637             :   friend BitsetType;
     638             : 
     639             :   UnionType(int length, Zone* zone) : StructuralType(kUnion, length, zone) {}
     640             : 
     641    21206504 :   static UnionType* New(int length, Zone* zone) {
     642    42412966 :     return new (zone->New(sizeof(UnionType))) UnionType(length, zone);
     643             :   }
     644             : 
     645             :   bool Wellformed() const;
     646             : };
     647             : 
     648             : }  // namespace compiler
     649             : }  // namespace internal
     650             : }  // namespace v8
     651             : 
     652             : #endif  // V8_COMPILER_TYPES_H_

Generated by: LCOV version 1.10