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

Side by Side Diff: runtime/vm/flow_graph_type_propagator.cc

Issue 2865603003: Revert "Void is not required to be `null` anymore." (Closed)
Patch Set: Created 3 years, 7 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 | « runtime/vm/flow_graph_compiler_x64.cc ('k') | runtime/vm/object.cc » ('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 (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_type_propagator.h" 5 #include "vm/flow_graph_type_propagator.h"
6 6
7 #include "vm/cha.h" 7 #include "vm/cha.h"
8 #include "vm/bit_vector.h" 8 #include "vm/bit_vector.h"
9 #include "vm/il_printer.h" 9 #include "vm/il_printer.h"
10 #include "vm/object_store.h" 10 #include "vm/object_store.h"
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 590
591 591
592 intptr_t CompileType::ToNullableCid() { 592 intptr_t CompileType::ToNullableCid() {
593 if (cid_ == kIllegalCid) { 593 if (cid_ == kIllegalCid) {
594 if (type_ == NULL) { 594 if (type_ == NULL) {
595 // Type propagation is turned off or has not yet run. 595 // Type propagation is turned off or has not yet run.
596 return kDynamicCid; 596 return kDynamicCid;
597 } else if (type_->IsMalformed()) { 597 } else if (type_->IsMalformed()) {
598 cid_ = kDynamicCid; 598 cid_ = kDynamicCid;
599 } else if (type_->IsVoidType()) { 599 } else if (type_->IsVoidType()) {
600 cid_ = kDynamicCid; 600 cid_ = kNullCid;
601 } else if (type_->IsFunctionType() || type_->IsDartFunctionType()) { 601 } else if (type_->IsFunctionType() || type_->IsDartFunctionType()) {
602 cid_ = kClosureCid; 602 cid_ = kClosureCid;
603 } else if (type_->HasResolvedTypeClass()) { 603 } else if (type_->HasResolvedTypeClass()) {
604 const Class& type_class = Class::Handle(type_->type_class()); 604 const Class& type_class = Class::Handle(type_->type_class());
605 Thread* thread = Thread::Current(); 605 Thread* thread = Thread::Current();
606 CHA* cha = thread->cha(); 606 CHA* cha = thread->cha();
607 // Don't infer a cid from an abstract type since there can be multiple 607 // Don't infer a cid from an abstract type since there can be multiple
608 // compatible classes with different cids. 608 // compatible classes with different cids.
609 if (!CHA::IsImplemented(type_class) && !CHA::HasSubclasses(type_class)) { 609 if (!CHA::IsImplemented(type_class) && !CHA::HasSubclasses(type_class)) {
610 if (type_class.IsPrivate()) { 610 if (type_class.IsPrivate()) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 677
678 bool CompileType::CanComputeIsInstanceOf(const AbstractType& type, 678 bool CompileType::CanComputeIsInstanceOf(const AbstractType& type,
679 bool is_nullable, 679 bool is_nullable,
680 bool* is_instance) { 680 bool* is_instance) {
681 ASSERT(is_instance != NULL); 681 ASSERT(is_instance != NULL);
682 // We cannot give an answer if the given type is malformed or malbounded. 682 // We cannot give an answer if the given type is malformed or malbounded.
683 if (type.IsMalformedOrMalbounded()) { 683 if (type.IsMalformedOrMalbounded()) {
684 return false; 684 return false;
685 } 685 }
686 686
687 if (type.IsDynamicType() || type.IsObjectType() || type.IsVoidType()) { 687 if (type.IsDynamicType() || type.IsObjectType()) {
688 *is_instance = true; 688 *is_instance = true;
689 return true; 689 return true;
690 } 690 }
691 691
692 if (IsNone()) { 692 if (IsNone()) {
693 return false; 693 return false;
694 } 694 }
695 695
696 // Consider the compile type of the value. 696 // Consider the compile type of the value.
697 const AbstractType& compile_type = *ToAbstractType(); 697 const AbstractType& compile_type = *ToAbstractType();
698 698
699 // The compile-type of a value should never be void. The result of a void
700 // function must always be null, which was checked to be null at the return
701 // statement inside the function.
702 ASSERT(!compile_type.IsVoidType());
703
699 if (compile_type.IsMalformedOrMalbounded()) { 704 if (compile_type.IsMalformedOrMalbounded()) {
700 return false; 705 return false;
701 } 706 }
702 707
703 // The null instance is an instance of Null, of Object, and of dynamic. 708 // The null instance is an instance of Null, of Object, and of dynamic.
704 // Functions that do not explicitly return a value, implicitly return null, 709 // Functions that do not explicitly return a value, implicitly return null,
705 // except generative constructors, which return the object being constructed. 710 // except generative constructors, which return the object being constructed.
706 // It is therefore acceptable for void functions to return null. 711 // It is therefore acceptable for void functions to return null.
707 if (compile_type.IsNullType()) { 712 if (compile_type.IsNullType()) {
708 *is_instance = is_nullable || type.IsObjectType() || type.IsDynamicType() || 713 *is_instance = is_nullable || type.IsObjectType() || type.IsDynamicType() ||
709 type.IsNullType() || type.IsVoidType(); 714 type.IsNullType() || type.IsVoidType();
710 return true; 715 return true;
711 } 716 }
712 717
718 // A non-null value is not an instance of void.
719 if (type.IsVoidType()) {
720 *is_instance = IsNull();
721 return HasDecidableNullability();
722 }
723
713 // If the value can be null then we can't eliminate the 724 // If the value can be null then we can't eliminate the
714 // check unless null is allowed. 725 // check unless null is allowed.
715 if (is_nullable_ && !is_nullable) { 726 if (is_nullable_ && !is_nullable) {
716 return false; 727 return false;
717 } 728 }
718 729
719 *is_instance = compile_type.IsMoreSpecificThan(type, NULL, NULL, Heap::kOld); 730 *is_instance = compile_type.IsMoreSpecificThan(type, NULL, NULL, Heap::kOld);
720 return *is_instance; 731 return *is_instance;
721 } 732 }
722 733
723 734
724 bool CompileType::IsMoreSpecificThan(const AbstractType& other) { 735 bool CompileType::IsMoreSpecificThan(const AbstractType& other) {
725 if (IsNone()) { 736 if (IsNone()) {
726 return false; 737 return false;
727 } 738 }
728 739
740 if (other.IsVoidType()) {
741 // The only value assignable to void is null.
742 return IsNull();
743 }
744
729 return ToAbstractType()->IsMoreSpecificThan(other, NULL, NULL, Heap::kOld); 745 return ToAbstractType()->IsMoreSpecificThan(other, NULL, NULL, Heap::kOld);
730 } 746 }
731 747
732 748
733 CompileType* Value::Type() { 749 CompileType* Value::Type() {
734 if (reaching_type_ == NULL) { 750 if (reaching_type_ == NULL) {
735 reaching_type_ = definition()->Type(); 751 reaching_type_ = definition()->Type();
736 } 752 }
737 return reaching_type_; 753 return reaching_type_;
738 } 754 }
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
920 } 936 }
921 937
922 938
923 CompileType AssertAssignableInstr::ComputeType() const { 939 CompileType AssertAssignableInstr::ComputeType() const {
924 CompileType* value_type = value()->Type(); 940 CompileType* value_type = value()->Type();
925 941
926 if (value_type->IsMoreSpecificThan(dst_type())) { 942 if (value_type->IsMoreSpecificThan(dst_type())) {
927 return *value_type; 943 return *value_type;
928 } 944 }
929 945
946 if (dst_type().IsVoidType()) {
947 // The only value assignable to void is null.
948 return CompileType::Null();
949 }
950
930 return CompileType::Create(value_type->ToCid(), dst_type()); 951 return CompileType::Create(value_type->ToCid(), dst_type());
931 } 952 }
932 953
933 954
934 bool AssertAssignableInstr::RecomputeType() { 955 bool AssertAssignableInstr::RecomputeType() {
935 return UpdateType(ComputeType()); 956 return UpdateType(ComputeType());
936 } 957 }
937 958
938 959
939 CompileType AssertBooleanInstr::ComputeType() const { 960 CompileType AssertBooleanInstr::ComputeType() const {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 : CompileType::Dynamic(); 1031 : CompileType::Dynamic();
1011 } 1032 }
1012 1033
1013 1034
1014 CompileType StaticCallInstr::ComputeType() const { 1035 CompileType StaticCallInstr::ComputeType() const {
1015 if (result_cid_ != kDynamicCid) { 1036 if (result_cid_ != kDynamicCid) {
1016 return CompileType::FromCid(result_cid_); 1037 return CompileType::FromCid(result_cid_);
1017 } 1038 }
1018 1039
1019 if (Isolate::Current()->type_checks()) { 1040 if (Isolate::Current()->type_checks()) {
1041 // Void functions are known to return null, which is checked at the return
1042 // from the function.
1020 const AbstractType& result_type = 1043 const AbstractType& result_type =
1021 AbstractType::ZoneHandle(function().result_type()); 1044 AbstractType::ZoneHandle(function().result_type());
1022 return CompileType::FromAbstractType(result_type); 1045 return CompileType::FromAbstractType(
1046 result_type.IsVoidType() ? AbstractType::ZoneHandle(Type::NullType())
1047 : result_type);
1023 } 1048 }
1024 1049
1025 return CompileType::Dynamic(); 1050 return CompileType::Dynamic();
1026 } 1051 }
1027 1052
1028 1053
1029 CompileType LoadLocalInstr::ComputeType() const { 1054 CompileType LoadLocalInstr::ComputeType() const {
1030 if (Isolate::Current()->type_checks()) { 1055 if (Isolate::Current()->type_checks()) {
1031 return CompileType::FromAbstractType(local().type()); 1056 return CompileType::FromAbstractType(local().type());
1032 } 1057 }
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
1519 CompileType MergedMathInstr::ComputeType() const { 1544 CompileType MergedMathInstr::ComputeType() const {
1520 return CompileType::Dynamic(); 1545 return CompileType::Dynamic();
1521 } 1546 }
1522 1547
1523 1548
1524 CompileType ExtractNthOutputInstr::ComputeType() const { 1549 CompileType ExtractNthOutputInstr::ComputeType() const {
1525 return CompileType::FromCid(definition_cid_); 1550 return CompileType::FromCid(definition_cid_);
1526 } 1551 }
1527 1552
1528 } // namespace dart 1553 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_x64.cc ('k') | runtime/vm/object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698