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 797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
808 // The parameterized_type is raw. Set its argument vector to null, which | 808 // The parameterized_type is raw. Set its argument vector to null, which |
809 // is more efficient in type tests. | 809 // is more efficient in type tests. |
810 full_arguments = TypeArguments::null(); | 810 full_arguments = TypeArguments::null(); |
811 } | 811 } |
812 type.set_arguments(full_arguments); | 812 type.set_arguments(full_arguments); |
813 } else { | 813 } else { |
814 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. | 814 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. |
815 } | 815 } |
816 } | 816 } |
817 | 817 |
818 // Self referencing types may get finalized indirectly. | 818 ASSERT(full_arguments.IsNull() || |
819 if (!type.IsFinalized()) { | 819 !full_arguments.IsRaw(0, num_type_arguments)); |
820 ASSERT(full_arguments.IsNull() || | |
821 !full_arguments.IsRaw(0, num_type_arguments)); | |
822 if (FLAG_trace_type_finalization) { | |
823 THR_Print("Marking type '%s' as finalized for class '%s'\n", | |
824 String::Handle(zone, type.Name()).ToCString(), | |
825 String::Handle(zone, cls.Name()).ToCString()); | |
826 } | |
827 // Mark the type as finalized. | |
828 type.SetIsFinalized(); | |
829 // Do not yet remove the type from the pending_types array. | |
830 } | |
831 return full_arguments.IsNull() ? 0 : full_arguments.Length(); | 820 return full_arguments.IsNull() ? 0 : full_arguments.Length(); |
832 } | 821 } |
833 | 822 |
834 | 823 |
835 // Finalize the type argument vector 'arguments' of the type defined by the | 824 // Finalize the type argument vector 'arguments' of the type defined by the |
836 // class 'cls' parameterized with the type arguments 'cls_args'. | 825 // class 'cls' parameterized with the type arguments 'cls_args'. |
837 // The vector 'cls_args' is already initialized as a subvector at the correct | 826 // The vector 'cls_args' is already initialized as a subvector at the correct |
838 // position in the passed in 'arguments' vector. | 827 // position in the passed in 'arguments' vector. |
839 // The subvector 'cls_args' has length cls.NumTypeParameters() and starts at | 828 // The subvector 'cls_args' has length cls.NumTypeParameters() and starts at |
840 // offset cls.NumTypeArguments() - cls.NumTypeParameters() of the 'arguments' | 829 // offset cls.NumTypeArguments() - cls.NumTypeParameters() of the 'arguments' |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1218 // allocated yet, and if canonicalization is required. | 1207 // allocated yet, and if canonicalization is required. |
1219 const bool is_root_type = | 1208 const bool is_root_type = |
1220 (pending_types == NULL) && (finalization >= kCanonicalize); | 1209 (pending_types == NULL) && (finalization >= kCanonicalize); |
1221 if (is_root_type) { | 1210 if (is_root_type) { |
1222 pending_types = new PendingTypes(zone, 4); | 1211 pending_types = new PendingTypes(zone, 4); |
1223 } | 1212 } |
1224 | 1213 |
1225 const intptr_t num_expanded_type_arguments = | 1214 const intptr_t num_expanded_type_arguments = |
1226 ExpandAndFinalizeTypeArguments(cls, type, pending_types); | 1215 ExpandAndFinalizeTypeArguments(cls, type, pending_types); |
1227 | 1216 |
| 1217 // Self referencing types may get finalized indirectly. |
| 1218 if (!type.IsFinalized()) { |
| 1219 // If the type is a function type, we also need to finalize the types in its |
| 1220 // signature, i.e. finalize the result type and parameter types of the |
| 1221 // signature function of this function type. |
| 1222 // We do this after marking this type as finalized in order to allow a |
| 1223 // typedef function type to refer to itself via its parameter types and |
| 1224 // result type. |
| 1225 if (type.IsFunctionType()) { |
| 1226 const Type& fun_type = Type::Cast(type); |
| 1227 const Class& scope_class = Class::Handle(zone, fun_type.type_class()); |
| 1228 if (scope_class.IsTypedefClass()) { |
| 1229 Function& signature = |
| 1230 Function::Handle(zone, scope_class.signature_function()); |
| 1231 if (!scope_class.is_type_finalized()) { |
| 1232 FinalizeSignature(scope_class, signature); |
| 1233 } |
| 1234 // If the function type is a generic typedef, instantiate its signature |
| 1235 // from its type arguments. |
| 1236 // Example: typedef T F<T>(T x) has uninstantiated signature (T x) => T. |
| 1237 // The instantiated signature of F(int) becomes (int x) => int. |
| 1238 // Note that after this step, the signature of the function type is not |
| 1239 // identical to the canonical signature of the typedef class anymore. |
| 1240 if (scope_class.IsGeneric() && !signature.HasInstantiatedSignature()) { |
| 1241 const TypeArguments& type_args = |
| 1242 TypeArguments::Handle(zone, fun_type.arguments()); |
| 1243 if (FLAG_trace_type_finalization) { |
| 1244 THR_Print("Instantiating signature '%s' of typedef '%s'\n", |
| 1245 String::Handle(zone, signature.Signature()).ToCString(), |
| 1246 String::Handle(zone, fun_type.Name()).ToCString()); |
| 1247 } |
| 1248 signature = signature.InstantiateSignatureFrom(type_args, Heap::kOld); |
| 1249 // Note that if type_args contains type parameters, signature is still |
| 1250 // uninstantiated here (typedef type parameters were substituted in |
| 1251 // the signature with typedef type arguments). |
| 1252 } |
| 1253 fun_type.set_signature(signature); |
| 1254 } else { |
| 1255 FinalizeSignature(cls, Function::Handle(zone, fun_type.signature())); |
| 1256 } |
| 1257 } |
| 1258 |
| 1259 if (FLAG_trace_type_finalization) { |
| 1260 THR_Print("Marking type '%s' as finalized for class '%s'\n", |
| 1261 String::Handle(zone, type.Name()).ToCString(), |
| 1262 String::Handle(zone, cls.Name()).ToCString()); |
| 1263 } |
| 1264 // Mark the type as finalized. |
| 1265 type.SetIsFinalized(); |
| 1266 } |
| 1267 |
1228 // If we are done finalizing a graph of mutually recursive types, check their | 1268 // If we are done finalizing a graph of mutually recursive types, check their |
1229 // bounds. | 1269 // bounds. |
1230 if (is_root_type) { | 1270 if (is_root_type) { |
1231 for (intptr_t i = pending_types->length() - 1; i >= 0; i--) { | 1271 for (intptr_t i = pending_types->length() - 1; i >= 0; i--) { |
1232 const AbstractType& type = pending_types->At(i); | 1272 const AbstractType& type = pending_types->At(i); |
1233 if (!type.IsMalformed() && !type.IsCanonical()) { | 1273 if (!type.IsMalformed() && !type.IsCanonical()) { |
1234 CheckTypeBounds(cls, type); | 1274 CheckTypeBounds(cls, type); |
1235 } | 1275 } |
1236 } | 1276 } |
1237 } | 1277 } |
1238 | 1278 |
1239 // If the type is a function type, we also need to finalize the types in its | |
1240 // signature, i.e. finalize the result type and parameter types of the | |
1241 // signature function of this function type. | |
1242 // We do this after marking this type as finalized in order to allow a | |
1243 // typedef function type to refer to itself via its parameter types and | |
1244 // result type. | |
1245 if (type.IsFunctionType()) { | |
1246 ASSERT(!type.IsBeingFinalized()); | |
1247 const Type& fun_type = Type::Cast(type); | |
1248 const Class& scope_class = Class::Handle(zone, fun_type.type_class()); | |
1249 if (scope_class.IsTypedefClass()) { | |
1250 Function& signature = | |
1251 Function::Handle(zone, scope_class.signature_function()); | |
1252 if (!scope_class.is_type_finalized()) { | |
1253 FinalizeSignature(scope_class, signature); | |
1254 } | |
1255 // If the function type is a generic typedef, instantiate its signature | |
1256 // from its type arguments. | |
1257 // Example: typedef T F<T>(T x) has uninstantiated signature (T x) => T. | |
1258 // The instantiated signature of F(int) becomes (int x) => int. | |
1259 // Note that after this step, the signature of the function type is not | |
1260 // identical to the canonical signature of the typedef class anymore. | |
1261 if (scope_class.IsGeneric() && !signature.HasInstantiatedSignature()) { | |
1262 const TypeArguments& type_args = | |
1263 TypeArguments::Handle(zone, fun_type.arguments()); | |
1264 if (FLAG_trace_type_finalization) { | |
1265 THR_Print("Instantiating signature '%s' of typedef '%s'\n", | |
1266 String::Handle(zone, signature.Signature()).ToCString(), | |
1267 String::Handle(zone, fun_type.Name()).ToCString()); | |
1268 } | |
1269 signature = signature.InstantiateSignatureFrom(type_args, Heap::kOld); | |
1270 // Note that if type_args contains type parameters, signature is still | |
1271 // uninstantiated here (typedef type parameters were substituted in the | |
1272 // signature with typedef type arguments). | |
1273 } | |
1274 fun_type.set_signature(signature); | |
1275 // The type was already marked as finalized and uninstantiated in | |
1276 // ExpandAndFinalizeTypeArguments above when its signature was not | |
1277 // instantiated yet. Check again by calling ResetIsFinalized(). | |
1278 fun_type.ResetIsFinalized(); | |
1279 } else { | |
1280 const Function& signature = Function::Handle(zone, fun_type.signature()); | |
1281 FinalizeSignature(cls, signature); | |
1282 } | |
1283 } | |
1284 | |
1285 if (FLAG_trace_type_finalization) { | 1279 if (FLAG_trace_type_finalization) { |
1286 THR_Print("Done finalizing type '%s' with %" Pd " type args: %s\n", | 1280 THR_Print("Done finalizing type '%s' with %" Pd " type args: %s\n", |
1287 String::Handle(zone, type.Name()).ToCString(), | 1281 String::Handle(zone, type.Name()).ToCString(), |
1288 num_expanded_type_arguments, type.ToCString()); | 1282 num_expanded_type_arguments, type.ToCString()); |
1289 } | 1283 } |
1290 | 1284 |
1291 if (finalization >= kCanonicalize) { | 1285 if (finalization >= kCanonicalize) { |
1292 if (FLAG_trace_type_finalization) { | 1286 if (FLAG_trace_type_finalization) { |
1293 THR_Print("Canonicalizing type '%s'\n", | 1287 THR_Print("Canonicalizing type '%s'\n", |
1294 String::Handle(zone, type.Name()).ToCString()); | 1288 String::Handle(zone, type.Name()).ToCString()); |
(...skipping 2458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3753 ProgramVisitor::VisitFunctions(&function_visitor); | 3747 ProgramVisitor::VisitFunctions(&function_visitor); |
3754 | 3748 |
3755 class ClearCodeClassVisitor : public ClassVisitor { | 3749 class ClearCodeClassVisitor : public ClassVisitor { |
3756 void Visit(const Class& cls) { cls.DisableAllocationStub(); } | 3750 void Visit(const Class& cls) { cls.DisableAllocationStub(); } |
3757 }; | 3751 }; |
3758 ClearCodeClassVisitor class_visitor; | 3752 ClearCodeClassVisitor class_visitor; |
3759 ProgramVisitor::VisitClasses(&class_visitor); | 3753 ProgramVisitor::VisitClasses(&class_visitor); |
3760 } | 3754 } |
3761 | 3755 |
3762 } // namespace dart | 3756 } // namespace dart |
OLD | NEW |