Index: runtime/vm/class_finalizer.cc |
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc |
index e094d0f869bf6be00908e91cf02d92ef81bbd37f..4baec475356187dc0b623a5a520adf8cb77132a7 100644 |
--- a/runtime/vm/class_finalizer.cc |
+++ b/runtime/vm/class_finalizer.cc |
@@ -364,7 +364,7 @@ void ClassFinalizer::ResolveRedirectingFactoryTarget( |
THR_Print("Resolving redirecting factory: %s\n", |
String::Handle(factory.name()).ToCString()); |
} |
- type ^= FinalizeType(cls, type, kCanonicalize); |
+ type ^= FinalizeType(cls, type); |
factory.SetRedirectionType(type); |
if (type.IsMalformedOrMalbounded()) { |
ASSERT(factory.RedirectionTarget() == Function::null()); |
@@ -460,7 +460,7 @@ void ClassFinalizer::ResolveRedirectingFactoryTarget( |
target_type ^= target_type.InstantiateFrom(type_args, &bound_error, NULL, |
NULL, Heap::kOld); |
if (bound_error.IsNull()) { |
- target_type ^= FinalizeType(cls, target_type, kCanonicalize); |
+ target_type ^= FinalizeType(cls, target_type); |
} else { |
ASSERT(target_type.IsInstantiated() && type_args.IsInstantiated()); |
const Script& script = Script::Handle(target_class.script()); |
@@ -642,6 +642,7 @@ void ClassFinalizer::FinalizeTypeParameters(const Class& cls, |
void ClassFinalizer::CheckRecursiveType(const Class& cls, |
const AbstractType& type, |
PendingTypes* pending_types) { |
+ ASSERT(pending_types != NULL); |
Zone* zone = Thread::Current()->zone(); |
if (FLAG_trace_type_finalization) { |
THR_Print("Checking recursive type '%s': %s\n", |
@@ -742,10 +743,12 @@ intptr_t ClassFinalizer::ExpandAndFinalizeTypeArguments( |
} |
// Mark the type as being finalized in order to detect self reference and |
- // postpone bound checking until after all types in the graph of |
+ // postpone bound checking (if required) until after all types in the graph of |
// mutually recursive types are finalized. |
type.SetIsBeingFinalized(); |
- pending_types->Add(type); |
+ if (pending_types != NULL) { |
+ pending_types->Add(type); |
+ } |
// The full type argument vector consists of the type arguments of the |
// super types of type_class, which are initialized from the parsed |
@@ -1010,7 +1013,7 @@ void ClassFinalizer::CheckTypeArgumentBounds(const Class& cls, |
declared_bound = type_param.bound(); |
if (!declared_bound.IsObjectType() && !declared_bound.IsDynamicType()) { |
if (!declared_bound.IsFinalized() && !declared_bound.IsBeingFinalized()) { |
- declared_bound = FinalizeType(cls, declared_bound, kCanonicalize); |
+ declared_bound = FinalizeType(cls, declared_bound); |
type_param.set_bound(declared_bound); |
} |
ASSERT(declared_bound.IsFinalized() || declared_bound.IsBeingFinalized()); |
@@ -1046,7 +1049,7 @@ void ClassFinalizer::CheckTypeArgumentBounds(const Class& cls, |
AbstractType& bound = |
AbstractType::Handle(TypeParameter::Cast(type_arg).bound()); |
if (!bound.IsFinalized() && !bound.IsBeingFinalized()) { |
- bound = FinalizeType(type_arg_cls, bound, kCanonicalize); |
+ bound = FinalizeType(type_arg_cls, bound); |
TypeParameter::Cast(type_arg).set_bound(bound); |
} |
} |
@@ -1198,8 +1201,9 @@ RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls, |
ASSERT(type.IsType()); |
// This type is the root type of the type graph if no pending types queue is |
- // allocated yet. |
- const bool is_root_type = (pending_types == NULL); |
+ // allocated yet, and if canonicalization is required. |
+ const bool is_root_type = |
+ (pending_types == NULL) && (finalization >= kCanonicalize); |
if (is_root_type) { |
pending_types = new PendingTypes(zone, 4); |
} |
@@ -1290,7 +1294,8 @@ void ClassFinalizer::ResolveSignature(const Class& cls, |
void ClassFinalizer::FinalizeSignature(const Class& cls, |
- const Function& function) { |
+ const Function& function, |
+ FinalizationKind finalization) { |
AbstractType& type = AbstractType::Handle(); |
AbstractType& finalized_type = AbstractType::Handle(); |
// Finalize upper bounds of function type parameters. |
@@ -1302,7 +1307,7 @@ void ClassFinalizer::FinalizeSignature(const Class& cls, |
for (intptr_t i = 0; i < num_type_params; i++) { |
type_param ^= type_params.TypeAt(i); |
type = type_param.bound(); |
- finalized_type = FinalizeType(cls, type, kCanonicalize); |
+ finalized_type = FinalizeType(cls, type, finalization); |
if (finalized_type.raw() != type.raw()) { |
type_param.set_bound(finalized_type); |
} |
@@ -1310,7 +1315,7 @@ void ClassFinalizer::FinalizeSignature(const Class& cls, |
} |
// Finalize result type. |
type = function.result_type(); |
- finalized_type = FinalizeType(cls, type, kCanonicalize); |
+ finalized_type = FinalizeType(cls, type, finalization); |
// The result type may be malformed or malbounded. |
if (finalized_type.raw() != type.raw()) { |
function.set_result_type(finalized_type); |
@@ -1319,7 +1324,7 @@ void ClassFinalizer::FinalizeSignature(const Class& cls, |
const intptr_t num_parameters = function.NumParameters(); |
for (intptr_t i = 0; i < num_parameters; i++) { |
type = function.ParameterTypeAt(i); |
- finalized_type = FinalizeType(cls, type, kCanonicalize); |
+ finalized_type = FinalizeType(cls, type, finalization); |
// The parameter type may be malformed or malbounded. |
if (type.raw() != finalized_type.raw()) { |
function.SetParameterTypeAt(i, finalized_type); |
@@ -1451,7 +1456,7 @@ void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { |
for (intptr_t i = 0; i < num_fields; i++) { |
field ^= array.At(i); |
type = field.type(); |
- type = FinalizeType(cls, type, kCanonicalize); |
+ type = FinalizeType(cls, type); |
field.SetFieldType(type); |
name = field.name(); |
if (field.is_static()) { |
@@ -1642,7 +1647,7 @@ void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { |
// yet loaded, do not attempt to resolve. |
Type& type = Type::Handle(zone, function.RedirectionType()); |
if (IsLoaded(type)) { |
- type ^= FinalizeType(cls, type, kCanonicalize); |
+ type ^= FinalizeType(cls, type); |
function.SetRedirectionType(type); |
} |
} |
@@ -1832,8 +1837,7 @@ void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) { |
if (!param_bound.IsInstantiated()) { |
// Make sure the bound is finalized before instantiating it. |
if (!param_bound.IsFinalized() && !param_bound.IsBeingFinalized()) { |
- param_bound = |
- FinalizeType(mixin_app_class, param_bound, kCanonicalize); |
+ param_bound = FinalizeType(mixin_app_class, param_bound); |
param.set_bound(param_bound); // In case part of recursive type. |
} |
param_bound = param_bound.InstantiateFrom( |
@@ -2387,7 +2391,7 @@ void ClassFinalizer::FinalizeTypesInClass(const Class& cls) { |
// unfinalized bounds. It is more efficient to finalize them early. |
// Finalize bounds even if running in production mode, so that a snapshot |
// contains them. |
- FinalizeUpperBounds(cls, kCanonicalizeWellFormed); |
+ FinalizeUpperBounds(cls); |
// Finalize super type. |
AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
if (!super_type.IsNull()) { |
@@ -2398,13 +2402,13 @@ void ClassFinalizer::FinalizeTypesInClass(const Class& cls) { |
// later executed in checked mode. Note that the finalized type argument |
// vector of any type of the base class will contain a BoundedType for the |
// out of bound type argument. |
- super_type = FinalizeType(cls, super_type, kCanonicalizeWellFormed); |
+ super_type = FinalizeType(cls, super_type); |
cls.set_super_type(super_type); |
} |
// Finalize mixin type. |
Type& mixin_type = Type::Handle(cls.mixin()); |
if (!mixin_type.IsNull()) { |
- mixin_type ^= FinalizeType(cls, mixin_type, kCanonicalizeWellFormed); |
+ mixin_type ^= FinalizeType(cls, mixin_type); |
cls.set_mixin(mixin_type); |
} |
if (cls.IsTypedefClass()) { |
@@ -2427,7 +2431,7 @@ void ClassFinalizer::FinalizeTypesInClass(const Class& cls) { |
ASSERT(signature.SignatureType() == type.raw()); |
// Resolve and finalize the signature type of this typedef. |
- type ^= FinalizeType(cls, type, kCanonicalizeWellFormed); |
+ type ^= FinalizeType(cls, type); |
// If a different canonical signature type is returned, update the signature |
// function of the typedef. |
@@ -2448,7 +2452,7 @@ void ClassFinalizer::FinalizeTypesInClass(const Class& cls) { |
AbstractType& seen_interf = AbstractType::Handle(); |
for (intptr_t i = 0; i < interface_types.Length(); i++) { |
interface_type ^= interface_types.At(i); |
- interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed); |
+ interface_type = FinalizeType(cls, interface_type); |
interface_types.SetAt(i, interface_type); |
// Check whether the interface is duplicated. We need to wait with |