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

Side by Side Diff: src/compiler/typer.cc

Issue 2381523002: [Turbofan] Introduce OtherNumberConstant. (Closed)
Patch Set: Better DCHECK in HeapConstantType(). Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/typed-optimization.cc ('k') | src/compiler/types.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/typer.h" 5 #include "src/compiler/typer.h"
6 6
7 #include <iomanip> 7 #include <iomanip>
8 8
9 #include "src/base/flags.h" 9 #include "src/base/flags.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 23 matching lines...) Expand all
34 34
35 Typer::Typer(Isolate* isolate, Graph* graph) 35 Typer::Typer(Isolate* isolate, Graph* graph)
36 : isolate_(isolate), 36 : isolate_(isolate),
37 graph_(graph), 37 graph_(graph),
38 decorator_(nullptr), 38 decorator_(nullptr),
39 cache_(TypeCache::Get()), 39 cache_(TypeCache::Get()),
40 operation_typer_(isolate, zone()) { 40 operation_typer_(isolate, zone()) {
41 Zone* zone = this->zone(); 41 Zone* zone = this->zone();
42 Factory* const factory = isolate->factory(); 42 Factory* const factory = isolate->factory();
43 43
44 singleton_false_ = Type::Constant(factory->false_value(), zone); 44 singleton_false_ = Type::HeapConstant(factory->false_value(), zone);
45 singleton_true_ = Type::Constant(factory->true_value(), zone); 45 singleton_true_ = Type::HeapConstant(factory->true_value(), zone);
46 singleton_the_hole_ = Type::Constant(factory->the_hole_value(), zone); 46 singleton_the_hole_ = Type::HeapConstant(factory->the_hole_value(), zone);
47 falsish_ = Type::Union( 47 falsish_ = Type::Union(
48 Type::Undetectable(), 48 Type::Undetectable(),
49 Type::Union(Type::Union(singleton_false_, cache_.kZeroish, zone), 49 Type::Union(Type::Union(singleton_false_, cache_.kZeroish, zone),
50 singleton_the_hole_, zone), 50 singleton_the_hole_, zone),
51 zone); 51 zone);
52 truish_ = Type::Union( 52 truish_ = Type::Union(
53 singleton_true_, 53 singleton_true_,
54 Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone); 54 Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone);
55 55
56 decorator_ = new (zone) Decorator(this); 56 decorator_ = new (zone) Decorator(this);
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 } 597 }
598 598
599 599
600 Type* Typer::Visitor::TypeFloat64Constant(Node* node) { 600 Type* Typer::Visitor::TypeFloat64Constant(Node* node) {
601 UNREACHABLE(); 601 UNREACHABLE();
602 return nullptr; 602 return nullptr;
603 } 603 }
604 604
605 605
606 Type* Typer::Visitor::TypeNumberConstant(Node* node) { 606 Type* Typer::Visitor::TypeNumberConstant(Node* node) {
607 Factory* f = isolate()->factory();
608 double number = OpParameter<double>(node); 607 double number = OpParameter<double>(node);
609 if (Type::IsInteger(number)) { 608 return Type::NewConstant(number, zone());
610 return Type::Range(number, number, zone());
611 }
612 return Type::Constant(f->NewNumber(number), zone());
613 } 609 }
614 610
615
616 Type* Typer::Visitor::TypeHeapConstant(Node* node) { 611 Type* Typer::Visitor::TypeHeapConstant(Node* node) {
617 return TypeConstant(OpParameter<Handle<HeapObject>>(node)); 612 return TypeConstant(OpParameter<Handle<HeapObject>>(node));
618 } 613 }
619 614
620 615
621 Type* Typer::Visitor::TypeExternalConstant(Node* node) { 616 Type* Typer::Visitor::TypeExternalConstant(Node* node) {
622 return Type::Internal(); 617 return Type::Internal();
623 } 618 }
624 619
625 620
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 824
830 Type* Typer::Visitor::JSEqualTyper(Type* lhs, Type* rhs, Typer* t) { 825 Type* Typer::Visitor::JSEqualTyper(Type* lhs, Type* rhs, Typer* t) {
831 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false_; 826 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false_;
832 if (lhs->Is(Type::NullOrUndefined()) && rhs->Is(Type::NullOrUndefined())) { 827 if (lhs->Is(Type::NullOrUndefined()) && rhs->Is(Type::NullOrUndefined())) {
833 return t->singleton_true_; 828 return t->singleton_true_;
834 } 829 }
835 if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) && 830 if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) &&
836 (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) { 831 (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) {
837 return t->singleton_false_; 832 return t->singleton_false_;
838 } 833 }
839 if (lhs->IsConstant() && rhs->Is(lhs)) { 834 if (lhs->IsHeapConstant() && rhs->Is(lhs)) {
840 // Types are equal and are inhabited only by a single semantic value, 835 // Types are equal and are inhabited only by a single semantic value,
841 // which is not nan due to the earlier check. 836 // which is not nan due to the earlier check.
842 return t->singleton_true_; 837 return t->singleton_true_;
843 } 838 }
844 return Type::Boolean(); 839 return Type::Boolean();
845 } 840 }
846 841
847 842
848 Type* Typer::Visitor::JSNotEqualTyper(Type* lhs, Type* rhs, Typer* t) { 843 Type* Typer::Visitor::JSNotEqualTyper(Type* lhs, Type* rhs, Typer* t) {
849 return Invert(JSEqualTyper(lhs, rhs, t), t); 844 return Invert(JSEqualTyper(lhs, rhs, t), t);
(...skipping 16 matching lines...) Expand all
866 if (!JSType(lhs)->Maybe(JSType(rhs))) return t->singleton_false_; 861 if (!JSType(lhs)->Maybe(JSType(rhs))) return t->singleton_false_;
867 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false_; 862 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false_;
868 if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) && 863 if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) &&
869 (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) { 864 (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) {
870 return t->singleton_false_; 865 return t->singleton_false_;
871 } 866 }
872 if ((lhs->Is(t->singleton_the_hole_) || rhs->Is(t->singleton_the_hole_)) && 867 if ((lhs->Is(t->singleton_the_hole_) || rhs->Is(t->singleton_the_hole_)) &&
873 !lhs->Maybe(rhs)) { 868 !lhs->Maybe(rhs)) {
874 return t->singleton_false_; 869 return t->singleton_false_;
875 } 870 }
876 if (lhs->IsConstant() && rhs->Is(lhs)) { 871 if (lhs->IsHeapConstant() && rhs->Is(lhs)) {
877 // Types are equal and are inhabited only by a single semantic value, 872 // Types are equal and are inhabited only by a single semantic value,
878 // which is not nan due to the earlier check. 873 // which is not nan due to the earlier check.
879 return t->singleton_true_; 874 return t->singleton_true_;
880 } 875 }
881 return Type::Boolean(); 876 return Type::Boolean();
882 } 877 }
883 878
884 879
885 Type* Typer::Visitor::JSStrictNotEqualTyper(Type* lhs, Type* rhs, Typer* t) { 880 Type* Typer::Visitor::JSStrictNotEqualTyper(Type* lhs, Type* rhs, Typer* t) {
886 return Invert(JSStrictEqualTyper(lhs, rhs, t), t); 881 return Invert(JSStrictEqualTyper(lhs, rhs, t), t);
(...skipping 13 matching lines...) Expand all
900 return ComparisonOutcome(kComparisonTrue) | 895 return ComparisonOutcome(kComparisonTrue) |
901 ComparisonOutcome(kComparisonFalse); 896 ComparisonOutcome(kComparisonFalse);
902 } 897 }
903 lhs = ToNumber(lhs, t); 898 lhs = ToNumber(lhs, t);
904 rhs = ToNumber(rhs, t); 899 rhs = ToNumber(rhs, t);
905 900
906 // Shortcut for NaNs. 901 // Shortcut for NaNs.
907 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return kComparisonUndefined; 902 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return kComparisonUndefined;
908 903
909 ComparisonOutcome result; 904 ComparisonOutcome result;
910 if (lhs->IsConstant() && rhs->Is(lhs)) { 905 if (lhs->IsHeapConstant() && rhs->Is(lhs)) {
911 // Types are equal and are inhabited only by a single semantic value. 906 // Types are equal and are inhabited only by a single semantic value.
912 result = kComparisonFalse; 907 result = kComparisonFalse;
913 } else if (lhs->Min() >= rhs->Max()) { 908 } else if (lhs->Min() >= rhs->Max()) {
914 result = kComparisonFalse; 909 result = kComparisonFalse;
915 } else if (lhs->Max() < rhs->Min()) { 910 } else if (lhs->Max() < rhs->Min()) {
916 result = kComparisonTrue; 911 result = kComparisonTrue;
917 } else { 912 } else {
918 // We cannot figure out the result, return both true and false. (We do not 913 // We cannot figure out the result, return both true and false. (We do not
919 // have to return undefined because that cannot affect the result of 914 // have to return undefined because that cannot affect the result of
920 // FalsifyUndefined.) 915 // FalsifyUndefined.)
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1014 return NumberModulus(ToNumber(lhs, t), ToNumber(rhs, t), t); 1009 return NumberModulus(ToNumber(lhs, t), ToNumber(rhs, t), t);
1015 } 1010 }
1016 1011
1017 1012
1018 // JS unary operators. 1013 // JS unary operators.
1019 1014
1020 1015
1021 Type* Typer::Visitor::JSTypeOfTyper(Type* type, Typer* t) { 1016 Type* Typer::Visitor::JSTypeOfTyper(Type* type, Typer* t) {
1022 Factory* const f = t->isolate()->factory(); 1017 Factory* const f = t->isolate()->factory();
1023 if (type->Is(Type::Boolean())) { 1018 if (type->Is(Type::Boolean())) {
1024 return Type::Constant(f->boolean_string(), t->zone()); 1019 return Type::HeapConstant(f->boolean_string(), t->zone());
1025 } else if (type->Is(Type::Number())) { 1020 } else if (type->Is(Type::Number())) {
1026 return Type::Constant(f->number_string(), t->zone()); 1021 return Type::HeapConstant(f->number_string(), t->zone());
1027 } else if (type->Is(Type::String())) { 1022 } else if (type->Is(Type::String())) {
1028 return Type::Constant(f->string_string(), t->zone()); 1023 return Type::HeapConstant(f->string_string(), t->zone());
1029 } else if (type->Is(Type::Symbol())) { 1024 } else if (type->Is(Type::Symbol())) {
1030 return Type::Constant(f->symbol_string(), t->zone()); 1025 return Type::HeapConstant(f->symbol_string(), t->zone());
1031 } else if (type->Is(Type::Union(Type::Undefined(), Type::OtherUndetectable(), 1026 } else if (type->Is(Type::Union(Type::Undefined(), Type::OtherUndetectable(),
1032 t->zone()))) { 1027 t->zone()))) {
1033 return Type::Constant(f->undefined_string(), t->zone()); 1028 return Type::HeapConstant(f->undefined_string(), t->zone());
1034 } else if (type->Is(Type::Null())) { 1029 } else if (type->Is(Type::Null())) {
1035 return Type::Constant(f->object_string(), t->zone()); 1030 return Type::HeapConstant(f->object_string(), t->zone());
1036 } else if (type->Is(Type::Function())) { 1031 } else if (type->Is(Type::Function())) {
1037 return Type::Constant(f->function_string(), t->zone()); 1032 return Type::HeapConstant(f->function_string(), t->zone());
1038 } else if (type->IsConstant()) { 1033 } else if (type->IsHeapConstant()) {
1039 return Type::Constant( 1034 return Type::HeapConstant(
1040 Object::TypeOf(t->isolate(), type->AsConstant()->Value()), t->zone()); 1035 Object::TypeOf(t->isolate(), type->AsHeapConstant()->Value()),
1036 t->zone());
1037 } else if (type->IsOtherNumberConstant()) {
1038 return Type::HeapConstant(f->number_string(), t->zone());
1041 } 1039 }
1042 return Type::InternalizedString(); 1040 return Type::InternalizedString();
1043 } 1041 }
1044 1042
1045 1043
1046 Type* Typer::Visitor::TypeJSTypeOf(Node* node) { 1044 Type* Typer::Visitor::TypeJSTypeOf(Node* node) {
1047 return TypeUnaryOp(node, JSTypeOfTyper); 1045 return TypeUnaryOp(node, JSTypeOfTyper);
1048 } 1046 }
1049 1047
1050 1048
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
1285 1283
1286 // JS other operators. 1284 // JS other operators.
1287 1285
1288 1286
1289 Type* Typer::Visitor::TypeJSCallConstruct(Node* node) { 1287 Type* Typer::Visitor::TypeJSCallConstruct(Node* node) {
1290 return Type::Receiver(); 1288 return Type::Receiver();
1291 } 1289 }
1292 1290
1293 1291
1294 Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) { 1292 Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) {
1295 if (fun->IsConstant() && fun->AsConstant()->Value()->IsJSFunction()) { 1293 if (fun->IsHeapConstant() && fun->AsHeapConstant()->Value()->IsJSFunction()) {
1296 Handle<JSFunction> function = 1294 Handle<JSFunction> function =
1297 Handle<JSFunction>::cast(fun->AsConstant()->Value()); 1295 Handle<JSFunction>::cast(fun->AsHeapConstant()->Value());
1298 if (function->shared()->HasBuiltinFunctionId()) { 1296 if (function->shared()->HasBuiltinFunctionId()) {
1299 switch (function->shared()->builtin_function_id()) { 1297 switch (function->shared()->builtin_function_id()) {
1300 case kMathRandom: 1298 case kMathRandom:
1301 return Type::PlainNumber(); 1299 return Type::PlainNumber();
1302 case kMathFloor: 1300 case kMathFloor:
1303 case kMathCeil: 1301 case kMathCeil:
1304 case kMathRound: 1302 case kMathRound:
1305 case kMathTrunc: 1303 case kMathTrunc:
1306 return t->cache_.kIntegerOrMinusZeroOrNaN; 1304 return t->cache_.kIntegerOrMinusZeroOrNaN;
1307 // Unary math functions. 1305 // Unary math functions.
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1530 Type* Typer::Visitor::TypePlainPrimitiveToWord32(Node* node) { 1528 Type* Typer::Visitor::TypePlainPrimitiveToWord32(Node* node) {
1531 return Type::Integral32(); 1529 return Type::Integral32();
1532 } 1530 }
1533 1531
1534 Type* Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) { 1532 Type* Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) {
1535 return Type::Number(); 1533 return Type::Number();
1536 } 1534 }
1537 1535
1538 // static 1536 // static
1539 Type* Typer::Visitor::ReferenceEqualTyper(Type* lhs, Type* rhs, Typer* t) { 1537 Type* Typer::Visitor::ReferenceEqualTyper(Type* lhs, Type* rhs, Typer* t) {
1540 if (lhs->IsConstant() && rhs->Is(lhs)) { 1538 if (lhs->IsHeapConstant() && rhs->Is(lhs)) {
1541 return t->singleton_true_; 1539 return t->singleton_true_;
1542 } 1540 }
1543 return Type::Boolean(); 1541 return Type::Boolean();
1544 } 1542 }
1545 1543
1546 1544
1547 Type* Typer::Visitor::TypeReferenceEqual(Node* node) { 1545 Type* Typer::Visitor::TypeReferenceEqual(Node* node) {
1548 return TypeBinaryOp(node, ReferenceEqualTyper); 1546 return TypeBinaryOp(node, ReferenceEqualTyper);
1549 } 1547 }
1550 1548
1551 Type* Typer::Visitor::TypeStringEqual(Node* node) { return Type::Boolean(); } 1549 Type* Typer::Visitor::TypeStringEqual(Node* node) { return Type::Boolean(); }
1552 1550
1553 Type* Typer::Visitor::TypeStringLessThan(Node* node) { return Type::Boolean(); } 1551 Type* Typer::Visitor::TypeStringLessThan(Node* node) { return Type::Boolean(); }
1554 1552
1555 Type* Typer::Visitor::TypeStringLessThanOrEqual(Node* node) { 1553 Type* Typer::Visitor::TypeStringLessThanOrEqual(Node* node) {
1556 return Type::Boolean(); 1554 return Type::Boolean();
1557 } 1555 }
1558 1556
1559 Type* Typer::Visitor::StringFromCharCodeTyper(Type* type, Typer* t) { 1557 Type* Typer::Visitor::StringFromCharCodeTyper(Type* type, Typer* t) {
1560 type = NumberToUint32(ToNumber(type, t), t); 1558 type = NumberToUint32(ToNumber(type, t), t);
1561 Factory* f = t->isolate()->factory(); 1559 Factory* f = t->isolate()->factory();
1562 double min = type->Min(); 1560 double min = type->Min();
1563 double max = type->Max(); 1561 double max = type->Max();
1564 if (min == max) { 1562 if (min == max) {
1565 uint32_t code = static_cast<uint32_t>(min) & String::kMaxUtf16CodeUnitU; 1563 uint32_t code = static_cast<uint32_t>(min) & String::kMaxUtf16CodeUnitU;
1566 Handle<String> string = f->LookupSingleCharacterStringFromCode(code); 1564 Handle<String> string = f->LookupSingleCharacterStringFromCode(code);
1567 return Type::Constant(string, t->zone()); 1565 return Type::HeapConstant(string, t->zone());
1568 } 1566 }
1569 return Type::String(); 1567 return Type::String();
1570 } 1568 }
1571 1569
1572 Type* Typer::Visitor::StringFromCodePointTyper(Type* type, Typer* t) { 1570 Type* Typer::Visitor::StringFromCodePointTyper(Type* type, Typer* t) {
1573 type = NumberToUint32(ToNumber(type, t), t); 1571 type = NumberToUint32(ToNumber(type, t), t);
1574 Factory* f = t->isolate()->factory(); 1572 Factory* f = t->isolate()->factory();
1575 double min = type->Min(); 1573 double min = type->Min();
1576 double max = type->Max(); 1574 double max = type->Max();
1577 if (min == max) { 1575 if (min == max) {
1578 uint32_t code = static_cast<uint32_t>(min) & String::kMaxUtf16CodeUnitU; 1576 uint32_t code = static_cast<uint32_t>(min) & String::kMaxUtf16CodeUnitU;
1579 Handle<String> string = f->LookupSingleCharacterStringFromCode(code); 1577 Handle<String> string = f->LookupSingleCharacterStringFromCode(code);
1580 return Type::Constant(string, t->zone()); 1578 return Type::HeapConstant(string, t->zone());
1581 } 1579 }
1582 return Type::String(); 1580 return Type::String();
1583 } 1581 }
1584 1582
1585 Type* Typer::Visitor::TypeStringCharCodeAt(Node* node) { 1583 Type* Typer::Visitor::TypeStringCharCodeAt(Node* node) {
1586 // TODO(bmeurer): We could do better here based on inputs. 1584 // TODO(bmeurer): We could do better here based on inputs.
1587 return Type::Range(0, kMaxUInt16, zone()); 1585 return Type::Range(0, kMaxUInt16, zone());
1588 } 1586 }
1589 1587
1590 Type* Typer::Visitor::TypeStringFromCharCode(Node* node) { 1588 Type* Typer::Visitor::TypeStringFromCharCode(Node* node) {
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1745 Type* Typer::Visitor::TypeArrayBufferWasNeutered(Node* node) { 1743 Type* Typer::Visitor::TypeArrayBufferWasNeutered(Node* node) {
1746 return Type::Boolean(); 1744 return Type::Boolean();
1747 } 1745 }
1748 1746
1749 // Heap constants. 1747 // Heap constants.
1750 1748
1751 Type* Typer::Visitor::TypeConstant(Handle<Object> value) { 1749 Type* Typer::Visitor::TypeConstant(Handle<Object> value) {
1752 if (Type::IsInteger(*value)) { 1750 if (Type::IsInteger(*value)) {
1753 return Type::Range(value->Number(), value->Number(), zone()); 1751 return Type::Range(value->Number(), value->Number(), zone());
1754 } 1752 }
1755 return Type::Constant(value, zone()); 1753 return Type::NewConstant(value, zone());
1756 } 1754 }
1757 1755
1758 } // namespace compiler 1756 } // namespace compiler
1759 } // namespace internal 1757 } // namespace internal
1760 } // namespace v8 1758 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/typed-optimization.cc ('k') | src/compiler/types.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698