[NativeAOT] Preserve GC bridge temporary peers through R8 - #12828
Open
jonathanpeppers wants to merge 1 commit into
Open
jonathanpeppers wants to merge 1 commit into
jonathanpeppers wants to merge 1 commit into
Conversation
R8 can reduce mono.android.GCUserPeer to an abstract class with no constructor or reference callbacks. NativeAOT constructs this helper through JNI when processing empty strongly connected components, so NewObject returns null and the GC bridge aborts. Keep only the helper class, default constructor, and two JNI reference callbacks. Add a Release NativeAOT build regression that verifies all three methods survive in the final DEX output. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The regression test must verify concreteness and reliably scope member checks to GCUserPeer.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Preserves the NativeAOT GC bridge peer through R8 and adds Release DEX regression coverage.
Changes:
- Adds targeted keep rules for
GCUserPeer. - Adds assertions for its constructor and reference-management methods.
File summaries
| File | Review |
|---|---|
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/TrimmableTypeMapBuildTests.cs |
Adds regression coverage; must also verify the class is non-abstract and fix per-class helper state handling. |
src/Xamarin.Android.Build.Tasks/Resources/proguard_trimmable_nativeaot.cfg |
Adds targeted GCUserPeer keep rules. |
Review details
Suppressed comments (1)
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/TrimmableTypeMapBuildTests.cs:1671
- ❌ Test validity —
DexUtils.ContainsClassWithMethoddoes not reset itshasTypeflag whenClass descriptorchanges (it only resetshasName), so a matching method/signature in an earlier DEX class can make this assertion succeed even whenGCUserPeerhas no such member. Since these are common methods and<init>()Vis ubiquitous, please fix the helper to reset the per-class match state (or use a class-scoped DEX parser) before relying on this regression test.
Assert.IsTrue (dexFiles.Any (dex => DexUtils.ContainsClassWithMethod (
"Lmono/android/GCUserPeer;", method, signature, dex, AndroidSdkPath)),
$"R8 must preserve GCUserPeer.{method}{signature} for the native GC bridge.");
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Lite
Comment on lines
+1669
to
+1671
| Assert.IsTrue (dexFiles.Any (dex => DexUtils.ContainsClassWithMethod ( | ||
| "Lmono/android/GCUserPeer;", method, signature, dex, AndroidSdkPath)), | ||
| $"R8 must preserve GCUserPeer.{method}{signature} for the native GC bridge."); |
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
NativeAOT Jetchat aborted during GC bridge processing with
Failed to create GC bridge temporary peer. The failed APK's DEX containsmono.android.GCUserPeeras an abstract class with no constructor or methods; the matching native source aborts when JNINewObject()returns null. KeepingIGCUserPeeralone does not preserve this JNI-created implementation.Preserve only
GCUserPeer, its default constructor, andmonodroidAddReference(Object)/monodroidClearReferences(). Add a Release NativeAOT/R8 build regression asserting that these methods survive in the final DEX. No GC algorithm changes, runtime fallback, or broad keep rules are introduced.Validation
NETSDK1147). Device gesture validation remains pending; no device run was performed in this session. The original RC1 abort did not log the pending Java exception.Pull Request
title and
description
should follow the
commit-messages.mdworkflow documentation, and in particular should include: