Home | History | Annotate | Download | only in src
      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_TYPE_CACHE_H_
      6 #define V8_TYPE_CACHE_H_
      7 
      8 #include "src/types.h"
      9 
     10 namespace v8 {
     11 namespace internal {
     12 
     13 class TypeCache final {
     14  private:
     15   // This has to be first for the initialization magic to work.
     16   Zone zone_;
     17 
     18  public:
     19   static TypeCache const& Get();
     20 
     21   TypeCache() = default;
     22 
     23   Type* const kInt8 =
     24       CreateNative(CreateRange<int8_t>(), Type::UntaggedIntegral8());
     25   Type* const kUint8 =
     26       CreateNative(CreateRange<uint8_t>(), Type::UntaggedIntegral8());
     27   Type* const kUint8Clamped = kUint8;
     28   Type* const kInt16 =
     29       CreateNative(CreateRange<int16_t>(), Type::UntaggedIntegral16());
     30   Type* const kUint16 =
     31       CreateNative(CreateRange<uint16_t>(), Type::UntaggedIntegral16());
     32   Type* const kInt32 =
     33       CreateNative(Type::Signed32(), Type::UntaggedIntegral32());
     34   Type* const kUint32 =
     35       CreateNative(Type::Unsigned32(), Type::UntaggedIntegral32());
     36   Type* const kFloat32 = CreateNative(Type::Number(), Type::UntaggedFloat32());
     37   Type* const kFloat64 = CreateNative(Type::Number(), Type::UntaggedFloat64());
     38 
     39   Type* const kSmi = CreateNative(Type::SignedSmall(), Type::TaggedSigned());
     40   Type* const kHeapNumber = CreateNative(Type::Number(), Type::TaggedPointer());
     41 
     42   Type* const kSingletonZero = CreateRange(0.0, 0.0);
     43   Type* const kSingletonOne = CreateRange(1.0, 1.0);
     44   Type* const kZeroOrOne = CreateRange(0.0, 1.0);
     45   Type* const kZeroToThirtyOne = CreateRange(0.0, 31.0);
     46   Type* const kZeroToThirtyTwo = CreateRange(0.0, 32.0);
     47   Type* const kZeroish =
     48       Type::Union(kSingletonZero, Type::MinusZeroOrNaN(), zone());
     49   Type* const kInteger = CreateRange(-V8_INFINITY, V8_INFINITY);
     50   Type* const kPositiveInteger = CreateRange(0.0, V8_INFINITY);
     51   Type* const kIntegerOrMinusZero =
     52       Type::Union(kInteger, Type::MinusZero(), zone());
     53   Type* const kIntegerOrMinusZeroOrNaN =
     54       Type::Union(kIntegerOrMinusZero, Type::NaN(), zone());
     55 
     56   Type* const kAdditiveSafeInteger =
     57       CreateRange(-4503599627370496.0, 4503599627370496.0);
     58   Type* const kSafeInteger = CreateRange(-kMaxSafeInteger, kMaxSafeInteger);
     59   Type* const kPositiveSafeInteger = CreateRange(0.0, kMaxSafeInteger);
     60 
     61   Type* const kUntaggedUndefined =
     62       Type::Intersect(Type::Undefined(), Type::Untagged(), zone());
     63 
     64   // Asm.js related types.
     65   Type* const kAsmSigned = kInt32;
     66   Type* const kAsmUnsigned = kUint32;
     67   Type* const kAsmInt = Type::Union(kAsmSigned, kAsmUnsigned, zone());
     68   Type* const kAsmFixnum = Type::Intersect(kAsmSigned, kAsmUnsigned, zone());
     69   Type* const kAsmFloat = kFloat32;
     70   Type* const kAsmDouble = kFloat64;
     71   Type* const kAsmFloatQ = Type::Union(kAsmFloat, kUntaggedUndefined, zone());
     72   Type* const kAsmDoubleQ = Type::Union(kAsmDouble, kUntaggedUndefined, zone());
     73   // Not part of the Asm.js type hierarchy, but represents a part of what
     74   // intish encompasses.
     75   Type* const kAsmIntQ = Type::Union(kAsmInt, kUntaggedUndefined, zone());
     76   Type* const kAsmFloatDoubleQ = Type::Union(kAsmFloatQ, kAsmDoubleQ, zone());
     77   // Asm.js size unions.
     78   Type* const kAsmSize8 = Type::Union(kInt8, kUint8, zone());
     79   Type* const kAsmSize16 = Type::Union(kInt16, kUint16, zone());
     80   Type* const kAsmSize32 =
     81       Type::Union(Type::Union(kInt32, kUint32, zone()), kAsmFloat, zone());
     82   Type* const kAsmSize64 = kFloat64;
     83   // Asm.js other types.
     84   Type* const kAsmComparable = Type::Union(
     85       kAsmSigned,
     86       Type::Union(kAsmUnsigned, Type::Union(kAsmDouble, kAsmFloat, zone()),
     87                   zone()),
     88       zone());
     89   Type* const kAsmIntArrayElement =
     90       Type::Union(Type::Union(kInt8, kUint8, zone()),
     91                   Type::Union(Type::Union(kInt16, kUint16, zone()),
     92                               Type::Union(kInt32, kUint32, zone()), zone()),
     93                   zone());
     94 
     95   // The FixedArray::length property always containts a smi in the range
     96   // [0, FixedArray::kMaxLength].
     97   Type* const kFixedArrayLengthType = CreateNative(
     98       CreateRange(0.0, FixedArray::kMaxLength), Type::TaggedSigned());
     99 
    100   // The FixedDoubleArray::length property always containts a smi in the range
    101   // [0, FixedDoubleArray::kMaxLength].
    102   Type* const kFixedDoubleArrayLengthType = CreateNative(
    103       CreateRange(0.0, FixedDoubleArray::kMaxLength), Type::TaggedSigned());
    104 
    105   // The JSArray::length property always contains a tagged number in the range
    106   // [0, kMaxUInt32].
    107   Type* const kJSArrayLengthType =
    108       CreateNative(Type::Unsigned32(), Type::Tagged());
    109 
    110   // The String::length property always contains a smi in the range
    111   // [0, String::kMaxLength].
    112   Type* const kStringLengthType =
    113       CreateNative(CreateRange(0.0, String::kMaxLength), Type::TaggedSigned());
    114 
    115   // When initializing arrays, we'll unfold the loop if the number of
    116   // elements is known to be of this type.
    117   Type* const kElementLoopUnrollType = CreateRange(0.0, 16.0);
    118 
    119 #define TYPED_ARRAY(TypeName, type_name, TYPE_NAME, ctype, size) \
    120   Type* const k##TypeName##Array = CreateArray(k##TypeName);
    121   TYPED_ARRAYS(TYPED_ARRAY)
    122 #undef TYPED_ARRAY
    123 
    124  private:
    125   Type* CreateArray(Type* element) { return Type::Array(element, zone()); }
    126 
    127   Type* CreateArrayFunction(Type* array) {
    128     Type* arg1 = Type::Union(Type::Unsigned32(), Type::Object(), zone());
    129     Type* arg2 = Type::Union(Type::Unsigned32(), Type::Undefined(), zone());
    130     Type* arg3 = arg2;
    131     return Type::Function(array, arg1, arg2, arg3, zone());
    132   }
    133 
    134   Type* CreateNative(Type* semantic, Type* representation) {
    135     return Type::Intersect(semantic, representation, zone());
    136   }
    137 
    138   template <typename T>
    139   Type* CreateRange() {
    140     return CreateRange(std::numeric_limits<T>::min(),
    141                        std::numeric_limits<T>::max());
    142   }
    143 
    144   Type* CreateRange(double min, double max) {
    145     return Type::Range(min, max, zone());
    146   }
    147 
    148   Zone* zone() { return &zone_; }
    149 };
    150 
    151 }  // namespace internal
    152 }  // namespace v8
    153 
    154 #endif  // V8_TYPE_CACHE_H_
    155