Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_COMPILER_TYPES_H_ | 5 #ifndef V8_COMPILER_TYPES_H_ |
| 6 #define V8_COMPILER_TYPES_H_ | 6 #define V8_COMPILER_TYPES_H_ |
| 7 | 7 |
| 8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
| 9 #include "src/handles.h" | 9 #include "src/handles.h" |
| 10 #include "src/objects-inl.h" | |
| 10 #include "src/objects.h" | 11 #include "src/objects.h" |
| 11 #include "src/ostreams.h" | 12 #include "src/ostreams.h" |
| 12 | 13 |
| 13 namespace v8 { | 14 namespace v8 { |
| 14 namespace internal { | 15 namespace internal { |
| 15 namespace compiler { | 16 namespace compiler { |
| 16 | 17 |
| 17 // SUMMARY | 18 // SUMMARY |
| 18 // | 19 // |
| 19 // A simple type system for compiler-internal use. It is based entirely on | 20 // A simple type system for compiler-internal use. It is based entirely on |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 256 static inline const Boundary* Boundaries(); | 257 static inline const Boundary* Boundaries(); |
| 257 static inline size_t BoundariesSize(); | 258 static inline size_t BoundariesSize(); |
| 258 }; | 259 }; |
| 259 | 260 |
| 260 // ----------------------------------------------------------------------------- | 261 // ----------------------------------------------------------------------------- |
| 261 // Superclass for non-bitset types (internal). | 262 // Superclass for non-bitset types (internal). |
| 262 class TypeBase { | 263 class TypeBase { |
| 263 protected: | 264 protected: |
| 264 friend class Type; | 265 friend class Type; |
| 265 | 266 |
| 266 enum Kind { kConstant, kTuple, kUnion, kRange }; | 267 enum Kind { kConstant, kNumberConstant, kTuple, kUnion, kRange }; |
| 267 | 268 |
| 268 Kind kind() const { return kind_; } | 269 Kind kind() const { return kind_; } |
| 269 explicit TypeBase(Kind kind) : kind_(kind) {} | 270 explicit TypeBase(Kind kind) : kind_(kind) {} |
| 270 | 271 |
| 271 static bool IsKind(Type* type, Kind kind) { | 272 static bool IsKind(Type* type, Kind kind) { |
| 272 if (BitsetType::IsBitset(type)) return false; | 273 if (BitsetType::IsBitset(type)) return false; |
| 273 TypeBase* base = reinterpret_cast<TypeBase*>(type); | 274 TypeBase* base = reinterpret_cast<TypeBase*>(type); |
| 274 return base->kind() == kind; | 275 return base->kind() == kind; |
| 275 } | 276 } |
| 276 | 277 |
| 277 // The hacky conversion to/from Type*. | 278 // The hacky conversion to/from Type*. |
| 278 static Type* AsType(TypeBase* type) { return reinterpret_cast<Type*>(type); } | 279 static Type* AsType(TypeBase* type) { return reinterpret_cast<Type*>(type); } |
| 279 static TypeBase* FromType(Type* type) { | 280 static TypeBase* FromType(Type* type) { |
| 280 return reinterpret_cast<TypeBase*>(type); | 281 return reinterpret_cast<TypeBase*>(type); |
| 281 } | 282 } |
| 282 | 283 |
| 283 private: | 284 private: |
| 284 Kind kind_; | 285 Kind kind_; |
| 285 }; | 286 }; |
| 286 | 287 |
| 287 // ----------------------------------------------------------------------------- | 288 // ----------------------------------------------------------------------------- |
| 288 // Constant types. | 289 // Constant types. |
| 289 | 290 |
| 291 class NumberConstantType : public TypeBase { | |
| 292 public: | |
| 293 double Value() { return value_; } | |
| 294 | |
| 295 static bool IsNumberConstant(double value) { | |
| 296 // Not an integer, not NaN, and not -0. | |
| 297 return !std::isnan(value) && nearbyint(value) != value && | |
|
mvstanton
2016/09/28 14:47:44
make sure you don't allow integers outside of smi
mvstanton
2016/10/04 11:55:55
Done.
| |
| 298 !i::IsMinusZero(value); | |
| 299 } | |
| 300 | |
| 301 private: | |
| 302 friend class Type; | |
| 303 friend class BitsetType; | |
| 304 | |
| 305 static Type* New(double value, Zone* zone) { | |
| 306 BitsetType::bitset bitset = BitsetType::Lub(value); | |
| 307 return AsType(new (zone->New(sizeof(NumberConstantType))) | |
| 308 NumberConstantType(bitset, value)); | |
| 309 } | |
| 310 | |
| 311 static NumberConstantType* cast(Type* type) { | |
| 312 DCHECK(IsKind(type, kNumberConstant)); | |
| 313 return static_cast<NumberConstantType*>(FromType(type)); | |
| 314 } | |
| 315 | |
| 316 NumberConstantType(BitsetType::bitset bitset, double value) | |
| 317 : TypeBase(kNumberConstant), bitset_(bitset), value_(value) { | |
| 318 CHECK(IsNumberConstant(value)); | |
| 319 } | |
| 320 | |
| 321 BitsetType::bitset Lub() { return bitset_; } | |
| 322 | |
|
mvstanton
2016/09/28 14:47:44
No need for bitset member.
mvstanton
2016/10/04 11:55:55
Done.
| |
| 323 BitsetType::bitset bitset_; | |
| 324 double value_; | |
| 325 }; | |
| 326 | |
| 290 class ConstantType : public TypeBase { | 327 class ConstantType : public TypeBase { |
| 291 public: | 328 public: |
| 292 i::Handle<i::Object> Value() { return object_; } | 329 i::Handle<i::Object> Value() { return object_; } |
| 293 | 330 |
| 294 private: | 331 private: |
| 295 friend class Type; | 332 friend class Type; |
| 296 friend class BitsetType; | 333 friend class BitsetType; |
| 297 | 334 |
| 298 static Type* New(i::Handle<i::Object> value, Zone* zone) { | 335 static Type* New(i::Handle<i::Object> value, Zone* zone) { |
| 299 BitsetType::bitset bitset = BitsetType::Lub(*value); | 336 BitsetType::bitset bitset = BitsetType::Lub(*value); |
| 300 return AsType(new (zone->New(sizeof(ConstantType))) | 337 return AsType(new (zone->New(sizeof(ConstantType))) |
| 301 ConstantType(bitset, value)); | 338 ConstantType(bitset, value)); |
| 302 } | 339 } |
| 303 | 340 |
| 304 static ConstantType* cast(Type* type) { | 341 static ConstantType* cast(Type* type) { |
| 305 DCHECK(IsKind(type, kConstant)); | 342 DCHECK(IsKind(type, kConstant)); |
| 306 return static_cast<ConstantType*>(FromType(type)); | 343 return static_cast<ConstantType*>(FromType(type)); |
| 307 } | 344 } |
| 308 | 345 |
| 309 ConstantType(BitsetType::bitset bitset, i::Handle<i::Object> object) | 346 ConstantType(BitsetType::bitset bitset, i::Handle<i::Object> object) |
| 310 : TypeBase(kConstant), bitset_(bitset), object_(object) {} | 347 : TypeBase(kConstant), bitset_(bitset), object_(object) { |
| 348 CHECK(!object->IsSmi()); // Smis should always be RangeTypes. | |
| 349 CHECK(!object->IsHeapNumber() || | |
| 350 !NumberConstantType::IsNumberConstant( | |
| 351 HeapNumber::cast(*object)->value())); | |
|
mvstanton
2016/09/28 14:47:44
Confusing!
mvstanton
2016/10/04 11:55:55
Done.
| |
| 352 } | |
| 311 | 353 |
| 312 BitsetType::bitset Lub() { return bitset_; } | 354 BitsetType::bitset Lub() { return bitset_; } |
| 313 | 355 |
| 314 BitsetType::bitset bitset_; | 356 BitsetType::bitset bitset_; |
| 315 Handle<i::Object> object_; | 357 Handle<i::Object> object_; |
| 316 }; | 358 }; |
| 317 // TODO(neis): Also cache value if numerical. | |
| 318 | 359 |
| 319 // ----------------------------------------------------------------------------- | 360 // ----------------------------------------------------------------------------- |
| 320 // Range types. | 361 // Range types. |
| 321 | 362 |
| 322 class RangeType : public TypeBase { | 363 class RangeType : public TypeBase { |
| 323 public: | 364 public: |
| 324 struct Limits { | 365 struct Limits { |
| 325 double min; | 366 double min; |
| 326 double max; | 367 double max; |
| 327 Limits(double min, double max) : min(min), max(max) {} | 368 Limits(double min, double max) : min(min), max(max) {} |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 467 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) | 508 PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) |
| 468 #undef DEFINE_TYPE_CONSTRUCTOR | 509 #undef DEFINE_TYPE_CONSTRUCTOR |
| 469 | 510 |
| 470 static Type* SignedSmall() { | 511 static Type* SignedSmall() { |
| 471 return BitsetType::New(BitsetType::SignedSmall()); | 512 return BitsetType::New(BitsetType::SignedSmall()); |
| 472 } | 513 } |
| 473 static Type* UnsignedSmall() { | 514 static Type* UnsignedSmall() { |
| 474 return BitsetType::New(BitsetType::UnsignedSmall()); | 515 return BitsetType::New(BitsetType::UnsignedSmall()); |
| 475 } | 516 } |
| 476 | 517 |
| 518 static Type* NumberConstant(double value, Zone* zone) { | |
| 519 return NumberConstantType::New(value, zone); | |
| 520 } | |
| 477 static Type* Constant(i::Handle<i::Object> value, Zone* zone) { | 521 static Type* Constant(i::Handle<i::Object> value, Zone* zone) { |
| 478 return ConstantType::New(value, zone); | 522 return ConstantType::New(value, zone); |
| 479 } | 523 } |
| 480 static Type* Range(double min, double max, Zone* zone) { | 524 static Type* Range(double min, double max, Zone* zone) { |
| 481 return RangeType::New(min, max, zone); | 525 return RangeType::New(min, max, zone); |
| 482 } | 526 } |
| 483 static Type* Tuple(Type* first, Type* second, Type* third, Zone* zone) { | 527 static Type* Tuple(Type* first, Type* second, Type* third, Zone* zone) { |
| 484 Type* tuple = TupleType::New(3, zone); | 528 Type* tuple = TupleType::New(3, zone); |
| 485 tuple->AsTuple()->InitElement(0, first); | 529 tuple->AsTuple()->InitElement(0, first); |
| 486 tuple->AsTuple()->InitElement(1, second); | 530 tuple->AsTuple()->InitElement(1, second); |
| 487 tuple->AsTuple()->InitElement(2, third); | 531 tuple->AsTuple()->InitElement(2, third); |
| 488 return tuple; | 532 return tuple; |
| 489 } | 533 } |
| 490 | 534 |
| 535 // NewConstant is a factory that returns Constant, Range or Number. | |
| 536 static Type* NewConstant(i::Handle<i::Object> value, Zone* zone); | |
| 537 | |
| 491 static Type* Union(Type* type1, Type* type2, Zone* zone); | 538 static Type* Union(Type* type1, Type* type2, Zone* zone); |
| 492 static Type* Intersect(Type* type1, Type* type2, Zone* zone); | 539 static Type* Intersect(Type* type1, Type* type2, Zone* zone); |
| 493 | 540 |
| 494 static Type* Of(double value, Zone* zone) { | 541 static Type* Of(double value, Zone* zone) { |
| 495 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value))); | 542 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value))); |
| 496 } | 543 } |
| 497 static Type* Of(i::Object* value, Zone* zone) { | 544 static Type* Of(i::Object* value, Zone* zone) { |
| 498 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value))); | 545 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value))); |
| 499 } | 546 } |
| 500 static Type* Of(i::Handle<i::Object> value, Zone* zone) { | 547 static Type* Of(i::Handle<i::Object> value, Zone* zone) { |
| 501 return Of(*value, zone); | 548 return Of(*value, zone); |
| 502 } | 549 } |
| 503 | 550 |
| 504 static Type* For(i::Map* map) { | 551 static Type* For(i::Map* map) { |
| 505 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(map))); | 552 return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(map))); |
| 506 } | 553 } |
| 507 static Type* For(i::Handle<i::Map> map) { return For(*map); } | 554 static Type* For(i::Handle<i::Map> map) { return For(*map); } |
| 508 | 555 |
| 509 // Predicates. | 556 // Predicates. |
| 510 bool IsInhabited() { return BitsetType::IsInhabited(this->BitsetLub()); } | 557 bool IsInhabited() { return BitsetType::IsInhabited(this->BitsetLub()); } |
| 511 | 558 |
| 512 bool Is(Type* that) { return this == that || this->SlowIs(that); } | 559 bool Is(Type* that) { return this == that || this->SlowIs(that); } |
| 513 bool Maybe(Type* that); | 560 bool Maybe(Type* that); |
| 514 bool Equals(Type* that) { return this->Is(that) && that->Is(this); } | 561 bool Equals(Type* that) { return this->Is(that) && that->Is(this); } |
| 515 | 562 |
| 516 // Inspection. | 563 // Inspection. |
| 517 bool IsRange() { return IsKind(TypeBase::kRange); } | 564 bool IsRange() { return IsKind(TypeBase::kRange); } |
| 518 bool IsConstant() { return IsKind(TypeBase::kConstant); } | 565 bool IsConstant() { return IsKind(TypeBase::kConstant); } |
| 566 bool IsNumberConstant() { return IsKind(TypeBase::kNumberConstant); } | |
| 519 bool IsTuple() { return IsKind(TypeBase::kTuple); } | 567 bool IsTuple() { return IsKind(TypeBase::kTuple); } |
| 520 | 568 |
| 521 ConstantType* AsConstant() { return ConstantType::cast(this); } | 569 ConstantType* AsConstant() { return ConstantType::cast(this); } |
| 570 NumberConstantType* AsNumberConstant() { | |
| 571 return NumberConstantType::cast(this); | |
| 572 } | |
| 522 RangeType* AsRange() { return RangeType::cast(this); } | 573 RangeType* AsRange() { return RangeType::cast(this); } |
| 523 TupleType* AsTuple() { return TupleType::cast(this); } | 574 TupleType* AsTuple() { return TupleType::cast(this); } |
| 524 | 575 |
| 525 // Minimum and maximum of a numeric type. | 576 // Minimum and maximum of a numeric type. |
| 526 // These functions do not distinguish between -0 and +0. If the type equals | 577 // These functions do not distinguish between -0 and +0. If the type equals |
| 527 // kNaN, they return NaN; otherwise kNaN is ignored. Only call these | 578 // kNaN, they return NaN; otherwise kNaN is ignored. Only call these |
| 528 // functions on subtypes of Number. | 579 // functions on subtypes of Number. |
| 529 double Min(); | 580 double Min(); |
| 530 double Max(); | 581 double Max(); |
| 531 | 582 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 576 UnionType* AsUnion() { return UnionType::cast(this); } | 627 UnionType* AsUnion() { return UnionType::cast(this); } |
| 577 | 628 |
| 578 bitset BitsetGlb() { return BitsetType::Glb(this); } | 629 bitset BitsetGlb() { return BitsetType::Glb(this); } |
| 579 bitset BitsetLub() { return BitsetType::Lub(this); } | 630 bitset BitsetLub() { return BitsetType::Lub(this); } |
| 580 | 631 |
| 581 bool SlowIs(Type* that); | 632 bool SlowIs(Type* that); |
| 582 | 633 |
| 583 static bool Overlap(RangeType* lhs, RangeType* rhs); | 634 static bool Overlap(RangeType* lhs, RangeType* rhs); |
| 584 static bool Contains(RangeType* lhs, RangeType* rhs); | 635 static bool Contains(RangeType* lhs, RangeType* rhs); |
| 585 static bool Contains(RangeType* range, ConstantType* constant); | 636 static bool Contains(RangeType* range, ConstantType* constant); |
| 637 static bool Contains(RangeType* range, NumberConstantType* constant); | |
| 586 static bool Contains(RangeType* range, i::Object* val); | 638 static bool Contains(RangeType* range, i::Object* val); |
| 587 | 639 |
| 588 static int UpdateRange(Type* type, UnionType* result, int size, Zone* zone); | 640 static int UpdateRange(Type* type, UnionType* result, int size, Zone* zone); |
| 589 | 641 |
| 590 static RangeType::Limits IntersectRangeAndBitset(Type* range, Type* bits, | 642 static RangeType::Limits IntersectRangeAndBitset(Type* range, Type* bits, |
| 591 Zone* zone); | 643 Zone* zone); |
| 592 static RangeType::Limits ToLimits(bitset bits, Zone* zone); | 644 static RangeType::Limits ToLimits(bitset bits, Zone* zone); |
| 593 | 645 |
| 594 bool SimplyEquals(Type* that); | 646 bool SimplyEquals(Type* that); |
| 595 | 647 |
| 596 static int AddToUnion(Type* type, UnionType* result, int size, Zone* zone); | 648 static int AddToUnion(Type* type, UnionType* result, int size, Zone* zone); |
| 597 static int IntersectAux(Type* type, Type* other, UnionType* result, int size, | 649 static int IntersectAux(Type* type, Type* other, UnionType* result, int size, |
| 598 RangeType::Limits* limits, Zone* zone); | 650 RangeType::Limits* limits, Zone* zone); |
| 599 static Type* NormalizeUnion(Type* unioned, int size, Zone* zone); | 651 static Type* NormalizeUnion(Type* unioned, int size, Zone* zone); |
| 600 static Type* NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone); | 652 static Type* NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone); |
| 601 }; | 653 }; |
| 602 | 654 |
| 603 } // namespace compiler | 655 } // namespace compiler |
| 604 } // namespace internal | 656 } // namespace internal |
| 605 } // namespace v8 | 657 } // namespace v8 |
| 606 | 658 |
| 607 #endif // V8_COMPILER_TYPES_H_ | 659 #endif // V8_COMPILER_TYPES_H_ |
| OLD | NEW |