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