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 |