| 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 #if !defined(DART_PRECOMPILED_RUNTIME) | 5 #if !defined(DART_PRECOMPILED_RUNTIME) |
| 6 | 6 |
| 7 #include "vm/flow_graph_type_propagator.h" | 7 #include "vm/flow_graph_type_propagator.h" |
| 8 | 8 |
| 9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
| 10 #include "vm/cha.h" | 10 #include "vm/cha.h" |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 SetCid(instr->ArgumentAt(0), instr->targets().MonomorphicReceiverCid()); | 287 SetCid(instr->ArgumentAt(0), instr->targets().MonomorphicReceiverCid()); |
| 288 return; | 288 return; |
| 289 } | 289 } |
| 290 CheckNonNullSelector(instr, instr->ArgumentAt(0), | 290 CheckNonNullSelector(instr, instr->ArgumentAt(0), |
| 291 instr->instance_call()->function_name()); | 291 instr->instance_call()->function_name()); |
| 292 } | 292 } |
| 293 | 293 |
| 294 void FlowGraphTypePropagator::VisitGuardFieldClass( | 294 void FlowGraphTypePropagator::VisitGuardFieldClass( |
| 295 GuardFieldClassInstr* guard) { | 295 GuardFieldClassInstr* guard) { |
| 296 const intptr_t cid = guard->field().guarded_cid(); | 296 const intptr_t cid = guard->field().guarded_cid(); |
| 297 if ((cid == kIllegalCid) || (cid == kDynamicCid) || | 297 if ((cid == kIllegalCid) || (cid == kDynamicCid)) { |
| 298 Field::IsExternalizableCid(cid)) { | |
| 299 return; | 298 return; |
| 300 } | 299 } |
| 301 | 300 |
| 302 Definition* def = guard->value()->definition(); | 301 Definition* def = guard->value()->definition(); |
| 303 CompileType* current = TypeOf(def); | 302 CompileType* current = TypeOf(def); |
| 304 if (current->IsNone() || (current->ToCid() != cid) || | 303 if (current->IsNone() || (current->ToCid() != cid) || |
| 305 (current->is_nullable() && !guard->field().is_nullable())) { | 304 (current->is_nullable() && !guard->field().is_nullable())) { |
| 306 const bool is_nullable = | 305 const bool is_nullable = |
| 307 guard->field().is_nullable() && current->is_nullable(); | 306 guard->field().is_nullable() && current->is_nullable(); |
| 308 SetTypeOf(def, new CompileType(is_nullable, cid, NULL)); | 307 SetTypeOf(def, new CompileType(is_nullable, cid, NULL)); |
| (...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 849 CompileType PushArgumentInstr::ComputeType() const { | 848 CompileType PushArgumentInstr::ComputeType() const { |
| 850 return CompileType::Dynamic(); | 849 return CompileType::Dynamic(); |
| 851 } | 850 } |
| 852 | 851 |
| 853 CompileType ConstantInstr::ComputeType() const { | 852 CompileType ConstantInstr::ComputeType() const { |
| 854 if (value().IsNull()) { | 853 if (value().IsNull()) { |
| 855 return CompileType::Null(); | 854 return CompileType::Null(); |
| 856 } | 855 } |
| 857 | 856 |
| 858 intptr_t cid = value().GetClassId(); | 857 intptr_t cid = value().GetClassId(); |
| 859 if (Field::IsExternalizableCid(cid)) { | |
| 860 cid = kDynamicCid; | |
| 861 } | |
| 862 | 858 |
| 863 if (value().IsInstance()) { | 859 if (value().IsInstance()) { |
| 864 // Allocate in old-space since this may be invoked from the | 860 // Allocate in old-space since this may be invoked from the |
| 865 // background compiler. | 861 // background compiler. |
| 866 return CompileType::Create( | 862 return CompileType::Create( |
| 867 cid, | 863 cid, |
| 868 AbstractType::ZoneHandle(Instance::Cast(value()).GetType(Heap::kOld))); | 864 AbstractType::ZoneHandle(Instance::Cast(value()).GetType(Heap::kOld))); |
| 869 } else { | 865 } else { |
| 870 // Type info for non-instance objects. | 866 // Type info for non-instance objects. |
| 871 return CompileType::FromCid(cid); | 867 return CompileType::FromCid(cid); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1015 if ((obj.raw() != Object::sentinel().raw()) && | 1011 if ((obj.raw() != Object::sentinel().raw()) && |
| 1016 (obj.raw() != Object::transition_sentinel().raw()) && !obj.IsNull()) { | 1012 (obj.raw() != Object::transition_sentinel().raw()) && !obj.IsNull()) { |
| 1017 is_nullable = CompileType::kNonNullable; | 1013 is_nullable = CompileType::kNonNullable; |
| 1018 cid = obj.GetClassId(); | 1014 cid = obj.GetClassId(); |
| 1019 } | 1015 } |
| 1020 } else if (field.guarded_cid() != kIllegalCid) { | 1016 } else if (field.guarded_cid() != kIllegalCid) { |
| 1021 cid = field.guarded_cid(); | 1017 cid = field.guarded_cid(); |
| 1022 if (!IsNullableCid(cid)) is_nullable = CompileType::kNonNullable; | 1018 if (!IsNullableCid(cid)) is_nullable = CompileType::kNonNullable; |
| 1023 } | 1019 } |
| 1024 } | 1020 } |
| 1025 if (Field::IsExternalizableCid(cid)) { | |
| 1026 cid = kDynamicCid; | |
| 1027 } | |
| 1028 return CompileType(is_nullable, cid, abstract_type); | 1021 return CompileType(is_nullable, cid, abstract_type); |
| 1029 } | 1022 } |
| 1030 | 1023 |
| 1031 CompileType CreateArrayInstr::ComputeType() const { | 1024 CompileType CreateArrayInstr::ComputeType() const { |
| 1032 // TODO(fschneider): Add abstract type and type arguments to the compile type. | 1025 // TODO(fschneider): Add abstract type and type arguments to the compile type. |
| 1033 return CompileType::FromCid(kArrayCid); | 1026 return CompileType::FromCid(kArrayCid); |
| 1034 } | 1027 } |
| 1035 | 1028 |
| 1036 CompileType AllocateObjectInstr::ComputeType() const { | 1029 CompileType AllocateObjectInstr::ComputeType() const { |
| 1037 if (!closure_function().IsNull()) { | 1030 if (!closure_function().IsNull()) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1054 CompileType LoadFieldInstr::ComputeType() const { | 1047 CompileType LoadFieldInstr::ComputeType() const { |
| 1055 // Type may be null if the field is a VM field, e.g. context parent. | 1048 // Type may be null if the field is a VM field, e.g. context parent. |
| 1056 // Keep it as null for debug purposes and do not return dynamic in production | 1049 // Keep it as null for debug purposes and do not return dynamic in production |
| 1057 // mode, since misuse of the type would remain undetected. | 1050 // mode, since misuse of the type would remain undetected. |
| 1058 if (type().IsNull()) { | 1051 if (type().IsNull()) { |
| 1059 return CompileType::Dynamic(); | 1052 return CompileType::Dynamic(); |
| 1060 } | 1053 } |
| 1061 | 1054 |
| 1062 const AbstractType* abstract_type = NULL; | 1055 const AbstractType* abstract_type = NULL; |
| 1063 if (Isolate::Current()->type_checks() && | 1056 if (Isolate::Current()->type_checks() && |
| 1064 (type().IsFunctionType() || | 1057 (type().IsFunctionType() || type().HasResolvedTypeClass())) { |
| 1065 (type().HasResolvedTypeClass() && | |
| 1066 !Field::IsExternalizableCid( | |
| 1067 Class::Handle(type().type_class()).id())))) { | |
| 1068 abstract_type = &type(); | 1058 abstract_type = &type(); |
| 1069 } | 1059 } |
| 1070 | 1060 |
| 1071 if ((field_ != NULL) && (field_->guarded_cid() != kIllegalCid)) { | 1061 if ((field_ != NULL) && (field_->guarded_cid() != kIllegalCid)) { |
| 1072 bool is_nullable = field_->is_nullable(); | 1062 bool is_nullable = field_->is_nullable(); |
| 1073 intptr_t field_cid = field_->guarded_cid(); | 1063 intptr_t field_cid = field_->guarded_cid(); |
| 1074 if (Field::IsExternalizableCid(field_cid)) { | |
| 1075 // We cannot assume that the type of the value in the field has not | |
| 1076 // changed on the fly. | |
| 1077 field_cid = kDynamicCid; | |
| 1078 } | |
| 1079 return CompileType(is_nullable, field_cid, abstract_type); | 1064 return CompileType(is_nullable, field_cid, abstract_type); |
| 1080 } | 1065 } |
| 1081 | 1066 |
| 1082 ASSERT(!Field::IsExternalizableCid(result_cid_)); | |
| 1083 return CompileType::Create(result_cid_, *abstract_type); | 1067 return CompileType::Create(result_cid_, *abstract_type); |
| 1084 } | 1068 } |
| 1085 | 1069 |
| 1086 CompileType LoadCodeUnitsInstr::ComputeType() const { | 1070 CompileType LoadCodeUnitsInstr::ComputeType() const { |
| 1087 switch (class_id()) { | 1071 switch (class_id()) { |
| 1088 case kOneByteStringCid: | 1072 case kOneByteStringCid: |
| 1089 case kExternalOneByteStringCid: | 1073 case kExternalOneByteStringCid: |
| 1090 case kTwoByteStringCid: | 1074 case kTwoByteStringCid: |
| 1091 case kExternalTwoByteStringCid: | 1075 case kExternalTwoByteStringCid: |
| 1092 return can_pack_into_smi() ? CompileType::FromCid(kSmiCid) | 1076 return can_pack_into_smi() ? CompileType::FromCid(kSmiCid) |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1394 return CompileType::Dynamic(); | 1378 return CompileType::Dynamic(); |
| 1395 } | 1379 } |
| 1396 | 1380 |
| 1397 CompileType ExtractNthOutputInstr::ComputeType() const { | 1381 CompileType ExtractNthOutputInstr::ComputeType() const { |
| 1398 return CompileType::FromCid(definition_cid_); | 1382 return CompileType::FromCid(definition_cid_); |
| 1399 } | 1383 } |
| 1400 | 1384 |
| 1401 } // namespace dart | 1385 } // namespace dart |
| 1402 | 1386 |
| 1403 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 1387 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
| OLD | NEW |