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_TYPES_H_ 6 #define V8_COMPILER_TYPES_H_ 7 8 #include "src/base/compiler-specific.h" 9 #include "src/conversions.h" 10 #include "src/globals.h" 11 #include "src/handles.h" 12 #include "src/objects.h" 13 #include "src/ostreams.h" 14 15 namespace v8 { 16 namespace internal { 17 namespace compiler { 18 19 // SUMMARY 20 // 21 // A simple type system for compiler-internal use. It is based entirely on 22 // union types, and all subtyping hence amounts to set inclusion. Besides the 23 // obvious primitive types and some predefined unions, the type language also 24 // can express class types (a.k.a. specific maps) and singleton types (i.e., 25 // concrete constants). 26 // 27 // The following equations and inequations hold: 28 // 29 // None <= T 30 // T <= Any 31 // 32 // Number = Signed32 \/ Unsigned32 \/ Double 33 // Smi <= Signed32 34 // Name = String \/ Symbol 35 // UniqueName = InternalizedString \/ Symbol 36 // InternalizedString < String 37 // 38 // Receiver = Object \/ Proxy 39 // OtherUndetectable < Object 40 // DetectableReceiver = Receiver - OtherUndetectable 41 // 42 // Constant(x) < T iff instance_type(map(x)) < T 43 // 44 // 45 // RANGE TYPES 46 // 47 // A range type represents a continuous integer interval by its minimum and 48 // maximum value. Either value may be an infinity, in which case that infinity 49 // itself is also included in the range. A range never contains NaN or -0. 50 // 51 // If a value v happens to be an integer n, then Constant(v) is considered a 52 // subtype of Range(n, n) (and therefore also a subtype of any larger range). 53 // In order to avoid large unions, however, it is usually a good idea to use 54 // Range rather than Constant. 55 // 56 // 57 // PREDICATES 58 // 59 // There are two main functions for testing types: 60 // 61 // T1->Is(T2) -- tests whether T1 is included in T2 (i.e., T1 <= T2) 62 // T1->Maybe(T2) -- tests whether T1 and T2 overlap (i.e., T1 /\ T2 =/= 0) 63 // 64 // Typically, the former is to be used to select representations (e.g., via 65 // T->Is(SignedSmall())), and the latter to check whether a specific case needs 66 // handling (e.g., via T->Maybe(Number())). 67 // 68 // There is no functionality to discover whether a type is a leaf in the 69 // lattice. That is intentional. It should always be possible to refine the 70 // lattice (e.g., splitting up number types further) without invalidating any 71 // existing assumptions or tests. 72 // Consequently, do not normally use Equals for type tests, always use Is! 73 // 74 // The NowIs operator implements state-sensitive subtying, as described above. 75 // Any compilation decision based on such temporary properties requires runtime 76 // guarding! 77 // 78 // 79 // PROPERTIES 80 // 81 // Various formal properties hold for constructors, operators, and predicates 82 // over types. For example, constructors are injective and subtyping is a 83 // complete partial order. 84 // 85 // See test/cctest/test-types.cc for a comprehensive executable specification, 86 // especially with respect to the properties of the more exotic 'temporal' 87 // constructors and predicates (those prefixed 'Now'). 88 // 89 // 90 // IMPLEMENTATION 91 // 92 // Internally, all 'primitive' types, and their unions, are represented as 93 // bitsets. Bit 0 is reserved for tagging. Only structured types require 94 // allocation. 95 96 // ----------------------------------------------------------------------------- 97 // Values for bitset types 98 99 // clang-format off 100 101 #define INTERNAL_BITSET_TYPE_LIST(V) \ 102 V(OtherUnsigned31, 1u << 1) \ 103 V(OtherUnsigned32, 1u << 2) \ 104 V(OtherSigned32, 1u << 3) \ 105 V(OtherNumber, 1u << 4) \ 106 107 #define PROPER_BITSET_TYPE_LIST(V) \ 108 V(None, 0u) \ 109 V(Negative31, 1u << 5) \ 110 V(Null, 1u << 6) \ 111 V(Undefined, 1u << 7) \ 112 V(Boolean, 1u << 8) \ 113 V(Unsigned30, 1u << 9) \ 114 V(MinusZero, 1u << 10) \ 115 V(NaN, 1u << 11) \ 116 V(Symbol, 1u << 12) \ 117 V(InternalizedString, 1u << 13) \ 118 V(OtherString, 1u << 14) \ 119 V(OtherCallable, 1u << 15) \ 120 V(OtherObject, 1u << 16) \ 121 V(OtherUndetectable, 1u << 17) \ 122 V(CallableProxy, 1u << 18) \ 123 V(OtherProxy, 1u << 19) \ 124 V(Function, 1u << 20) \ 125 V(BoundFunction, 1u << 21) \ 126 V(Hole, 1u << 22) \ 127 V(OtherInternal, 1u << 23) \ 128 V(ExternalPointer, 1u << 24) \ 129 \ 130 V(Signed31, kUnsigned30 | kNegative31) \ 131 V(Signed32, kSigned31 | kOtherUnsigned31 | \ 132 kOtherSigned32) \ 133 V(Signed32OrMinusZero, kSigned32 | kMinusZero) \ 134 V(Signed32OrMinusZeroOrNaN, kSigned32 | kMinusZero | kNaN) \ 135 V(Negative32, kNegative31 | kOtherSigned32) \ 136 V(Unsigned31, kUnsigned30 | kOtherUnsigned31) \ 137 V(Unsigned32, kUnsigned30 | kOtherUnsigned31 | \ 138 kOtherUnsigned32) \ 139 V(Unsigned32OrMinusZero, kUnsigned32 | kMinusZero) \ 140 V(Unsigned32OrMinusZeroOrNaN, kUnsigned32 | kMinusZero | kNaN) \ 141 V(Integral32, kSigned32 | kUnsigned32) \ 142 V(Integral32OrMinusZeroOrNaN, kIntegral32 | kMinusZero | kNaN) \ 143 V(PlainNumber, kIntegral32 | kOtherNumber) \ 144 V(OrderedNumber, kPlainNumber | kMinusZero) \ 145 V(MinusZeroOrNaN, kMinusZero | kNaN) \ 146 V(Number, kOrderedNumber | kNaN) \ 147 V(String, kInternalizedString | kOtherString) \ 148 V(UniqueName, kSymbol | kInternalizedString) \ 149 V(Name, kSymbol | kString) \ 150 V(InternalizedStringOrNull, kInternalizedString | kNull) \ 151 V(BooleanOrNumber, kBoolean | kNumber) \ 152 V(BooleanOrNullOrNumber, kBooleanOrNumber | kNull) \ 153 V(BooleanOrNullOrUndefined, kBoolean | kNull | kUndefined) \ 154 V(Oddball, kBooleanOrNullOrUndefined | kHole) \ 155 V(NullOrNumber, kNull | kNumber) \ 156 V(NullOrUndefined, kNull | kUndefined) \ 157 V(Undetectable, kNullOrUndefined | kOtherUndetectable) \ 158 V(NumberOrOddball, kNumber | kNullOrUndefined | kBoolean | \ 159 kHole) \ 160 V(NumberOrString, kNumber | kString) \ 161 V(NumberOrUndefined, kNumber | kUndefined) \ 162 V(PlainPrimitive, kNumberOrString | kBoolean | \ 163 kNullOrUndefined) \ 164 V(Primitive, kSymbol | kPlainPrimitive) \ 165 V(OtherUndetectableOrUndefined, kOtherUndetectable | kUndefined) \ 166 V(Proxy, kCallableProxy | kOtherProxy) \ 167 V(DetectableCallable, kFunction | kBoundFunction | \ 168 kOtherCallable | kCallableProxy) \ 169 V(Callable, kDetectableCallable | kOtherUndetectable) \ 170 V(NonCallable, kOtherObject | kOtherProxy) \ 171 V(NonCallableOrNull, kNonCallable | kNull) \ 172 V(DetectableObject, kFunction | kBoundFunction | \ 173 kOtherCallable | kOtherObject) \ 174 V(DetectableReceiver, kDetectableObject | kProxy) \ 175 V(DetectableReceiverOrNull, kDetectableReceiver | kNull) \ 176 V(Object, kDetectableObject | kOtherUndetectable) \ 177 V(Receiver, kObject | kProxy) \ 178 V(ReceiverOrUndefined, kReceiver | kUndefined) \ 179 V(ReceiverOrNullOrUndefined, kReceiver | kNull | kUndefined) \ 180 V(SymbolOrReceiver, kSymbol | kReceiver) \ 181 V(StringOrReceiver, kString | kReceiver) \ 182 V(Unique, kBoolean | kUniqueName | kNull | \ 183 kUndefined | kReceiver) \ 184 V(Internal, kHole | kExternalPointer | kOtherInternal) \ 185 V(NonInternal, kPrimitive | kReceiver) \ 186 V(NonNumber, kUnique | kString | kInternal) \ 187 V(Any, 0xfffffffeu) 188 189 // clang-format on 190 191 /* 192 * The following diagrams show how integers (in the mathematical sense) are 193 * divided among the different atomic numerical types. 194 * 195 * ON OS32 N31 U30 OU31 OU32 ON 196 * ______[_______[_______[_______[_______[_______[_______ 197 * -2^31 -2^30 0 2^30 2^31 2^32 198 * 199 * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1. 200 * 201 * Some of the atomic numerical bitsets are internal only (see 202 * INTERNAL_BITSET_TYPE_LIST). To a types user, they should only occur in 203 * union with certain other bitsets. For instance, OtherNumber should only 204 * occur as part of PlainNumber. 205 */ 206 207 #define BITSET_TYPE_LIST(V) \ 208 INTERNAL_BITSET_TYPE_LIST(V) \ 209 PROPER_BITSET_TYPE_LIST(V) 210 211 class Type; 212 213 // ----------------------------------------------------------------------------- 214 // Bitset types (internal). 215 216 class V8_EXPORT_PRIVATE BitsetType { 217 public: 218 typedef uint32_t bitset; // Internal 219 220 enum : uint32_t { 221 #define DECLARE_TYPE(type, value) k##type = (value), 222 BITSET_TYPE_LIST(DECLARE_TYPE) 223 #undef DECLARE_TYPE 224 kUnusedEOL = 0 225 }; 226 227 static bitset SignedSmall(); 228 static bitset UnsignedSmall(); 229 230 bitset Bitset() { 231 return static_cast<bitset>(reinterpret_cast<uintptr_t>(this) ^ 1u); 232 } 233 234 static bool IsInhabited(bitset bits) { return bits != kNone; } 235 236 static bool Is(bitset bits1, bitset bits2) { 237 return (bits1 | bits2) == bits2; 238 } 239 240 static double Min(bitset); 241 static double Max(bitset); 242 243 static bitset Glb(Type* type); // greatest lower bound that's a bitset 244 static bitset Glb(double min, double max); 245 static bitset Lub(Type* type); // least upper bound that's a bitset 246 static bitset Lub(i::Map* map); 247 static bitset Lub(i::Object* value); 248 static bitset Lub(double value); 249 static bitset Lub(double min, double max); 250 static bitset ExpandInternals(bitset bits); 251 252 static const char* Name(bitset); 253 static void Print(std::ostream& os, bitset); // NOLINT 254 #ifdef DEBUG 255 static void Print(bitset); 256 #endif 257 258 static bitset NumberBits(bitset bits); 259 260 static bool IsBitset(Type* type) { 261 return reinterpret_cast<uintptr_t>(type) & 1; 262 } 263 264 static Type* NewForTesting(bitset bits) { return New(bits); } 265 266 private: 267 friend class Type; 268 269 static Type* New(bitset bits) { 270 return reinterpret_cast<Type*>(static_cast<uintptr_t>(bits | 1u)); 271 } 272 273 struct Boundary { 274 bitset internal; 275 bitset external; 276 double min; 277 }; 278 static const Boundary BoundariesArray[]; 279 static inline const Boundary* Boundaries(); 280 static inline size_t BoundariesSize(); 281 }; 282 283 // ----------------------------------------------------------------------------- 284 // Superclass for non-bitset types (internal). 285 class TypeBase { 286 protected: 287 friend class Type; 288 289 enum Kind { kHeapConstant, kOtherNumberConstant, kTuple, kUnion, kRange }; 290 291 Kind kind() const { return kind_; } 292 explicit TypeBase(Kind kind) : kind_(kind) {} 293 294 static bool IsKind(Type* type, Kind kind) { 295 if (BitsetType::IsBitset(type)) return false; 296 TypeBase* base = reinterpret_cast<TypeBase*>(type); 297 return base->kind() == kind; 298 } 299 300 // The hacky conversion to/from Type*. 301 static Type* AsType(TypeBase* type) { return reinterpret_cast<Type*>(type); } 302 static TypeBase* FromType(Type* type) { 303 return reinterpret_cast<TypeBase*>(type); 304 } 305 306 private: 307 Kind kind_; 308 }; 309 310 // ----------------------------------------------------------------------------- 311 // Constant types. 312 313 class OtherNumberConstantType : public TypeBase { 314 public: 315 double Value() { return value_; } 316 317 static bool IsOtherNumberConstant(double value); 318 static bool IsOtherNumberConstant(Object* value); 319 320 private: 321 friend class Type; 322 friend class BitsetType; 323 324 static Type* New(double value, Zone* zone) { 325 return AsType(new (zone->New(sizeof(OtherNumberConstantType))) 326 OtherNumberConstantType(value)); // NOLINT 327 } 328 329 static OtherNumberConstantType* cast(Type* type) { 330 DCHECK(IsKind(type, kOtherNumberConstant)); 331 return static_cast<OtherNumberConstantType*>(FromType(type)); 332 } 333 334 explicit OtherNumberConstantType(double value) 335 : TypeBase(kOtherNumberConstant), value_(value) { 336 CHECK(IsOtherNumberConstant(value)); 337 } 338 339 BitsetType::bitset Lub() { return BitsetType::kOtherNumber; } 340 341 double value_; 342 }; 343 344 class V8_EXPORT_PRIVATE HeapConstantType : public NON_EXPORTED_BASE(TypeBase) { 345 public: 346 i::Handle<i::HeapObject> Value() { return object_; } 347 348 private: 349 friend class Type; 350 friend class BitsetType; 351 352 static Type* New(i::Handle<i::HeapObject> value, Zone* zone) { 353 BitsetType::bitset bitset = BitsetType::Lub(*value); 354 return AsType(new (zone->New(sizeof(HeapConstantType))) 355 HeapConstantType(bitset, value)); 356 } 357 358 static HeapConstantType* cast(Type* type) { 359 DCHECK(IsKind(type, kHeapConstant)); 360 return static_cast<HeapConstantType*>(FromType(type)); 361 } 362 363 HeapConstantType(BitsetType::bitset bitset, i::Handle<i::HeapObject> object); 364 365 BitsetType::bitset Lub() { return bitset_; } 366 367 BitsetType::bitset bitset_; 368 Handle<i::HeapObject> object_; 369 }; 370 371 // ----------------------------------------------------------------------------- 372 // Range types. 373 374 class RangeType : public TypeBase { 375 public: 376 struct Limits { 377 double min; 378 double max; 379 Limits(double min, double max) : min(min), max(max) {} 380 explicit Limits(RangeType* range) : min(range->Min()), max(range->Max()) {} 381 bool IsEmpty(); 382 static Limits Empty() { return Limits(1, 0); } 383 static Limits Intersect(Limits lhs, Limits rhs); 384 static Limits Union(Limits lhs, Limits rhs); 385 }; 386 387 double Min() { return limits_.min; } 388 double Max() { return limits_.max; } 389 390 private: 391 friend class Type; 392 friend class BitsetType; 393 friend class UnionType; 394 395 static Type* New(double min, double max, Zone* zone) { 396 return New(Limits(min, max), zone); 397 } 398 399 static bool IsInteger(double x) { 400 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities. 401 } 402 403 static Type* New(Limits lim, Zone* zone) { 404 DCHECK(IsInteger(lim.min) && IsInteger(lim.max)); 405 DCHECK(lim.min <= lim.max); 406 BitsetType::bitset bits = BitsetType::Lub(lim.min, lim.max); 407 408 return AsType(new (zone->New(sizeof(RangeType))) RangeType(bits, lim)); 409 } 410 411 static RangeType* cast(Type* type) { 412 DCHECK(IsKind(type, kRange)); 413 return static_cast<RangeType*>(FromType(type)); 414 } 415 416 RangeType(BitsetType::bitset bitset, Limits limits) 417 : TypeBase(kRange), bitset_(bitset), limits_(limits) {} 418 419 BitsetType::bitset Lub() { return bitset_; } 420 421 BitsetType::bitset bitset_; 422 Limits limits_; 423 }; 424 425 // ----------------------------------------------------------------------------- 426 // Superclass for types with variable number of type fields. 427 class StructuralType : public TypeBase { 428 public: 429 int LengthForTesting() { return Length(); } 430 431 protected: 432 friend class Type; 433 434 int Length() { return length_; } 435 436 Type* Get(int i) { 437 DCHECK(0 <= i && i < this->Length()); 438 return elements_[i]; 439 } 440 441 void Set(int i, Type* type) { 442 DCHECK(0 <= i && i < this->Length()); 443 elements_[i] = type; 444 } 445 446 void Shrink(int length) { 447 DCHECK(2 <= length && length <= this->Length()); 448 length_ = length; 449 } 450 451 StructuralType(Kind kind, int length, i::Zone* zone) 452 : TypeBase(kind), length_(length) { 453 elements_ = reinterpret_cast<Type**>(zone->New(sizeof(Type*) * length)); 454 } 455 456 private: 457 int length_; 458 Type** elements_; 459 }; 460 461 // ----------------------------------------------------------------------------- 462 // Tuple types. 463 464 class TupleType : public StructuralType { 465 public: 466 int Arity() { return this->Length(); } 467 Type* Element(int i) { return this->Get(i); } 468 469 void InitElement(int i, Type* type) { this->Set(i, type); } 470 471 private: 472 friend class Type; 473 474 TupleType(int length, Zone* zone) : StructuralType(kTuple, length, zone) {} 475 476 static Type* New(int length, Zone* zone) { 477 return AsType(new (zone->New(sizeof(TupleType))) TupleType(length, zone)); 478 } 479 480 static TupleType* cast(Type* type) { 481 DCHECK(IsKind(type, kTuple)); 482 return static_cast<TupleType*>(FromType(type)); 483 } 484 }; 485 486 // ----------------------------------------------------------------------------- 487 // Union types (internal). 488 // A union is a structured type with the following invariants: 489 // - its length is at least 2 490 // - at most one field is a bitset, and it must go into index 0 491 // - no field is a union 492 // - no field is a subtype of any other field 493 class UnionType : public StructuralType { 494 private: 495 friend Type; 496 friend BitsetType; 497 498 UnionType(int length, Zone* zone) : StructuralType(kUnion, length, zone) {} 499 500 static Type* New(int length, Zone* zone) { 501 return AsType(new (zone->New(sizeof(UnionType))) UnionType(length, zone)); 502 } 503 504 static UnionType* cast(Type* type) { 505 DCHECK(IsKind(type, kUnion)); 506 return static_cast<UnionType*>(FromType(type)); 507 } 508 509 bool Wellformed(); 510 }; 511 512 class V8_EXPORT_PRIVATE Type { 513 public: 514 typedef BitsetType::bitset bitset; // Internal 515 516 // Constructors. 517 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ 518 static Type* type() { return BitsetType::New(BitsetType::k##type); } 519 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) 520 #undef DEFINE_TYPE_CONSTRUCTOR 521 522 static Type* SignedSmall() { 523 return BitsetType::New(BitsetType::SignedSmall()); 524 } 525 static Type* UnsignedSmall() { 526 return BitsetType::New(BitsetType::UnsignedSmall()); 527 } 528 529 static Type* OtherNumberConstant(double value, Zone* zone) { 530 return OtherNumberConstantType::New(value, zone); 531 } 532 static Type* HeapConstant(i::Handle<i::HeapObject> value, Zone* zone) { 533 return HeapConstantType::New(value, zone); 534 } 535 static Type* Range(double min, double max, Zone* zone) { 536 return RangeType::New(min, max, zone); 537 } 538 static Type* Tuple(Type* first, Type* second, Type* third, Zone* zone) { 539 Type* tuple = TupleType::New(3, zone); 540 tuple->AsTuple()->InitElement(0, first); 541 tuple->AsTuple()->InitElement(1, second); 542 tuple->AsTuple()->InitElement(2, third); 543 return tuple; 544 } 545 546 // NewConstant is a factory that returns Constant, Range or Number. 547 static Type* NewConstant(i::Handle<i::Object> value, Zone* zone); 548 static Type* NewConstant(double value, Zone* zone); 549 550 static Type* Union(Type* type1, Type* type2, Zone* zone); 551 static Type* Intersect(Type* type1, Type* type2, Zone* zone); 552 553 static Type* Of(double value, Zone* zone) { 554 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value))); 555 } 556 static Type* Of(i::Object* value, Zone* zone) { 557 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value))); 558 } 559 static Type* Of(i::Handle<i::Object> value, Zone* zone) { 560 return Of(*value, zone); 561 } 562 563 static Type* For(i::Map* map) { 564 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(map))); 565 } 566 static Type* For(i::Handle<i::Map> map) { return For(*map); } 567 568 // Predicates. 569 bool IsInhabited() { return BitsetType::IsInhabited(this->BitsetLub()); } 570 571 bool Is(Type* that) { return this == that || this->SlowIs(that); } 572 bool Maybe(Type* that); 573 bool Equals(Type* that) { return this->Is(that) && that->Is(this); } 574 575 // Inspection. 576 bool IsRange() { return IsKind(TypeBase::kRange); } 577 bool IsHeapConstant() { return IsKind(TypeBase::kHeapConstant); } 578 bool IsOtherNumberConstant() { 579 return IsKind(TypeBase::kOtherNumberConstant); 580 } 581 bool IsTuple() { return IsKind(TypeBase::kTuple); } 582 583 HeapConstantType* AsHeapConstant() { return HeapConstantType::cast(this); } 584 OtherNumberConstantType* AsOtherNumberConstant() { 585 return OtherNumberConstantType::cast(this); 586 } 587 RangeType* AsRange() { return RangeType::cast(this); } 588 TupleType* AsTuple() { return TupleType::cast(this); } 589 590 // Minimum and maximum of a numeric type. 591 // These functions do not distinguish between -0 and +0. If the type equals 592 // kNaN, they return NaN; otherwise kNaN is ignored. Only call these 593 // functions on subtypes of Number. 594 double Min(); 595 double Max(); 596 597 // Extracts a range from the type: if the type is a range or a union 598 // containing a range, that range is returned; otherwise, NULL is returned. 599 Type* GetRange(); 600 601 static bool IsInteger(i::Object* x); 602 static bool IsInteger(double x) { 603 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities. 604 } 605 606 int NumConstants(); 607 608 // Printing. 609 610 void PrintTo(std::ostream& os); 611 612 #ifdef DEBUG 613 void Print(); 614 #endif 615 616 // Helpers for testing. 617 bool IsBitsetForTesting() { return IsBitset(); } 618 bool IsUnionForTesting() { return IsUnion(); } 619 bitset AsBitsetForTesting() { return AsBitset(); } 620 UnionType* AsUnionForTesting() { return AsUnion(); } 621 622 private: 623 // Friends. 624 template <class> 625 friend class Iterator; 626 friend BitsetType; 627 friend UnionType; 628 629 // Internal inspection. 630 bool IsKind(TypeBase::Kind kind) { return TypeBase::IsKind(this, kind); } 631 632 bool IsNone() { return this == None(); } 633 bool IsAny() { return this == Any(); } 634 bool IsBitset() { return BitsetType::IsBitset(this); } 635 bool IsUnion() { return IsKind(TypeBase::kUnion); } 636 637 bitset AsBitset() { 638 DCHECK(this->IsBitset()); 639 return reinterpret_cast<BitsetType*>(this)->Bitset(); 640 } 641 UnionType* AsUnion() { return UnionType::cast(this); } 642 643 bitset BitsetGlb() { return BitsetType::Glb(this); } 644 bitset BitsetLub() { return BitsetType::Lub(this); } 645 646 bool SlowIs(Type* that); 647 648 static bool Overlap(RangeType* lhs, RangeType* rhs); 649 static bool Contains(RangeType* lhs, RangeType* rhs); 650 static bool Contains(RangeType* range, i::Object* val); 651 652 static int UpdateRange(Type* type, UnionType* result, int size, Zone* zone); 653 654 static RangeType::Limits IntersectRangeAndBitset(Type* range, Type* bits, 655 Zone* zone); 656 static RangeType::Limits ToLimits(bitset bits, Zone* zone); 657 658 bool SimplyEquals(Type* that); 659 660 static int AddToUnion(Type* type, UnionType* result, int size, Zone* zone); 661 static int IntersectAux(Type* type, Type* other, UnionType* result, int size, 662 RangeType::Limits* limits, Zone* zone); 663 static Type* NormalizeUnion(Type* unioned, int size, Zone* zone); 664 static Type* NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone); 665 }; 666 667 } // namespace compiler 668 } // namespace internal 669 } // namespace v8 670 671 #endif // V8_COMPILER_TYPES_H_ 672