| Index: runtime/vm/code_generator.cc
|
| diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
|
| index 4e6a05ca231d28c7c5e9bd6c057c4069415130f3..604a5632703438aa24d00b023374a29bdf7b5942 100644
|
| --- a/runtime/vm/code_generator.cc
|
| +++ b/runtime/vm/code_generator.cc
|
| @@ -414,13 +414,15 @@ static void UpdateTypeTestCache(
|
| return;
|
| }
|
| // If the type is uninstantiated and refers to parent function type
|
| - // parameters, the context is required in the type test and the cache
|
| - // therefore cannot be used.
|
| - if (!type.IsInstantiated(kParentFunctions)) {
|
| + // parameters, the function_type_arguments may not have been canonicalized
|
| + // when concatenated. The optimization still works, but the cache could grow
|
| + // uncontrollably. For now, do not update the cache in this case.
|
| + // TODO(regis): Revisit.
|
| + if (!function_type_arguments.IsNull() &&
|
| + !function_type_arguments.IsCanonical()) {
|
| if (FLAG_trace_type_checks) {
|
| OS::Print(
|
| - "UpdateTypeTestCache: type refers to parent function's type "
|
| - "parameters\n");
|
| + "UpdateTypeTestCache: function_type_arguments is not canonical\n");
|
| }
|
| return;
|
| }
|
| @@ -428,8 +430,26 @@ static void UpdateTypeTestCache(
|
| Object& instance_class_id_or_function = Object::Handle();
|
| TypeArguments& instance_type_arguments = TypeArguments::Handle();
|
| if (instance_class.IsClosureClass()) {
|
| + // If the closure instance is generic, we cannot perform the optimization,
|
| + // because one more input (function_type_arguments) would need to be
|
| + // considered. For now, only perform the optimization if the closure's
|
| + // function_type_arguments is null, meaning the closure function is not
|
| + // generic.
|
| + // TODO(regis): In addition to null (non-generic closure), we should also
|
| + // accept Object::empty_type_arguments() (non-nested generic closure).
|
| + // In that case, update stubs and simulator_dbc accordingly.
|
| + if (Closure::Cast(instance).function_type_arguments() !=
|
| + TypeArguments::null()) {
|
| + if (FLAG_trace_type_checks) {
|
| + OS::Print(
|
| + "UpdateTypeTestCache: closure function_type_arguments is "
|
| + "not null\n");
|
| + }
|
| + return;
|
| + }
|
| instance_class_id_or_function = Closure::Cast(instance).function();
|
| - instance_type_arguments = Closure::Cast(instance).instantiator();
|
| + instance_type_arguments =
|
| + Closure::Cast(instance).instantiator_type_arguments();
|
| } else {
|
| instance_class_id_or_function = Smi::New(instance_class.id());
|
| if (instance_class.NumTypeArguments() > 0) {
|
|
|