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

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

Issue 2806893002: Make finalization of recursive function types more robust, especially since (Closed)
Patch Set: updated tests status 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 | « no previous file | runtime/vm/object.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 797 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698