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