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

Generated by: LCOV version 1.10