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/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
6 | 6 |
7 #include "vm/code_generator.h" | 7 #include "vm/code_generator.h" |
8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
9 #include "vm/hash_table.h" | 9 #include "vm/hash_table.h" |
10 #include "vm/heap.h" | 10 #include "vm/heap.h" |
(...skipping 907 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
918 "Instantiating TypeRef '%s': '%s'\n" | 918 "Instantiating TypeRef '%s': '%s'\n" |
919 " instantiator: '%s'\n", | 919 " instantiator: '%s'\n", |
920 String::Handle(super_type_arg.Name()).ToCString(), | 920 String::Handle(super_type_arg.Name()).ToCString(), |
921 ref_type.ToCString(), arguments.ToCString()); | 921 ref_type.ToCString(), arguments.ToCString()); |
922 } | 922 } |
923 // In the typical case of an F-bounded type, the instantiation of the | 923 // In the typical case of an F-bounded type, the instantiation of the |
924 // super_type_arg from arguments is a fixpoint. Take the shortcut. | 924 // super_type_arg from arguments is a fixpoint. Take the shortcut. |
925 // Example: class B<T>; class D<T> extends B<D<T>>; | 925 // Example: class B<T>; class D<T> extends B<D<T>>; |
926 // While finalizing D<T>, the super type arg D<T> (a typeref) gets | 926 // While finalizing D<T>, the super type arg D<T> (a typeref) gets |
927 // instantiated from vector [T], yielding itself. | 927 // instantiated from vector [T], yielding itself. |
928 // | |
929 if (super_type_arg.IsTypeRef() && super_type_arg.IsBeingFinalized() && | 928 if (super_type_arg.IsTypeRef() && super_type_arg.IsBeingFinalized() && |
930 (super_type_arg.arguments() == arguments.raw())) { | 929 (super_type_arg.arguments() == arguments.raw())) { |
931 arguments.SetTypeAt(i, super_type_arg); | 930 arguments.SetTypeAt(i, super_type_arg); |
932 continue; | 931 continue; |
933 } | 932 } |
934 Error& error = Error::Handle(); | 933 Error& error = Error::Handle(); |
935 super_type_arg = super_type_arg.InstantiateFrom( | 934 super_type_arg = super_type_arg.InstantiateFrom( |
936 arguments, Object::null_type_arguments(), &error, | 935 arguments, Object::null_type_arguments(), &error, |
937 instantiation_trail, NULL, Heap::kOld); | 936 instantiation_trail, NULL, Heap::kOld); |
938 if (!error.IsNull()) { | 937 if (!error.IsNull()) { |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1167 if (FLAG_trace_type_finalization) { | 1166 if (FLAG_trace_type_finalization) { |
1168 THR_Print("Finalizing type '%s' for class '%s'\n", | 1167 THR_Print("Finalizing type '%s' for class '%s'\n", |
1169 String::Handle(zone, type.Name()).ToCString(), | 1168 String::Handle(zone, type.Name()).ToCString(), |
1170 String::Handle(zone, cls.Name()).ToCString()); | 1169 String::Handle(zone, cls.Name()).ToCString()); |
1171 } | 1170 } |
1172 | 1171 |
1173 if (type.IsTypeParameter()) { | 1172 if (type.IsTypeParameter()) { |
1174 const TypeParameter& type_parameter = TypeParameter::Cast(type); | 1173 const TypeParameter& type_parameter = TypeParameter::Cast(type); |
1175 const Class& parameterized_class = | 1174 const Class& parameterized_class = |
1176 Class::Handle(zone, type_parameter.parameterized_class()); | 1175 Class::Handle(zone, type_parameter.parameterized_class()); |
| 1176 intptr_t offset; |
1177 if (!parameterized_class.IsNull()) { | 1177 if (!parameterized_class.IsNull()) { |
1178 // The index must reflect the position of this type parameter in the type | 1178 // The index must reflect the position of this type parameter in the type |
1179 // arguments vector of its parameterized class. The offset to add is the | 1179 // arguments vector of its parameterized class. The offset to add is the |
1180 // number of type arguments in the super type, which is equal to the | 1180 // number of type arguments in the super type, which is equal to the |
1181 // difference in number of type arguments and type parameters of the | 1181 // difference in number of type arguments and type parameters of the |
1182 // parameterized class. | 1182 // parameterized class. |
1183 const intptr_t offset = parameterized_class.NumTypeArguments() - | 1183 offset = parameterized_class.NumTypeArguments() - |
1184 parameterized_class.NumTypeParameters(); | 1184 parameterized_class.NumTypeParameters(); |
1185 // Calling NumTypeParameters() may finalize this type parameter if it | |
1186 // belongs to a mixin application class. | |
1187 if (!type_parameter.IsFinalized()) { | |
1188 type_parameter.set_index(type_parameter.index() + offset); | |
1189 type_parameter.SetIsFinalized(); | |
1190 } else { | |
1191 ASSERT(cls.IsMixinApplication()); | |
1192 } | |
1193 } else { | 1185 } else { |
1194 // A function type parameter is always finalized. | 1186 const Function& function = |
1195 ASSERT(type_parameter.IsFinalized()); | 1187 Function::Handle(zone, type_parameter.parameterized_function()); |
| 1188 ASSERT(!function.IsNull()); |
| 1189 offset = function.NumParentTypeParameters(); |
| 1190 } |
| 1191 // Calling NumTypeParameters() may finalize this type parameter if it |
| 1192 // belongs to a mixin application class. |
| 1193 if (!type_parameter.IsFinalized()) { |
| 1194 type_parameter.set_index(type_parameter.index() + offset); |
| 1195 type_parameter.SetIsFinalized(); |
| 1196 } else { |
| 1197 ASSERT(cls.IsMixinApplication()); |
1196 } | 1198 } |
1197 | 1199 |
1198 if (FLAG_trace_type_finalization) { | 1200 if (FLAG_trace_type_finalization) { |
1199 THR_Print("Done finalizing type parameter '%s' with index %" Pd "\n", | 1201 THR_Print("Done finalizing type parameter '%s' with index %" Pd "\n", |
1200 String::Handle(zone, type_parameter.name()).ToCString(), | 1202 String::Handle(zone, type_parameter.name()).ToCString(), |
1201 type_parameter.index()); | 1203 type_parameter.index()); |
1202 } | 1204 } |
1203 | 1205 |
1204 // We do not canonicalize type parameters. | 1206 // We do not canonicalize type parameters. |
1205 return type_parameter.raw(); | 1207 return type_parameter.raw(); |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1338 ResolveType(cls, type); | 1340 ResolveType(cls, type); |
1339 } | 1341 } |
1340 } | 1342 } |
1341 | 1343 |
1342 | 1344 |
1343 void ClassFinalizer::FinalizeSignature(const Class& cls, | 1345 void ClassFinalizer::FinalizeSignature(const Class& cls, |
1344 const Function& function, | 1346 const Function& function, |
1345 FinalizationKind finalization) { | 1347 FinalizationKind finalization) { |
1346 AbstractType& type = AbstractType::Handle(); | 1348 AbstractType& type = AbstractType::Handle(); |
1347 AbstractType& finalized_type = AbstractType::Handle(); | 1349 AbstractType& finalized_type = AbstractType::Handle(); |
1348 // Finalize upper bounds of function type parameters. | 1350 // Finalize function type parameters and their upper bounds. |
| 1351 const intptr_t num_parent_type_params = function.NumParentTypeParameters(); |
1349 const intptr_t num_type_params = function.NumTypeParameters(); | 1352 const intptr_t num_type_params = function.NumTypeParameters(); |
1350 if (num_type_params > 0) { | 1353 if (num_type_params > 0) { |
1351 TypeParameter& type_param = TypeParameter::Handle(); | 1354 TypeParameter& type_param = TypeParameter::Handle(); |
1352 const TypeArguments& type_params = | 1355 const TypeArguments& type_params = |
1353 TypeArguments::Handle(function.type_parameters()); | 1356 TypeArguments::Handle(function.type_parameters()); |
1354 for (intptr_t i = 0; i < num_type_params; i++) { | 1357 for (intptr_t i = 0; i < num_type_params; i++) { |
1355 type_param ^= type_params.TypeAt(i); | 1358 type_param ^= type_params.TypeAt(i); |
| 1359 if (!type_param.IsFinalized()) { |
| 1360 type_param.set_index(num_parent_type_params + i); |
| 1361 type_param.SetIsFinalized(); |
| 1362 } |
1356 type = type_param.bound(); | 1363 type = type_param.bound(); |
1357 finalized_type = FinalizeType(cls, type, finalization); | 1364 finalized_type = FinalizeType(cls, type, finalization); |
1358 if (finalized_type.raw() != type.raw()) { | 1365 if (finalized_type.raw() != type.raw()) { |
1359 type_param.set_bound(finalized_type); | 1366 type_param.set_bound(finalized_type); |
1360 } | 1367 } |
1361 } | 1368 } |
1362 } | 1369 } |
1363 // Finalize result type. | 1370 // Finalize result type. |
1364 type = function.result_type(); | 1371 type = function.result_type(); |
1365 finalized_type = FinalizeType(cls, type, finalization); | 1372 finalized_type = FinalizeType(cls, type, finalization); |
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1815 // the super class of its mixin. Note also that the other mixin | 1822 // the super class of its mixin. Note also that the other mixin |
1816 // application will only mixin the last mixin type listed in the first | 1823 // application will only mixin the last mixin type listed in the first |
1817 // mixin application it is mixing in. | 1824 // mixin application it is mixing in. |
1818 param_bound = thread->isolate()->object_store()->object_type(); | 1825 param_bound = thread->isolate()->object_store()->object_type(); |
1819 for (intptr_t i = 0; i < num_super_type_params; i++) { | 1826 for (intptr_t i = 0; i < num_super_type_params; i++) { |
1820 param ^= super_type_params.TypeAt(i); | 1827 param ^= super_type_params.TypeAt(i); |
1821 param_name = param.name(); | 1828 param_name = param.name(); |
1822 param_name = | 1829 param_name = |
1823 Symbols::FromConcat(thread, param_name, Symbols::Backtick()); | 1830 Symbols::FromConcat(thread, param_name, Symbols::Backtick()); |
1824 cloned_param = | 1831 cloned_param = |
1825 TypeParameter::New(mixin_app_class, null_function, cloned_index, 0, | 1832 TypeParameter::New(mixin_app_class, null_function, cloned_index, |
1826 param_name, param_bound, param.token_pos()); | 1833 param_name, param_bound, param.token_pos()); |
1827 cloned_type_params.SetTypeAt(cloned_index, cloned_param); | 1834 cloned_type_params.SetTypeAt(cloned_index, cloned_param); |
1828 // Change the type arguments of the super type to refer to the | 1835 // Change the type arguments of the super type to refer to the |
1829 // cloned type parameters of the mixin application class. | 1836 // cloned type parameters of the mixin application class. |
1830 super_type_args.SetTypeAt(cloned_index, cloned_param); | 1837 super_type_args.SetTypeAt(cloned_index, cloned_param); |
1831 cloned_index++; | 1838 cloned_index++; |
1832 } | 1839 } |
1833 // The super type may have a BoundedType as type argument, but cannot be | 1840 // The super type may have a BoundedType as type argument, but cannot be |
1834 // a BoundedType itself. | 1841 // a BoundedType itself. |
1835 Type::Cast(super_type).set_arguments(super_type_args); | 1842 Type::Cast(super_type).set_arguments(super_type_args); |
(...skipping 17 matching lines...) Expand all Loading... |
1853 for (intptr_t i = 0; i < num_mixin_type_params; i++) { | 1860 for (intptr_t i = 0; i < num_mixin_type_params; i++) { |
1854 param ^= mixin_params.TypeAt(i); | 1861 param ^= mixin_params.TypeAt(i); |
1855 param_name = param.name(); | 1862 param_name = param.name(); |
1856 param_bound = param.bound(); // The bound will be adjusted below. | 1863 param_bound = param.bound(); // The bound will be adjusted below. |
1857 if (!param_bound.IsInstantiated()) { | 1864 if (!param_bound.IsInstantiated()) { |
1858 has_uninstantiated_bounds = true; | 1865 has_uninstantiated_bounds = true; |
1859 } | 1866 } |
1860 cloned_param = | 1867 cloned_param = |
1861 TypeParameter::New(mixin_app_class, null_function, | 1868 TypeParameter::New(mixin_app_class, null_function, |
1862 cloned_index, // Unfinalized index. | 1869 cloned_index, // Unfinalized index. |
1863 0, param_name, param_bound, param.token_pos()); | 1870 param_name, param_bound, param.token_pos()); |
1864 cloned_type_params.SetTypeAt(cloned_index, cloned_param); | 1871 cloned_type_params.SetTypeAt(cloned_index, cloned_param); |
1865 mixin_type_args.SetTypeAt(i, cloned_param); // Unfinalized length. | 1872 mixin_type_args.SetTypeAt(i, cloned_param); // Unfinalized length. |
1866 instantiator.SetTypeAt(offset + i, cloned_param); // Finalized length. | 1873 instantiator.SetTypeAt(offset + i, cloned_param); // Finalized length. |
1867 cloned_index++; | 1874 cloned_index++; |
1868 } | 1875 } |
1869 | 1876 |
1870 // Third, replace the type parameters appearing in the bounds of the mixin | 1877 // Third, replace the type parameters appearing in the bounds of the mixin |
1871 // type parameters, if any, by the cloned type parameters. This can be | 1878 // type parameters, if any, by the cloned type parameters. This can be |
1872 // done by instantiating each bound using the instantiator built above. | 1879 // done by instantiating each bound using the instantiator built above. |
1873 // If the mixin class extends a generic super class, its first finalized | 1880 // If the mixin class extends a generic super class, its first finalized |
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2427 ReportError(cls, cls.token_pos(), | 2434 ReportError(cls, cls.token_pos(), |
2428 "class '%s' has a cycle in its superclass relationship", | 2435 "class '%s' has a cycle in its superclass relationship", |
2429 name.ToCString()); | 2436 name.ToCString()); |
2430 } | 2437 } |
2431 // Finalize super class. | 2438 // Finalize super class. |
2432 Class& super_class = Class::Handle(cls.SuperClass()); | 2439 Class& super_class = Class::Handle(cls.SuperClass()); |
2433 if (!super_class.IsNull()) { | 2440 if (!super_class.IsNull()) { |
2434 FinalizeTypesInClass(super_class); | 2441 FinalizeTypesInClass(super_class); |
2435 } | 2442 } |
2436 // Finalize type parameters before finalizing the super type. | 2443 // Finalize type parameters before finalizing the super type. |
2437 FinalizeTypeParameters(cls); // May change super type. | 2444 FinalizeTypeParameters(cls); // May change super type while applying mixin. |
2438 super_class = cls.SuperClass(); | 2445 super_class = cls.SuperClass(); // Get again possibly changed super class. |
2439 ASSERT(super_class.IsNull() || super_class.is_type_finalized()); | 2446 ASSERT(super_class.IsNull() || super_class.is_type_finalized()); |
2440 // Only resolving rather than finalizing the upper bounds here would result in | 2447 // Only resolving rather than finalizing the upper bounds here would result in |
2441 // instantiated type parameters of the super type to temporarily have | 2448 // instantiated type parameters of the super type to temporarily have |
2442 // unfinalized bounds. It is more efficient to finalize them early. | 2449 // unfinalized bounds. It is more efficient to finalize them early. |
2443 // Finalize bounds even if running in production mode, so that a snapshot | 2450 // Finalize bounds even if running in production mode, so that a snapshot |
2444 // contains them. | 2451 // contains them. |
2445 FinalizeUpperBounds(cls); | 2452 FinalizeUpperBounds(cls); |
2446 // Finalize super type. | 2453 // Finalize super type. |
2447 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 2454 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
2448 if (!super_type.IsNull()) { | 2455 if (!super_type.IsNull()) { |
(...skipping 1314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3763 ProgramVisitor::VisitFunctions(&function_visitor); | 3770 ProgramVisitor::VisitFunctions(&function_visitor); |
3764 | 3771 |
3765 class ClearCodeClassVisitor : public ClassVisitor { | 3772 class ClearCodeClassVisitor : public ClassVisitor { |
3766 void Visit(const Class& cls) { cls.DisableAllocationStub(); } | 3773 void Visit(const Class& cls) { cls.DisableAllocationStub(); } |
3767 }; | 3774 }; |
3768 ClearCodeClassVisitor class_visitor; | 3775 ClearCodeClassVisitor class_visitor; |
3769 ProgramVisitor::VisitClasses(&class_visitor); | 3776 ProgramVisitor::VisitClasses(&class_visitor); |
3770 } | 3777 } |
3771 | 3778 |
3772 } // namespace dart | 3779 } // namespace dart |
OLD | NEW |