| OLD | NEW |
| 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/regexp_assembler.h" | 10 #include "vm/regexp_assembler.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 flow_graph->zone(), flow_graph->reverse_postorder().length())), | 31 flow_graph->zone(), flow_graph->reverse_postorder().length())), |
| 32 types_(flow_graph->current_ssa_temp_index()), | 32 types_(flow_graph->current_ssa_temp_index()), |
| 33 in_worklist_(new(flow_graph->zone()) BitVector( | 33 in_worklist_(new(flow_graph->zone()) BitVector( |
| 34 flow_graph->zone(), flow_graph->current_ssa_temp_index())), | 34 flow_graph->zone(), flow_graph->current_ssa_temp_index())), |
| 35 asserts_(NULL), | 35 asserts_(NULL), |
| 36 collected_asserts_(NULL) { | 36 collected_asserts_(NULL) { |
| 37 for (intptr_t i = 0; i < flow_graph->current_ssa_temp_index(); i++) { | 37 for (intptr_t i = 0; i < flow_graph->current_ssa_temp_index(); i++) { |
| 38 types_.Add(NULL); | 38 types_.Add(NULL); |
| 39 } | 39 } |
| 40 | 40 |
| 41 if (Isolate::Current()->TypeChecksEnabled()) { | 41 if (Isolate::Current()->flags().type_checks()) { |
| 42 asserts_ = new ZoneGrowableArray<AssertAssignableInstr*>( | 42 asserts_ = new ZoneGrowableArray<AssertAssignableInstr*>( |
| 43 flow_graph->current_ssa_temp_index()); | 43 flow_graph->current_ssa_temp_index()); |
| 44 for (intptr_t i = 0; i < flow_graph->current_ssa_temp_index(); i++) { | 44 for (intptr_t i = 0; i < flow_graph->current_ssa_temp_index(); i++) { |
| 45 asserts_->Add(NULL); | 45 asserts_->Add(NULL); |
| 46 } | 46 } |
| 47 | 47 |
| 48 collected_asserts_ = new ZoneGrowableArray<intptr_t>(10); | 48 collected_asserts_ = new ZoneGrowableArray<intptr_t>(10); |
| 49 } | 49 } |
| 50 } | 50 } |
| 51 | 51 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 | 113 |
| 114 | 114 |
| 115 void FlowGraphTypePropagator::PropagateRecursive(BlockEntryInstr* block) { | 115 void FlowGraphTypePropagator::PropagateRecursive(BlockEntryInstr* block) { |
| 116 if (visited_blocks_->Contains(block->postorder_number())) { | 116 if (visited_blocks_->Contains(block->postorder_number())) { |
| 117 return; | 117 return; |
| 118 } | 118 } |
| 119 visited_blocks_->Add(block->postorder_number()); | 119 visited_blocks_->Add(block->postorder_number()); |
| 120 | 120 |
| 121 const intptr_t rollback_point = rollback_.length(); | 121 const intptr_t rollback_point = rollback_.length(); |
| 122 | 122 |
| 123 if (Isolate::Current()->TypeChecksEnabled()) { | 123 if (Isolate::Current()->flags().type_checks()) { |
| 124 StrengthenAsserts(block); | 124 StrengthenAsserts(block); |
| 125 } | 125 } |
| 126 | 126 |
| 127 block->Accept(this); | 127 block->Accept(this); |
| 128 | 128 |
| 129 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { | 129 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
| 130 Instruction* instr = it.Current(); | 130 Instruction* instr = it.Current(); |
| 131 | 131 |
| 132 for (intptr_t i = 0; i < instr->InputCount(); i++) { | 132 for (intptr_t i = 0; i < instr->InputCount(); i++) { |
| 133 VisitValue(instr->InputAt(i)); | 133 VisitValue(instr->InputAt(i)); |
| (...skipping 780 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 914 kContextCid, | 914 kContextCid, |
| 915 &AbstractType::ZoneHandle(Type::DynamicType())); | 915 &AbstractType::ZoneHandle(Type::DynamicType())); |
| 916 } | 916 } |
| 917 | 917 |
| 918 | 918 |
| 919 CompileType StaticCallInstr::ComputeType() const { | 919 CompileType StaticCallInstr::ComputeType() const { |
| 920 if (result_cid_ != kDynamicCid) { | 920 if (result_cid_ != kDynamicCid) { |
| 921 return CompileType::FromCid(result_cid_); | 921 return CompileType::FromCid(result_cid_); |
| 922 } | 922 } |
| 923 | 923 |
| 924 if (Isolate::Current()->TypeChecksEnabled()) { | 924 if (Isolate::Current()->flags().type_checks()) { |
| 925 // Void functions are known to return null, which is checked at the return | 925 // Void functions are known to return null, which is checked at the return |
| 926 // from the function. | 926 // from the function. |
| 927 const AbstractType& result_type = | 927 const AbstractType& result_type = |
| 928 AbstractType::ZoneHandle(function().result_type()); | 928 AbstractType::ZoneHandle(function().result_type()); |
| 929 return CompileType::FromAbstractType(result_type.IsVoidType() | 929 return CompileType::FromAbstractType(result_type.IsVoidType() |
| 930 ? AbstractType::ZoneHandle(Type::NullType()) | 930 ? AbstractType::ZoneHandle(Type::NullType()) |
| 931 : result_type); | 931 : result_type); |
| 932 } | 932 } |
| 933 | 933 |
| 934 return CompileType::Dynamic(); | 934 return CompileType::Dynamic(); |
| 935 } | 935 } |
| 936 | 936 |
| 937 | 937 |
| 938 CompileType LoadLocalInstr::ComputeType() const { | 938 CompileType LoadLocalInstr::ComputeType() const { |
| 939 if (Isolate::Current()->TypeChecksEnabled()) { | 939 if (Isolate::Current()->flags().type_checks()) { |
| 940 return CompileType::FromAbstractType(local().type()); | 940 return CompileType::FromAbstractType(local().type()); |
| 941 } | 941 } |
| 942 return CompileType::Dynamic(); | 942 return CompileType::Dynamic(); |
| 943 } | 943 } |
| 944 | 944 |
| 945 | 945 |
| 946 CompileType PushTempInstr::ComputeType() const { | 946 CompileType PushTempInstr::ComputeType() const { |
| 947 return CompileType::Dynamic(); | 947 return CompileType::Dynamic(); |
| 948 } | 948 } |
| 949 | 949 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 973 // TODO(srdjan): Do better and determine if it is a one or two byte string. | 973 // TODO(srdjan): Do better and determine if it is a one or two byte string. |
| 974 return CompileType::String(); | 974 return CompileType::String(); |
| 975 } | 975 } |
| 976 | 976 |
| 977 | 977 |
| 978 CompileType LoadStaticFieldInstr::ComputeType() const { | 978 CompileType LoadStaticFieldInstr::ComputeType() const { |
| 979 bool is_nullable = CompileType::kNullable; | 979 bool is_nullable = CompileType::kNullable; |
| 980 intptr_t cid = kDynamicCid; | 980 intptr_t cid = kDynamicCid; |
| 981 AbstractType* abstract_type = NULL; | 981 AbstractType* abstract_type = NULL; |
| 982 const Field& field = this->StaticField(); | 982 const Field& field = this->StaticField(); |
| 983 if (Isolate::Current()->TypeChecksEnabled()) { | 983 if (Isolate::Current()->flags().type_checks()) { |
| 984 cid = kIllegalCid; | 984 cid = kIllegalCid; |
| 985 abstract_type = &AbstractType::ZoneHandle(field.type()); | 985 abstract_type = &AbstractType::ZoneHandle(field.type()); |
| 986 } | 986 } |
| 987 ASSERT(field.is_static()); | 987 ASSERT(field.is_static()); |
| 988 if (field.is_final()) { | 988 if (field.is_final()) { |
| 989 const Instance& obj = Instance::Handle(field.value()); | 989 const Instance& obj = Instance::Handle(field.value()); |
| 990 if ((obj.raw() != Object::sentinel().raw()) && | 990 if ((obj.raw() != Object::sentinel().raw()) && |
| 991 (obj.raw() != Object::transition_sentinel().raw()) && | 991 (obj.raw() != Object::transition_sentinel().raw()) && |
| 992 !obj.IsNull()) { | 992 !obj.IsNull()) { |
| 993 is_nullable = CompileType::kNonNullable; | 993 is_nullable = CompileType::kNonNullable; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1031 | 1031 |
| 1032 CompileType LoadFieldInstr::ComputeType() const { | 1032 CompileType LoadFieldInstr::ComputeType() const { |
| 1033 // Type may be null if the field is a VM field, e.g. context parent. | 1033 // Type may be null if the field is a VM field, e.g. context parent. |
| 1034 // Keep it as null for debug purposes and do not return dynamic in production | 1034 // Keep it as null for debug purposes and do not return dynamic in production |
| 1035 // mode, since misuse of the type would remain undetected. | 1035 // mode, since misuse of the type would remain undetected. |
| 1036 if (type().IsNull()) { | 1036 if (type().IsNull()) { |
| 1037 return CompileType::Dynamic(); | 1037 return CompileType::Dynamic(); |
| 1038 } | 1038 } |
| 1039 | 1039 |
| 1040 const AbstractType* abstract_type = NULL; | 1040 const AbstractType* abstract_type = NULL; |
| 1041 if (Isolate::Current()->TypeChecksEnabled()) { | 1041 if (Isolate::Current()->flags().type_checks()) { |
| 1042 ASSERT(!type().HasResolvedTypeClass() || | 1042 ASSERT(!type().HasResolvedTypeClass() || |
| 1043 !Field::IsExternalizableCid(Class::Handle( | 1043 !Field::IsExternalizableCid(Class::Handle( |
| 1044 type().type_class()).id())); | 1044 type().type_class()).id())); |
| 1045 abstract_type = &type(); | 1045 abstract_type = &type(); |
| 1046 } | 1046 } |
| 1047 | 1047 |
| 1048 if ((field_ != NULL) && (field_->guarded_cid() != kIllegalCid)) { | 1048 if ((field_ != NULL) && (field_->guarded_cid() != kIllegalCid)) { |
| 1049 bool is_nullable = field_->is_nullable(); | 1049 bool is_nullable = field_->is_nullable(); |
| 1050 intptr_t field_cid = field_->guarded_cid(); | 1050 intptr_t field_cid = field_->guarded_cid(); |
| 1051 if (Field::IsExternalizableCid(field_cid)) { | 1051 if (Field::IsExternalizableCid(field_cid)) { |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1424 CompileType MergedMathInstr::ComputeType() const { | 1424 CompileType MergedMathInstr::ComputeType() const { |
| 1425 return CompileType::Dynamic(); | 1425 return CompileType::Dynamic(); |
| 1426 } | 1426 } |
| 1427 | 1427 |
| 1428 | 1428 |
| 1429 CompileType ExtractNthOutputInstr::ComputeType() const { | 1429 CompileType ExtractNthOutputInstr::ComputeType() const { |
| 1430 return CompileType::FromCid(definition_cid_); | 1430 return CompileType::FromCid(definition_cid_); |
| 1431 } | 1431 } |
| 1432 | 1432 |
| 1433 } // namespace dart | 1433 } // namespace dart |
| OLD | NEW |