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

Unified Diff: runtime/vm/class_finalizer.cc

Issue 2791393002: Clean up finalization of recursive types in the VM. (Closed)
Patch Set: Created 3 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | runtime/vm/object.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/class_finalizer.cc
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index c78900ae671c4e9ba89ff0c9910430bd07dca1d3..4fc3a7718820ef44d093e6a23f6c68339ccbb767 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -927,6 +927,17 @@ void ClassFinalizer::FinalizeTypeArguments(const Class& cls,
String::Handle(super_type_arg.Name()).ToCString(),
ref_type.ToCString(), arguments.ToCString());
}
+ // In the typical case of an F-bounded type, the instantiation of the
+ // super_type_arg from arguments is a fixpoint. Take the shortcut.
+ // Example: class B<T>; class D<T> extends B<D<T>>;
+ // While finalizing D<T>, the super type arg D<T> (a typeref) gets
+ // instantiated from vector [T], yielding itself.
+ //
+ if (super_type_arg.IsTypeRef() && super_type_arg.IsBeingFinalized() &&
+ (super_type_arg.arguments() == arguments.raw())) {
+ arguments.SetTypeAt(i, super_type_arg);
+ continue;
+ }
Error& error = Error::Handle();
super_type_arg = super_type_arg.InstantiateFrom(
arguments, &error, instantiation_trail, NULL, Heap::kOld);
@@ -940,21 +951,18 @@ void ClassFinalizer::FinalizeTypeArguments(const Class& cls,
*bound_error = error.raw();
}
}
- if (!super_type_arg.IsFinalized() &&
- !super_type_arg.IsBeingFinalized()) {
+ if (super_type_arg.IsBeingFinalized()) {
// The super_type_arg was instantiated from a type being finalized.
// We need to finish finalizing its type arguments.
- if (super_type_arg.IsTypeRef()) {
- super_type_arg = TypeRef::Cast(super_type_arg).type();
- }
- Type::Cast(super_type_arg).SetIsBeingFinalized();
- pending_types->Add(super_type_arg);
- const Class& cls = Class::Handle(super_type_arg.type_class());
+ ASSERT(super_type_arg.IsTypeRef());
+ AbstractType& ref_super_type_arg =
+ AbstractType::Handle(TypeRef::Cast(super_type_arg).type());
+ ref_super_type_arg.SetIsFinalized();
+ const Class& cls = Class::Handle(ref_super_type_arg.type_class());
FinalizeTypeArguments(
- cls, TypeArguments::Handle(super_type_arg.arguments()),
+ cls, TypeArguments::Handle(ref_super_type_arg.arguments()),
cls.NumTypeArguments() - cls.NumTypeParameters(), bound_error,
pending_types, instantiation_trail);
- Type::Cast(super_type_arg).SetIsFinalized();
}
}
}
« 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