| Index: runtime/vm/precompiler.cc
|
| diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
|
| index a990a0898600e0f84b131676e7b7bdc82bc692e3..c691a807f2f4ec5b3d8550d57e5b5dd2ffa47adc 100644
|
| --- a/runtime/vm/precompiler.cc
|
| +++ b/runtime/vm/precompiler.cc
|
| @@ -713,6 +713,7 @@ void Precompiler::DropUncompiledFunctions() {
|
| Class& cls = Class::Handle(Z);
|
| Array& functions = Array::Handle(Z);
|
| Function& function = Function::Handle(Z);
|
| + Function& function2 = Function::Handle(Z);
|
| GrowableObjectArray& retained_functions = GrowableObjectArray::Handle(Z);
|
| GrowableObjectArray& closures = GrowableObjectArray::Handle(Z);
|
|
|
| @@ -729,7 +730,16 @@ void Precompiler::DropUncompiledFunctions() {
|
| retained_functions = GrowableObjectArray::New();
|
| for (intptr_t j = 0; j < functions.Length(); j++) {
|
| function ^= functions.At(j);
|
| - if (function.HasCode()) {
|
| + bool retain = function.HasCode();
|
| + if (!retain && function.HasImplicitClosureFunction()) {
|
| + // It can happen that all uses of an implicit closure inline their
|
| + // target function, leaving the target function uncompiled. Keep
|
| + // the target function anyway so we can enumerate it to bind its
|
| + // static calls, etc.
|
| + function2 = function.ImplicitClosureFunction();
|
| + retain = function2.HasCode();
|
| + }
|
| + if (retain) {
|
| retained_functions.Add(function);
|
| function.DropUncompiledImplicitClosureFunction();
|
| } else {
|
| @@ -780,7 +790,10 @@ void Precompiler::BindStaticCalls() {
|
| }
|
|
|
| void VisitFunction(const Function& function) {
|
| - ASSERT(function.HasCode());
|
| + if (!function.HasCode()) {
|
| + ASSERT(function.HasImplicitClosureFunction());
|
| + return;
|
| + }
|
| code_ = function.CurrentCode();
|
| table_ = code_.static_calls_target_table();
|
|
|
| @@ -837,6 +850,10 @@ void Precompiler::DedupStackmaps() {
|
| }
|
|
|
| void VisitFunction(const Function& function) {
|
| + if (!function.HasCode()) {
|
| + ASSERT(function.HasImplicitClosureFunction());
|
| + return;
|
| + }
|
| code_ = function.CurrentCode();
|
| stackmaps_ = code_.stackmaps();
|
| if (stackmaps_.IsNull()) return;
|
| @@ -876,6 +893,7 @@ void Precompiler::VisitFunctions(FunctionVisitor* visitor) {
|
| Library& lib = Library::Handle(Z);
|
| Class& cls = Class::Handle(Z);
|
| Array& functions = Array::Handle(Z);
|
| + Object& object = Object::Handle(Z);
|
| Function& function = Function::Handle(Z);
|
| GrowableObjectArray& closures = GrowableObjectArray::Handle(Z);
|
|
|
| @@ -897,6 +915,15 @@ void Precompiler::VisitFunctions(FunctionVisitor* visitor) {
|
| visitor->VisitFunction(function);
|
| }
|
| }
|
| +
|
| + functions = cls.invocation_dispatcher_cache();
|
| + for (intptr_t j = 0; j < functions.Length(); j++) {
|
| + object = functions.At(j);
|
| + if (object.IsFunction()) {
|
| + function ^= functions.At(j);
|
| + visitor->VisitFunction(function);
|
| + }
|
| + }
|
| }
|
| }
|
| closures = isolate()->object_store()->closure_functions();
|
|
|