• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
TypeCache()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);
TYPED_ARRAYS(TYPED_ARRAY)129   TYPED_ARRAYS(TYPED_ARRAY)
130 #undef TYPED_ARRAY
131 
132  private:
133   Type* CreateArray(Type* element) { return Type::Array(element, zone()); }
134 
CreateArrayFunction(Type * array)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 
CreateNative(Type * semantic,Type * representation)142   Type* CreateNative(Type* semantic, Type* representation) {
143     return Type::Intersect(semantic, representation, zone());
144   }
145 
146   template <typename T>
CreateRange()147   Type* CreateRange() {
148     return CreateRange(std::numeric_limits<T>::min(),
149                        std::numeric_limits<T>::max());
150   }
151 
CreateRange(double min,double max)152   Type* CreateRange(double min, double max) {
153     return Type::Range(min, max, zone());
154   }
155 
zone()156   Zone* zone() { return &zone_; }
157 };
158 
159 }  // namespace internal
160 }  // namespace v8
161 
162 #endif  // V8_TYPE_CACHE_H_
163