Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: src/types.cc

Issue 882063002: [turbofan] Use unboxed doubles in range types. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Make tests less fragile. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/types.h ('k') | src/types-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include <iomanip> 5 #include <iomanip>
6 6
7 #include "src/types.h" 7 #include "src/types.h"
8 8
9 #include "src/ostreams.h" 9 #include "src/ostreams.h"
10 #include "src/types-inl.h" 10 #include "src/types-inl.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 14
15 15
16 // NOTE: If code is marked as being a "shortcut", this means that removing 16 // NOTE: If code is marked as being a "shortcut", this means that removing
17 // the code won't affect the semantics of the surrounding function definition. 17 // the code won't affect the semantics of the surrounding function definition.
18 18
19 19
20 // ----------------------------------------------------------------------------- 20 // -----------------------------------------------------------------------------
21 // Range-related helper functions. 21 // Range-related helper functions.
22 22
23 // The result may be invalid (max < min). 23 // The result may be invalid (max < min).
24 template<class Config> 24 template<class Config>
25 typename TypeImpl<Config>::Limits TypeImpl<Config>::Intersect( 25 typename TypeImpl<Config>::Limits TypeImpl<Config>::Intersect(
26 Limits lhs, Limits rhs) { 26 Limits lhs, Limits rhs) {
27 DisallowHeapAllocation no_allocation; 27 DisallowHeapAllocation no_allocation;
28 Limits result(lhs); 28 Limits result(lhs);
29 if (lhs.min->Number() < rhs.min->Number()) result.min = rhs.min; 29 if (lhs.min < rhs.min) result.min = rhs.min;
30 if (lhs.max->Number() > rhs.max->Number()) result.max = rhs.max; 30 if (lhs.max > rhs.max) result.max = rhs.max;
31 result.representation = lhs.representation & rhs.representation; 31 result.representation = lhs.representation & rhs.representation;
32 return result; 32 return result;
33 } 33 }
34 34
35 35
36 template <class Config> 36 template <class Config>
37 bool TypeImpl<Config>::IsEmpty(Limits lim) { 37 bool TypeImpl<Config>::IsEmpty(Limits lim) {
38 return lim.min->Number() > lim.max->Number(); 38 return lim.min > lim.max;
39 } 39 }
40 40
41 41
42 template <class Config> 42 template <class Config>
43 typename TypeImpl<Config>::Limits TypeImpl<Config>::Union(Limits lhs, 43 typename TypeImpl<Config>::Limits TypeImpl<Config>::Union(Limits lhs,
44 Limits rhs) { 44 Limits rhs) {
45 DisallowHeapAllocation no_allocation; 45 DisallowHeapAllocation no_allocation;
46 Limits result(lhs); 46 Limits result(lhs);
47 if (lhs.min->Number() > rhs.min->Number()) result.min = rhs.min; 47 if (lhs.min > rhs.min) result.min = rhs.min;
48 if (lhs.max->Number() < rhs.max->Number()) result.max = rhs.max; 48 if (lhs.max < rhs.max) result.max = rhs.max;
49 result.representation = lhs.representation | rhs.representation; 49 result.representation = lhs.representation | rhs.representation;
50 return result; 50 return result;
51 } 51 }
52 52
53 53
54 template<class Config> 54 template<class Config>
55 bool TypeImpl<Config>::Overlap( 55 bool TypeImpl<Config>::Overlap(
56 typename TypeImpl<Config>::RangeType* lhs, 56 typename TypeImpl<Config>::RangeType* lhs,
57 typename TypeImpl<Config>::RangeType* rhs) { 57 typename TypeImpl<Config>::RangeType* rhs) {
58 DisallowHeapAllocation no_allocation; 58 DisallowHeapAllocation no_allocation;
59 typename TypeImpl<Config>::Limits lim = Intersect(Limits(lhs), Limits(rhs)); 59 typename TypeImpl<Config>::Limits lim = Intersect(Limits(lhs), Limits(rhs));
60 return lim.min->Number() <= lim.max->Number(); 60 return lim.min <= lim.max;
61 } 61 }
62 62
63 63
64 template<class Config> 64 template<class Config>
65 bool TypeImpl<Config>::Contains( 65 bool TypeImpl<Config>::Contains(
66 typename TypeImpl<Config>::RangeType* lhs, 66 typename TypeImpl<Config>::RangeType* lhs,
67 typename TypeImpl<Config>::RangeType* rhs) { 67 typename TypeImpl<Config>::RangeType* rhs) {
68 DisallowHeapAllocation no_allocation; 68 DisallowHeapAllocation no_allocation;
69 return rhs->Bound()->Is(lhs->Bound()) && 69 return BitsetType::Is(rhs->Bound(), lhs->Bound()) &&
70 lhs->Min()->Number() <= rhs->Min()->Number() && 70 lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max();
71 rhs->Max()->Number() <= lhs->Max()->Number();
72 } 71 }
73 72
74 73
75 template <class Config> 74 template <class Config>
76 bool TypeImpl<Config>::Contains(typename TypeImpl<Config>::RangeType* lhs, 75 bool TypeImpl<Config>::Contains(typename TypeImpl<Config>::RangeType* lhs,
77 typename TypeImpl<Config>::ConstantType* rhs) { 76 typename TypeImpl<Config>::ConstantType* rhs) {
78 DisallowHeapAllocation no_allocation; 77 DisallowHeapAllocation no_allocation;
79 return IsInteger(*rhs->Value()) && rhs->Bound()->Is(lhs->Bound()) && 78 return IsInteger(*rhs->Value()) &&
80 lhs->Min()->Number() <= rhs->Value()->Number() && 79 BitsetType::Is(rhs->Bound()->AsBitset(), lhs->Bound()) &&
81 rhs->Value()->Number() <= lhs->Max()->Number(); 80 lhs->Min() <= rhs->Value()->Number() &&
81 rhs->Value()->Number() <= lhs->Max();
82 } 82 }
83 83
84 84
85 template<class Config> 85 template<class Config>
86 bool TypeImpl<Config>::Contains( 86 bool TypeImpl<Config>::Contains(
87 typename TypeImpl<Config>::RangeType* range, i::Object* val) { 87 typename TypeImpl<Config>::RangeType* range, i::Object* val) {
88 DisallowHeapAllocation no_allocation; 88 DisallowHeapAllocation no_allocation;
89 return IsInteger(val) && 89 return IsInteger(val) &&
90 BitsetType::Is(BitsetType::Lub(val), range->Bound()->AsBitset()) && 90 BitsetType::Is(BitsetType::Lub(val), range->Bound()) &&
91 range->Min()->Number() <= val->Number() && 91 range->Min() <= val->Number() && val->Number() <= range->Max();
92 val->Number() <= range->Max()->Number();
93 } 92 }
94 93
95 94
96 // ----------------------------------------------------------------------------- 95 // -----------------------------------------------------------------------------
97 // Min and Max computation. 96 // Min and Max computation.
98 97
99 template<class Config> 98 template<class Config>
100 double TypeImpl<Config>::Min() { 99 double TypeImpl<Config>::Min() {
101 DCHECK(this->Is(Number())); 100 DCHECK(this->Is(Number()));
102 if (this->IsBitset()) return BitsetType::Min(this->AsBitset()); 101 if (this->IsBitset()) return BitsetType::Min(this->AsBitset());
103 if (this->IsUnion()) { 102 if (this->IsUnion()) {
104 double min = +V8_INFINITY; 103 double min = +V8_INFINITY;
105 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { 104 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
106 min = std::min(min, this->AsUnion()->Get(i)->Min()); 105 min = std::min(min, this->AsUnion()->Get(i)->Min());
107 } 106 }
108 return min; 107 return min;
109 } 108 }
110 if (this->IsRange()) return this->AsRange()->Min()->Number(); 109 if (this->IsRange()) return this->AsRange()->Min();
111 if (this->IsConstant()) return this->AsConstant()->Value()->Number(); 110 if (this->IsConstant()) return this->AsConstant()->Value()->Number();
112 UNREACHABLE(); 111 UNREACHABLE();
113 return 0; 112 return 0;
114 } 113 }
115 114
116 115
117 template<class Config> 116 template<class Config>
118 double TypeImpl<Config>::Max() { 117 double TypeImpl<Config>::Max() {
119 DCHECK(this->Is(Number())); 118 DCHECK(this->Is(Number()));
120 if (this->IsBitset()) return BitsetType::Max(this->AsBitset()); 119 if (this->IsBitset()) return BitsetType::Max(this->AsBitset());
121 if (this->IsUnion()) { 120 if (this->IsUnion()) {
122 double max = -V8_INFINITY; 121 double max = -V8_INFINITY;
123 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { 122 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
124 max = std::max(max, this->AsUnion()->Get(i)->Max()); 123 max = std::max(max, this->AsUnion()->Get(i)->Max());
125 } 124 }
126 return max; 125 return max;
127 } 126 }
128 if (this->IsRange()) return this->AsRange()->Max()->Number(); 127 if (this->IsRange()) return this->AsRange()->Max();
129 if (this->IsConstant()) return this->AsConstant()->Value()->Number(); 128 if (this->IsConstant()) return this->AsConstant()->Value()->Number();
130 UNREACHABLE(); 129 UNREACHABLE();
131 return 0; 130 return 0;
132 } 131 }
133 132
134 133
135 // ----------------------------------------------------------------------------- 134 // -----------------------------------------------------------------------------
136 // Glb and lub computation. 135 // Glb and lub computation.
137 136
138 137
139 // The largest bitset subsumed by this type. 138 // The largest bitset subsumed by this type.
140 template<class Config> 139 template<class Config>
141 typename TypeImpl<Config>::bitset 140 typename TypeImpl<Config>::bitset
142 TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) { 141 TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) {
143 DisallowHeapAllocation no_allocation; 142 DisallowHeapAllocation no_allocation;
144 if (type->IsBitset()) { 143 if (type->IsBitset()) {
145 return type->AsBitset(); 144 return type->AsBitset();
146 } else if (type->IsUnion()) { 145 } else if (type->IsUnion()) {
147 SLOW_DCHECK(type->AsUnion()->Wellformed()); 146 SLOW_DCHECK(type->AsUnion()->Wellformed());
148 return type->AsUnion()->Get(0)->BitsetGlb() | 147 return type->AsUnion()->Get(0)->BitsetGlb() |
149 type->AsUnion()->Get(1)->BitsetGlb(); // Shortcut. 148 type->AsUnion()->Get(1)->BitsetGlb(); // Shortcut.
150 } else if (type->IsRange()) { 149 } else if (type->IsRange()) {
151 bitset glb = SEMANTIC(BitsetType::Glb(type->AsRange()->Min()->Number(), 150 bitset glb = SEMANTIC(
152 type->AsRange()->Max()->Number())); 151 BitsetType::Glb(type->AsRange()->Min(), type->AsRange()->Max()));
153 if (glb == 0) { 152 if (glb == 0) {
154 return kNone; 153 return kNone;
155 } else { 154 } else {
156 return glb | REPRESENTATION(type->BitsetLub()); 155 return glb | REPRESENTATION(type->BitsetLub());
157 } 156 }
158 } else { 157 } else {
159 // (The remaining BitsetGlb's are None anyway). 158 // (The remaining BitsetGlb's are None anyway).
160 return kNone; 159 return kNone;
161 } 160 }
162 } 161 }
(...skipping 11 matching lines...) Expand all
174 bitset |= type->AsUnion()->Get(i)->BitsetLub(); 173 bitset |= type->AsUnion()->Get(i)->BitsetLub();
175 } 174 }
176 return bitset; 175 return bitset;
177 } 176 }
178 if (type->IsClass()) { 177 if (type->IsClass()) {
179 // Little hack to avoid the need for a region for handlification here... 178 // Little hack to avoid the need for a region for handlification here...
180 return Config::is_class(type) ? Lub(*Config::as_class(type)) : 179 return Config::is_class(type) ? Lub(*Config::as_class(type)) :
181 type->AsClass()->Bound(NULL)->AsBitset(); 180 type->AsClass()->Bound(NULL)->AsBitset();
182 } 181 }
183 if (type->IsConstant()) return type->AsConstant()->Bound()->AsBitset(); 182 if (type->IsConstant()) return type->AsConstant()->Bound()->AsBitset();
184 if (type->IsRange()) return type->AsRange()->Bound()->AsBitset(); 183 if (type->IsRange()) return type->AsRange()->Bound();
185 if (type->IsContext()) return kInternal & kTaggedPointer; 184 if (type->IsContext()) return kInternal & kTaggedPointer;
186 if (type->IsArray()) return kArray; 185 if (type->IsArray()) return kArray;
187 if (type->IsFunction()) return kOtherObject; // TODO(rossberg): kFunction 186 if (type->IsFunction()) return kOtherObject; // TODO(rossberg): kFunction
188 UNREACHABLE(); 187 UNREACHABLE();
189 return kNone; 188 return kNone;
190 } 189 }
191 190
192 191
193 template<class Config> 192 template<class Config>
194 typename TypeImpl<Config>::bitset 193 typename TypeImpl<Config>::bitset
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 template <class Config> 757 template <class Config>
759 typename TypeImpl<Config>::Limits TypeImpl<Config>::ToLimits(bitset bits, 758 typename TypeImpl<Config>::Limits TypeImpl<Config>::ToLimits(bitset bits,
760 Region* region) { 759 Region* region) {
761 bitset representation = REPRESENTATION(bits); 760 bitset representation = REPRESENTATION(bits);
762 bitset number_bits = BitsetType::NumberBits(bits); 761 bitset number_bits = BitsetType::NumberBits(bits);
763 762
764 if (representation == BitsetType::kNone && number_bits == BitsetType::kNone) { 763 if (representation == BitsetType::kNone && number_bits == BitsetType::kNone) {
765 return Limits::Empty(region); 764 return Limits::Empty(region);
766 } 765 }
767 766
768 double bitset_min = BitsetType::Min(number_bits); 767 return Limits(BitsetType::Min(number_bits), BitsetType::Max(number_bits),
769 double bitset_max = BitsetType::Max(number_bits);
770
771 // TODO(jarin) Get rid of the heap numbers.
772 i::Factory* f = i::Isolate::Current()->factory();
773
774 return Limits(f->NewNumber(bitset_min), f->NewNumber(bitset_max),
775 representation); 768 representation);
776 } 769 }
777 770
778 771
779 template <class Config> 772 template <class Config>
780 typename TypeImpl<Config>::Limits TypeImpl<Config>::IntersectRangeAndBitset( 773 typename TypeImpl<Config>::Limits TypeImpl<Config>::IntersectRangeAndBitset(
781 TypeHandle range, TypeHandle bitset, Region* region) { 774 TypeHandle range, TypeHandle bitset, Region* region) {
782 Limits range_lims(range->AsRange()); 775 Limits range_lims(range->AsRange());
783 Limits bitset_lims = ToLimits(bitset->AsBitset(), region); 776 Limits bitset_lims = ToLimits(bitset->AsBitset(), region);
784 return Intersect(range_lims, bitset_lims); 777 return Intersect(range_lims, bitset_lims);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
867 bitset range_lub = range->BitsetLub(); 860 bitset range_lub = range->BitsetLub();
868 if (BitsetType::Is(BitsetType::NumberBits(range_lub), *bits)) { 861 if (BitsetType::Is(BitsetType::NumberBits(range_lub), *bits)) {
869 *bits |= range_lub; 862 *bits |= range_lub;
870 return None(region); 863 return None(region);
871 } 864 }
872 865
873 // Slow path: reconcile the bitset range and the range. 866 // Slow path: reconcile the bitset range and the range.
874 double bitset_min = BitsetType::Min(number_bits); 867 double bitset_min = BitsetType::Min(number_bits);
875 double bitset_max = BitsetType::Max(number_bits); 868 double bitset_max = BitsetType::Max(number_bits);
876 869
877 i::Handle<i::Object> range_min_obj = range->Min(); 870 double range_min = range->Min();
878 i::Handle<i::Object> range_max_obj = range->Max(); 871 double range_max = range->Max();
879 double range_min = range_min_obj->Number();
880 double range_max = range_max_obj->Number();
881 872
882 bitset range_representation = REPRESENTATION(range->BitsetLub()); 873 bitset range_representation = REPRESENTATION(range->BitsetLub());
883 bitset bits_representation = REPRESENTATION(*bits); 874 bitset bits_representation = REPRESENTATION(*bits);
884 bitset representation = 875 bitset representation =
885 (bits_representation | range_representation) & BitsetType::kNumber; 876 (bits_representation | range_representation) & BitsetType::kNumber;
886 877
887 // Remove the number bits from the bitset, they would just confuse us now. 878 // Remove the number bits from the bitset, they would just confuse us now.
888 *bits &= ~number_bits; 879 *bits &= ~number_bits;
889 if (bits_representation == *bits) { 880 if (bits_representation == *bits) {
890 *bits = BitsetType::kNone; 881 *bits = BitsetType::kNone;
891 } 882 }
892 883
893 if (representation == range_representation && range_min <= bitset_min && 884 if (representation == range_representation && range_min <= bitset_min &&
894 range_max >= bitset_max) { 885 range_max >= bitset_max) {
895 // Bitset is contained within the range, just return the range. 886 // Bitset is contained within the range, just return the range.
896 return range; 887 return range;
897 } 888 }
898 889
899 if (bitset_min < range_min) { 890 if (bitset_min < range_min) {
900 // TODO(jarin) Get rid of the heap numbers. 891 range_min = bitset_min;
901 range_min_obj = i::Isolate::Current()->factory()->NewNumber(bitset_min);
902 } 892 }
903 if (bitset_max > range_max) { 893 if (bitset_max > range_max) {
904 // TODO(jarin) Get rid of the heap numbers. 894 range_max = bitset_max;
905 range_max_obj = i::Isolate::Current()->factory()->NewNumber(bitset_max);
906 } 895 }
907 return RangeType::New(range_min_obj, range_max_obj, 896 return RangeType::New(range_min, range_max,
908 BitsetType::New(representation, region), region); 897 BitsetType::New(representation, region), region);
909 } 898 }
910 899
911 900
912 template<class Config> 901 template<class Config>
913 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union( 902 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
914 TypeHandle type1, TypeHandle type2, Region* region) { 903 TypeHandle type1, TypeHandle type2, Region* region) {
915 904
916 // Fast case: bit sets. 905 // Fast case: bit sets.
917 if (type1->IsBitset() && type2->IsBitset()) { 906 if (type1->IsBitset() && type2->IsBitset()) {
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
1220 BitsetType::Print(os, SEMANTIC(this->AsBitset())); 1209 BitsetType::Print(os, SEMANTIC(this->AsBitset()));
1221 } else if (this->IsClass()) { 1210 } else if (this->IsClass()) {
1222 os << "Class(" << static_cast<void*>(*this->AsClass()->Map()) << " < "; 1211 os << "Class(" << static_cast<void*>(*this->AsClass()->Map()) << " < ";
1223 BitsetType::New(BitsetType::Lub(this))->PrintTo(os, dim); 1212 BitsetType::New(BitsetType::Lub(this))->PrintTo(os, dim);
1224 os << ")"; 1213 os << ")";
1225 } else if (this->IsConstant()) { 1214 } else if (this->IsConstant()) {
1226 os << "Constant(" << Brief(*this->AsConstant()->Value()) << ")"; 1215 os << "Constant(" << Brief(*this->AsConstant()->Value()) << ")";
1227 } else if (this->IsRange()) { 1216 } else if (this->IsRange()) {
1228 std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed); 1217 std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed);
1229 std::streamsize saved_precision = os.precision(0); 1218 std::streamsize saved_precision = os.precision(0);
1230 os << "Range(" << this->AsRange()->Min()->Number() << ", " 1219 os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max()
1231 << this->AsRange()->Max()->Number() << ")"; 1220 << ")";
1232 os.flags(saved_flags); 1221 os.flags(saved_flags);
1233 os.precision(saved_precision); 1222 os.precision(saved_precision);
1234 } else if (this->IsContext()) { 1223 } else if (this->IsContext()) {
1235 os << "Context("; 1224 os << "Context(";
1236 this->AsContext()->Outer()->PrintTo(os, dim); 1225 this->AsContext()->Outer()->PrintTo(os, dim);
1237 os << ")"; 1226 os << ")";
1238 } else if (this->IsUnion()) { 1227 } else if (this->IsUnion()) {
1239 os << "("; 1228 os << "(";
1240 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { 1229 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
1241 TypeHandle type_i = this->AsUnion()->Get(i); 1230 TypeHandle type_i = this->AsUnion()->Get(i);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1298 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; 1287 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>;
1299 1288
1300 template TypeImpl<ZoneTypeConfig>::TypeHandle 1289 template TypeImpl<ZoneTypeConfig>::TypeHandle
1301 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( 1290 TypeImpl<ZoneTypeConfig>::Convert<HeapType>(
1302 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); 1291 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*);
1303 template TypeImpl<HeapTypeConfig>::TypeHandle 1292 template TypeImpl<HeapTypeConfig>::TypeHandle
1304 TypeImpl<HeapTypeConfig>::Convert<Type>( 1293 TypeImpl<HeapTypeConfig>::Convert<Type>(
1305 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); 1294 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*);
1306 1295
1307 } } // namespace v8::internal 1296 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/types.h ('k') | src/types-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698