Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(205)

Side by Side Diff: runtime/vm/class_finalizer.cc

Issue 2793033005: Keep types in signatures of function types properly instantiated as the function (Closed)
Patch Set: added comment and sync Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/bootstrap_natives.h ('k') | runtime/vm/dart_api_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 for (intptr_t i = 0; i < num_arguments; i++) { 559 for (intptr_t i = 0; i < num_arguments; i++) {
560 type_argument = arguments.TypeAt(i); 560 type_argument = arguments.TypeAt(i);
561 ResolveType(cls, type_argument); 561 ResolveType(cls, type_argument);
562 } 562 }
563 } 563 }
564 // Resolve signature if function type. 564 // Resolve signature if function type.
565 if (type.IsFunctionType()) { 565 if (type.IsFunctionType()) {
566 const Function& signature = Function::Handle(Type::Cast(type).signature()); 566 const Function& signature = Function::Handle(Type::Cast(type).signature());
567 Type& signature_type = Type::Handle(signature.SignatureType()); 567 Type& signature_type = Type::Handle(signature.SignatureType());
568 if (signature_type.raw() != type.raw()) { 568 if (signature_type.raw() != type.raw()) {
569 // This type was promoted to a function type because its type class is a
570 // typedef class. The promotion is achieved by assigning the signature
571 // function of the typedef class to this type. This function is pointing
572 // to the original typedef function type, which is not this type.
573 // By resolving the typedef function type (which may already be resolved,
574 // hence saving work), we will resolve the shared signature function.
575 ASSERT(Class::Handle(type.type_class()).IsTypedefClass());
569 ResolveType(cls, signature_type); 576 ResolveType(cls, signature_type);
570 } else { 577 } else {
571 const Class& scope_class = Class::Handle(type.type_class()); 578 const Class& scope_class = Class::Handle(type.type_class());
572 if (scope_class.IsTypedefClass()) { 579 if (scope_class.IsTypedefClass()) {
580 // This type is the original function type of the typedef class.
573 ResolveSignature(scope_class, signature); 581 ResolveSignature(scope_class, signature);
574 } else { 582 } else {
583 ASSERT(scope_class.IsClosureClass());
575 ResolveSignature(cls, signature); 584 ResolveSignature(cls, signature);
576 if ((type.arguments() != TypeArguments::null()) && 585 ASSERT(type.arguments() == TypeArguments::null());
577 signature.HasInstantiatedSignature()) { 586 if (signature.IsSignatureFunction()) {
578 ASSERT(scope_class.IsGeneric()); 587 // Drop fields that are not necessary anymore after resolution.
579 // Although the scope class of this function type is generic, 588 // The parent function, owner, and token position of a shared
580 // the signature of this function type does not refer to any 589 // canonical function type are meaningless, since the canonical
581 // of its type parameters. Reset its scope class to _Closure. 590 // representent is picked arbitrarily.
582 Type::Cast(type).set_type_class(Class::Handle( 591 signature.set_parent_function(Function::Handle());
583 Isolate::Current()->object_store()->closure_class())); 592 // TODO(regis): As long as we support metadata in typedef signatures,
584 type.set_arguments(Object::null_type_arguments()); 593 // we cannot reset these fields used to reparse a typedef.
585 } 594 // Note that the scope class of a typedef function type is always
586 } 595 // preserved as the typedef class (not reset to _Closure class),
587 if (signature.IsSignatureFunction()) { 596 // thereby preventing sharing of canonical function types between
588 // Drop fields that are not necessary anymore after resolution. 597 // typedefs. Not being shared, these fields are therefore always
589 // The parent function, owner, and token position of a shared 598 // meaningful for typedefs.
590 // canonical function type are meaningless, since the canonical 599 if (!scope_class.IsTypedefClass()) {
591 // representent is picked arbitrarily. 600 signature.set_owner(Object::Handle());
592 signature.set_parent_function(Function::Handle()); 601 signature.set_token_pos(TokenPosition::kNoSource);
593 // TODO(regis): As long as we support metadata in typedef signatures, 602 }
594 // we cannot reset these fields used to reparse a typedef.
595 // Note that the scope class of a typedef function type is always
596 // preserved as the typedef class (not reset to _Closure class), thereby
597 // preventing sharing of canonical function types between typedefs.
598 // Not being shared, these fields are therefore always meaningful for
599 // typedefs.
600 if (!scope_class.IsTypedefClass()) {
601 signature.set_owner(Object::Handle());
602 signature.set_token_pos(TokenPosition::kNoSource);
603 } 603 }
604 } 604 }
605 } 605 }
606 } 606 }
607 } 607 }
608 608
609 609
610 void ClassFinalizer::FinalizeTypeParameters(const Class& cls, 610 void ClassFinalizer::FinalizeTypeParameters(const Class& cls,
611 PendingTypes* pending_types) { 611 PendingTypes* pending_types) {
612 if (FLAG_trace_type_finalization) { 612 if (FLAG_trace_type_finalization) {
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 ASSERT(num_super_type_args == 884 ASSERT(num_super_type_args ==
885 (cls.NumTypeArguments() - cls.NumOwnTypeArguments())); 885 (cls.NumTypeArguments() - cls.NumOwnTypeArguments()));
886 if (!super_type.IsFinalized() && !super_type.IsBeingFinalized()) { 886 if (!super_type.IsFinalized() && !super_type.IsBeingFinalized()) {
887 super_type ^= FinalizeType(cls, super_type, kFinalize, pending_types); 887 super_type ^= FinalizeType(cls, super_type, kFinalize, pending_types);
888 cls.set_super_type(super_type); 888 cls.set_super_type(super_type);
889 } 889 }
890 TypeArguments& super_type_args = 890 TypeArguments& super_type_args =
891 TypeArguments::Handle(super_type.arguments()); 891 TypeArguments::Handle(super_type.arguments());
892 // Offset of super type's type parameters in cls' type argument vector. 892 // Offset of super type's type parameters in cls' type argument vector.
893 const intptr_t super_offset = num_super_type_args - num_super_type_params; 893 const intptr_t super_offset = num_super_type_args - num_super_type_params;
894 // If the super type is raw (i.e. super_type_args is null), set to dynamic.
894 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); 895 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType());
895 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) { 896 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) {
896 if (!super_type_args.IsNull()) { 897 if (!super_type_args.IsNull()) {
897 super_type_arg = super_type_args.TypeAt(i); 898 super_type_arg = super_type_args.TypeAt(i);
898 if (!super_type_arg.IsTypeRef()) { 899 if (!super_type_arg.IsTypeRef()) {
899 if (super_type_arg.IsBeingFinalized()) { 900 if (super_type_arg.IsBeingFinalized()) {
900 ASSERT(super_type_arg.IsType()); 901 ASSERT(super_type_arg.IsType());
901 CheckRecursiveType(cls, super_type_arg, pending_types); 902 CheckRecursiveType(cls, super_type_arg, pending_types);
902 if (FLAG_trace_type_finalization) { 903 if (FLAG_trace_type_finalization) {
903 THR_Print("Creating TypeRef '%s': '%s'\n", 904 THR_Print("Creating TypeRef '%s': '%s'\n",
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
1232 if (!type.IsMalformed() && !type.IsCanonical()) { 1233 if (!type.IsMalformed() && !type.IsCanonical()) {
1233 CheckTypeBounds(cls, type); 1234 CheckTypeBounds(cls, type);
1234 } 1235 }
1235 } 1236 }
1236 } 1237 }
1237 1238
1238 // If the type is a function type, we also need to finalize the types in its 1239 // If the type is a function type, we also need to finalize the types in its
1239 // signature, i.e. finalize the result type and parameter types of the 1240 // signature, i.e. finalize the result type and parameter types of the
1240 // signature function of this function type. 1241 // signature function of this function type.
1241 // We do this after marking this type as finalized in order to allow a 1242 // We do this after marking this type as finalized in order to allow a
1242 // function type to refer to itself via its parameter types and result type. 1243 // typedef function type to refer to itself via its parameter types and
1243 // Note that we do not instantiate these types according to the type 1244 // result type.
1244 // arguments. This will happen on demand when executing a type test.
1245 if (type.IsFunctionType()) { 1245 if (type.IsFunctionType()) {
1246 const Function& signature = 1246 ASSERT(!type.IsBeingFinalized());
1247 Function::Handle(zone, Type::Cast(type).signature()); 1247 const Type& fun_type = Type::Cast(type);
1248 const Class& scope_class = 1248 const Class& scope_class = Class::Handle(zone, fun_type.type_class());
1249 Class::Handle(zone, Type::Cast(type).type_class());
1250 if (scope_class.IsTypedefClass()) { 1249 if (scope_class.IsTypedefClass()) {
1251 FinalizeSignature(scope_class, signature); 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();
1252 } else { 1279 } else {
1280 const Function& signature = Function::Handle(zone, fun_type.signature());
1253 FinalizeSignature(cls, signature); 1281 FinalizeSignature(cls, signature);
1254 } 1282 }
1255 } 1283 }
1256 1284
1257 if (FLAG_trace_type_finalization) { 1285 if (FLAG_trace_type_finalization) {
1258 THR_Print("Done finalizing type '%s' with %" Pd " type args: %s\n", 1286 THR_Print("Done finalizing type '%s' with %" Pd " type args: %s\n",
1259 String::Handle(zone, type.Name()).ToCString(), 1287 String::Handle(zone, type.Name()).ToCString(),
1260 num_expanded_type_arguments, type.ToCString()); 1288 num_expanded_type_arguments, type.ToCString());
1261 } 1289 }
1262 1290
(...skipping 2462 matching lines...) Expand 10 before | Expand all | Expand 10 after
3725 ProgramVisitor::VisitFunctions(&function_visitor); 3753 ProgramVisitor::VisitFunctions(&function_visitor);
3726 3754
3727 class ClearCodeClassVisitor : public ClassVisitor { 3755 class ClearCodeClassVisitor : public ClassVisitor {
3728 void Visit(const Class& cls) { cls.DisableAllocationStub(); } 3756 void Visit(const Class& cls) { cls.DisableAllocationStub(); }
3729 }; 3757 };
3730 ClearCodeClassVisitor class_visitor; 3758 ClearCodeClassVisitor class_visitor;
3731 ProgramVisitor::VisitClasses(&class_visitor); 3759 ProgramVisitor::VisitClasses(&class_visitor);
3732 } 3760 }
3733 3761
3734 } // namespace dart 3762 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/bootstrap_natives.h ('k') | runtime/vm/dart_api_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698