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

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

Issue 2718513002: Void is not required to be `null` anymore. (Closed)
Patch Set: Update Kernel code. 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/kernel_to_il.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_ = kNullCid; 600 cid_ = kDynamicCid;
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()) { 687 if (type.IsDynamicType() || type.IsObjectType() || type.IsVoidType()) {
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
704 if (compile_type.IsMalformedOrMalbounded()) { 699 if (compile_type.IsMalformedOrMalbounded()) {
705 return false; 700 return false;
706 } 701 }
707 702
708 // The null instance is an instance of Null, of Object, and of dynamic. 703 // The null instance is an instance of Null, of Object, and of dynamic.
709 // Functions that do not explicitly return a value, implicitly return null, 704 // Functions that do not explicitly return a value, implicitly return null,
710 // except generative constructors, which return the object being constructed. 705 // except generative constructors, which return the object being constructed.
711 // It is therefore acceptable for void functions to return null. 706 // It is therefore acceptable for void functions to return null.
712 if (compile_type.IsNullType()) { 707 if (compile_type.IsNullType()) {
713 *is_instance = is_nullable || type.IsObjectType() || type.IsDynamicType() || 708 *is_instance = is_nullable || type.IsObjectType() || type.IsDynamicType() ||
714 type.IsNullType() || type.IsVoidType(); 709 type.IsNullType() || type.IsVoidType();
715 return true; 710 return true;
716 } 711 }
717 712
718 // A non-null value is not an instance of void.
719 if (type.IsVoidType()) {
720 *is_instance = IsNull();
721 return HasDecidableNullability();
722 }
723
724 // If the value can be null then we can't eliminate the 713 // If the value can be null then we can't eliminate the
725 // check unless null is allowed. 714 // check unless null is allowed.
726 if (is_nullable_ && !is_nullable) { 715 if (is_nullable_ && !is_nullable) {
727 return false; 716 return false;
728 } 717 }
729 718
730 *is_instance = compile_type.IsMoreSpecificThan(type, NULL, NULL, Heap::kOld); 719 *is_instance = compile_type.IsMoreSpecificThan(type, NULL, NULL, Heap::kOld);
731 return *is_instance; 720 return *is_instance;
732 } 721 }
733 722
734 723
735 bool CompileType::IsMoreSpecificThan(const AbstractType& other) { 724 bool CompileType::IsMoreSpecificThan(const AbstractType& other) {
736 if (IsNone()) { 725 if (IsNone()) {
737 return false; 726 return false;
738 } 727 }
739 728
740 if (other.IsVoidType()) {
741 // The only value assignable to void is null.
742 return IsNull();
743 }
744
745 return ToAbstractType()->IsMoreSpecificThan(other, NULL, NULL, Heap::kOld); 729 return ToAbstractType()->IsMoreSpecificThan(other, NULL, NULL, Heap::kOld);
746 } 730 }
747 731
748 732
749 CompileType* Value::Type() { 733 CompileType* Value::Type() {
750 if (reaching_type_ == NULL) { 734 if (reaching_type_ == NULL) {
751 reaching_type_ = definition()->Type(); 735 reaching_type_ = definition()->Type();
752 } 736 }
753 return reaching_type_; 737 return reaching_type_;
754 } 738 }
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
936 } 920 }
937 921
938 922
939 CompileType AssertAssignableInstr::ComputeType() const { 923 CompileType AssertAssignableInstr::ComputeType() const {
940 CompileType* value_type = value()->Type(); 924 CompileType* value_type = value()->Type();
941 925
942 if (value_type->IsMoreSpecificThan(dst_type())) { 926 if (value_type->IsMoreSpecificThan(dst_type())) {
943 return *value_type; 927 return *value_type;
944 } 928 }
945 929
946 if (dst_type().IsVoidType()) {
947 // The only value assignable to void is null.
948 return CompileType::Null();
949 }
950
951 return CompileType::Create(value_type->ToCid(), dst_type()); 930 return CompileType::Create(value_type->ToCid(), dst_type());
952 } 931 }
953 932
954 933
955 bool AssertAssignableInstr::RecomputeType() { 934 bool AssertAssignableInstr::RecomputeType() {
956 return UpdateType(ComputeType()); 935 return UpdateType(ComputeType());
957 } 936 }
958 937
959 938
960 CompileType AssertBooleanInstr::ComputeType() const { 939 CompileType AssertBooleanInstr::ComputeType() const {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1031 : CompileType::Dynamic(); 1010 : CompileType::Dynamic();
1032 } 1011 }
1033 1012
1034 1013
1035 CompileType StaticCallInstr::ComputeType() const { 1014 CompileType StaticCallInstr::ComputeType() const {
1036 if (result_cid_ != kDynamicCid) { 1015 if (result_cid_ != kDynamicCid) {
1037 return CompileType::FromCid(result_cid_); 1016 return CompileType::FromCid(result_cid_);
1038 } 1017 }
1039 1018
1040 if (Isolate::Current()->type_checks()) { 1019 if (Isolate::Current()->type_checks()) {
1041 // Void functions are known to return null, which is checked at the return
1042 // from the function.
1043 const AbstractType& result_type = 1020 const AbstractType& result_type =
1044 AbstractType::ZoneHandle(function().result_type()); 1021 AbstractType::ZoneHandle(function().result_type());
1045 return CompileType::FromAbstractType( 1022 return CompileType::FromAbstractType(result_type);
1046 result_type.IsVoidType() ? AbstractType::ZoneHandle(Type::NullType())
1047 : result_type);
1048 } 1023 }
1049 1024
1050 return CompileType::Dynamic(); 1025 return CompileType::Dynamic();
1051 } 1026 }
1052 1027
1053 1028
1054 CompileType LoadLocalInstr::ComputeType() const { 1029 CompileType LoadLocalInstr::ComputeType() const {
1055 if (Isolate::Current()->type_checks()) { 1030 if (Isolate::Current()->type_checks()) {
1056 return CompileType::FromAbstractType(local().type()); 1031 return CompileType::FromAbstractType(local().type());
1057 } 1032 }
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
1544 CompileType MergedMathInstr::ComputeType() const { 1519 CompileType MergedMathInstr::ComputeType() const {
1545 return CompileType::Dynamic(); 1520 return CompileType::Dynamic();
1546 } 1521 }
1547 1522
1548 1523
1549 CompileType ExtractNthOutputInstr::ComputeType() const { 1524 CompileType ExtractNthOutputInstr::ComputeType() const {
1550 return CompileType::FromCid(definition_cid_); 1525 return CompileType::FromCid(definition_cid_);
1551 } 1526 }
1552 1527
1553 } // namespace dart 1528 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_x64.cc ('k') | runtime/vm/kernel_to_il.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698