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/compiler/typer.h" | 5 #include "src/compiler/typer.h" |
6 | 6 |
7 #include "src/base/flags.h" | 7 #include "src/base/flags.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/compilation-dependencies.h" | 9 #include "src/compilation-dependencies.h" |
10 #include "src/compiler/common-operator.h" | 10 #include "src/compiler/common-operator.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 | 22 |
23 class Typer::Decorator final : public GraphDecorator { | 23 class Typer::Decorator final : public GraphDecorator { |
24 public: | 24 public: |
25 explicit Decorator(Typer* typer) : typer_(typer) {} | 25 explicit Decorator(Typer* typer) : typer_(typer) {} |
26 void Decorate(Node* node) final; | 26 void Decorate(Node* node) final; |
27 | 27 |
28 private: | 28 private: |
29 Typer* const typer_; | 29 Typer* const typer_; |
30 }; | 30 }; |
31 | 31 |
32 | |
33 Typer::Typer(Isolate* isolate, Graph* graph, Flags flags, | 32 Typer::Typer(Isolate* isolate, Graph* graph, Flags flags, |
34 CompilationDependencies* dependencies, | 33 CompilationDependencies* dependencies, FunctionType* function_type) |
35 Type::FunctionType* function_type) | |
36 : isolate_(isolate), | 34 : isolate_(isolate), |
37 graph_(graph), | 35 graph_(graph), |
38 flags_(flags), | 36 flags_(flags), |
39 dependencies_(dependencies), | 37 dependencies_(dependencies), |
40 function_type_(function_type), | 38 function_type_(function_type), |
41 decorator_(nullptr), | 39 decorator_(nullptr), |
42 cache_(TypeCache::Get()) { | 40 cache_(TypeCache::Get()) { |
43 Zone* zone = this->zone(); | 41 Zone* zone = this->zone(); |
44 Factory* const factory = isolate->factory(); | 42 Factory* const factory = isolate->factory(); |
45 | 43 |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 static Type* ToBoolean(Type*, Typer*); | 234 static Type* ToBoolean(Type*, Typer*); |
237 static Type* ToInteger(Type*, Typer*); | 235 static Type* ToInteger(Type*, Typer*); |
238 static Type* ToLength(Type*, Typer*); | 236 static Type* ToLength(Type*, Typer*); |
239 static Type* ToName(Type*, Typer*); | 237 static Type* ToName(Type*, Typer*); |
240 static Type* ToNumber(Type*, Typer*); | 238 static Type* ToNumber(Type*, Typer*); |
241 static Type* ToObject(Type*, Typer*); | 239 static Type* ToObject(Type*, Typer*); |
242 static Type* ToString(Type*, Typer*); | 240 static Type* ToString(Type*, Typer*); |
243 static Type* NumberToInt32(Type*, Typer*); | 241 static Type* NumberToInt32(Type*, Typer*); |
244 static Type* NumberToUint32(Type*, Typer*); | 242 static Type* NumberToUint32(Type*, Typer*); |
245 | 243 |
246 static Type* JSAddRanger(Type::RangeType*, Type::RangeType*, Typer*); | 244 static Type* JSAddRanger(RangeType*, RangeType*, Typer*); |
247 static Type* JSSubtractRanger(Type::RangeType*, Type::RangeType*, Typer*); | 245 static Type* JSSubtractRanger(RangeType*, RangeType*, Typer*); |
248 static Type* JSMultiplyRanger(Type::RangeType*, Type::RangeType*, Typer*); | 246 static Type* JSDivideRanger(RangeType*, RangeType*, Typer*); |
249 static Type* JSDivideRanger(Type::RangeType*, Type::RangeType*, Typer*); | 247 static Type* JSModulusRanger(RangeType*, RangeType*, Typer*); |
250 static Type* JSModulusRanger(Type::RangeType*, Type::RangeType*, Typer*); | |
251 | 248 |
252 static ComparisonOutcome JSCompareTyper(Type*, Type*, Typer*); | 249 static ComparisonOutcome JSCompareTyper(Type*, Type*, Typer*); |
253 | 250 |
254 #define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*); | 251 #define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*); |
255 JS_SIMPLE_BINOP_LIST(DECLARE_METHOD) | 252 JS_SIMPLE_BINOP_LIST(DECLARE_METHOD) |
256 #undef DECLARE_METHOD | 253 #undef DECLARE_METHOD |
257 | 254 |
258 static Type* JSTypeOfTyper(Type*, Typer*); | 255 static Type* JSTypeOfTyper(Type*, Typer*); |
259 static Type* JSLoadPropertyTyper(Type*, Type*, Typer*); | 256 static Type* JSLoadPropertyTyper(Type*, Type*, Typer*); |
260 static Type* JSCallFunctionTyper(Type*, Typer*); | 257 static Type* JSCallFunctionTyper(Type*, Typer*); |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
506 } | 503 } |
507 return Type::Unsigned32(); | 504 return Type::Unsigned32(); |
508 } | 505 } |
509 | 506 |
510 | 507 |
511 // ----------------------------------------------------------------------------- | 508 // ----------------------------------------------------------------------------- |
512 | 509 |
513 | 510 |
514 // Control operators. | 511 // Control operators. |
515 | 512 |
516 | 513 Type* Typer::Visitor::TypeStart(Node* node) { return Type::Internal(); } |
517 Type* Typer::Visitor::TypeStart(Node* node) { return Type::Internal(zone()); } | |
518 | |
519 | 514 |
520 Type* Typer::Visitor::TypeIfException(Node* node) { return Type::Any(); } | 515 Type* Typer::Visitor::TypeIfException(Node* node) { return Type::Any(); } |
521 | 516 |
522 | 517 |
523 // Common operators. | 518 // Common operators. |
524 | 519 |
525 | 520 |
526 Type* Typer::Visitor::TypeParameter(Node* node) { | 521 Type* Typer::Visitor::TypeParameter(Node* node) { |
527 if (Type::FunctionType* function_type = typer_->function_type()) { | 522 if (FunctionType* function_type = typer_->function_type()) { |
528 int const index = ParameterIndexOf(node->op()); | 523 int const index = ParameterIndexOf(node->op()); |
529 if (index >= 0 && index < function_type->Arity()) { | 524 if (index >= 0 && index < function_type->Arity()) { |
530 return function_type->Parameter(index); | 525 return function_type->Parameter(index); |
531 } | 526 } |
532 } | 527 } |
533 return Type::Any(); | 528 return Type::Any(); |
534 } | 529 } |
535 | 530 |
536 | 531 |
537 Type* Typer::Visitor::TypeOsrValue(Node* node) { return Type::Any(); } | 532 Type* Typer::Visitor::TypeOsrValue(Node* node) { return Type::Any(); } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 return Type::Constant(f->NewNumber(number), zone()); | 566 return Type::Constant(f->NewNumber(number), zone()); |
572 } | 567 } |
573 | 568 |
574 | 569 |
575 Type* Typer::Visitor::TypeHeapConstant(Node* node) { | 570 Type* Typer::Visitor::TypeHeapConstant(Node* node) { |
576 return TypeConstant(OpParameter<Handle<HeapObject>>(node)); | 571 return TypeConstant(OpParameter<Handle<HeapObject>>(node)); |
577 } | 572 } |
578 | 573 |
579 | 574 |
580 Type* Typer::Visitor::TypeExternalConstant(Node* node) { | 575 Type* Typer::Visitor::TypeExternalConstant(Node* node) { |
581 return Type::Internal(zone()); | 576 return Type::Internal(); |
582 } | 577 } |
583 | 578 |
584 | 579 |
585 Type* Typer::Visitor::TypeSelect(Node* node) { | 580 Type* Typer::Visitor::TypeSelect(Node* node) { |
586 return Type::Union(Operand(node, 1), Operand(node, 2), zone()); | 581 return Type::Union(Operand(node, 1), Operand(node, 2), zone()); |
587 } | 582 } |
588 | 583 |
589 | 584 |
590 Type* Typer::Visitor::TypePhi(Node* node) { | 585 Type* Typer::Visitor::TypePhi(Node* node) { |
591 int arity = node->op()->ValueInputCount(); | 586 int arity = node->op()->ValueInputCount(); |
(...skipping 28 matching lines...) Expand all Loading... |
620 UNREACHABLE(); | 615 UNREACHABLE(); |
621 return nullptr; | 616 return nullptr; |
622 } | 617 } |
623 | 618 |
624 | 619 |
625 Type* Typer::Visitor::TypeFinishRegion(Node* node) { return Operand(node, 0); } | 620 Type* Typer::Visitor::TypeFinishRegion(Node* node) { return Operand(node, 0); } |
626 | 621 |
627 | 622 |
628 Type* Typer::Visitor::TypeFrameState(Node* node) { | 623 Type* Typer::Visitor::TypeFrameState(Node* node) { |
629 // TODO(rossberg): Ideally FrameState wouldn't have a value output. | 624 // TODO(rossberg): Ideally FrameState wouldn't have a value output. |
630 return Type::Internal(zone()); | 625 return Type::Internal(); |
| 626 } |
| 627 |
| 628 Type* Typer::Visitor::TypeStateValues(Node* node) { return Type::Internal(); } |
| 629 |
| 630 Type* Typer::Visitor::TypeObjectState(Node* node) { return Type::Internal(); } |
| 631 |
| 632 Type* Typer::Visitor::TypeTypedStateValues(Node* node) { |
| 633 return Type::Internal(); |
631 } | 634 } |
632 | 635 |
633 | 636 |
634 Type* Typer::Visitor::TypeStateValues(Node* node) { | |
635 return Type::Internal(zone()); | |
636 } | |
637 | |
638 | |
639 Type* Typer::Visitor::TypeObjectState(Node* node) { | |
640 return Type::Internal(zone()); | |
641 } | |
642 | |
643 | |
644 Type* Typer::Visitor::TypeTypedStateValues(Node* node) { | |
645 return Type::Internal(zone()); | |
646 } | |
647 | |
648 | |
649 Type* Typer::Visitor::TypeCall(Node* node) { return Type::Any(); } | 637 Type* Typer::Visitor::TypeCall(Node* node) { return Type::Any(); } |
650 | 638 |
651 | 639 |
652 Type* Typer::Visitor::TypeProjection(Node* node) { | 640 Type* Typer::Visitor::TypeProjection(Node* node) { |
653 Type* const type = Operand(node, 0); | 641 Type* const type = Operand(node, 0); |
654 if (type->Is(Type::None())) return Type::None(); | 642 if (type->Is(Type::None())) return Type::None(); |
655 int const index = static_cast<int>(ProjectionIndexOf(node->op())); | 643 int const index = static_cast<int>(ProjectionIndexOf(node->op())); |
656 if (type->IsTuple() && index < type->AsTuple()->Arity()) { | 644 if (type->IsTuple() && index < type->AsTuple()->Arity()) { |
657 return type->AsTuple()->Element(index); | 645 return type->AsTuple()->Element(index); |
658 } | 646 } |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
948 double x = -V8_INFINITY; | 936 double x = -V8_INFINITY; |
949 for (size_t i = 0; i < n; ++i) { | 937 for (size_t i = 0; i < n; ++i) { |
950 if (!std::isnan(a[i])) { | 938 if (!std::isnan(a[i])) { |
951 x = std::max(a[i], x); | 939 x = std::max(a[i], x); |
952 } | 940 } |
953 } | 941 } |
954 DCHECK(!std::isnan(x)); | 942 DCHECK(!std::isnan(x)); |
955 return x == 0 ? 0 : x; // -0 -> 0 | 943 return x == 0 ? 0 : x; // -0 -> 0 |
956 } | 944 } |
957 | 945 |
958 | 946 Type* Typer::Visitor::JSAddRanger(RangeType* lhs, RangeType* rhs, Typer* t) { |
959 Type* Typer::Visitor::JSAddRanger(Type::RangeType* lhs, Type::RangeType* rhs, | |
960 Typer* t) { | |
961 double results[4]; | 947 double results[4]; |
962 results[0] = lhs->Min() + rhs->Min(); | 948 results[0] = lhs->Min() + rhs->Min(); |
963 results[1] = lhs->Min() + rhs->Max(); | 949 results[1] = lhs->Min() + rhs->Max(); |
964 results[2] = lhs->Max() + rhs->Min(); | 950 results[2] = lhs->Max() + rhs->Min(); |
965 results[3] = lhs->Max() + rhs->Max(); | 951 results[3] = lhs->Max() + rhs->Max(); |
966 // Since none of the inputs can be -0, the result cannot be -0 either. | 952 // Since none of the inputs can be -0, the result cannot be -0 either. |
967 // However, it can be nan (the sum of two infinities of opposite sign). | 953 // However, it can be nan (the sum of two infinities of opposite sign). |
968 // On the other hand, if none of the "results" above is nan, then the actual | 954 // On the other hand, if none of the "results" above is nan, then the actual |
969 // result cannot be nan either. | 955 // result cannot be nan either. |
970 int nans = 0; | 956 int nans = 0; |
(...skipping 25 matching lines...) Expand all Loading... |
996 lhs = Rangify(ToNumber(lhs, t), t); | 982 lhs = Rangify(ToNumber(lhs, t), t); |
997 rhs = Rangify(ToNumber(rhs, t), t); | 983 rhs = Rangify(ToNumber(rhs, t), t); |
998 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 984 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
999 if (lhs->IsRange() && rhs->IsRange()) { | 985 if (lhs->IsRange() && rhs->IsRange()) { |
1000 return JSAddRanger(lhs->AsRange(), rhs->AsRange(), t); | 986 return JSAddRanger(lhs->AsRange(), rhs->AsRange(), t); |
1001 } | 987 } |
1002 // TODO(neis): Deal with numeric bitsets here and elsewhere. | 988 // TODO(neis): Deal with numeric bitsets here and elsewhere. |
1003 return Type::Number(); | 989 return Type::Number(); |
1004 } | 990 } |
1005 | 991 |
1006 | 992 Type* Typer::Visitor::JSSubtractRanger(RangeType* lhs, RangeType* rhs, |
1007 Type* Typer::Visitor::JSSubtractRanger(Type::RangeType* lhs, | 993 Typer* t) { |
1008 Type::RangeType* rhs, Typer* t) { | |
1009 double results[4]; | 994 double results[4]; |
1010 results[0] = lhs->Min() - rhs->Min(); | 995 results[0] = lhs->Min() - rhs->Min(); |
1011 results[1] = lhs->Min() - rhs->Max(); | 996 results[1] = lhs->Min() - rhs->Max(); |
1012 results[2] = lhs->Max() - rhs->Min(); | 997 results[2] = lhs->Max() - rhs->Min(); |
1013 results[3] = lhs->Max() - rhs->Max(); | 998 results[3] = lhs->Max() - rhs->Max(); |
1014 // Since none of the inputs can be -0, the result cannot be -0. | 999 // Since none of the inputs can be -0, the result cannot be -0. |
1015 // However, it can be nan (the subtraction of two infinities of same sign). | 1000 // However, it can be nan (the subtraction of two infinities of same sign). |
1016 // On the other hand, if none of the "results" above is nan, then the actual | 1001 // On the other hand, if none of the "results" above is nan, then the actual |
1017 // result cannot be nan either. | 1002 // result cannot be nan either. |
1018 int nans = 0; | 1003 int nans = 0; |
(...skipping 16 matching lines...) Expand all Loading... |
1035 lhs = Rangify(ToNumber(lhs, t), t); | 1020 lhs = Rangify(ToNumber(lhs, t), t); |
1036 rhs = Rangify(ToNumber(rhs, t), t); | 1021 rhs = Rangify(ToNumber(rhs, t), t); |
1037 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 1022 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
1038 if (lhs->IsRange() && rhs->IsRange()) { | 1023 if (lhs->IsRange() && rhs->IsRange()) { |
1039 return JSSubtractRanger(lhs->AsRange(), rhs->AsRange(), t); | 1024 return JSSubtractRanger(lhs->AsRange(), rhs->AsRange(), t); |
1040 } | 1025 } |
1041 return Type::Number(); | 1026 return Type::Number(); |
1042 } | 1027 } |
1043 | 1028 |
1044 | 1029 |
1045 Type* Typer::Visitor::JSMultiplyRanger(Type::RangeType* lhs, | |
1046 Type::RangeType* rhs, Typer* t) { | |
1047 double results[4]; | |
1048 double lmin = lhs->Min(); | |
1049 double lmax = lhs->Max(); | |
1050 double rmin = rhs->Min(); | |
1051 double rmax = rhs->Max(); | |
1052 results[0] = lmin * rmin; | |
1053 results[1] = lmin * rmax; | |
1054 results[2] = lmax * rmin; | |
1055 results[3] = lmax * rmax; | |
1056 // If the result may be nan, we give up on calculating a precise type, because | |
1057 // the discontinuity makes it too complicated. Note that even if none of the | |
1058 // "results" above is nan, the actual result may still be, so we have to do a | |
1059 // different check: | |
1060 bool maybe_nan = (lhs->Maybe(t->cache_.kSingletonZero) && | |
1061 (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) || | |
1062 (rhs->Maybe(t->cache_.kSingletonZero) && | |
1063 (lmin == -V8_INFINITY || lmax == +V8_INFINITY)); | |
1064 if (maybe_nan) return t->cache_.kIntegerOrMinusZeroOrNaN; // Giving up. | |
1065 bool maybe_minuszero = (lhs->Maybe(t->cache_.kSingletonZero) && rmin < 0) || | |
1066 (rhs->Maybe(t->cache_.kSingletonZero) && lmin < 0); | |
1067 Type* range = | |
1068 Type::Range(array_min(results, 4), array_max(results, 4), t->zone()); | |
1069 return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone()) | |
1070 : range; | |
1071 } | |
1072 | |
1073 | |
1074 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { | 1030 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { |
1075 lhs = Rangify(ToNumber(lhs, t), t); | 1031 lhs = Rangify(ToNumber(lhs, t), t); |
1076 rhs = Rangify(ToNumber(rhs, t), t); | 1032 rhs = Rangify(ToNumber(rhs, t), t); |
1077 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 1033 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
1078 if (lhs->IsRange() && rhs->IsRange()) { | 1034 if (lhs->IsRange() && rhs->IsRange()) { |
1079 return JSMultiplyRanger(lhs->AsRange(), rhs->AsRange(), t); | 1035 double results[4]; |
| 1036 double lmin = lhs->AsRange()->Min(); |
| 1037 double lmax = lhs->AsRange()->Max(); |
| 1038 double rmin = rhs->AsRange()->Min(); |
| 1039 double rmax = rhs->AsRange()->Max(); |
| 1040 results[0] = lmin * rmin; |
| 1041 results[1] = lmin * rmax; |
| 1042 results[2] = lmax * rmin; |
| 1043 results[3] = lmax * rmax; |
| 1044 // If the result may be nan, we give up on calculating a precise type, |
| 1045 // because |
| 1046 // the discontinuity makes it too complicated. Note that even if none of |
| 1047 // the |
| 1048 // "results" above is nan, the actual result may still be, so we have to do |
| 1049 // a |
| 1050 // different check: |
| 1051 bool maybe_nan = (lhs->Maybe(t->cache_.kSingletonZero) && |
| 1052 (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) || |
| 1053 (rhs->Maybe(t->cache_.kSingletonZero) && |
| 1054 (lmin == -V8_INFINITY || lmax == +V8_INFINITY)); |
| 1055 if (maybe_nan) return t->cache_.kIntegerOrMinusZeroOrNaN; // Giving up. |
| 1056 bool maybe_minuszero = (lhs->Maybe(t->cache_.kSingletonZero) && rmin < 0) || |
| 1057 (rhs->Maybe(t->cache_.kSingletonZero) && lmin < 0); |
| 1058 Type* range = |
| 1059 Type::Range(array_min(results, 4), array_max(results, 4), t->zone()); |
| 1060 return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone()) |
| 1061 : range; |
1080 } | 1062 } |
1081 return Type::Number(); | 1063 return Type::Number(); |
1082 } | 1064 } |
1083 | 1065 |
1084 | 1066 |
1085 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) { | 1067 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) { |
1086 lhs = ToNumber(lhs, t); | 1068 lhs = ToNumber(lhs, t); |
1087 rhs = ToNumber(rhs, t); | 1069 rhs = ToNumber(rhs, t); |
1088 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 1070 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
1089 // Division is tricky, so all we do is try ruling out nan. | 1071 // Division is tricky, so all we do is try ruling out nan. |
1090 // TODO(neis): try ruling out -0 as well? | 1072 // TODO(neis): try ruling out -0 as well? |
1091 bool maybe_nan = | 1073 bool maybe_nan = |
1092 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->cache_.kZeroish) || | 1074 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->cache_.kZeroish) || |
1093 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && | 1075 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && |
1094 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); | 1076 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); |
1095 return maybe_nan ? Type::Number() : Type::OrderedNumber(); | 1077 return maybe_nan ? Type::Number() : Type::OrderedNumber(); |
1096 } | 1078 } |
1097 | 1079 |
1098 | 1080 Type* Typer::Visitor::JSModulusRanger(RangeType* lhs, RangeType* rhs, |
1099 Type* Typer::Visitor::JSModulusRanger(Type::RangeType* lhs, | 1081 Typer* t) { |
1100 Type::RangeType* rhs, Typer* t) { | |
1101 double lmin = lhs->Min(); | 1082 double lmin = lhs->Min(); |
1102 double lmax = lhs->Max(); | 1083 double lmax = lhs->Max(); |
1103 double rmin = rhs->Min(); | 1084 double rmin = rhs->Min(); |
1104 double rmax = rhs->Max(); | 1085 double rmax = rhs->Max(); |
1105 | 1086 |
1106 double labs = std::max(std::abs(lmin), std::abs(lmax)); | 1087 double labs = std::max(std::abs(lmin), std::abs(lmax)); |
1107 double rabs = std::max(std::abs(rmin), std::abs(rmax)) - 1; | 1088 double rabs = std::max(std::abs(rmin), std::abs(rmax)) - 1; |
1108 double abs = std::min(labs, rabs); | 1089 double abs = std::min(labs, rabs); |
1109 bool maybe_minus_zero = false; | 1090 bool maybe_minus_zero = false; |
1110 double omin = 0; | 1091 double omin = 0; |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1284 JSFunction::EnsureHasInitialMap(function); | 1265 JSFunction::EnsureHasInitialMap(function); |
1285 Handle<Map> initial_map(function->initial_map(), isolate()); | 1266 Handle<Map> initial_map(function->initial_map(), isolate()); |
1286 dependencies()->AssumeInitialMapCantChange(initial_map); | 1267 dependencies()->AssumeInitialMapCantChange(initial_map); |
1287 return Type::Constant(handle(initial_map->prototype(), isolate()), | 1268 return Type::Constant(handle(initial_map->prototype(), isolate()), |
1288 zone()); | 1269 zone()); |
1289 } | 1270 } |
1290 } | 1271 } |
1291 } else if (receiver->IsClass() && | 1272 } else if (receiver->IsClass() && |
1292 receiver->AsClass()->Map()->IsJSFunctionMap()) { | 1273 receiver->AsClass()->Map()->IsJSFunctionMap()) { |
1293 Handle<Map> map = receiver->AsClass()->Map(); | 1274 Handle<Map> map = receiver->AsClass()->Map(); |
1294 return map->has_non_instance_prototype() ? Type::Primitive(zone()) | 1275 return map->has_non_instance_prototype() ? Type::Primitive() |
1295 : Type::Receiver(zone()); | 1276 : Type::Receiver(); |
1296 } | 1277 } |
1297 } | 1278 } |
1298 return Type::Any(); | 1279 return Type::Any(); |
1299 } | 1280 } |
1300 | 1281 |
1301 | 1282 |
1302 Type* Typer::Visitor::TypeJSLoadGlobal(Node* node) { return Type::Any(); } | 1283 Type* Typer::Visitor::TypeJSLoadGlobal(Node* node) { return Type::Any(); } |
1303 | 1284 |
1304 | 1285 |
1305 // Returns a somewhat larger range if we previously assigned | 1286 // Returns a somewhat larger range if we previously assigned |
(...skipping 27 matching lines...) Expand all Loading... |
1333 DCHECK(current_type->Maybe(integer)); | 1314 DCHECK(current_type->Maybe(integer)); |
1334 | 1315 |
1335 Type* current_integer = Type::Intersect(current_type, integer, zone()); | 1316 Type* current_integer = Type::Intersect(current_type, integer, zone()); |
1336 Type* previous_integer = Type::Intersect(previous_type, integer, zone()); | 1317 Type* previous_integer = Type::Intersect(previous_type, integer, zone()); |
1337 | 1318 |
1338 // Once we start weakening a node, we should always weaken. | 1319 // Once we start weakening a node, we should always weaken. |
1339 if (!IsWeakened(node->id())) { | 1320 if (!IsWeakened(node->id())) { |
1340 // Only weaken if there is range involved; we should converge quickly | 1321 // Only weaken if there is range involved; we should converge quickly |
1341 // for all other types (the exception is a union of many constants, | 1322 // for all other types (the exception is a union of many constants, |
1342 // but we currently do not increase the number of constants in unions). | 1323 // but we currently do not increase the number of constants in unions). |
1343 Type::RangeType* previous = previous_integer->GetRange(); | 1324 Type* previous = previous_integer->GetRange(); |
1344 Type::RangeType* current = current_integer->GetRange(); | 1325 Type* current = current_integer->GetRange(); |
1345 if (current == nullptr || previous == nullptr) { | 1326 if (current == nullptr || previous == nullptr) { |
1346 return current_type; | 1327 return current_type; |
1347 } | 1328 } |
1348 // Range is involved => we are weakening. | 1329 // Range is involved => we are weakening. |
1349 SetWeakened(node->id()); | 1330 SetWeakened(node->id()); |
1350 } | 1331 } |
1351 | 1332 |
1352 double current_min = current_integer->Min(); | 1333 double current_min = current_integer->Min(); |
1353 double new_min = current_min; | 1334 double new_min = current_min; |
1354 // Find the closest lower entry in the list of allowed | 1335 // Find the closest lower entry in the list of allowed |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1395 } | 1376 } |
1396 | 1377 |
1397 | 1378 |
1398 Type* Typer::Visitor::TypeJSStoreGlobal(Node* node) { | 1379 Type* Typer::Visitor::TypeJSStoreGlobal(Node* node) { |
1399 UNREACHABLE(); | 1380 UNREACHABLE(); |
1400 return nullptr; | 1381 return nullptr; |
1401 } | 1382 } |
1402 | 1383 |
1403 | 1384 |
1404 Type* Typer::Visitor::TypeJSDeleteProperty(Node* node) { | 1385 Type* Typer::Visitor::TypeJSDeleteProperty(Node* node) { |
1405 return Type::Boolean(zone()); | 1386 return Type::Boolean(); |
1406 } | 1387 } |
1407 | 1388 |
| 1389 Type* Typer::Visitor::TypeJSHasProperty(Node* node) { return Type::Boolean(); } |
1408 | 1390 |
1409 Type* Typer::Visitor::TypeJSHasProperty(Node* node) { | 1391 Type* Typer::Visitor::TypeJSInstanceOf(Node* node) { return Type::Boolean(); } |
1410 return Type::Boolean(zone()); | |
1411 } | |
1412 | |
1413 | |
1414 Type* Typer::Visitor::TypeJSInstanceOf(Node* node) { | |
1415 return Type::Boolean(zone()); | |
1416 } | |
1417 | |
1418 | 1392 |
1419 // JS context operators. | 1393 // JS context operators. |
1420 | 1394 |
1421 | 1395 |
1422 Type* Typer::Visitor::TypeJSLoadContext(Node* node) { | 1396 Type* Typer::Visitor::TypeJSLoadContext(Node* node) { |
1423 ContextAccess const& access = ContextAccessOf(node->op()); | 1397 ContextAccess const& access = ContextAccessOf(node->op()); |
1424 if (access.index() == Context::EXTENSION_INDEX) { | 1398 if (access.index() == Context::EXTENSION_INDEX) { |
1425 return Type::TaggedPointer(); | 1399 return Type::TaggedPointer(); |
1426 } | 1400 } |
1427 // Since contexts are mutable, we just return the top. | 1401 // Since contexts are mutable, we just return the top. |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1556 Type* Typer::Visitor::TypeJSCallRuntime(Node* node) { | 1530 Type* Typer::Visitor::TypeJSCallRuntime(Node* node) { |
1557 switch (CallRuntimeParametersOf(node->op()).id()) { | 1531 switch (CallRuntimeParametersOf(node->op()).id()) { |
1558 case Runtime::kInlineIsSmi: | 1532 case Runtime::kInlineIsSmi: |
1559 case Runtime::kInlineIsArray: | 1533 case Runtime::kInlineIsArray: |
1560 case Runtime::kInlineIsDate: | 1534 case Runtime::kInlineIsDate: |
1561 case Runtime::kInlineIsTypedArray: | 1535 case Runtime::kInlineIsTypedArray: |
1562 case Runtime::kInlineIsMinusZero: | 1536 case Runtime::kInlineIsMinusZero: |
1563 case Runtime::kInlineIsFunction: | 1537 case Runtime::kInlineIsFunction: |
1564 case Runtime::kInlineIsRegExp: | 1538 case Runtime::kInlineIsRegExp: |
1565 case Runtime::kInlineIsJSReceiver: | 1539 case Runtime::kInlineIsJSReceiver: |
1566 return Type::Boolean(zone()); | 1540 return Type::Boolean(); |
1567 case Runtime::kInlineDoubleLo: | 1541 case Runtime::kInlineDoubleLo: |
1568 case Runtime::kInlineDoubleHi: | 1542 case Runtime::kInlineDoubleHi: |
1569 return Type::Signed32(); | 1543 return Type::Signed32(); |
1570 case Runtime::kInlineConstructDouble: | 1544 case Runtime::kInlineConstructDouble: |
1571 case Runtime::kInlineMathFloor: | 1545 case Runtime::kInlineMathFloor: |
1572 case Runtime::kInlineMathSqrt: | 1546 case Runtime::kInlineMathSqrt: |
1573 case Runtime::kInlineMathAcos: | 1547 case Runtime::kInlineMathAcos: |
1574 case Runtime::kInlineMathAsin: | 1548 case Runtime::kInlineMathAsin: |
1575 case Runtime::kInlineMathAtan: | 1549 case Runtime::kInlineMathAtan: |
1576 case Runtime::kInlineMathAtan2: | 1550 case Runtime::kInlineMathAtan2: |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1620 Type* Typer::Visitor::TypeJSForInPrepare(Node* node) { | 1594 Type* Typer::Visitor::TypeJSForInPrepare(Node* node) { |
1621 STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength); | 1595 STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength); |
1622 Factory* const f = isolate()->factory(); | 1596 Factory* const f = isolate()->factory(); |
1623 Type* const cache_type = Type::Union( | 1597 Type* const cache_type = Type::Union( |
1624 typer_->cache_.kSmi, Type::Class(f->meta_map(), zone()), zone()); | 1598 typer_->cache_.kSmi, Type::Class(f->meta_map(), zone()), zone()); |
1625 Type* const cache_array = Type::Class(f->fixed_array_map(), zone()); | 1599 Type* const cache_array = Type::Class(f->fixed_array_map(), zone()); |
1626 Type* const cache_length = typer_->cache_.kFixedArrayLengthType; | 1600 Type* const cache_length = typer_->cache_.kFixedArrayLengthType; |
1627 return Type::Tuple(cache_type, cache_array, cache_length, zone()); | 1601 return Type::Tuple(cache_type, cache_array, cache_length, zone()); |
1628 } | 1602 } |
1629 | 1603 |
1630 | 1604 Type* Typer::Visitor::TypeJSForInDone(Node* node) { return Type::Boolean(); } |
1631 Type* Typer::Visitor::TypeJSForInDone(Node* node) { | |
1632 return Type::Boolean(zone()); | |
1633 } | |
1634 | |
1635 | 1605 |
1636 Type* Typer::Visitor::TypeJSForInStep(Node* node) { | 1606 Type* Typer::Visitor::TypeJSForInStep(Node* node) { |
1637 STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength); | 1607 STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength); |
1638 return Type::Range(1, FixedArray::kMaxLength + 1, zone()); | 1608 return Type::Range(1, FixedArray::kMaxLength + 1, zone()); |
1639 } | 1609 } |
1640 | 1610 |
1641 | 1611 |
1642 Type* Typer::Visitor::TypeJSLoadMessage(Node* node) { return Type::Any(); } | 1612 Type* Typer::Visitor::TypeJSLoadMessage(Node* node) { return Type::Any(); } |
1643 | 1613 |
1644 | 1614 |
1645 Type* Typer::Visitor::TypeJSStoreMessage(Node* node) { | 1615 Type* Typer::Visitor::TypeJSStoreMessage(Node* node) { |
1646 UNREACHABLE(); | 1616 UNREACHABLE(); |
1647 return nullptr; | 1617 return nullptr; |
1648 } | 1618 } |
1649 | 1619 |
1650 | 1620 |
1651 Type* Typer::Visitor::TypeJSStackCheck(Node* node) { return Type::Any(); } | 1621 Type* Typer::Visitor::TypeJSStackCheck(Node* node) { return Type::Any(); } |
1652 | 1622 |
1653 | 1623 |
1654 // Simplified operators. | 1624 // Simplified operators. |
1655 | 1625 |
1656 | 1626 Type* Typer::Visitor::TypeBooleanNot(Node* node) { return Type::Boolean(); } |
1657 Type* Typer::Visitor::TypeBooleanNot(Node* node) { | |
1658 return Type::Boolean(zone()); | |
1659 } | |
1660 | |
1661 | 1627 |
1662 Type* Typer::Visitor::TypeBooleanToNumber(Node* node) { | 1628 Type* Typer::Visitor::TypeBooleanToNumber(Node* node) { |
1663 return TypeUnaryOp(node, ToNumber); | 1629 return TypeUnaryOp(node, ToNumber); |
1664 } | 1630 } |
1665 | 1631 |
| 1632 Type* Typer::Visitor::TypeNumberEqual(Node* node) { return Type::Boolean(); } |
1666 | 1633 |
1667 Type* Typer::Visitor::TypeNumberEqual(Node* node) { | 1634 Type* Typer::Visitor::TypeNumberLessThan(Node* node) { return Type::Boolean(); } |
1668 return Type::Boolean(zone()); | 1635 |
| 1636 Type* Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) { |
| 1637 return Type::Boolean(); |
1669 } | 1638 } |
1670 | 1639 |
| 1640 Type* Typer::Visitor::TypeNumberAdd(Node* node) { return Type::Number(); } |
1671 | 1641 |
1672 Type* Typer::Visitor::TypeNumberLessThan(Node* node) { | 1642 Type* Typer::Visitor::TypeNumberSubtract(Node* node) { return Type::Number(); } |
1673 return Type::Boolean(zone()); | |
1674 } | |
1675 | 1643 |
| 1644 Type* Typer::Visitor::TypeNumberMultiply(Node* node) { return Type::Number(); } |
1676 | 1645 |
1677 Type* Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) { | 1646 Type* Typer::Visitor::TypeNumberDivide(Node* node) { return Type::Number(); } |
1678 return Type::Boolean(zone()); | |
1679 } | |
1680 | 1647 |
1681 | 1648 Type* Typer::Visitor::TypeNumberModulus(Node* node) { return Type::Number(); } |
1682 Type* Typer::Visitor::TypeNumberAdd(Node* node) { return Type::Number(zone()); } | |
1683 | |
1684 | |
1685 Type* Typer::Visitor::TypeNumberSubtract(Node* node) { | |
1686 return Type::Number(zone()); | |
1687 } | |
1688 | |
1689 | |
1690 Type* Typer::Visitor::TypeNumberMultiply(Node* node) { | |
1691 return Type::Number(zone()); | |
1692 } | |
1693 | |
1694 | |
1695 Type* Typer::Visitor::TypeNumberDivide(Node* node) { | |
1696 return Type::Number(zone()); | |
1697 } | |
1698 | |
1699 | |
1700 Type* Typer::Visitor::TypeNumberModulus(Node* node) { | |
1701 return Type::Number(zone()); | |
1702 } | |
1703 | |
1704 | 1649 |
1705 Type* Typer::Visitor::TypeNumberBitwiseOr(Node* node) { | 1650 Type* Typer::Visitor::TypeNumberBitwiseOr(Node* node) { |
1706 return Type::Signed32(zone()); | 1651 return Type::Signed32(); |
1707 } | 1652 } |
1708 | 1653 |
1709 | 1654 |
1710 Type* Typer::Visitor::TypeNumberBitwiseXor(Node* node) { | 1655 Type* Typer::Visitor::TypeNumberBitwiseXor(Node* node) { |
1711 return Type::Signed32(zone()); | 1656 return Type::Signed32(); |
1712 } | 1657 } |
1713 | 1658 |
1714 | 1659 |
1715 Type* Typer::Visitor::TypeNumberBitwiseAnd(Node* node) { | 1660 Type* Typer::Visitor::TypeNumberBitwiseAnd(Node* node) { |
1716 return Type::Signed32(zone()); | 1661 return Type::Signed32(); |
1717 } | 1662 } |
1718 | 1663 |
1719 | 1664 |
1720 Type* Typer::Visitor::TypeNumberShiftLeft(Node* node) { | 1665 Type* Typer::Visitor::TypeNumberShiftLeft(Node* node) { |
1721 return Type::Signed32(zone()); | 1666 return Type::Signed32(); |
1722 } | 1667 } |
1723 | 1668 |
1724 | 1669 |
1725 Type* Typer::Visitor::TypeNumberShiftRight(Node* node) { | 1670 Type* Typer::Visitor::TypeNumberShiftRight(Node* node) { |
1726 return Type::Signed32(zone()); | 1671 return Type::Signed32(); |
1727 } | 1672 } |
1728 | 1673 |
1729 | 1674 |
1730 Type* Typer::Visitor::TypeNumberShiftRightLogical(Node* node) { | 1675 Type* Typer::Visitor::TypeNumberShiftRightLogical(Node* node) { |
1731 return Type::Unsigned32(zone()); | 1676 return Type::Unsigned32(); |
1732 } | 1677 } |
1733 | 1678 |
1734 | 1679 |
1735 Type* Typer::Visitor::TypeNumberToInt32(Node* node) { | 1680 Type* Typer::Visitor::TypeNumberToInt32(Node* node) { |
1736 return TypeUnaryOp(node, NumberToInt32); | 1681 return TypeUnaryOp(node, NumberToInt32); |
1737 } | 1682 } |
1738 | 1683 |
1739 | 1684 |
1740 Type* Typer::Visitor::TypeNumberToUint32(Node* node) { | 1685 Type* Typer::Visitor::TypeNumberToUint32(Node* node) { |
1741 return TypeUnaryOp(node, NumberToUint32); | 1686 return TypeUnaryOp(node, NumberToUint32); |
1742 } | 1687 } |
1743 | 1688 |
1744 | 1689 |
1745 Type* Typer::Visitor::TypeNumberIsHoleNaN(Node* node) { | 1690 Type* Typer::Visitor::TypeNumberIsHoleNaN(Node* node) { |
1746 return Type::Boolean(zone()); | 1691 return Type::Boolean(); |
1747 } | 1692 } |
1748 | 1693 |
1749 | 1694 |
1750 Type* Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) { | 1695 Type* Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) { |
1751 return TypeUnaryOp(node, ToNumber); | 1696 return TypeUnaryOp(node, ToNumber); |
1752 } | 1697 } |
1753 | 1698 |
1754 | 1699 |
1755 // static | 1700 // static |
1756 Type* Typer::Visitor::ReferenceEqualTyper(Type* lhs, Type* rhs, Typer* t) { | 1701 Type* Typer::Visitor::ReferenceEqualTyper(Type* lhs, Type* rhs, Typer* t) { |
1757 if (lhs->IsConstant() && rhs->Is(lhs)) { | 1702 if (lhs->IsConstant() && rhs->Is(lhs)) { |
1758 return t->singleton_true_; | 1703 return t->singleton_true_; |
1759 } | 1704 } |
1760 return Type::Boolean(); | 1705 return Type::Boolean(); |
1761 } | 1706 } |
1762 | 1707 |
1763 | 1708 |
1764 Type* Typer::Visitor::TypeReferenceEqual(Node* node) { | 1709 Type* Typer::Visitor::TypeReferenceEqual(Node* node) { |
1765 return TypeBinaryOp(node, ReferenceEqualTyper); | 1710 return TypeBinaryOp(node, ReferenceEqualTyper); |
1766 } | 1711 } |
1767 | 1712 |
| 1713 Type* Typer::Visitor::TypeStringEqual(Node* node) { return Type::Boolean(); } |
1768 | 1714 |
1769 Type* Typer::Visitor::TypeStringEqual(Node* node) { | 1715 Type* Typer::Visitor::TypeStringLessThan(Node* node) { return Type::Boolean(); } |
1770 return Type::Boolean(zone()); | 1716 |
| 1717 Type* Typer::Visitor::TypeStringLessThanOrEqual(Node* node) { |
| 1718 return Type::Boolean(); |
1771 } | 1719 } |
1772 | 1720 |
1773 | 1721 |
1774 Type* Typer::Visitor::TypeStringLessThan(Node* node) { | |
1775 return Type::Boolean(zone()); | |
1776 } | |
1777 | |
1778 | |
1779 Type* Typer::Visitor::TypeStringLessThanOrEqual(Node* node) { | |
1780 return Type::Boolean(zone()); | |
1781 } | |
1782 | |
1783 | |
1784 namespace { | 1722 namespace { |
1785 | 1723 |
1786 Type* ChangeRepresentation(Type* type, Type* rep, Zone* zone) { | 1724 Type* ChangeRepresentation(Type* type, Type* rep, Zone* zone) { |
1787 return Type::Union(Type::Semantic(type, zone), | 1725 return Type::Union(Type::Semantic(type, zone), |
1788 Type::Representation(rep, zone), zone); | 1726 Type::Representation(rep, zone), zone); |
1789 } | 1727 } |
1790 | 1728 |
1791 } // namespace | 1729 } // namespace |
1792 | 1730 |
1793 | 1731 |
(...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2452 } | 2390 } |
2453 if (Type::IsInteger(*value)) { | 2391 if (Type::IsInteger(*value)) { |
2454 return Type::Range(value->Number(), value->Number(), zone()); | 2392 return Type::Range(value->Number(), value->Number(), zone()); |
2455 } | 2393 } |
2456 return Type::Constant(value, zone()); | 2394 return Type::Constant(value, zone()); |
2457 } | 2395 } |
2458 | 2396 |
2459 } // namespace compiler | 2397 } // namespace compiler |
2460 } // namespace internal | 2398 } // namespace internal |
2461 } // namespace v8 | 2399 } // namespace v8 |
OLD | NEW |