@@ -1461,6 +1461,7 @@ void Precompiler::TraceForRetainedFunctions() {
14611461 Library& lib = Library::Handle (Z);
14621462 Class& cls = Class::Handle (Z);
14631463 Array& functions = Array::Handle (Z);
1464+ String& name = String::Handle (Z);
14641465 Function& function = Function::Handle (Z);
14651466 Function& function2 = Function::Handle (Z);
14661467 GrowableObjectArray& closures = GrowableObjectArray::Handle (Z);
@@ -1487,6 +1488,19 @@ void Precompiler::TraceForRetainedFunctions() {
14871488 AddTypesOf (function);
14881489 }
14891490 }
1491+
1492+ {
1493+ functions = cls.invocation_dispatcher_cache ();
1494+ InvocationDispatcherTable dispatchers (functions);
1495+ for (auto dispatcher : dispatchers) {
1496+ name = dispatcher.Get <Class::kInvocationDispatcherName >();
1497+ if (name.IsNull ()) break ; // Reached last entry.
1498+ function = dispatcher.Get <Class::kInvocationDispatcherFunction >();
1499+ if (possibly_retained_functions_.ContainsKey (function)) {
1500+ AddTypesOf (function);
1501+ }
1502+ }
1503+ }
14901504 }
14911505 }
14921506
@@ -1601,6 +1615,26 @@ void Precompiler::DropFunctions() {
16011615 GrowableObjectArray& retained_functions = GrowableObjectArray::Handle (Z);
16021616 GrowableObjectArray& closures = GrowableObjectArray::Handle (Z);
16031617
1618+ auto drop_function = [&](const Function& function) {
1619+ if (function.HasCode ()) {
1620+ code = function.CurrentCode ();
1621+ function.ClearCode ();
1622+ // Wrap the owner of the code object in case the code object will be
1623+ // serialized but the function object will not.
1624+ owner = code.owner ();
1625+ owner = WeakSerializationReference::Wrap (Z, owner);
1626+ code.set_owner (owner);
1627+ }
1628+ dropped_function_count_++;
1629+ if (FLAG_trace_precompiler) {
1630+ THR_Print (" Dropping function %s\n " ,
1631+ function.ToLibNamePrefixedQualifiedCString ());
1632+ }
1633+ };
1634+
1635+ auto & dispatchers_array = Array::Handle (Z);
1636+ auto & name = String::Handle (Z);
1637+ auto & desc = Array::Handle (Z);
16041638 for (intptr_t i = 0 ; i < libraries_.Length (); i++) {
16051639 lib ^= libraries_.At (i);
16061640 ClassDictionaryIterator it (lib, ClassDictionaryIterator::kIteratePrivate );
@@ -1610,26 +1644,12 @@ void Precompiler::DropFunctions() {
16101644 retained_functions = GrowableObjectArray::New ();
16111645 for (intptr_t j = 0 ; j < functions.Length (); j++) {
16121646 function ^= functions.At (j);
1613- bool retain = functions_to_retain_.ContainsKey (function);
16141647 function.DropUncompiledImplicitClosureFunction ();
16151648 function.ClearBytecode ();
1616- if (retain ) {
1649+ if (functions_to_retain_. ContainsKey (function) ) {
16171650 retained_functions.Add (function);
16181651 } else {
1619- if (function.HasCode ()) {
1620- code = function.CurrentCode ();
1621- function.ClearCode ();
1622- // Wrap the owner of the code object in case the code object will be
1623- // serialized but the function object will not.
1624- owner = code.owner ();
1625- owner = WeakSerializationReference::Wrap (Z, owner);
1626- code.set_owner (owner);
1627- }
1628- dropped_function_count_++;
1629- if (FLAG_trace_precompiler) {
1630- THR_Print (" Dropping function %s\n " ,
1631- function.ToLibNamePrefixedQualifiedCString ());
1632- }
1652+ drop_function (function);
16331653 }
16341654 }
16351655
@@ -1639,32 +1659,47 @@ void Precompiler::DropFunctions() {
16391659 } else {
16401660 cls.SetFunctions (Object::empty_array ());
16411661 }
1662+
1663+ retained_functions = GrowableObjectArray::New ();
1664+ {
1665+ dispatchers_array = cls.invocation_dispatcher_cache ();
1666+ InvocationDispatcherTable dispatchers (dispatchers_array);
1667+ for (auto dispatcher : dispatchers) {
1668+ name = dispatcher.Get <Class::kInvocationDispatcherName >();
1669+ if (name.IsNull ()) break ; // Reached last entry.
1670+ desc = dispatcher.Get <Class::kInvocationDispatcherArgsDesc >();
1671+ function = dispatcher.Get <Class::kInvocationDispatcherFunction >();
1672+ if (functions_to_retain_.ContainsKey (function)) {
1673+ retained_functions.Add (name);
1674+ retained_functions.Add (desc);
1675+ retained_functions.Add (function);
1676+ } else {
1677+ drop_function (function);
1678+ }
1679+ }
1680+ }
1681+ if (retained_functions.Length () > 0 ) {
1682+ // Last entry must be null.
1683+ retained_functions.Add (Object::null_object ());
1684+ retained_functions.Add (Object::null_object ());
1685+ retained_functions.Add (Object::null_object ());
1686+ functions = Array::MakeFixedLength (retained_functions);
1687+ } else {
1688+ functions = Object::empty_array ().raw ();
1689+ }
1690+ cls.set_invocation_dispatcher_cache (functions);
16421691 }
16431692 }
16441693
16451694 closures = isolate ()->object_store ()->closure_functions ();
16461695 retained_functions = GrowableObjectArray::New ();
16471696 for (intptr_t j = 0 ; j < closures.Length (); j++) {
16481697 function ^= closures.At (j);
1649- bool retain = functions_to_retain_.ContainsKey (function);
16501698 function.ClearBytecode ();
1651- if (retain ) {
1699+ if (functions_to_retain_. ContainsKey (function) ) {
16521700 retained_functions.Add (function);
16531701 } else {
1654- if (function.HasCode ()) {
1655- code = function.CurrentCode ();
1656- function.ClearCode ();
1657- // Wrap the owner of the code object in case the code object will be
1658- // serialized but the function object will not.
1659- owner = code.owner ();
1660- owner = WeakSerializationReference::Wrap (Z, owner);
1661- code.set_owner (owner);
1662- }
1663- dropped_function_count_++;
1664- if (FLAG_trace_precompiler) {
1665- THR_Print (" Dropping function %s\n " ,
1666- function.ToLibNamePrefixedQualifiedCString ());
1667- }
1702+ drop_function (function);
16681703 }
16691704 }
16701705 isolate ()->object_store ()->set_closure_functions (retained_functions);
0 commit comments