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 #include "src/bootstrapper.h" | 5 #include "src/bootstrapper.h" |
6 #include "src/compiler/graph-inl.h" | 6 #include "src/compiler/graph-inl.h" |
7 #include "src/compiler/graph-reducer.h" | 7 #include "src/compiler/graph-reducer.h" |
8 #include "src/compiler/js-operator.h" | 8 #include "src/compiler/js-operator.h" |
9 #include "src/compiler/node.h" | 9 #include "src/compiler/node.h" |
10 #include "src/compiler/node-properties-inl.h" | 10 #include "src/compiler/node-properties-inl.h" |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 return Type::Intersect(semantic, representation, zone()); | 122 return Type::Intersect(semantic, representation, zone()); |
123 } | 123 } |
124 | 124 |
125 template <typename T> | 125 template <typename T> |
126 Type* CreateRange() const { | 126 Type* CreateRange() const { |
127 return CreateRange(std::numeric_limits<T>::min(), | 127 return CreateRange(std::numeric_limits<T>::min(), |
128 std::numeric_limits<T>::max()); | 128 std::numeric_limits<T>::max()); |
129 } | 129 } |
130 | 130 |
131 Type* CreateRange(double min, double max) const { | 131 Type* CreateRange(double min, double max) const { |
132 return Type::Range(factory()->NewNumber(min), factory()->NewNumber(max), | 132 return Type::Range(min, max, zone()); |
133 zone()); | |
134 } | 133 } |
135 | 134 |
136 Factory* factory() const { return isolate()->factory(); } | 135 Factory* factory() const { return isolate()->factory(); } |
137 Isolate* isolate() const { return isolate_; } | 136 Isolate* isolate() const { return isolate_; } |
138 Zone* zone() const { return zone_; } | 137 Zone* zone() const { return zone_; } |
139 | 138 |
140 Type* cache_[kNumLazyCachedTypes]; | 139 Type* cache_[kNumLazyCachedTypes]; |
141 Isolate* isolate_; | 140 Isolate* isolate_; |
142 Zone* zone_; | 141 Zone* zone_; |
143 }; | 142 }; |
(...skipping 13 matching lines...) Expand all Loading... |
157 : isolate_(isolate), | 156 : isolate_(isolate), |
158 graph_(graph), | 157 graph_(graph), |
159 context_(context), | 158 context_(context), |
160 decorator_(NULL), | 159 decorator_(NULL), |
161 cache_(new (graph->zone()) LazyTypeCache(isolate, graph->zone())), | 160 cache_(new (graph->zone()) LazyTypeCache(isolate, graph->zone())), |
162 weaken_min_limits_(graph->zone()), | 161 weaken_min_limits_(graph->zone()), |
163 weaken_max_limits_(graph->zone()) { | 162 weaken_max_limits_(graph->zone()) { |
164 Zone* zone = this->zone(); | 163 Zone* zone = this->zone(); |
165 Factory* f = isolate->factory(); | 164 Factory* f = isolate->factory(); |
166 | 165 |
167 Handle<Object> zero = f->NewNumber(0); | |
168 Handle<Object> one = f->NewNumber(1); | |
169 Handle<Object> infinity = f->NewNumber(+V8_INFINITY); | 166 Handle<Object> infinity = f->NewNumber(+V8_INFINITY); |
170 Handle<Object> minusinfinity = f->NewNumber(-V8_INFINITY); | 167 Handle<Object> minusinfinity = f->NewNumber(-V8_INFINITY); |
171 | 168 |
172 Type* number = Type::Number(); | 169 Type* number = Type::Number(); |
173 Type* signed32 = Type::Signed32(); | 170 Type* signed32 = Type::Signed32(); |
174 Type* unsigned32 = Type::Unsigned32(); | 171 Type* unsigned32 = Type::Unsigned32(); |
175 Type* nan_or_minuszero = Type::Union(Type::NaN(), Type::MinusZero(), zone); | 172 Type* nan_or_minuszero = Type::Union(Type::NaN(), Type::MinusZero(), zone); |
176 Type* truncating_to_zero = | 173 Type* truncating_to_zero = |
177 Type::Union(Type::Union(Type::Constant(infinity, zone), | 174 Type::Union(Type::Union(Type::Constant(infinity, zone), |
178 Type::Constant(minusinfinity, zone), zone), | 175 Type::Constant(minusinfinity, zone), zone), |
179 nan_or_minuszero, zone); | 176 nan_or_minuszero, zone); |
180 | 177 |
181 boolean_or_number = Type::Union(Type::Boolean(), Type::Number(), zone); | 178 boolean_or_number = Type::Union(Type::Boolean(), Type::Number(), zone); |
182 undefined_or_null = Type::Union(Type::Undefined(), Type::Null(), zone); | 179 undefined_or_null = Type::Union(Type::Undefined(), Type::Null(), zone); |
183 undefined_or_number = Type::Union(Type::Undefined(), Type::Number(), zone); | 180 undefined_or_number = Type::Union(Type::Undefined(), Type::Number(), zone); |
184 singleton_false = Type::Constant(f->false_value(), zone); | 181 singleton_false = Type::Constant(f->false_value(), zone); |
185 singleton_true = Type::Constant(f->true_value(), zone); | 182 singleton_true = Type::Constant(f->true_value(), zone); |
186 singleton_zero = Type::Range(zero, zero, zone); | 183 singleton_zero = Type::Range(0.0, 0.0, zone); |
187 singleton_one = Type::Range(one, one, zone); | 184 singleton_one = Type::Range(1.0, 1.0, zone); |
188 zero_or_one = Type::Union(singleton_zero, singleton_one, zone); | 185 zero_or_one = Type::Union(singleton_zero, singleton_one, zone); |
189 zeroish = Type::Union(singleton_zero, nan_or_minuszero, zone); | 186 zeroish = Type::Union(singleton_zero, nan_or_minuszero, zone); |
190 signed32ish = Type::Union(signed32, truncating_to_zero, zone); | 187 signed32ish = Type::Union(signed32, truncating_to_zero, zone); |
191 unsigned32ish = Type::Union(unsigned32, truncating_to_zero, zone); | 188 unsigned32ish = Type::Union(unsigned32, truncating_to_zero, zone); |
192 falsish = Type::Union(Type::Undetectable(), | 189 falsish = Type::Union(Type::Undetectable(), |
193 Type::Union(Type::Union(singleton_false, zeroish, zone), | 190 Type::Union(Type::Union(singleton_false, zeroish, zone), |
194 undefined_or_null, zone), | 191 undefined_or_null, zone), |
195 zone); | 192 zone); |
196 truish = Type::Union( | 193 truish = Type::Union( |
197 singleton_true, | 194 singleton_true, |
198 Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone); | 195 Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone); |
199 integer = Type::Range(minusinfinity, infinity, zone); | 196 integer = Type::Range(-V8_INFINITY, V8_INFINITY, zone); |
200 weakint = Type::Union(integer, nan_or_minuszero, zone); | 197 weakint = Type::Union(integer, nan_or_minuszero, zone); |
201 | 198 |
202 number_fun0_ = Type::Function(number, zone); | 199 number_fun0_ = Type::Function(number, zone); |
203 number_fun1_ = Type::Function(number, number, zone); | 200 number_fun1_ = Type::Function(number, number, zone); |
204 number_fun2_ = Type::Function(number, number, number, zone); | 201 number_fun2_ = Type::Function(number, number, number, zone); |
205 | 202 |
206 weakint_fun1_ = Type::Function(weakint, number, zone); | 203 weakint_fun1_ = Type::Function(weakint, number, zone); |
207 random_fun_ = Type::Function(Type::OrderedNumber(), zone); | 204 random_fun_ = Type::Function(Type::OrderedNumber(), zone); |
208 | 205 |
209 const int limits_count = 20; | 206 const int limits_count = 20; |
210 | 207 |
211 weaken_min_limits_.reserve(limits_count + 1); | 208 weaken_min_limits_.reserve(limits_count + 1); |
212 weaken_max_limits_.reserve(limits_count + 1); | 209 weaken_max_limits_.reserve(limits_count + 1); |
213 | 210 |
214 double limit = 1 << 30; | 211 double limit = 1 << 30; |
215 weaken_min_limits_.push_back(f->NewNumber(0)); | 212 weaken_min_limits_.push_back(0); |
216 weaken_max_limits_.push_back(f->NewNumber(0)); | 213 weaken_max_limits_.push_back(0); |
217 for (int i = 0; i < limits_count; i++) { | 214 for (int i = 0; i < limits_count; i++) { |
218 weaken_min_limits_.push_back(f->NewNumber(-limit)); | 215 weaken_min_limits_.push_back(-limit); |
219 weaken_max_limits_.push_back(f->NewNumber(limit - 1)); | 216 weaken_max_limits_.push_back(limit - 1); |
220 limit *= 2; | 217 limit *= 2; |
221 } | 218 } |
222 | 219 |
223 decorator_ = new (zone) Decorator(this); | 220 decorator_ = new (zone) Decorator(this); |
224 graph_->AddDecorator(decorator_); | 221 graph_->AddDecorator(decorator_); |
225 } | 222 } |
226 | 223 |
227 | 224 |
228 Typer::~Typer() { | 225 Typer::~Typer() { |
229 graph_->RemoveDecorator(decorator_); | 226 graph_->RemoveDecorator(decorator_); |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 return type; // Give up on non-integer types. | 486 return type; // Give up on non-integer types. |
490 } | 487 } |
491 double min = type->Min(); | 488 double min = type->Min(); |
492 double max = type->Max(); | 489 double max = type->Max(); |
493 // Handle the degenerate case of empty bitset types (such as | 490 // Handle the degenerate case of empty bitset types (such as |
494 // OtherUnsigned31 and OtherSigned32 on 64-bit architectures). | 491 // OtherUnsigned31 and OtherSigned32 on 64-bit architectures). |
495 if (std::isnan(min)) { | 492 if (std::isnan(min)) { |
496 DCHECK(std::isnan(max)); | 493 DCHECK(std::isnan(max)); |
497 return type; | 494 return type; |
498 } | 495 } |
499 Factory* f = t->isolate()->factory(); | 496 return Type::Range(min, max, t->zone()); |
500 return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone()); | |
501 } | 497 } |
502 | 498 |
503 | 499 |
504 // Type conversion. | 500 // Type conversion. |
505 | 501 |
506 | 502 |
507 Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) { | 503 Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) { |
508 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) { | 504 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) { |
509 return type; | 505 return type; |
510 } | 506 } |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
603 // OSR values explicitly have type {None} before OSR form is deconstructed. | 599 // OSR values explicitly have type {None} before OSR form is deconstructed. |
604 if (node->InputAt(0)->opcode() == IrOpcode::kOsrLoopEntry) { | 600 if (node->InputAt(0)->opcode() == IrOpcode::kOsrLoopEntry) { |
605 return Bounds(Type::None(), Type::None()); | 601 return Bounds(Type::None(), Type::None()); |
606 } | 602 } |
607 // TODO(turbofan): preserve the type of OSR values after deconstruction. | 603 // TODO(turbofan): preserve the type of OSR values after deconstruction. |
608 return Bounds::Unbounded(zone()); | 604 return Bounds::Unbounded(zone()); |
609 } | 605 } |
610 | 606 |
611 | 607 |
612 Bounds Typer::Visitor::TypeInt32Constant(Node* node) { | 608 Bounds Typer::Visitor::TypeInt32Constant(Node* node) { |
613 Factory* f = isolate()->factory(); | 609 double number = OpParameter<int32_t>(node); |
614 Handle<Object> number = f->NewNumber(OpParameter<int32_t>(node)); | |
615 return Bounds(Type::Intersect( | 610 return Bounds(Type::Intersect( |
616 Type::Range(number, number, zone()), Type::UntaggedSigned32(), zone())); | 611 Type::Range(number, number, zone()), Type::UntaggedSigned32(), zone())); |
617 } | 612 } |
618 | 613 |
619 | 614 |
620 Bounds Typer::Visitor::TypeInt64Constant(Node* node) { | 615 Bounds Typer::Visitor::TypeInt64Constant(Node* node) { |
621 // TODO(rossberg): This actually seems to be a PointerConstant so far... | 616 // TODO(rossberg): This actually seems to be a PointerConstant so far... |
622 return Bounds(Type::Internal()); // TODO(rossberg): Add int64 bitset type? | 617 return Bounds(Type::Internal()); // TODO(rossberg): Add int64 bitset type? |
623 } | 618 } |
624 | 619 |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
819 Type* Typer::Visitor::JSGreaterThanOrEqualTyper( | 814 Type* Typer::Visitor::JSGreaterThanOrEqualTyper( |
820 Type* lhs, Type* rhs, Typer* t) { | 815 Type* lhs, Type* rhs, Typer* t) { |
821 return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t); | 816 return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t); |
822 } | 817 } |
823 | 818 |
824 | 819 |
825 // JS bitwise operators. | 820 // JS bitwise operators. |
826 | 821 |
827 | 822 |
828 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) { | 823 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) { |
829 Factory* f = t->isolate()->factory(); | |
830 lhs = NumberToInt32(ToNumber(lhs, t), t); | 824 lhs = NumberToInt32(ToNumber(lhs, t), t); |
831 rhs = NumberToInt32(ToNumber(rhs, t), t); | 825 rhs = NumberToInt32(ToNumber(rhs, t), t); |
832 double lmin = lhs->Min(); | 826 double lmin = lhs->Min(); |
833 double rmin = rhs->Min(); | 827 double rmin = rhs->Min(); |
834 double lmax = lhs->Max(); | 828 double lmax = lhs->Max(); |
835 double rmax = rhs->Max(); | 829 double rmax = rhs->Max(); |
836 // Or-ing any two values results in a value no smaller than their minimum. | 830 // Or-ing any two values results in a value no smaller than their minimum. |
837 // Even no smaller than their maximum if both values are non-negative. | 831 // Even no smaller than their maximum if both values are non-negative. |
838 double min = | 832 double min = |
839 lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin); | 833 lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin); |
840 double max = Type::Signed32()->Max(); | 834 double max = Type::Signed32()->Max(); |
841 | 835 |
842 // Or-ing with 0 is essentially a conversion to int32. | 836 // Or-ing with 0 is essentially a conversion to int32. |
843 if (rmin == 0 && rmax == 0) { | 837 if (rmin == 0 && rmax == 0) { |
844 min = lmin; | 838 min = lmin; |
845 max = lmax; | 839 max = lmax; |
846 } | 840 } |
847 if (lmin == 0 && lmax == 0) { | 841 if (lmin == 0 && lmax == 0) { |
848 min = rmin; | 842 min = rmin; |
849 max = rmax; | 843 max = rmax; |
850 } | 844 } |
851 | 845 |
852 if (lmax < 0 || rmax < 0) { | 846 if (lmax < 0 || rmax < 0) { |
853 // Or-ing two values of which at least one is negative results in a negative | 847 // Or-ing two values of which at least one is negative results in a negative |
854 // value. | 848 // value. |
855 max = std::min(max, -1.0); | 849 max = std::min(max, -1.0); |
856 } | 850 } |
857 return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone()); | 851 return Type::Range(min, max, t->zone()); |
858 // TODO(neis): Be precise for singleton inputs, here and elsewhere. | 852 // TODO(neis): Be precise for singleton inputs, here and elsewhere. |
859 } | 853 } |
860 | 854 |
861 | 855 |
862 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) { | 856 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) { |
863 Factory* f = t->isolate()->factory(); | |
864 lhs = NumberToInt32(ToNumber(lhs, t), t); | 857 lhs = NumberToInt32(ToNumber(lhs, t), t); |
865 rhs = NumberToInt32(ToNumber(rhs, t), t); | 858 rhs = NumberToInt32(ToNumber(rhs, t), t); |
866 double lmin = lhs->Min(); | 859 double lmin = lhs->Min(); |
867 double rmin = rhs->Min(); | 860 double rmin = rhs->Min(); |
868 double lmax = lhs->Max(); | 861 double lmax = lhs->Max(); |
869 double rmax = rhs->Max(); | 862 double rmax = rhs->Max(); |
870 double min = Type::Signed32()->Min(); | 863 double min = Type::Signed32()->Min(); |
871 // And-ing any two values results in a value no larger than their maximum. | 864 // And-ing any two values results in a value no larger than their maximum. |
872 // Even no larger than their minimum if both values are non-negative. | 865 // Even no larger than their minimum if both values are non-negative. |
873 double max = | 866 double max = |
874 lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax); | 867 lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax); |
875 // And-ing with a non-negative value x causes the result to be between | 868 // And-ing with a non-negative value x causes the result to be between |
876 // zero and x. | 869 // zero and x. |
877 if (lmin >= 0) { | 870 if (lmin >= 0) { |
878 min = 0; | 871 min = 0; |
879 max = std::min(max, lmax); | 872 max = std::min(max, lmax); |
880 } | 873 } |
881 if (rmin >= 0) { | 874 if (rmin >= 0) { |
882 min = 0; | 875 min = 0; |
883 max = std::min(max, rmax); | 876 max = std::min(max, rmax); |
884 } | 877 } |
885 return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone()); | 878 return Type::Range(min, max, t->zone()); |
886 } | 879 } |
887 | 880 |
888 | 881 |
889 Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) { | 882 Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) { |
890 lhs = NumberToInt32(ToNumber(lhs, t), t); | 883 lhs = NumberToInt32(ToNumber(lhs, t), t); |
891 rhs = NumberToInt32(ToNumber(rhs, t), t); | 884 rhs = NumberToInt32(ToNumber(rhs, t), t); |
892 double lmin = lhs->Min(); | 885 double lmin = lhs->Min(); |
893 double rmin = rhs->Min(); | 886 double rmin = rhs->Min(); |
894 double lmax = lhs->Max(); | 887 double lmax = lhs->Max(); |
895 double rmax = rhs->Max(); | 888 double rmax = rhs->Max(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
935 if (rhs->Min() > 0 && rhs->Max() <= 31) { | 928 if (rhs->Min() > 0 && rhs->Max() <= 31) { |
936 // Right-shifting by a positive value yields a small integer value. | 929 // Right-shifting by a positive value yields a small integer value. |
937 double shift_min = kMinInt >> static_cast<int>(rhs->Min()); | 930 double shift_min = kMinInt >> static_cast<int>(rhs->Min()); |
938 double shift_max = kMaxInt >> static_cast<int>(rhs->Min()); | 931 double shift_max = kMaxInt >> static_cast<int>(rhs->Min()); |
939 min = std::max(min, shift_min); | 932 min = std::max(min, shift_min); |
940 max = std::min(max, shift_max); | 933 max = std::min(max, shift_max); |
941 } | 934 } |
942 // TODO(jarin) Ideally, the following micro-optimization should be performed | 935 // TODO(jarin) Ideally, the following micro-optimization should be performed |
943 // by the type constructor. | 936 // by the type constructor. |
944 if (max != Type::Signed32()->Max() || min != Type::Signed32()->Min()) { | 937 if (max != Type::Signed32()->Max() || min != Type::Signed32()->Min()) { |
945 Factory* f = t->isolate()->factory(); | 938 return Type::Range(min, max, t->zone()); |
946 return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone()); | |
947 } | 939 } |
948 return Type::Signed32(); | 940 return Type::Signed32(); |
949 } | 941 } |
950 | 942 |
951 | 943 |
952 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) { | 944 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) { |
953 lhs = NumberToUint32(ToNumber(lhs, t), t); | 945 lhs = NumberToUint32(ToNumber(lhs, t), t); |
954 Factory* f = t->isolate()->factory(); | |
955 // Logical right-shifting any value cannot make it larger. | 946 // Logical right-shifting any value cannot make it larger. |
956 Handle<Object> min = f->NewNumber(0); | 947 return Type::Range(0.0, lhs->Max(), t->zone()); |
957 Handle<Object> max = f->NewNumber(lhs->Max()); | |
958 return Type::Range(min, max, t->zone()); | |
959 } | 948 } |
960 | 949 |
961 | 950 |
962 // JS arithmetic operators. | 951 // JS arithmetic operators. |
963 | 952 |
964 | 953 |
965 // Returns the array's least element, ignoring NaN. | 954 // Returns the array's least element, ignoring NaN. |
966 // There must be at least one non-NaN element. | 955 // There must be at least one non-NaN element. |
967 // Any -0 is converted to 0. | 956 // Any -0 is converted to 0. |
968 static double array_min(double a[], size_t n) { | 957 static double array_min(double a[], size_t n) { |
(...skipping 21 matching lines...) Expand all Loading... |
990 } | 979 } |
991 } | 980 } |
992 DCHECK(!std::isnan(x)); | 981 DCHECK(!std::isnan(x)); |
993 return x == 0 ? 0 : x; // -0 -> 0 | 982 return x == 0 ? 0 : x; // -0 -> 0 |
994 } | 983 } |
995 | 984 |
996 | 985 |
997 Type* Typer::Visitor::JSAddRanger(Type::RangeType* lhs, Type::RangeType* rhs, | 986 Type* Typer::Visitor::JSAddRanger(Type::RangeType* lhs, Type::RangeType* rhs, |
998 Typer* t) { | 987 Typer* t) { |
999 double results[4]; | 988 double results[4]; |
1000 results[0] = lhs->Min()->Number() + rhs->Min()->Number(); | 989 results[0] = lhs->Min() + rhs->Min(); |
1001 results[1] = lhs->Min()->Number() + rhs->Max()->Number(); | 990 results[1] = lhs->Min() + rhs->Max(); |
1002 results[2] = lhs->Max()->Number() + rhs->Min()->Number(); | 991 results[2] = lhs->Max() + rhs->Min(); |
1003 results[3] = lhs->Max()->Number() + rhs->Max()->Number(); | 992 results[3] = lhs->Max() + rhs->Max(); |
1004 // Since none of the inputs can be -0, the result cannot be -0 either. | 993 // Since none of the inputs can be -0, the result cannot be -0 either. |
1005 // However, it can be nan (the sum of two infinities of opposite sign). | 994 // However, it can be nan (the sum of two infinities of opposite sign). |
1006 // On the other hand, if none of the "results" above is nan, then the actual | 995 // On the other hand, if none of the "results" above is nan, then the actual |
1007 // result cannot be nan either. | 996 // result cannot be nan either. |
1008 int nans = 0; | 997 int nans = 0; |
1009 for (int i = 0; i < 4; ++i) { | 998 for (int i = 0; i < 4; ++i) { |
1010 if (std::isnan(results[i])) ++nans; | 999 if (std::isnan(results[i])) ++nans; |
1011 } | 1000 } |
1012 if (nans == 4) return Type::NaN(); // [-inf..-inf] + [inf..inf] or vice versa | 1001 if (nans == 4) return Type::NaN(); // [-inf..-inf] + [inf..inf] or vice versa |
1013 Factory* f = t->isolate()->factory(); | 1002 Type* range = |
1014 Type* range = Type::Range(f->NewNumber(array_min(results, 4)), | 1003 Type::Range(array_min(results, 4), array_max(results, 4), t->zone()); |
1015 f->NewNumber(array_max(results, 4)), t->zone()); | |
1016 return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone()); | 1004 return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone()); |
1017 // Examples: | 1005 // Examples: |
1018 // [-inf, -inf] + [+inf, +inf] = NaN | 1006 // [-inf, -inf] + [+inf, +inf] = NaN |
1019 // [-inf, -inf] + [n, +inf] = [-inf, -inf] \/ NaN | 1007 // [-inf, -inf] + [n, +inf] = [-inf, -inf] \/ NaN |
1020 // [-inf, +inf] + [n, +inf] = [-inf, +inf] \/ NaN | 1008 // [-inf, +inf] + [n, +inf] = [-inf, +inf] \/ NaN |
1021 // [-inf, m] + [n, +inf] = [-inf, +inf] \/ NaN | 1009 // [-inf, m] + [n, +inf] = [-inf, +inf] \/ NaN |
1022 } | 1010 } |
1023 | 1011 |
1024 | 1012 |
1025 Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) { | 1013 Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) { |
(...skipping 13 matching lines...) Expand all Loading... |
1039 return JSAddRanger(lhs->AsRange(), rhs->AsRange(), t); | 1027 return JSAddRanger(lhs->AsRange(), rhs->AsRange(), t); |
1040 } | 1028 } |
1041 // TODO(neis): Deal with numeric bitsets here and elsewhere. | 1029 // TODO(neis): Deal with numeric bitsets here and elsewhere. |
1042 return Type::Number(); | 1030 return Type::Number(); |
1043 } | 1031 } |
1044 | 1032 |
1045 | 1033 |
1046 Type* Typer::Visitor::JSSubtractRanger(Type::RangeType* lhs, | 1034 Type* Typer::Visitor::JSSubtractRanger(Type::RangeType* lhs, |
1047 Type::RangeType* rhs, Typer* t) { | 1035 Type::RangeType* rhs, Typer* t) { |
1048 double results[4]; | 1036 double results[4]; |
1049 results[0] = lhs->Min()->Number() - rhs->Min()->Number(); | 1037 results[0] = lhs->Min() - rhs->Min(); |
1050 results[1] = lhs->Min()->Number() - rhs->Max()->Number(); | 1038 results[1] = lhs->Min() - rhs->Max(); |
1051 results[2] = lhs->Max()->Number() - rhs->Min()->Number(); | 1039 results[2] = lhs->Max() - rhs->Min(); |
1052 results[3] = lhs->Max()->Number() - rhs->Max()->Number(); | 1040 results[3] = lhs->Max() - rhs->Max(); |
1053 // Since none of the inputs can be -0, the result cannot be -0. | 1041 // Since none of the inputs can be -0, the result cannot be -0. |
1054 // However, it can be nan (the subtraction of two infinities of same sign). | 1042 // However, it can be nan (the subtraction of two infinities of same sign). |
1055 // On the other hand, if none of the "results" above is nan, then the actual | 1043 // On the other hand, if none of the "results" above is nan, then the actual |
1056 // result cannot be nan either. | 1044 // result cannot be nan either. |
1057 int nans = 0; | 1045 int nans = 0; |
1058 for (int i = 0; i < 4; ++i) { | 1046 for (int i = 0; i < 4; ++i) { |
1059 if (std::isnan(results[i])) ++nans; | 1047 if (std::isnan(results[i])) ++nans; |
1060 } | 1048 } |
1061 if (nans == 4) return Type::NaN(); // [inf..inf] - [inf..inf] (all same sign) | 1049 if (nans == 4) return Type::NaN(); // [inf..inf] - [inf..inf] (all same sign) |
1062 Factory* f = t->isolate()->factory(); | 1050 Type* range = |
1063 Type* range = Type::Range(f->NewNumber(array_min(results, 4)), | 1051 Type::Range(array_min(results, 4), array_max(results, 4), t->zone()); |
1064 f->NewNumber(array_max(results, 4)), t->zone()); | |
1065 return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone()); | 1052 return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone()); |
1066 // Examples: | 1053 // Examples: |
1067 // [-inf, +inf] - [-inf, +inf] = [-inf, +inf] \/ NaN | 1054 // [-inf, +inf] - [-inf, +inf] = [-inf, +inf] \/ NaN |
1068 // [-inf, -inf] - [-inf, -inf] = NaN | 1055 // [-inf, -inf] - [-inf, -inf] = NaN |
1069 // [-inf, -inf] - [n, +inf] = [-inf, -inf] \/ NaN | 1056 // [-inf, -inf] - [n, +inf] = [-inf, -inf] \/ NaN |
1070 // [m, +inf] - [-inf, n] = [-inf, +inf] \/ NaN | 1057 // [m, +inf] - [-inf, n] = [-inf, +inf] \/ NaN |
1071 } | 1058 } |
1072 | 1059 |
1073 | 1060 |
1074 Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) { | 1061 Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) { |
1075 lhs = Rangify(ToNumber(lhs, t), t); | 1062 lhs = Rangify(ToNumber(lhs, t), t); |
1076 rhs = Rangify(ToNumber(rhs, t), t); | 1063 rhs = Rangify(ToNumber(rhs, t), t); |
1077 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 1064 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
1078 if (lhs->IsRange() && rhs->IsRange()) { | 1065 if (lhs->IsRange() && rhs->IsRange()) { |
1079 return JSSubtractRanger(lhs->AsRange(), rhs->AsRange(), t); | 1066 return JSSubtractRanger(lhs->AsRange(), rhs->AsRange(), t); |
1080 } | 1067 } |
1081 return Type::Number(); | 1068 return Type::Number(); |
1082 } | 1069 } |
1083 | 1070 |
1084 | 1071 |
1085 Type* Typer::Visitor::JSMultiplyRanger(Type::RangeType* lhs, | 1072 Type* Typer::Visitor::JSMultiplyRanger(Type::RangeType* lhs, |
1086 Type::RangeType* rhs, Typer* t) { | 1073 Type::RangeType* rhs, Typer* t) { |
1087 double results[4]; | 1074 double results[4]; |
1088 double lmin = lhs->Min()->Number(); | 1075 double lmin = lhs->Min(); |
1089 double lmax = lhs->Max()->Number(); | 1076 double lmax = lhs->Max(); |
1090 double rmin = rhs->Min()->Number(); | 1077 double rmin = rhs->Min(); |
1091 double rmax = rhs->Max()->Number(); | 1078 double rmax = rhs->Max(); |
1092 results[0] = lmin * rmin; | 1079 results[0] = lmin * rmin; |
1093 results[1] = lmin * rmax; | 1080 results[1] = lmin * rmax; |
1094 results[2] = lmax * rmin; | 1081 results[2] = lmax * rmin; |
1095 results[3] = lmax * rmax; | 1082 results[3] = lmax * rmax; |
1096 // If the result may be nan, we give up on calculating a precise type, because | 1083 // If the result may be nan, we give up on calculating a precise type, because |
1097 // the discontinuity makes it too complicated. Note that even if none of the | 1084 // the discontinuity makes it too complicated. Note that even if none of the |
1098 // "results" above is nan, the actual result may still be, so we have to do a | 1085 // "results" above is nan, the actual result may still be, so we have to do a |
1099 // different check: | 1086 // different check: |
1100 bool maybe_nan = (lhs->Maybe(t->singleton_zero) && | 1087 bool maybe_nan = (lhs->Maybe(t->singleton_zero) && |
1101 (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) || | 1088 (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) || |
1102 (rhs->Maybe(t->singleton_zero) && | 1089 (rhs->Maybe(t->singleton_zero) && |
1103 (lmin == -V8_INFINITY || lmax == +V8_INFINITY)); | 1090 (lmin == -V8_INFINITY || lmax == +V8_INFINITY)); |
1104 if (maybe_nan) return t->weakint; // Giving up. | 1091 if (maybe_nan) return t->weakint; // Giving up. |
1105 bool maybe_minuszero = (lhs->Maybe(t->singleton_zero) && rmin < 0) || | 1092 bool maybe_minuszero = (lhs->Maybe(t->singleton_zero) && rmin < 0) || |
1106 (rhs->Maybe(t->singleton_zero) && lmin < 0); | 1093 (rhs->Maybe(t->singleton_zero) && lmin < 0); |
1107 Factory* f = t->isolate()->factory(); | 1094 Type* range = |
1108 Type* range = Type::Range(f->NewNumber(array_min(results, 4)), | 1095 Type::Range(array_min(results, 4), array_max(results, 4), t->zone()); |
1109 f->NewNumber(array_max(results, 4)), t->zone()); | |
1110 return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone()) | 1096 return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone()) |
1111 : range; | 1097 : range; |
1112 } | 1098 } |
1113 | 1099 |
1114 | 1100 |
1115 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { | 1101 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { |
1116 lhs = Rangify(ToNumber(lhs, t), t); | 1102 lhs = Rangify(ToNumber(lhs, t), t); |
1117 rhs = Rangify(ToNumber(rhs, t), t); | 1103 rhs = Rangify(ToNumber(rhs, t), t); |
1118 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 1104 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
1119 if (lhs->IsRange() && rhs->IsRange()) { | 1105 if (lhs->IsRange() && rhs->IsRange()) { |
(...skipping 12 matching lines...) Expand all Loading... |
1132 bool maybe_nan = | 1118 bool maybe_nan = |
1133 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) || | 1119 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) || |
1134 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && | 1120 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && |
1135 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); | 1121 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); |
1136 return maybe_nan ? Type::Number() : Type::OrderedNumber(); | 1122 return maybe_nan ? Type::Number() : Type::OrderedNumber(); |
1137 } | 1123 } |
1138 | 1124 |
1139 | 1125 |
1140 Type* Typer::Visitor::JSModulusRanger(Type::RangeType* lhs, | 1126 Type* Typer::Visitor::JSModulusRanger(Type::RangeType* lhs, |
1141 Type::RangeType* rhs, Typer* t) { | 1127 Type::RangeType* rhs, Typer* t) { |
1142 double lmin = lhs->Min()->Number(); | 1128 double lmin = lhs->Min(); |
1143 double lmax = lhs->Max()->Number(); | 1129 double lmax = lhs->Max(); |
1144 double rmin = rhs->Min()->Number(); | 1130 double rmin = rhs->Min(); |
1145 double rmax = rhs->Max()->Number(); | 1131 double rmax = rhs->Max(); |
1146 | 1132 |
1147 double labs = std::max(std::abs(lmin), std::abs(lmax)); | 1133 double labs = std::max(std::abs(lmin), std::abs(lmax)); |
1148 double rabs = std::max(std::abs(rmin), std::abs(rmax)) - 1; | 1134 double rabs = std::max(std::abs(rmin), std::abs(rmax)) - 1; |
1149 double abs = std::min(labs, rabs); | 1135 double abs = std::min(labs, rabs); |
1150 bool maybe_minus_zero = false; | 1136 bool maybe_minus_zero = false; |
1151 double omin = 0; | 1137 double omin = 0; |
1152 double omax = 0; | 1138 double omax = 0; |
1153 if (lmin >= 0) { // {lhs} positive. | 1139 if (lmin >= 0) { // {lhs} positive. |
1154 omin = 0; | 1140 omin = 0; |
1155 omax = abs; | 1141 omax = abs; |
1156 } else if (lmax <= 0) { // {lhs} negative. | 1142 } else if (lmax <= 0) { // {lhs} negative. |
1157 omin = 0 - abs; | 1143 omin = 0 - abs; |
1158 omax = 0; | 1144 omax = 0; |
1159 maybe_minus_zero = true; | 1145 maybe_minus_zero = true; |
1160 } else { | 1146 } else { |
1161 omin = 0 - abs; | 1147 omin = 0 - abs; |
1162 omax = abs; | 1148 omax = abs; |
1163 maybe_minus_zero = true; | 1149 maybe_minus_zero = true; |
1164 } | 1150 } |
1165 | 1151 |
1166 Factory* f = t->isolate()->factory(); | 1152 Type* result = Type::Range(omin, omax, t->zone()); |
1167 Type* result = Type::Range(f->NewNumber(omin), f->NewNumber(omax), t->zone()); | |
1168 if (maybe_minus_zero) | 1153 if (maybe_minus_zero) |
1169 result = Type::Union(result, Type::MinusZero(), t->zone()); | 1154 result = Type::Union(result, Type::MinusZero(), t->zone()); |
1170 return result; | 1155 return result; |
1171 } | 1156 } |
1172 | 1157 |
1173 | 1158 |
1174 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { | 1159 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { |
1175 lhs = ToNumber(lhs, t); | 1160 lhs = ToNumber(lhs, t); |
1176 rhs = ToNumber(rhs, t); | 1161 rhs = ToNumber(rhs, t); |
1177 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 1162 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1280 Type* previous_number = | 1265 Type* previous_number = |
1281 Type::Intersect(previous_type, typer_->integer, zone()); | 1266 Type::Intersect(previous_type, typer_->integer, zone()); |
1282 Type* current_number = Type::Intersect(current_type, typer_->integer, zone()); | 1267 Type* current_number = Type::Intersect(current_type, typer_->integer, zone()); |
1283 if (!current_number->IsRange() || !previous_number->IsRange()) { | 1268 if (!current_number->IsRange() || !previous_number->IsRange()) { |
1284 return current_type; | 1269 return current_type; |
1285 } | 1270 } |
1286 | 1271 |
1287 Type::RangeType* previous = previous_number->AsRange(); | 1272 Type::RangeType* previous = previous_number->AsRange(); |
1288 Type::RangeType* current = current_number->AsRange(); | 1273 Type::RangeType* current = current_number->AsRange(); |
1289 | 1274 |
1290 double current_min = current->Min()->Number(); | 1275 double current_min = current->Min(); |
1291 Handle<Object> new_min = current->Min(); | 1276 double new_min = current_min; |
1292 | |
1293 // Find the closest lower entry in the list of allowed | 1277 // Find the closest lower entry in the list of allowed |
1294 // minima (or negative infinity if there is no such entry). | 1278 // minima (or negative infinity if there is no such entry). |
1295 if (current_min != previous->Min()->Number()) { | 1279 if (current_min != previous->Min()) { |
1296 new_min = typer_->integer->AsRange()->Min(); | 1280 new_min = typer_->integer->AsRange()->Min(); |
1297 for (const auto val : typer_->weaken_min_limits_) { | 1281 for (const auto val : typer_->weaken_min_limits_) { |
1298 if (val->Number() <= current_min) { | 1282 if (val <= current_min) { |
1299 new_min = val; | 1283 new_min = val; |
1300 break; | 1284 break; |
1301 } | 1285 } |
1302 } | 1286 } |
1303 } | 1287 } |
1304 | 1288 |
1305 double current_max = current->Max()->Number(); | 1289 double current_max = current->Max(); |
1306 Handle<Object> new_max = current->Max(); | 1290 double new_max = current_max; |
1307 // Find the closest greater entry in the list of allowed | 1291 // Find the closest greater entry in the list of allowed |
1308 // maxima (or infinity if there is no such entry). | 1292 // maxima (or infinity if there is no such entry). |
1309 if (current_max != previous->Max()->Number()) { | 1293 if (current_max != previous->Max()) { |
1310 new_max = typer_->integer->AsRange()->Max(); | 1294 new_max = typer_->integer->AsRange()->Max(); |
1311 for (const auto val : typer_->weaken_max_limits_) { | 1295 for (const auto val : typer_->weaken_max_limits_) { |
1312 if (val->Number() >= current_max) { | 1296 if (val >= current_max) { |
1313 new_max = val; | 1297 new_max = val; |
1314 break; | 1298 break; |
1315 } | 1299 } |
1316 } | 1300 } |
1317 } | 1301 } |
1318 | 1302 |
1319 return Type::Union(current_type, | 1303 return Type::Union(current_type, |
1320 Type::Range(new_min, new_max, typer_->zone()), | 1304 Type::Range(new_min, new_max, typer_->zone()), |
1321 typer_->zone()); | 1305 typer_->zone()); |
1322 } | 1306 } |
(...skipping 830 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2153 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 2137 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
2154 #undef TYPED_ARRAY_CASE | 2138 #undef TYPED_ARRAY_CASE |
2155 } | 2139 } |
2156 } | 2140 } |
2157 return Type::Constant(value, zone()); | 2141 return Type::Constant(value, zone()); |
2158 } | 2142 } |
2159 | 2143 |
2160 } // namespace compiler | 2144 } // namespace compiler |
2161 } // namespace internal | 2145 } // namespace internal |
2162 } // namespace v8 | 2146 } // namespace v8 |
OLD | NEW |