• 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_COMPILER_TYPE_CACHE_H_
6 #define V8_COMPILER_TYPE_CACHE_H_
7 
8 #include "src/compiler/types.h"
9 #include "src/date/date.h"
10 #include "src/objects/code.h"
11 #include "src/objects/js-array-buffer.h"
12 #include "src/objects/string.h"
13 
14 namespace v8 {
15 namespace internal {
16 namespace compiler {
17 
18 class V8_EXPORT_PRIVATE TypeCache final {
19  private:
20   // This has to be first for the initialization magic to work.
21   AccountingAllocator allocator;
22   Zone zone_;
23 
24  public:
25   static TypeCache const* Get();
26 
TypeCache()27   TypeCache() : zone_(&allocator, ZONE_NAME) {}
28 
29   Type const kInt8 = CreateRange<int8_t>();
30   Type const kUint8 = CreateRange<uint8_t>();
31   Type const kUint8Clamped = kUint8;
32   Type const kUint8OrMinusZeroOrNaN =
33       Type::Union(kUint8, Type::MinusZeroOrNaN(), zone());
34   Type const kInt16 = CreateRange<int16_t>();
35   Type const kUint16 = CreateRange<uint16_t>();
36   Type const kUnsigned31 = Type::Unsigned31();
37   Type const kInt32 = Type::Signed32();
38   Type const kUint32 = Type::Unsigned32();
39   Type const kDoubleRepresentableInt64 = CreateRange(
40       std::numeric_limits<int64_t>::min(), kMaxDoubleRepresentableInt64);
41   Type const kDoubleRepresentableUint64 = CreateRange(
42       std::numeric_limits<uint64_t>::min(), kMaxDoubleRepresentableUint64);
43   Type const kFloat32 = Type::Number();
44   Type const kFloat64 = Type::Number();
45   Type const kBigInt64 = Type::BigInt();
46   Type const kBigUint64 = Type::BigInt();
47 
48   Type const kHoleySmi = Type::Union(Type::SignedSmall(), Type::Hole(), zone());
49 
50   Type const kSingletonZero = CreateRange(0.0, 0.0);
51   Type const kSingletonOne = CreateRange(1.0, 1.0);
52   Type const kSingletonTen = CreateRange(10.0, 10.0);
53   Type const kSingletonMinusOne = CreateRange(-1.0, -1.0);
54   Type const kZeroOrMinusZero =
55       Type::Union(kSingletonZero, Type::MinusZero(), zone());
56   Type const kZeroOrUndefined =
57       Type::Union(kSingletonZero, Type::Undefined(), zone());
58   Type const kTenOrUndefined =
59       Type::Union(kSingletonTen, Type::Undefined(), zone());
60   Type const kMinusOneOrZero = CreateRange(-1.0, 0.0);
61   Type const kMinusOneToOneOrMinusZeroOrNaN = Type::Union(
62       Type::Union(CreateRange(-1.0, 1.0), Type::MinusZero(), zone()),
63       Type::NaN(), zone());
64   Type const kZeroOrOne = CreateRange(0.0, 1.0);
65   Type const kZeroOrOneOrNaN = Type::Union(kZeroOrOne, Type::NaN(), zone());
66   Type const kZeroToThirtyOne = CreateRange(0.0, 31.0);
67   Type const kZeroToThirtyTwo = CreateRange(0.0, 32.0);
68   Type const kZeroish =
69       Type::Union(kSingletonZero, Type::MinusZeroOrNaN(), zone());
70   Type const kInteger = CreateRange(-V8_INFINITY, V8_INFINITY);
71   Type const kIntegerOrMinusZero =
72       Type::Union(kInteger, Type::MinusZero(), zone());
73   Type const kIntegerOrMinusZeroOrNaN =
74       Type::Union(kIntegerOrMinusZero, Type::NaN(), zone());
75   Type const kPositiveInteger = CreateRange(0.0, V8_INFINITY);
76   Type const kPositiveIntegerOrMinusZero =
77       Type::Union(kPositiveInteger, Type::MinusZero(), zone());
78   Type const kPositiveIntegerOrNaN =
79       Type::Union(kPositiveInteger, Type::NaN(), zone());
80   Type const kPositiveIntegerOrMinusZeroOrNaN =
81       Type::Union(kPositiveIntegerOrMinusZero, Type::NaN(), zone());
82 
83   Type const kAdditiveSafeInteger =
84       CreateRange(-4503599627370495.0, 4503599627370495.0);
85   Type const kSafeInteger = CreateRange(-kMaxSafeInteger, kMaxSafeInteger);
86   Type const kAdditiveSafeIntegerOrMinusZero =
87       Type::Union(kAdditiveSafeInteger, Type::MinusZero(), zone());
88   Type const kSafeIntegerOrMinusZero =
89       Type::Union(kSafeInteger, Type::MinusZero(), zone());
90   Type const kPositiveSafeInteger = CreateRange(0.0, kMaxSafeInteger);
91 
92   // The FixedArray::length property always containts a smi in the range
93   // [0, FixedArray::kMaxLength].
94   Type const kFixedArrayLengthType = CreateRange(0.0, FixedArray::kMaxLength);
95 
96   // The WeakFixedArray::length property always containts a smi in the range
97   // [0, WeakFixedArray::kMaxLength].
98   Type const kWeakFixedArrayLengthType =
99       CreateRange(0.0, WeakFixedArray::kMaxLength);
100 
101   // The FixedDoubleArray::length property always containts a smi in the range
102   // [0, FixedDoubleArray::kMaxLength].
103   Type const kFixedDoubleArrayLengthType =
104       CreateRange(0.0, FixedDoubleArray::kMaxLength);
105 
106   // The JSArray::length property always contains a tagged number in the range
107   // [0, kMaxUInt32].
108   Type const kJSArrayLengthType = Type::Unsigned32();
109 
110   // The JSArrayBuffer::byte_length property is limited to safe integer range
111   // per specification, but on 32-bit architectures is implemented as uint32_t
112   // field, so it's in the [0, kMaxUInt32] range in that case.
113   Type const kJSArrayBufferByteLengthType =
114       CreateRange(0.0, JSArrayBuffer::kMaxByteLength);
115 
116   // The type for the JSArrayBufferView::byte_length property is the same as
117   // JSArrayBuffer::byte_length above.
118   Type const kJSArrayBufferViewByteLengthType = kJSArrayBufferByteLengthType;
119 
120   // The type for the JSArrayBufferView::byte_offset property is the same as
121   // JSArrayBuffer::byte_length above.
122   Type const kJSArrayBufferViewByteOffsetType = kJSArrayBufferByteLengthType;
123 
124   // The JSTypedArray::length property always contains an untagged number in
125   // the range [0, JSTypedArray::kMaxLength].
126   Type const kJSTypedArrayLengthType =
127       CreateRange(0.0, JSTypedArray::kMaxLength);
128 
129   // The String::length property always contains a smi in the range
130   // [0, String::kMaxLength].
131   Type const kStringLengthType = CreateRange(0.0, String::kMaxLength);
132 
133   // A time value always contains a tagged number in the range
134   // [-kMaxTimeInMs, kMaxTimeInMs].
135   Type const kTimeValueType =
136       CreateRange(-DateCache::kMaxTimeInMs, DateCache::kMaxTimeInMs);
137 
138   // The JSDate::day property always contains a tagged number in the range
139   // [1, 31] or NaN.
140   Type const kJSDateDayType =
141       Type::Union(CreateRange(1, 31.0), Type::NaN(), zone());
142 
143   // The JSDate::hour property always contains a tagged number in the range
144   // [0, 23] or NaN.
145   Type const kJSDateHourType =
146       Type::Union(CreateRange(0, 23.0), Type::NaN(), zone());
147 
148   // The JSDate::minute property always contains a tagged number in the range
149   // [0, 59] or NaN.
150   Type const kJSDateMinuteType =
151       Type::Union(CreateRange(0, 59.0), Type::NaN(), zone());
152 
153   // The JSDate::month property always contains a tagged number in the range
154   // [0, 11] or NaN.
155   Type const kJSDateMonthType =
156       Type::Union(CreateRange(0, 11.0), Type::NaN(), zone());
157 
158   // The JSDate::second property always contains a tagged number in the range
159   // [0, 59] or NaN.
160   Type const kJSDateSecondType = kJSDateMinuteType;
161 
162   // The JSDate::value property always contains a tagged number in the range
163   // [-kMaxTimeInMs, kMaxTimeInMs] or NaN.
164   Type const kJSDateValueType =
165       Type::Union(kTimeValueType, Type::NaN(), zone());
166 
167   // The JSDate::weekday property always contains a tagged number in the range
168   // [0, 6] or NaN.
169   Type const kJSDateWeekdayType =
170       Type::Union(CreateRange(0, 6.0), Type::NaN(), zone());
171 
172   // The JSDate::year property always contains a tagged number in the signed
173   // small range or NaN.
174   Type const kJSDateYearType =
175       Type::Union(Type::SignedSmall(), Type::NaN(), zone());
176 
177   // The valid number of arguments for JavaScript functions. We can never
178   // materialize more than the max size of a fixed array, because we require a
179   // fixed array in spread/apply calls.
180   Type const kArgumentsLengthType = CreateRange(0.0, FixedArray::kMaxLength);
181 
182   // The valid number of arguments for rest parameters. We can never
183   // materialize more than the max size of a fixed array, because we require a
184   // fixed array in spread/apply calls.
185   Type const kRestLengthType = CreateRange(0.0, FixedArray::kMaxLength);
186 
187   // The JSArrayIterator::kind property always contains an integer in the
188   // range [0, 2], representing the possible IterationKinds.
189   Type const kJSArrayIteratorKindType = CreateRange(0.0, 2.0);
190 
191  private:
192   template <typename T>
CreateRange()193   Type CreateRange() {
194     T min = std::numeric_limits<T>::min();
195     T max = std::numeric_limits<T>::max();
196     DCHECK_EQ(min, static_cast<T>(static_cast<double>(min)));
197     DCHECK_EQ(max, static_cast<T>(static_cast<double>(max)));
198     return CreateRange(min, max);
199   }
200 
CreateRange(double min,double max)201   Type CreateRange(double min, double max) {
202     return Type::Range(min, max, zone());
203   }
204 
zone()205   Zone* zone() { return &zone_; }
206 
207   static constexpr double kMaxDoubleRepresentableInt64 = 9223372036854774784.0;
208   static constexpr double kMaxDoubleRepresentableUint64 =
209       18446744073709549568.0;
210 };
211 
212 }  // namespace compiler
213 }  // namespace internal
214 }  // namespace v8
215 
216 #endif  // V8_COMPILER_TYPE_CACHE_H_
217