From e8a2b8e28c6a1bcb42f2d4b307a8076ee32ccd6b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 20 Mar 2026 16:31:18 +0000 Subject: [PATCH 1/3] Initial plan From 8215697e2e187cb6b5c9f004c324faaaf8b80102 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 20 Mar 2026 17:05:27 +0000 Subject: [PATCH 2/3] Address copilot reviewer comments: nullable Func, whitespace fix, updated csproj comment Co-authored-by: sbomer <787361+sbomer@users.noreply.github.com> --- .../Linker/MonoDroid.Tuner/AddKeepAlivesHelper.cs | 10 +++++----- .../MonoDroid.Tuner/PostTrimmingAddKeepAlivesStep.cs | 4 ++-- .../Tasks/PostTrimmingPipeline.cs | 9 ++++++++- .../Xamarin.Android.Build.Tasks.csproj | 3 ++- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesHelper.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesHelper.cs index c051fe30971..5eb15079c14 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesHelper.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesHelper.cs @@ -9,7 +9,7 @@ namespace MonoDroid.Tuner { static class AddKeepAlivesHelper { - internal static bool AddKeepAlives (AssemblyDefinition assembly, IMetadataResolver resolver, Func getCorlibAssembly, Action logMessage) + internal static bool AddKeepAlives (AssemblyDefinition assembly, IMetadataResolver resolver, Func getCorlibAssembly, Action logMessage) { if (!assembly.MainModule.HasTypeReference ("Java.Lang.Object")) return false; @@ -27,9 +27,9 @@ internal static bool AddKeepAlives (AssemblyDefinition assembly, IMetadataResolv return changed; } - static bool ProcessType (TypeDefinition type, IMetadataResolver resolver, ref MethodDefinition? methodKeepAlive, Func getCorlibAssembly, Action logMessage) + static bool ProcessType (TypeDefinition type, IMetadataResolver resolver, ref MethodDefinition? methodKeepAlive, Func getCorlibAssembly, Action logMessage) { - bool changed = false; + bool changed = false; if (MightNeedFix (type, resolver)) changed |= AddKeepAlives (type, ref methodKeepAlive, getCorlibAssembly, logMessage); @@ -47,7 +47,7 @@ static bool MightNeedFix (TypeDefinition type, IMetadataResolver resolver) return !type.IsAbstract && type.IsSubclassOf ("Java.Lang.Object", resolver); } - static bool AddKeepAlives (TypeDefinition type, ref MethodDefinition? methodKeepAlive, Func getCorlibAssembly, Action logMessage) + static bool AddKeepAlives (TypeDefinition type, ref MethodDefinition? methodKeepAlive, Func getCorlibAssembly, Action logMessage) { bool changed = false; foreach (MethodDefinition method in type.Methods) { @@ -97,7 +97,7 @@ static bool AddKeepAlives (TypeDefinition type, ref MethodDefinition? methodKeep return changed; } - static MethodDefinition? GetKeepAliveMethod (Func getCorlibAssembly, Action logMessage) + static MethodDefinition? GetKeepAliveMethod (Func getCorlibAssembly, Action logMessage) { var corlibAssembly = getCorlibAssembly (); if (corlibAssembly == null) diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PostTrimmingAddKeepAlivesStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PostTrimmingAddKeepAlivesStep.cs index 0a7392789cf..e725b5714ec 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PostTrimmingAddKeepAlivesStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PostTrimmingAddKeepAlivesStep.cs @@ -13,10 +13,10 @@ namespace MonoDroid.Tuner; class PostTrimmingAddKeepAlivesStep : IAssemblyModifierPipelineStep { readonly IMetadataResolver cache; - readonly Func getCorlibAssembly; + readonly Func getCorlibAssembly; readonly Action logMessage; - public PostTrimmingAddKeepAlivesStep (IMetadataResolver cache, Func getCorlibAssembly, Action logMessage) + public PostTrimmingAddKeepAlivesStep (IMetadataResolver cache, Func getCorlibAssembly, Action logMessage) { this.cache = cache; this.getCorlibAssembly = getCorlibAssembly; diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/PostTrimmingPipeline.cs b/src/Xamarin.Android.Build.Tasks/Tasks/PostTrimmingPipeline.cs index 4084e48cd77..e7e14e2e7f5 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/PostTrimmingPipeline.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/PostTrimmingPipeline.cs @@ -49,7 +49,14 @@ public override bool RunTask () steps.Add (new StripEmbeddedLibrariesStep (Log)); if (AddKeepAlives) { steps.Add (new PostTrimmingAddKeepAlivesStep (cache, - () => resolver.Resolve (AssemblyNameReference.Parse ("System.Private.CoreLib")), + () => { + try { + return resolver.Resolve (AssemblyNameReference.Parse ("System.Private.CoreLib")); + } catch (AssemblyResolutionException ex) { + Log.LogErrorFromException (ex, showStackTrace: false); + return null; + } + }, (msg) => Log.LogDebugMessage (msg))); } diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj index 62a40d93337..c9157be3712 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj @@ -44,7 +44,8 @@ - + + From e6b2e5b1d6d11a8b76cebe417d5bb5b207868dff Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 20 Mar 2026 17:44:14 +0000 Subject: [PATCH 3/3] Memoize corlib resolution in PostTrimmingPipeline to avoid repeated resolution attempts Co-authored-by: sbomer <787361+sbomer@users.noreply.github.com> Agent-Logs-Url: https://github.com/dotnet/android/sessions/399b2f01-0576-42f4-a1d4-d0f0d31f5eb7 --- .../Tasks/PostTrimmingPipeline.cs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/PostTrimmingPipeline.cs b/src/Xamarin.Android.Build.Tasks/Tasks/PostTrimmingPipeline.cs index e7e14e2e7f5..7a33ea3c7be 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/PostTrimmingPipeline.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/PostTrimmingPipeline.cs @@ -48,14 +48,21 @@ public override bool RunTask () var steps = new List (); steps.Add (new StripEmbeddedLibrariesStep (Log)); if (AddKeepAlives) { + // Memoize the corlib resolution so the attempt (and any error logging) happens at most once, + // regardless of how many assemblies/methods need KeepAlive injection. + AssemblyDefinition? corlibAssembly = null; + bool corlibResolutionAttempted = false; steps.Add (new PostTrimmingAddKeepAlivesStep (cache, () => { - try { - return resolver.Resolve (AssemblyNameReference.Parse ("System.Private.CoreLib")); - } catch (AssemblyResolutionException ex) { - Log.LogErrorFromException (ex, showStackTrace: false); - return null; + if (!corlibResolutionAttempted) { + corlibResolutionAttempted = true; + try { + corlibAssembly = resolver.Resolve (AssemblyNameReference.Parse ("System.Private.CoreLib")); + } catch (AssemblyResolutionException ex) { + Log.LogErrorFromException (ex, showStackTrace: false); + } } + return corlibAssembly; }, (msg) => Log.LogDebugMessage (msg))); }