| 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 |