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_TYPES_H_ | 5 #ifndef V8_TYPES_H_ |
6 #define V8_TYPES_H_ | 6 #define V8_TYPES_H_ |
7 | 7 |
8 #include "src/factory.h" | 8 #include "src/factory.h" |
9 #include "src/handles.h" | 9 #include "src/handles.h" |
10 #include "src/ostreams.h" | 10 #include "src/ostreams.h" |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 // However, we also define a 'temporal' variant of the subtyping relation that | 61 // However, we also define a 'temporal' variant of the subtyping relation that |
62 // considers the _current_ state only, i.e., Constant(x) <_now Class(map(x)). | 62 // considers the _current_ state only, i.e., Constant(x) <_now Class(map(x)). |
63 // | 63 // |
64 // REPRESENTATIONAL DIMENSION | 64 // REPRESENTATIONAL DIMENSION |
65 // | 65 // |
66 // For the representation axis, the following holds: | 66 // For the representation axis, the following holds: |
67 // | 67 // |
68 // None <= R | 68 // None <= R |
69 // R <= Any | 69 // R <= Any |
70 // | 70 // |
71 // UntaggedInt <= UntaggedInt8 \/ UntaggedInt16 \/ UntaggedInt32) | 71 // UntaggedInt = UntaggedInt1 \/ UntaggedInt8 \/ |
72 // UntaggedFloat <= UntaggedFloat32 \/ UntaggedFloat64 | 72 // UntaggedInt16 \/ UntaggedInt32 |
73 // UntaggedNumber <= UntaggedInt \/ UntaggedFloat | 73 // UntaggedFloat = UntaggedFloat32 \/ UntaggedFloat64 |
74 // Untagged <= UntaggedNumber \/ UntaggedPtr | 74 // UntaggedNumber = UntaggedInt \/ UntaggedFloat |
75 // Tagged <= TaggedInt \/ TaggedPtr | 75 // Untagged = UntaggedNumber \/ UntaggedPtr |
| 76 // Tagged = TaggedInt \/ TaggedPtr |
76 // | 77 // |
77 // Subtyping relates the two dimensions, for example: | 78 // Subtyping relates the two dimensions, for example: |
78 // | 79 // |
79 // Number <= Tagged \/ UntaggedNumber | 80 // Number <= Tagged \/ UntaggedNumber |
80 // Object <= TaggedPtr \/ UntaggedPtr | 81 // Object <= TaggedPtr \/ UntaggedPtr |
81 // | 82 // |
82 // That holds because the semantic type constructors defined by the API create | 83 // That holds because the semantic type constructors defined by the API create |
83 // types that allow for all possible representations, and dually, the ones for | 84 // types that allow for all possible representations, and dually, the ones for |
84 // representation types initially include all semantic ranges. Representations | 85 // representation types initially include all semantic ranges. Representations |
85 // can then e.g. be narrowed for a given semantic type using intersection: | 86 // can then e.g. be narrowed for a given semantic type using intersection: |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 UnionType* AsUnion() { return UnionType::cast(this); } | 458 UnionType* AsUnion() { return UnionType::cast(this); } |
458 | 459 |
459 // Auxiliary functions. | 460 // Auxiliary functions. |
460 | 461 |
461 int BitsetGlb() { return BitsetType::Glb(this); } | 462 int BitsetGlb() { return BitsetType::Glb(this); } |
462 int BitsetLub() { return BitsetType::Lub(this); } | 463 int BitsetLub() { return BitsetType::Lub(this); } |
463 int InherentBitsetLub() { return BitsetType::InherentLub(this); } | 464 int InherentBitsetLub() { return BitsetType::InherentLub(this); } |
464 | 465 |
465 bool SlowIs(TypeImpl* that); | 466 bool SlowIs(TypeImpl* that); |
466 | 467 |
467 TypeHandle Narrow(int bitset, Region* region); | 468 TypeHandle Rebound(int bitset, Region* region); |
468 int BoundBy(TypeImpl* that); | 469 int BoundBy(TypeImpl* that); |
469 int IndexInUnion(int bound, UnionHandle unioned, int current_size); | 470 int IndexInUnion(int bound, UnionHandle unioned, int current_size); |
470 static int ExtendUnion( | 471 static int ExtendUnion( |
471 UnionHandle unioned, int current_size, TypeHandle t, | 472 UnionHandle unioned, int current_size, TypeHandle t, |
472 TypeHandle other, bool is_intersect, Region* region); | 473 TypeHandle other, bool is_intersect, Region* region); |
473 static int NormalizeUnion(UnionHandle unioned, int current_size, int bitset); | 474 static int NormalizeUnion(UnionHandle unioned, int current_size, int bitset); |
474 }; | 475 }; |
475 | 476 |
476 | 477 |
477 // ----------------------------------------------------------------------------- | 478 // ----------------------------------------------------------------------------- |
(...skipping 17 matching lines...) Expand all Loading... |
495 return static_cast<BitsetType*>(Config::from_bitset(bitset)); | 496 return static_cast<BitsetType*>(Config::from_bitset(bitset)); |
496 } | 497 } |
497 static TypeHandle New(int bitset, Region* region) { | 498 static TypeHandle New(int bitset, Region* region) { |
498 return Config::from_bitset(bitset, region); | 499 return Config::from_bitset(bitset, region); |
499 } | 500 } |
500 | 501 |
501 static bool IsInhabited(int bitset) { | 502 static bool IsInhabited(int bitset) { |
502 return (bitset & kRepresentation) && (bitset & kSemantic); | 503 return (bitset & kRepresentation) && (bitset & kSemantic); |
503 } | 504 } |
504 | 505 |
| 506 static bool Is(int bitset1, int bitset2) { |
| 507 return (bitset1 | bitset2) == bitset2; |
| 508 } |
| 509 |
505 static int Glb(TypeImpl* type); // greatest lower bound that's a bitset | 510 static int Glb(TypeImpl* type); // greatest lower bound that's a bitset |
506 static int Lub(TypeImpl* type); // least upper bound that's a bitset | 511 static int Lub(TypeImpl* type); // least upper bound that's a bitset |
507 static int Lub(i::Object* value); | 512 static int Lub(i::Object* value); |
508 static int Lub(double value); | 513 static int Lub(double value); |
509 static int Lub(int32_t value); | 514 static int Lub(int32_t value); |
510 static int Lub(uint32_t value); | 515 static int Lub(uint32_t value); |
511 static int Lub(i::Map* map); | 516 static int Lub(i::Map* map); |
512 static int InherentLub(TypeImpl* type); | 517 static int InherentLub(TypeImpl* type); |
513 | 518 |
514 static const char* Name(int bitset); | 519 static const char* Name(int bitset); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 : this->Get(0); | 610 : this->Get(0); |
606 } | 611 } |
607 i::Handle<i::Map> Map() { | 612 i::Handle<i::Map> Map() { |
608 return Config::is_class(this) | 613 return Config::is_class(this) |
609 ? Config::as_class(this) | 614 ? Config::as_class(this) |
610 : this->template GetValue<i::Map>(1); | 615 : this->template GetValue<i::Map>(1); |
611 } | 616 } |
612 | 617 |
613 static ClassHandle New( | 618 static ClassHandle New( |
614 i::Handle<i::Map> map, TypeHandle bound, Region* region) { | 619 i::Handle<i::Map> map, TypeHandle bound, Region* region) { |
| 620 ASSERT(BitsetType::Is(bound->AsBitset(), BitsetType::Lub(*map))); |
615 ClassHandle type = Config::template cast<ClassType>( | 621 ClassHandle type = Config::template cast<ClassType>( |
616 StructuralType::New(StructuralType::kClassTag, 2, region)); | 622 StructuralType::New(StructuralType::kClassTag, 2, region)); |
617 type->Set(0, bound); | 623 type->Set(0, bound); |
618 type->SetValue(1, map); | 624 type->SetValue(1, map); |
619 return type; | 625 return type; |
620 } | 626 } |
621 | 627 |
622 static ClassHandle New(i::Handle<i::Map> map, Region* region) { | 628 static ClassHandle New(i::Handle<i::Map> map, Region* region) { |
623 ClassHandle type = | 629 ClassHandle type = |
624 Config::template cast<ClassType>(Config::from_class(map, region)); | 630 Config::template cast<ClassType>(Config::from_class(map, region)); |
(...skipping 16 matching lines...) Expand all Loading... |
641 // Constant types. | 647 // Constant types. |
642 | 648 |
643 template<class Config> | 649 template<class Config> |
644 class TypeImpl<Config>::ConstantType : public StructuralType { | 650 class TypeImpl<Config>::ConstantType : public StructuralType { |
645 public: | 651 public: |
646 TypeHandle Bound() { return this->Get(0); } | 652 TypeHandle Bound() { return this->Get(0); } |
647 i::Handle<i::Object> Value() { return this->template GetValue<i::Object>(1); } | 653 i::Handle<i::Object> Value() { return this->template GetValue<i::Object>(1); } |
648 | 654 |
649 static ConstantHandle New( | 655 static ConstantHandle New( |
650 i::Handle<i::Object> value, TypeHandle bound, Region* region) { | 656 i::Handle<i::Object> value, TypeHandle bound, Region* region) { |
| 657 ASSERT(BitsetType::Is(bound->AsBitset(), BitsetType::Lub(*value))); |
651 ConstantHandle type = Config::template cast<ConstantType>( | 658 ConstantHandle type = Config::template cast<ConstantType>( |
652 StructuralType::New(StructuralType::kConstantTag, 2, region)); | 659 StructuralType::New(StructuralType::kConstantTag, 2, region)); |
653 type->Set(0, bound); | 660 type->Set(0, bound); |
654 type->SetValue(1, value); | 661 type->SetValue(1, value); |
655 return type; | 662 return type; |
656 } | 663 } |
657 | 664 |
658 static ConstantHandle New(i::Handle<i::Object> value, Region* region) { | 665 static ConstantHandle New(i::Handle<i::Object> value, Region* region) { |
659 TypeHandle bound = BitsetType::New(BitsetType::Lub(*value), region); | 666 TypeHandle bound = BitsetType::New(BitsetType::Lub(*value), region); |
660 return New(value, bound, region); | 667 return New(value, bound, region); |
(...skipping 11 matching lines...) Expand all Loading... |
672 | 679 |
673 template<class Config> | 680 template<class Config> |
674 class TypeImpl<Config>::RangeType : public StructuralType { | 681 class TypeImpl<Config>::RangeType : public StructuralType { |
675 public: | 682 public: |
676 TypeHandle Bound() { return this->Get(0); } | 683 TypeHandle Bound() { return this->Get(0); } |
677 double Min() { return this->template GetValue<i::HeapNumber>(1)->value(); } | 684 double Min() { return this->template GetValue<i::HeapNumber>(1)->value(); } |
678 double Max() { return this->template GetValue<i::HeapNumber>(2)->value(); } | 685 double Max() { return this->template GetValue<i::HeapNumber>(2)->value(); } |
679 | 686 |
680 static RangeHandle New( | 687 static RangeHandle New( |
681 double min, double max, TypeHandle bound, Region* region) { | 688 double min, double max, TypeHandle bound, Region* region) { |
682 ASSERT(SEMANTIC(bound->AsBitset() | BitsetType::kNumber) | 689 ASSERT(BitsetType::Is(bound->AsBitset(), BitsetType::kNumber)); |
683 == SEMANTIC(BitsetType::kNumber)); | |
684 ASSERT(!std::isnan(min) && !std::isnan(max) && min <= max); | 690 ASSERT(!std::isnan(min) && !std::isnan(max) && min <= max); |
685 RangeHandle type = Config::template cast<RangeType>( | 691 RangeHandle type = Config::template cast<RangeType>( |
686 StructuralType::New(StructuralType::kRangeTag, 3, region)); | 692 StructuralType::New(StructuralType::kRangeTag, 3, region)); |
687 type->Set(0, bound); | 693 type->Set(0, bound); |
688 Factory* factory = Config::isolate(region)->factory(); | 694 Factory* factory = Config::isolate(region)->factory(); |
689 Handle<HeapNumber> minV = factory->NewHeapNumber(min); | 695 Handle<HeapNumber> minV = factory->NewHeapNumber(min); |
690 Handle<HeapNumber> maxV = factory->NewHeapNumber(max); | 696 Handle<HeapNumber> maxV = factory->NewHeapNumber(max); |
691 type->SetValue(1, minV); | 697 type->SetValue(1, minV); |
692 type->SetValue(2, maxV); | 698 type->SetValue(2, maxV); |
693 return type; | 699 return type; |
(...skipping 14 matching lines...) Expand all Loading... |
708 // ----------------------------------------------------------------------------- | 714 // ----------------------------------------------------------------------------- |
709 // Context types. | 715 // Context types. |
710 | 716 |
711 template<class Config> | 717 template<class Config> |
712 class TypeImpl<Config>::ContextType : public StructuralType { | 718 class TypeImpl<Config>::ContextType : public StructuralType { |
713 public: | 719 public: |
714 TypeHandle Bound() { return this->Get(0); } | 720 TypeHandle Bound() { return this->Get(0); } |
715 TypeHandle Outer() { return this->Get(1); } | 721 TypeHandle Outer() { return this->Get(1); } |
716 | 722 |
717 static ContextHandle New(TypeHandle outer, TypeHandle bound, Region* region) { | 723 static ContextHandle New(TypeHandle outer, TypeHandle bound, Region* region) { |
| 724 ASSERT(BitsetType::Is( |
| 725 bound->AsBitset(), BitsetType::kInternal & BitsetType::kTaggedPtr)); |
718 ContextHandle type = Config::template cast<ContextType>( | 726 ContextHandle type = Config::template cast<ContextType>( |
719 StructuralType::New(StructuralType::kContextTag, 2, region)); | 727 StructuralType::New(StructuralType::kContextTag, 2, region)); |
720 type->Set(0, bound); | 728 type->Set(0, bound); |
721 type->Set(1, outer); | 729 type->Set(1, outer); |
722 return type; | 730 return type; |
723 } | 731 } |
724 | 732 |
725 static ContextHandle New(TypeHandle outer, Region* region) { | 733 static ContextHandle New(TypeHandle outer, Region* region) { |
726 TypeHandle bound = BitsetType::New( | 734 TypeHandle bound = BitsetType::New( |
727 BitsetType::kInternal & BitsetType::kTaggedPtr, region); | 735 BitsetType::kInternal & BitsetType::kTaggedPtr, region); |
(...skipping 10 matching lines...) Expand all Loading... |
738 // ----------------------------------------------------------------------------- | 746 // ----------------------------------------------------------------------------- |
739 // Array types. | 747 // Array types. |
740 | 748 |
741 template<class Config> | 749 template<class Config> |
742 class TypeImpl<Config>::ArrayType : public StructuralType { | 750 class TypeImpl<Config>::ArrayType : public StructuralType { |
743 public: | 751 public: |
744 TypeHandle Bound() { return this->Get(0); } | 752 TypeHandle Bound() { return this->Get(0); } |
745 TypeHandle Element() { return this->Get(1); } | 753 TypeHandle Element() { return this->Get(1); } |
746 | 754 |
747 static ArrayHandle New(TypeHandle element, TypeHandle bound, Region* region) { | 755 static ArrayHandle New(TypeHandle element, TypeHandle bound, Region* region) { |
748 ASSERT(SEMANTIC(bound->AsBitset()) == SEMANTIC(BitsetType::kArray)); | 756 ASSERT(BitsetType::Is(bound->AsBitset(), BitsetType::kArray)); |
749 ArrayHandle type = Config::template cast<ArrayType>( | 757 ArrayHandle type = Config::template cast<ArrayType>( |
750 StructuralType::New(StructuralType::kArrayTag, 2, region)); | 758 StructuralType::New(StructuralType::kArrayTag, 2, region)); |
751 type->Set(0, bound); | 759 type->Set(0, bound); |
752 type->Set(1, element); | 760 type->Set(1, element); |
753 return type; | 761 return type; |
754 } | 762 } |
755 | 763 |
756 static ArrayHandle New(TypeHandle element, Region* region) { | 764 static ArrayHandle New(TypeHandle element, Region* region) { |
757 TypeHandle bound = BitsetType::New(BitsetType::kArray, region); | 765 TypeHandle bound = BitsetType::New(BitsetType::kArray, region); |
758 return New(element, bound, region); | 766 return New(element, bound, region); |
(...skipping 16 matching lines...) Expand all Loading... |
775 TypeHandle Bound() { return this->Get(0); } | 783 TypeHandle Bound() { return this->Get(0); } |
776 TypeHandle Result() { return this->Get(1); } | 784 TypeHandle Result() { return this->Get(1); } |
777 TypeHandle Receiver() { return this->Get(2); } | 785 TypeHandle Receiver() { return this->Get(2); } |
778 TypeHandle Parameter(int i) { return this->Get(3 + i); } | 786 TypeHandle Parameter(int i) { return this->Get(3 + i); } |
779 | 787 |
780 void InitParameter(int i, TypeHandle type) { this->Set(3 + i, type); } | 788 void InitParameter(int i, TypeHandle type) { this->Set(3 + i, type); } |
781 | 789 |
782 static FunctionHandle New( | 790 static FunctionHandle New( |
783 TypeHandle result, TypeHandle receiver, TypeHandle bound, | 791 TypeHandle result, TypeHandle receiver, TypeHandle bound, |
784 int arity, Region* region) { | 792 int arity, Region* region) { |
785 ASSERT(SEMANTIC(bound->AsBitset()) == SEMANTIC(BitsetType::kFunction)); | 793 ASSERT(BitsetType::Is(bound->AsBitset(), BitsetType::kFunction)); |
786 FunctionHandle type = Config::template cast<FunctionType>( | 794 FunctionHandle type = Config::template cast<FunctionType>( |
787 StructuralType::New(StructuralType::kFunctionTag, 3 + arity, region)); | 795 StructuralType::New(StructuralType::kFunctionTag, 3 + arity, region)); |
788 type->Set(0, bound); | 796 type->Set(0, bound); |
789 type->Set(1, result); | 797 type->Set(1, result); |
790 type->Set(2, receiver); | 798 type->Set(2, receiver); |
791 return type; | 799 return type; |
792 } | 800 } |
793 | 801 |
794 static FunctionHandle New( | 802 static FunctionHandle New( |
795 TypeHandle result, TypeHandle receiver, int arity, Region* region) { | 803 TypeHandle result, TypeHandle receiver, int arity, Region* region) { |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
983 bool Narrows(BoundsImpl that) { | 991 bool Narrows(BoundsImpl that) { |
984 return that.lower->Is(this->lower) && this->upper->Is(that.upper); | 992 return that.lower->Is(this->lower) && this->upper->Is(that.upper); |
985 } | 993 } |
986 }; | 994 }; |
987 | 995 |
988 typedef BoundsImpl<ZoneTypeConfig> Bounds; | 996 typedef BoundsImpl<ZoneTypeConfig> Bounds; |
989 | 997 |
990 } } // namespace v8::internal | 998 } } // namespace v8::internal |
991 | 999 |
992 #endif // V8_TYPES_H_ | 1000 #endif // V8_TYPES_H_ |
OLD | NEW |