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