• 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