blob: 80614104293bcf568da2fe00b737a2d9f8367358 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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_TYPES_H_
6#define V8_TYPES_H_
7
8#include "src/conversions.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009#include "src/handles.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010#include "src/objects.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000011#include "src/ostreams.h"
12
13namespace v8 {
14namespace internal {
15
16// SUMMARY
17//
18// A simple type system for compiler-internal use. It is based entirely on
19// union types, and all subtyping hence amounts to set inclusion. Besides the
20// obvious primitive types and some predefined unions, the type language also
21// can express class types (a.k.a. specific maps) and singleton types (i.e.,
22// concrete constants).
23//
24// Types consist of two dimensions: semantic (value range) and representation.
25// Both are related through subtyping.
26//
27//
28// SEMANTIC DIMENSION
29//
30// The following equations and inequations hold for the semantic axis:
31//
32// None <= T
33// T <= Any
34//
35// Number = Signed32 \/ Unsigned32 \/ Double
36// Smi <= Signed32
37// Name = String \/ Symbol
38// UniqueName = InternalizedString \/ Symbol
39// InternalizedString < String
40//
41// Receiver = Object \/ Proxy
42// Array < Object
43// Function < Object
44// RegExp < Object
Ben Murdochda12d292016-06-02 14:46:10 +010045// OtherUndetectable < Object
46// DetectableReceiver = Receiver - OtherUndetectable
Ben Murdochb8a8cc12014-11-26 15:28:44 +000047//
48// Class(map) < T iff instance_type(map) < T
49// Constant(x) < T iff instance_type(map(x)) < T
50// Array(T) < Array
51// Function(R, S, T0, T1, ...) < Function
52// Context(T) < Internal
53//
54// Both structural Array and Function types are invariant in all parameters;
55// relaxing this would make Union and Intersect operations more involved.
56// There is no subtyping relation between Array, Function, or Context types
57// and respective Constant types, since these types cannot be reconstructed
58// for arbitrary heap values.
59// Note also that Constant(x) < Class(map(x)) does _not_ hold, since x's map can
60// change! (Its instance type cannot, however.)
61// TODO(rossberg): the latter is not currently true for proxies, because of fix,
62// but will hold once we implement direct proxies.
63// However, we also define a 'temporal' variant of the subtyping relation that
64// considers the _current_ state only, i.e., Constant(x) <_now Class(map(x)).
65//
66//
67// REPRESENTATIONAL DIMENSION
68//
69// For the representation axis, the following holds:
70//
71// None <= R
72// R <= Any
73//
74// UntaggedInt = UntaggedInt1 \/ UntaggedInt8 \/
75// UntaggedInt16 \/ UntaggedInt32
76// UntaggedFloat = UntaggedFloat32 \/ UntaggedFloat64
77// UntaggedNumber = UntaggedInt \/ UntaggedFloat
78// Untagged = UntaggedNumber \/ UntaggedPtr
79// Tagged = TaggedInt \/ TaggedPtr
80//
81// Subtyping relates the two dimensions, for example:
82//
83// Number <= Tagged \/ UntaggedNumber
84// Object <= TaggedPtr \/ UntaggedPtr
85//
86// That holds because the semantic type constructors defined by the API create
87// types that allow for all possible representations, and dually, the ones for
88// representation types initially include all semantic ranges. Representations
89// can then e.g. be narrowed for a given semantic type using intersection:
90//
91// SignedSmall /\ TaggedInt (a 'smi')
92// Number /\ TaggedPtr (a heap number)
93//
94//
95// RANGE TYPES
96//
97// A range type represents a continuous integer interval by its minimum and
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000098// maximum value. Either value may be an infinity, in which case that infinity
99// itself is also included in the range. A range never contains NaN or -0.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000100//
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000101// If a value v happens to be an integer n, then Constant(v) is considered a
102// subtype of Range(n, n) (and therefore also a subtype of any larger range).
103// In order to avoid large unions, however, it is usually a good idea to use
104// Range rather than Constant.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000105//
106//
107// PREDICATES
108//
109// There are two main functions for testing types:
110//
111// T1->Is(T2) -- tests whether T1 is included in T2 (i.e., T1 <= T2)
112// T1->Maybe(T2) -- tests whether T1 and T2 overlap (i.e., T1 /\ T2 =/= 0)
113//
114// Typically, the former is to be used to select representations (e.g., via
115// T->Is(SignedSmall())), and the latter to check whether a specific case needs
116// handling (e.g., via T->Maybe(Number())).
117//
118// There is no functionality to discover whether a type is a leaf in the
119// lattice. That is intentional. It should always be possible to refine the
120// lattice (e.g., splitting up number types further) without invalidating any
121// existing assumptions or tests.
122// Consequently, do not normally use Equals for type tests, always use Is!
123//
124// The NowIs operator implements state-sensitive subtying, as described above.
125// Any compilation decision based on such temporary properties requires runtime
126// guarding!
127//
128//
129// PROPERTIES
130//
131// Various formal properties hold for constructors, operators, and predicates
132// over types. For example, constructors are injective and subtyping is a
133// complete partial order.
134//
135// See test/cctest/test-types.cc for a comprehensive executable specification,
136// especially with respect to the properties of the more exotic 'temporal'
137// constructors and predicates (those prefixed 'Now').
138//
139//
140// IMPLEMENTATION
141//
142// Internally, all 'primitive' types, and their unions, are represented as
143// bitsets. Bit 0 is reserved for tagging. Class is a heap pointer to the
144// respective map. Only structured types require allocation.
145// Note that the bitset representation is closed under both Union and Intersect.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000146
147
148// -----------------------------------------------------------------------------
149// Values for bitset types
150
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000151// clang-format off
152
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000153#define MASK_BITSET_TYPE_LIST(V) \
Ben Murdoch097c5b22016-05-18 11:27:45 +0100154 V(Representation, 0xffc00000u) \
155 V(Semantic, 0x003ffffeu)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000156
157#define REPRESENTATION(k) ((k) & BitsetType::kRepresentation)
158#define SEMANTIC(k) ((k) & BitsetType::kSemantic)
159
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400160#define REPRESENTATION_BITSET_TYPE_LIST(V) \
161 V(None, 0) \
Ben Murdoch097c5b22016-05-18 11:27:45 +0100162 V(UntaggedBit, 1u << 22 | kSemantic) \
163 V(UntaggedIntegral8, 1u << 23 | kSemantic) \
164 V(UntaggedIntegral16, 1u << 24 | kSemantic) \
165 V(UntaggedIntegral32, 1u << 25 | kSemantic) \
166 V(UntaggedFloat32, 1u << 26 | kSemantic) \
167 V(UntaggedFloat64, 1u << 27 | kSemantic) \
168 V(UntaggedSimd128, 1u << 28 | kSemantic) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400169 V(UntaggedPointer, 1u << 29 | kSemantic) \
170 V(TaggedSigned, 1u << 30 | kSemantic) \
171 V(TaggedPointer, 1u << 31 | kSemantic) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000172 \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000173 V(UntaggedIntegral, kUntaggedBit | kUntaggedIntegral8 | \
174 kUntaggedIntegral16 | kUntaggedIntegral32) \
175 V(UntaggedFloat, kUntaggedFloat32 | kUntaggedFloat64) \
176 V(UntaggedNumber, kUntaggedIntegral | kUntaggedFloat) \
177 V(Untagged, kUntaggedNumber | kUntaggedPointer) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400178 V(Tagged, kTaggedSigned | kTaggedPointer)
179
180#define INTERNAL_BITSET_TYPE_LIST(V) \
181 V(OtherUnsigned31, 1u << 1 | REPRESENTATION(kTagged | kUntaggedNumber)) \
182 V(OtherUnsigned32, 1u << 2 | REPRESENTATION(kTagged | kUntaggedNumber)) \
183 V(OtherSigned32, 1u << 3 | REPRESENTATION(kTagged | kUntaggedNumber)) \
184 V(OtherNumber, 1u << 4 | REPRESENTATION(kTagged | kUntaggedNumber))
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000185
186#define SEMANTIC_BITSET_TYPE_LIST(V) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000187 V(Negative31, 1u << 5 | REPRESENTATION(kTagged | kUntaggedNumber)) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400188 V(Null, 1u << 6 | REPRESENTATION(kTaggedPointer)) \
189 V(Undefined, 1u << 7 | REPRESENTATION(kTaggedPointer)) \
190 V(Boolean, 1u << 8 | REPRESENTATION(kTaggedPointer)) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000191 V(Unsigned30, 1u << 9 | REPRESENTATION(kTagged | kUntaggedNumber)) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400192 V(MinusZero, 1u << 10 | REPRESENTATION(kTagged | kUntaggedNumber)) \
193 V(NaN, 1u << 11 | REPRESENTATION(kTagged | kUntaggedNumber)) \
194 V(Symbol, 1u << 12 | REPRESENTATION(kTaggedPointer)) \
195 V(InternalizedString, 1u << 13 | REPRESENTATION(kTaggedPointer)) \
196 V(OtherString, 1u << 14 | REPRESENTATION(kTaggedPointer)) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000197 V(Simd, 1u << 15 | REPRESENTATION(kTaggedPointer)) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400198 V(OtherObject, 1u << 17 | REPRESENTATION(kTaggedPointer)) \
Ben Murdochda12d292016-06-02 14:46:10 +0100199 V(OtherUndetectable, 1u << 16 | REPRESENTATION(kTaggedPointer)) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400200 V(Proxy, 1u << 18 | REPRESENTATION(kTaggedPointer)) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000201 V(Function, 1u << 19 | REPRESENTATION(kTaggedPointer)) \
202 V(Internal, 1u << 20 | REPRESENTATION(kTagged | kUntagged)) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000203 \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000204 V(Signed31, kUnsigned30 | kNegative31) \
205 V(Signed32, kSigned31 | kOtherUnsigned31 | kOtherSigned32) \
206 V(Negative32, kNegative31 | kOtherSigned32) \
207 V(Unsigned31, kUnsigned30 | kOtherUnsigned31) \
208 V(Unsigned32, kUnsigned30 | kOtherUnsigned31 | \
209 kOtherUnsigned32) \
210 V(Integral32, kSigned32 | kUnsigned32) \
211 V(PlainNumber, kIntegral32 | kOtherNumber) \
212 V(OrderedNumber, kPlainNumber | kMinusZero) \
213 V(MinusZeroOrNaN, kMinusZero | kNaN) \
214 V(Number, kOrderedNumber | kNaN) \
215 V(String, kInternalizedString | kOtherString) \
216 V(UniqueName, kSymbol | kInternalizedString) \
217 V(Name, kSymbol | kString) \
218 V(BooleanOrNumber, kBoolean | kNumber) \
219 V(BooleanOrNullOrUndefined, kBoolean | kNull | kUndefined) \
220 V(NullOrUndefined, kNull | kUndefined) \
Ben Murdochda12d292016-06-02 14:46:10 +0100221 V(Undetectable, kNullOrUndefined | kOtherUndetectable) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000222 V(NumberOrString, kNumber | kString) \
223 V(NumberOrUndefined, kNumber | kUndefined) \
224 V(PlainPrimitive, kNumberOrString | kBoolean | kNullOrUndefined) \
225 V(Primitive, kSymbol | kSimd | kPlainPrimitive) \
226 V(DetectableReceiver, kFunction | kOtherObject | kProxy) \
Ben Murdochda12d292016-06-02 14:46:10 +0100227 V(Object, kFunction | kOtherObject | kOtherUndetectable) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000228 V(Receiver, kObject | kProxy) \
229 V(StringOrReceiver, kString | kReceiver) \
230 V(Unique, kBoolean | kUniqueName | kNull | kUndefined | \
231 kReceiver) \
232 V(NonNumber, kUnique | kString | kInternal) \
233 V(Any, 0xfffffffeu)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000234
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000235// clang-format on
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400236
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000237/*
238 * The following diagrams show how integers (in the mathematical sense) are
239 * divided among the different atomic numerical types.
240 *
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000241 * ON OS32 N31 U30 OU31 OU32 ON
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000242 * ______[_______[_______[_______[_______[_______[_______
243 * -2^31 -2^30 0 2^30 2^31 2^32
244 *
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000245 * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1.
246 *
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000247 * Some of the atomic numerical bitsets are internal only (see
248 * INTERNAL_BITSET_TYPE_LIST). To a types user, they should only occur in
249 * union with certain other bitsets. For instance, OtherNumber should only
250 * occur as part of PlainNumber.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000251 */
252
253#define PROPER_BITSET_TYPE_LIST(V) \
254 REPRESENTATION_BITSET_TYPE_LIST(V) \
255 SEMANTIC_BITSET_TYPE_LIST(V)
256
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400257#define BITSET_TYPE_LIST(V) \
258 MASK_BITSET_TYPE_LIST(V) \
259 REPRESENTATION_BITSET_TYPE_LIST(V) \
260 INTERNAL_BITSET_TYPE_LIST(V) \
261 SEMANTIC_BITSET_TYPE_LIST(V)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000262
Ben Murdoch097c5b22016-05-18 11:27:45 +0100263class Type;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000264
265// -----------------------------------------------------------------------------
266// Bitset types (internal).
267
Ben Murdoch097c5b22016-05-18 11:27:45 +0100268class BitsetType {
269 public:
270 typedef uint32_t bitset; // Internal
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000271
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000272 enum : uint32_t {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100273#define DECLARE_TYPE(type, value) k##type = (value),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000274 BITSET_TYPE_LIST(DECLARE_TYPE)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100275#undef DECLARE_TYPE
276 kUnusedEOL = 0
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000277 };
278
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000279 static bitset SignedSmall();
280 static bitset UnsignedSmall();
281
Ben Murdoch097c5b22016-05-18 11:27:45 +0100282 bitset Bitset() {
283 return static_cast<bitset>(reinterpret_cast<uintptr_t>(this) ^ 1u);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000284 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000285
286 static bool IsInhabited(bitset bits) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000287 return SEMANTIC(bits) != kNone && REPRESENTATION(bits) != kNone;
288 }
289
290 static bool SemanticIsInhabited(bitset bits) {
291 return SEMANTIC(bits) != kNone;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000292 }
293
294 static bool Is(bitset bits1, bitset bits2) {
295 return (bits1 | bits2) == bits2;
296 }
297
298 static double Min(bitset);
299 static double Max(bitset);
300
Ben Murdoch097c5b22016-05-18 11:27:45 +0100301 static bitset Glb(Type* type); // greatest lower bound that's a bitset
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000302 static bitset Glb(double min, double max);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100303 static bitset Lub(Type* type); // least upper bound that's a bitset
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400304 static bitset Lub(i::Map* map);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000305 static bitset Lub(i::Object* value);
306 static bitset Lub(double value);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400307 static bitset Lub(double min, double max);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000308 static bitset ExpandInternals(bitset bits);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000309
310 static const char* Name(bitset);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400311 static void Print(std::ostream& os, bitset); // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000312#ifdef DEBUG
313 static void Print(bitset);
314#endif
315
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000316 static bitset NumberBits(bitset bits);
317
Ben Murdoch097c5b22016-05-18 11:27:45 +0100318 static bool IsBitset(Type* type) {
319 return reinterpret_cast<uintptr_t>(type) & 1;
320 }
321
322 static Type* NewForTesting(bitset bits) { return New(bits); }
323
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000324 private:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100325 friend class Type;
326
327 static Type* New(bitset bits) {
328 return reinterpret_cast<Type*>(static_cast<uintptr_t>(bits | 1u));
329 }
330
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000331 struct Boundary {
332 bitset internal;
333 bitset external;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000334 double min;
335 };
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000336 static const Boundary BoundariesArray[];
337 static inline const Boundary* Boundaries();
338 static inline size_t BoundariesSize();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000339};
340
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000341// -----------------------------------------------------------------------------
342// Superclass for non-bitset types (internal).
Ben Murdoch097c5b22016-05-18 11:27:45 +0100343class TypeBase {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000344 protected:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100345 friend class Type;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000346
Ben Murdoch097c5b22016-05-18 11:27:45 +0100347 enum Kind {
348 kClass,
349 kConstant,
350 kContext,
351 kArray,
352 kFunction,
353 kTuple,
354 kUnion,
355 kRange
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000356 };
357
Ben Murdoch097c5b22016-05-18 11:27:45 +0100358 Kind kind() const { return kind_; }
359 explicit TypeBase(Kind kind) : kind_(kind) {}
360
361 static bool IsKind(Type* type, Kind kind) {
362 if (BitsetType::IsBitset(type)) return false;
363 TypeBase* base = reinterpret_cast<TypeBase*>(type);
364 return base->kind() == kind;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000365 }
366
Ben Murdoch097c5b22016-05-18 11:27:45 +0100367 // The hacky conversion to/from Type*.
368 static Type* AsType(TypeBase* type) { return reinterpret_cast<Type*>(type); }
369 static TypeBase* FromType(Type* type) {
370 return reinterpret_cast<TypeBase*>(type);
371 }
372
373 private:
374 Kind kind_;
375};
376
377// -----------------------------------------------------------------------------
378// Class types.
379
380class ClassType : public TypeBase {
381 public:
382 i::Handle<i::Map> Map() { return map_; }
383
384 private:
385 friend class Type;
386 friend class BitsetType;
387
388 static Type* New(i::Handle<i::Map> map, Zone* zone) {
389 return AsType(new (zone->New(sizeof(ClassType)))
390 ClassType(BitsetType::Lub(*map), map));
391 }
392
393 static ClassType* cast(Type* type) {
394 DCHECK(IsKind(type, kClass));
395 return static_cast<ClassType*>(FromType(type));
396 }
397
398 ClassType(BitsetType::bitset bitset, i::Handle<i::Map> map)
399 : TypeBase(kClass), bitset_(bitset), map_(map) {}
400
401 BitsetType::bitset Lub() { return bitset_; }
402
403 BitsetType::bitset bitset_;
404 Handle<i::Map> map_;
405};
406
407// -----------------------------------------------------------------------------
408// Constant types.
409
410class ConstantType : public TypeBase {
411 public:
412 i::Handle<i::Object> Value() { return object_; }
413
414 private:
415 friend class Type;
416 friend class BitsetType;
417
418 static Type* New(i::Handle<i::Object> value, Zone* zone) {
419 BitsetType::bitset bitset = BitsetType::Lub(*value);
420 return AsType(new (zone->New(sizeof(ConstantType)))
421 ConstantType(bitset, value));
422 }
423
424 static ConstantType* cast(Type* type) {
425 DCHECK(IsKind(type, kConstant));
426 return static_cast<ConstantType*>(FromType(type));
427 }
428
429 ConstantType(BitsetType::bitset bitset, i::Handle<i::Object> object)
430 : TypeBase(kConstant), bitset_(bitset), object_(object) {}
431
432 BitsetType::bitset Lub() { return bitset_; }
433
434 BitsetType::bitset bitset_;
435 Handle<i::Object> object_;
436};
437// TODO(neis): Also cache value if numerical.
438// TODO(neis): Allow restricting the representation.
439
440// -----------------------------------------------------------------------------
441// Range types.
442
443class RangeType : public TypeBase {
444 public:
445 struct Limits {
446 double min;
447 double max;
448 Limits(double min, double max) : min(min), max(max) {}
449 explicit Limits(RangeType* range) : min(range->Min()), max(range->Max()) {}
450 bool IsEmpty();
451 static Limits Empty() { return Limits(1, 0); }
452 static Limits Intersect(Limits lhs, Limits rhs);
453 static Limits Union(Limits lhs, Limits rhs);
454 };
455
456 double Min() { return limits_.min; }
457 double Max() { return limits_.max; }
458
459 private:
460 friend class Type;
461 friend class BitsetType;
462 friend class UnionType;
463
464 static Type* New(double min, double max, BitsetType::bitset representation,
465 Zone* zone) {
466 return New(Limits(min, max), representation, zone);
467 }
468
469 static bool IsInteger(double x) {
470 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities.
471 }
472
473 static Type* New(Limits lim, BitsetType::bitset representation, Zone* zone) {
474 DCHECK(IsInteger(lim.min) && IsInteger(lim.max));
475 DCHECK(lim.min <= lim.max);
476 DCHECK(REPRESENTATION(representation) == representation);
477 BitsetType::bitset bits =
478 SEMANTIC(BitsetType::Lub(lim.min, lim.max)) | representation;
479
480 return AsType(new (zone->New(sizeof(RangeType))) RangeType(bits, lim));
481 }
482
483 static RangeType* cast(Type* type) {
484 DCHECK(IsKind(type, kRange));
485 return static_cast<RangeType*>(FromType(type));
486 }
487
488 RangeType(BitsetType::bitset bitset, Limits limits)
489 : TypeBase(kRange), bitset_(bitset), limits_(limits) {}
490
491 BitsetType::bitset Lub() { return bitset_; }
492
493 BitsetType::bitset bitset_;
494 Limits limits_;
495};
496
497// -----------------------------------------------------------------------------
498// Context types.
499
500class ContextType : public TypeBase {
501 public:
502 Type* Outer() { return outer_; }
503
504 private:
505 friend class Type;
506
507 static Type* New(Type* outer, Zone* zone) {
508 return AsType(new (zone->New(sizeof(ContextType))) ContextType(outer));
509 }
510
511 static ContextType* cast(Type* type) {
512 DCHECK(IsKind(type, kContext));
513 return static_cast<ContextType*>(FromType(type));
514 }
515
516 explicit ContextType(Type* outer) : TypeBase(kContext), outer_(outer) {}
517
518 Type* outer_;
519};
520
521// -----------------------------------------------------------------------------
522// Array types.
523
524class ArrayType : public TypeBase {
525 public:
526 Type* Element() { return element_; }
527
528 private:
529 friend class Type;
530
531 explicit ArrayType(Type* element) : TypeBase(kArray), element_(element) {}
532
533 static Type* New(Type* element, Zone* zone) {
534 return AsType(new (zone->New(sizeof(ArrayType))) ArrayType(element));
535 }
536
537 static ArrayType* cast(Type* type) {
538 DCHECK(IsKind(type, kArray));
539 return static_cast<ArrayType*>(FromType(type));
540 }
541
542 Type* element_;
543};
544
545// -----------------------------------------------------------------------------
546// Superclass for types with variable number of type fields.
547class StructuralType : public TypeBase {
548 public:
549 int LengthForTesting() { return Length(); }
550
551 protected:
552 friend class Type;
553
554 int Length() { return length_; }
555
556 Type* Get(int i) {
557 DCHECK(0 <= i && i < this->Length());
558 return elements_[i];
559 }
560
561 void Set(int i, Type* type) {
562 DCHECK(0 <= i && i < this->Length());
563 elements_[i] = type;
564 }
565
566 void Shrink(int length) {
567 DCHECK(2 <= length && length <= this->Length());
568 length_ = length;
569 }
570
571 StructuralType(Kind kind, int length, i::Zone* zone)
572 : TypeBase(kind), length_(length) {
573 elements_ = reinterpret_cast<Type**>(zone->New(sizeof(Type*) * length));
574 }
575
576 private:
577 int length_;
578 Type** elements_;
579};
580
581// -----------------------------------------------------------------------------
582// Function types.
583
584class FunctionType : public StructuralType {
585 public:
586 int Arity() { return this->Length() - 2; }
587 Type* Result() { return this->Get(0); }
588 Type* Receiver() { return this->Get(1); }
589 Type* Parameter(int i) { return this->Get(2 + i); }
590
591 void InitParameter(int i, Type* type) { this->Set(2 + i, type); }
592
593 private:
594 friend class Type;
595
596 FunctionType(Type* result, Type* receiver, int arity, Zone* zone)
597 : StructuralType(kFunction, 2 + arity, zone) {
598 Set(0, result);
599 Set(1, receiver);
600 }
601
602 static Type* New(Type* result, Type* receiver, int arity, Zone* zone) {
603 return AsType(new (zone->New(sizeof(FunctionType)))
604 FunctionType(result, receiver, arity, zone));
605 }
606
607 static FunctionType* cast(Type* type) {
608 DCHECK(IsKind(type, kFunction));
609 return static_cast<FunctionType*>(FromType(type));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000610 }
611};
612
Ben Murdoch097c5b22016-05-18 11:27:45 +0100613// -----------------------------------------------------------------------------
614// Tuple types.
615
616class TupleType : public StructuralType {
617 public:
618 int Arity() { return this->Length(); }
619 Type* Element(int i) { return this->Get(i); }
620
621 void InitElement(int i, Type* type) { this->Set(i, type); }
622
623 private:
624 friend class Type;
625
626 TupleType(int length, Zone* zone) : StructuralType(kTuple, length, zone) {}
627
628 static Type* New(int length, Zone* zone) {
629 return AsType(new (zone->New(sizeof(TupleType))) TupleType(length, zone));
630 }
631
632 static TupleType* cast(Type* type) {
633 DCHECK(IsKind(type, kTuple));
634 return static_cast<TupleType*>(FromType(type));
635 }
636};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000637
638// -----------------------------------------------------------------------------
639// Union types (internal).
640// A union is a structured type with the following invariants:
641// - its length is at least 2
642// - at most one field is a bitset, and it must go into index 0
643// - no field is a union
644// - no field is a subtype of any other field
Ben Murdoch097c5b22016-05-18 11:27:45 +0100645class UnionType : public StructuralType {
646 private:
647 friend Type;
648 friend BitsetType;
649
650 UnionType(int length, Zone* zone) : StructuralType(kUnion, length, zone) {}
651
652 static Type* New(int length, Zone* zone) {
653 return AsType(new (zone->New(sizeof(UnionType))) UnionType(length, zone));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000654 }
655
Ben Murdoch097c5b22016-05-18 11:27:45 +0100656 static UnionType* cast(Type* type) {
657 DCHECK(IsKind(type, kUnion));
658 return static_cast<UnionType*>(FromType(type));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000659 }
660
661 bool Wellformed();
662};
663
Ben Murdoch097c5b22016-05-18 11:27:45 +0100664class Type {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000665 public:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100666 typedef BitsetType::bitset bitset; // Internal
667
668// Constructors.
669#define DEFINE_TYPE_CONSTRUCTOR(type, value) \
670 static Type* type() { return BitsetType::New(BitsetType::k##type); }
671 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
672#undef DEFINE_TYPE_CONSTRUCTOR
673
674 static Type* SignedSmall() {
675 return BitsetType::New(BitsetType::SignedSmall());
676 }
677 static Type* UnsignedSmall() {
678 return BitsetType::New(BitsetType::UnsignedSmall());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000679 }
680
Ben Murdoch097c5b22016-05-18 11:27:45 +0100681 static Type* Class(i::Handle<i::Map> map, Zone* zone) {
682 return ClassType::New(map, zone);
683 }
684 static Type* Constant(i::Handle<i::Object> value, Zone* zone) {
685 return ConstantType::New(value, zone);
686 }
687 static Type* Range(double min, double max, Zone* zone) {
688 return RangeType::New(min, max, REPRESENTATION(BitsetType::kTagged |
689 BitsetType::kUntaggedNumber),
690 zone);
691 }
692 static Type* Context(Type* outer, Zone* zone) {
693 return ContextType::New(outer, zone);
694 }
695 static Type* Array(Type* element, Zone* zone) {
696 return ArrayType::New(element, zone);
697 }
698 static Type* Function(Type* result, Type* receiver, int arity, Zone* zone) {
699 return FunctionType::New(result, receiver, arity, zone);
700 }
701 static Type* Function(Type* result, Zone* zone) {
702 return Function(result, Any(), 0, zone);
703 }
704 static Type* Function(Type* result, Type* param0, Zone* zone) {
705 Type* function = Function(result, Any(), 1, zone);
706 function->AsFunction()->InitParameter(0, param0);
707 return function;
708 }
709 static Type* Function(Type* result, Type* param0, Type* param1, Zone* zone) {
710 Type* function = Function(result, Any(), 2, zone);
711 function->AsFunction()->InitParameter(0, param0);
712 function->AsFunction()->InitParameter(1, param1);
713 return function;
714 }
715 static Type* Function(Type* result, Type* param0, Type* param1, Type* param2,
716 Zone* zone) {
717 Type* function = Function(result, Any(), 3, zone);
718 function->AsFunction()->InitParameter(0, param0);
719 function->AsFunction()->InitParameter(1, param1);
720 function->AsFunction()->InitParameter(2, param2);
721 return function;
722 }
723 static Type* Function(Type* result, int arity, Type** params, Zone* zone) {
724 Type* function = Function(result, Any(), arity, zone);
725 for (int i = 0; i < arity; ++i) {
726 function->AsFunction()->InitParameter(i, params[i]);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000727 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100728 return function;
729 }
730 static Type* Tuple(Type* first, Type* second, Type* third, Zone* zone) {
731 Type* tuple = TupleType::New(3, zone);
732 tuple->AsTuple()->InitElement(0, first);
733 tuple->AsTuple()->InitElement(1, second);
734 tuple->AsTuple()->InitElement(2, third);
735 return tuple;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000736 }
737
Ben Murdoch097c5b22016-05-18 11:27:45 +0100738#define CONSTRUCT_SIMD_TYPE(NAME, Name, name, lane_count, lane_type) \
739 static Type* Name(Isolate* isolate, Zone* zone);
740 SIMD128_TYPES(CONSTRUCT_SIMD_TYPE)
741#undef CONSTRUCT_SIMD_TYPE
742
743 static Type* Union(Type* type1, Type* type2, Zone* reg);
744 static Type* Intersect(Type* type1, Type* type2, Zone* reg);
745
746 static Type* Of(double value, Zone* zone) {
747 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value)));
748 }
749 static Type* Of(i::Object* value, Zone* zone) {
750 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value)));
751 }
752 static Type* Of(i::Handle<i::Object> value, Zone* zone) {
753 return Of(*value, zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000754 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000755
Ben Murdoch097c5b22016-05-18 11:27:45 +0100756 // Extraction of components.
757 static Type* Representation(Type* t, Zone* zone);
758 static Type* Semantic(Type* t, Zone* zone);
759
760 // Predicates.
761 bool IsInhabited() { return BitsetType::IsInhabited(this->BitsetLub()); }
762
763 bool Is(Type* that) { return this == that || this->SlowIs(that); }
764 bool Maybe(Type* that);
765 bool Equals(Type* that) { return this->Is(that) && that->Is(this); }
766
767 // Equivalent to Constant(val)->Is(this), but avoiding allocation.
768 bool Contains(i::Object* val);
769 bool Contains(i::Handle<i::Object> val) { return this->Contains(*val); }
770
771 // State-dependent versions of the above that consider subtyping between
772 // a constant and its map class.
773 static Type* NowOf(i::Object* value, Zone* zone);
774 static Type* NowOf(i::Handle<i::Object> value, Zone* zone) {
775 return NowOf(*value, zone);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000776 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100777 bool NowIs(Type* that);
778 bool NowContains(i::Object* val);
779 bool NowContains(i::Handle<i::Object> val) { return this->NowContains(*val); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000780
Ben Murdoch097c5b22016-05-18 11:27:45 +0100781 bool NowStable();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000782
Ben Murdoch097c5b22016-05-18 11:27:45 +0100783 // Inspection.
784 bool IsRange() { return IsKind(TypeBase::kRange); }
785 bool IsClass() { return IsKind(TypeBase::kClass); }
786 bool IsConstant() { return IsKind(TypeBase::kConstant); }
787 bool IsContext() { return IsKind(TypeBase::kContext); }
788 bool IsArray() { return IsKind(TypeBase::kArray); }
789 bool IsFunction() { return IsKind(TypeBase::kFunction); }
790 bool IsTuple() { return IsKind(TypeBase::kTuple); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000791
Ben Murdoch097c5b22016-05-18 11:27:45 +0100792 ClassType* AsClass() { return ClassType::cast(this); }
793 ConstantType* AsConstant() { return ConstantType::cast(this); }
794 RangeType* AsRange() { return RangeType::cast(this); }
795 ContextType* AsContext() { return ContextType::cast(this); }
796 ArrayType* AsArray() { return ArrayType::cast(this); }
797 FunctionType* AsFunction() { return FunctionType::cast(this); }
798 TupleType* AsTuple() { return TupleType::cast(this); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000799
Ben Murdoch097c5b22016-05-18 11:27:45 +0100800 // Minimum and maximum of a numeric type.
801 // These functions do not distinguish between -0 and +0. If the type equals
802 // kNaN, they return NaN; otherwise kNaN is ignored. Only call these
803 // functions on subtypes of Number.
804 double Min();
805 double Max();
806
807 // Extracts a range from the type: if the type is a range or a union
808 // containing a range, that range is returned; otherwise, NULL is returned.
809 Type* GetRange();
810
811 static bool IsInteger(i::Object* x);
812 static bool IsInteger(double x) {
813 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000814 }
815
Ben Murdoch097c5b22016-05-18 11:27:45 +0100816 int NumClasses();
817 int NumConstants();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000818
Ben Murdoch097c5b22016-05-18 11:27:45 +0100819 template <class T>
820 class Iterator {
821 public:
822 bool Done() const { return index_ < 0; }
823 i::Handle<T> Current();
824 void Advance();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000825
Ben Murdoch097c5b22016-05-18 11:27:45 +0100826 private:
827 friend class Type;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000828
Ben Murdoch097c5b22016-05-18 11:27:45 +0100829 Iterator() : index_(-1) {}
830 explicit Iterator(Type* type) : type_(type), index_(-1) { Advance(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000831
Ben Murdoch097c5b22016-05-18 11:27:45 +0100832 inline bool matches(Type* type);
833 inline Type* get_type();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000834
Ben Murdoch097c5b22016-05-18 11:27:45 +0100835 Type* type_;
836 int index_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000837 };
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000838
Ben Murdoch097c5b22016-05-18 11:27:45 +0100839 Iterator<i::Map> Classes() {
840 if (this->IsBitset()) return Iterator<i::Map>();
841 return Iterator<i::Map>(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000842 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100843 Iterator<i::Object> Constants() {
844 if (this->IsBitset()) return Iterator<i::Object>();
845 return Iterator<i::Object>(this);
846 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000847
Ben Murdoch097c5b22016-05-18 11:27:45 +0100848 // Printing.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000849
Ben Murdoch097c5b22016-05-18 11:27:45 +0100850 enum PrintDimension { BOTH_DIMS, SEMANTIC_DIM, REPRESENTATION_DIM };
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000851
Ben Murdoch097c5b22016-05-18 11:27:45 +0100852 void PrintTo(std::ostream& os, PrintDimension dim = BOTH_DIMS); // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000853
Ben Murdoch097c5b22016-05-18 11:27:45 +0100854#ifdef DEBUG
855 void Print();
856#endif
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000857
Ben Murdoch097c5b22016-05-18 11:27:45 +0100858 // Helpers for testing.
859 bool IsBitsetForTesting() { return IsBitset(); }
860 bool IsUnionForTesting() { return IsUnion(); }
861 bitset AsBitsetForTesting() { return AsBitset(); }
862 UnionType* AsUnionForTesting() { return AsUnion(); }
863
864 private:
865 // Friends.
866 template <class>
867 friend class Iterator;
868 friend BitsetType;
869 friend UnionType;
870
871 // Internal inspection.
872 bool IsKind(TypeBase::Kind kind) { return TypeBase::IsKind(this, kind); }
873
874 bool IsNone() { return this == None(); }
875 bool IsAny() { return this == Any(); }
876 bool IsBitset() { return BitsetType::IsBitset(this); }
877 bool IsUnion() { return IsKind(TypeBase::kUnion); }
878
879 bitset AsBitset() {
880 DCHECK(this->IsBitset());
881 return reinterpret_cast<BitsetType*>(this)->Bitset();
882 }
883 UnionType* AsUnion() { return UnionType::cast(this); }
884
885 bitset Representation();
886
887 // Auxiliary functions.
888 bool SemanticMaybe(Type* that);
889
890 bitset BitsetGlb() { return BitsetType::Glb(this); }
891 bitset BitsetLub() { return BitsetType::Lub(this); }
892
893 bool SlowIs(Type* that);
894 bool SemanticIs(Type* that);
895
896 static bool Overlap(RangeType* lhs, RangeType* rhs);
897 static bool Contains(RangeType* lhs, RangeType* rhs);
898 static bool Contains(RangeType* range, ConstantType* constant);
899 static bool Contains(RangeType* range, i::Object* val);
900
901 static int UpdateRange(Type* type, UnionType* result, int size, Zone* zone);
902
903 static RangeType::Limits IntersectRangeAndBitset(Type* range, Type* bits,
904 Zone* zone);
905 static RangeType::Limits ToLimits(bitset bits, Zone* zone);
906
907 bool SimplyEquals(Type* that);
908
909 static int AddToUnion(Type* type, UnionType* result, int size, Zone* zone);
910 static int IntersectAux(Type* type, Type* other, UnionType* result, int size,
911 RangeType::Limits* limits, Zone* zone);
912 static Type* NormalizeUnion(Type* unioned, int size, Zone* zone);
913 static Type* NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000914};
915
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000916// -----------------------------------------------------------------------------
917// Type bounds. A simple struct to represent a pair of lower/upper types.
918
Ben Murdoch097c5b22016-05-18 11:27:45 +0100919struct Bounds {
920 Type* lower;
921 Type* upper;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000922
Ben Murdoch097c5b22016-05-18 11:27:45 +0100923 Bounds()
924 : // Make sure accessing uninitialized bounds crashes big-time.
925 lower(nullptr),
926 upper(nullptr) {}
927 explicit Bounds(Type* t) : lower(t), upper(t) {}
928 Bounds(Type* l, Type* u) : lower(l), upper(u) { DCHECK(lower->Is(upper)); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000929
930 // Unrestricted bounds.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100931 static Bounds Unbounded() { return Bounds(Type::None(), Type::Any()); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000932
933 // Meet: both b1 and b2 are known to hold.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100934 static Bounds Both(Bounds b1, Bounds b2, Zone* zone) {
935 Type* lower = Type::Union(b1.lower, b2.lower, zone);
936 Type* upper = Type::Intersect(b1.upper, b2.upper, zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000937 // Lower bounds are considered approximate, correct as necessary.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400938 if (!lower->Is(upper)) lower = upper;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100939 return Bounds(lower, upper);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000940 }
941
942 // Join: either b1 or b2 is known to hold.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100943 static Bounds Either(Bounds b1, Bounds b2, Zone* zone) {
944 Type* lower = Type::Intersect(b1.lower, b2.lower, zone);
945 Type* upper = Type::Union(b1.upper, b2.upper, zone);
946 return Bounds(lower, upper);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000947 }
948
Ben Murdoch097c5b22016-05-18 11:27:45 +0100949 static Bounds NarrowLower(Bounds b, Type* t, Zone* zone) {
950 Type* lower = Type::Union(b.lower, t, zone);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400951 // Lower bounds are considered approximate, correct as necessary.
952 if (!lower->Is(b.upper)) lower = b.upper;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100953 return Bounds(lower, b.upper);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000954 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100955 static Bounds NarrowUpper(Bounds b, Type* t, Zone* zone) {
956 Type* lower = b.lower;
957 Type* upper = Type::Intersect(b.upper, t, zone);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400958 // Lower bounds are considered approximate, correct as necessary.
959 if (!lower->Is(upper)) lower = upper;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100960 return Bounds(lower, upper);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000961 }
962
Ben Murdoch097c5b22016-05-18 11:27:45 +0100963 bool Narrows(Bounds that) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000964 return that.lower->Is(this->lower) && this->upper->Is(that.upper);
965 }
966};
967
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000968} // namespace internal
969} // namespace v8
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000970
971#endif // V8_TYPES_H_