@@ -1461,6 +1461,7 @@ void Precompiler::TraceForRetainedFunctions() {
1461
1461
Library& lib = Library::Handle (Z);
1462
1462
Class& cls = Class::Handle (Z);
1463
1463
Array& functions = Array::Handle (Z);
1464
+ String& name = String::Handle (Z);
1464
1465
Function& function = Function::Handle (Z);
1465
1466
Function& function2 = Function::Handle (Z);
1466
1467
GrowableObjectArray& closures = GrowableObjectArray::Handle (Z);
@@ -1487,6 +1488,19 @@ void Precompiler::TraceForRetainedFunctions() {
1487
1488
AddTypesOf (function);
1488
1489
}
1489
1490
}
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
+ }
1490
1504
}
1491
1505
}
1492
1506
@@ -1601,6 +1615,26 @@ void Precompiler::DropFunctions() {
1601
1615
GrowableObjectArray& retained_functions = GrowableObjectArray::Handle (Z);
1602
1616
GrowableObjectArray& closures = GrowableObjectArray::Handle (Z);
1603
1617
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);
1604
1638
for (intptr_t i = 0 ; i < libraries_.Length (); i++) {
1605
1639
lib ^= libraries_.At (i);
1606
1640
ClassDictionaryIterator it (lib, ClassDictionaryIterator::kIteratePrivate );
@@ -1610,26 +1644,12 @@ void Precompiler::DropFunctions() {
1610
1644
retained_functions = GrowableObjectArray::New ();
1611
1645
for (intptr_t j = 0 ; j < functions.Length (); j++) {
1612
1646
function ^= functions.At (j);
1613
- bool retain = functions_to_retain_.ContainsKey (function);
1614
1647
function.DropUncompiledImplicitClosureFunction ();
1615
1648
function.ClearBytecode ();
1616
- if (retain ) {
1649
+ if (functions_to_retain_. ContainsKey (function) ) {
1617
1650
retained_functions.Add (function);
1618
1651
} 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);
1633
1653
}
1634
1654
}
1635
1655
@@ -1639,32 +1659,47 @@ void Precompiler::DropFunctions() {
1639
1659
} else {
1640
1660
cls.SetFunctions (Object::empty_array ());
1641
1661
}
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);
1642
1691
}
1643
1692
}
1644
1693
1645
1694
closures = isolate ()->object_store ()->closure_functions ();
1646
1695
retained_functions = GrowableObjectArray::New ();
1647
1696
for (intptr_t j = 0 ; j < closures.Length (); j++) {
1648
1697
function ^= closures.At (j);
1649
- bool retain = functions_to_retain_.ContainsKey (function);
1650
1698
function.ClearBytecode ();
1651
- if (retain ) {
1699
+ if (functions_to_retain_. ContainsKey (function) ) {
1652
1700
retained_functions.Add (function);
1653
1701
} 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);
1668
1703
}
1669
1704
}
1670
1705
isolate ()->object_store ()->set_closure_functions (retained_functions);
0 commit comments