Skip to content

[TrimmableTypeMap] Fix app initialization and startup#11252

Open
simonrozsival wants to merge 14 commits intomainfrom
trimmable-typemap-startup-fixes
Open

[TrimmableTypeMap] Fix app initialization and startup#11252
simonrozsival wants to merge 14 commits intomainfrom
trimmable-typemap-startup-fixes

Conversation

@simonrozsival
Copy link
Copy Markdown
Member

Summary

  • initialize trimmable typemap data before AndroidRuntime construction, then register the mono.android.Runtime.registerNatives(Class) bridge after JniRuntime.Current is available
  • emit root TypeMapAssemblyTargetAttribute<T> entries with per-assembly anchors in aggregate mode while preserving the single shared anchor in merged mode
  • keep GenerateJavaPeer=false Java.Interop peers as direct typemap entries, suppress inherited activation constructors for them, and split target-type lookup from generated-proxy lookup

Validation

  • ./dotnet-local.sh test tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests.csproj -tl:off -v:minimal
  • ulimit -n 4096 && ./dotnet-local.sh build src/Mono.Android/Mono.Android.csproj -p:DisableApiCompatibilityCheck=True -p:RunAnalyzers=false -tl:off -v:minimal

simonrozsival and others added 3 commits April 30, 2026 10:28
Initialize typemap data before AndroidRuntime construction, then register the trimmable Runtime.registerNatives bridge after JniRuntime.Current is available.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Emit TypeMapAssemblyTargetAttribute<T> with per-assembly anchors in aggregate mode while preserving the shared anchor in merged mode.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep GenerateJavaPeer=false peers as direct typemap entries, suppress inherited activation constructors for them, and split target-type lookup from generated-proxy lookup.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@simonrozsival simonrozsival added copilot `copilot-cli` or other AIs were used to author this trimmable-type-map labels Apr 30, 2026
Copilot AI review requested due to automatic review settings April 30, 2026 08:33
@simonrozsival simonrozsival added copilot `copilot-cli` or other AIs were used to author this trimmable-type-map labels Apr 30, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts the trimmable typemap startup sequence and typemap metadata generation so that managed typemap data is available before AndroidRuntime construction, while native registrations that require JniRuntime.Current happen after the runtime is set.

Changes:

  • Move trimmable typemap data initialization earlier in JNIEnvInit.Initialize() and register mono.android.Runtime.registerNatives(Class) after JniRuntime.SetCurrent().
  • Update root typemap generation to emit TypeMapAssemblyTargetAttribute<T> with per-assembly anchors in aggregate mode and a shared anchor in merged mode, with new metadata-level tests.
  • Refine scanning/model building and runtime lookup to treat GenerateJavaPeer=false peers as direct typemap entries, suppress inherited activation ctor resolution for them, and split “target type” vs “proxy type” lookup paths.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/TestFixtures/TestTypes.cs Adds a Java.Interop-style activation ctor to support activation-ctor scanning scenarios in tests.
tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Scanner/JavaPeerScannerTests.cs Adds coverage ensuring GenerateJavaPeer=false peers do not inherit activation ctors.
tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/TypeMapModelBuilderTests.cs Ensures non-generated peers without activation ctors produce no proxy types/associations.
tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/RootTypeMapAssemblyGeneratorTests.cs Adds tests validating per-assembly vs shared anchor behavior by decoding attribute/type spec metadata.
src/Mono.Android/Microsoft.Android.Runtime/TrimmableTypeMap.cs Splits native registration from initialization and adds separate caches for target-type and proxy lookup.
src/Mono.Android/Microsoft.Android.Runtime/SingleUniverseTypeMap.cs Splits target-type enumeration from proxy-type enumeration and centralizes alias entry traversal.
src/Mono.Android/Microsoft.Android.Runtime/ITypeMapWithAliasing.cs Updates interface to expose separate target/proxy enumeration methods.
src/Mono.Android/Microsoft.Android.Runtime/AggregateTypeMap.cs Implements new interface shape across multiple universes.
src/Mono.Android/Android.Runtime/JNIEnvInit.cs Adjusts initialization ordering and registers typemap native bridge after JniRuntime.Current exists.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerScanner.cs Suppresses inherited activation ctor discovery for IsFromJniTypeSignature && DoNotGenerateAcw.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/RootTypeMapAssemblyGenerator.cs Emits TypeMapAssemblyTargetAttribute<T> using per-assembly anchors in aggregate mode.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/ModelBuilder.cs Extracts proxy-creation predicate to keep direct typemap entries for non-generated peers.

@simonrozsival simonrozsival changed the title Fix trimmable typemap startup [TrimmableTypeMap] Fix app initialization and startup Apr 30, 2026
simonrozsival and others added 11 commits April 30, 2026 11:08
Separate shared-universe and per-assembly-universe TypeMapAssemblyTargetAttribute emission paths for clarity.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Limit the trimmable typemap scanner to Register/component peers for now and restore proxy-only runtime lookup semantics.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove the temporary NeedsProxy helper refactor and the extra blank line so this PR stays focused on functional changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Exclude Java.Interop JniTypeSignature ManagedPeer tests that are outside the current trimmable typemap scope and add equivalent Android [Register]-based coverage for dispose, finalization, nested dispose, and generic holder activation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Android app assemblies do not have a managed entry point, so remove the SDK default EntryPoint trimmer root and root the app assembly with RootMode=All for CoreCLR trimmable typemap builds.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CoreCLRTrimmable is a test flavor, not an NUnit category. Since it runs on CoreCLR, keep the standard CoreCLRIgnore and NTLM exclusions while also excluding trimmable-specific categories.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move trimmable typemap assembly preparation out of _GenerateJavaStubs so packaging, compression, and register-attribute removal see the generated typemap assemblies even when Java stub generation is skipped.

Update CoreCLR typemap store handling to depend on the prepared typemap assembly item groups.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Capture component attribute values needed by the trimmable typemap scanner, including content provider authorities, and normalize connector managed type names consistently.

Keep scanner coverage for the component and connector metadata paths.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Record invoker type associations on their generated proxies so trimmable typemap lookup can resolve invoker registered JNI names without generating separate proxy entries.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Prefer pregenerated trimmable typemap JNI names in the type manager and walk base types for managed-only subclasses that do not have their own Register attribute.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Register JNI natives through pregenerated JniNativeMethod entries and ldftn function pointers instead of generated delegate registration.

Generate UCO forwarders with the legacy marshal-method wrapper shape and keep inherited activation pregenerated with direct activation constructor calls.

Cover the direct registration, UCO wrapper, default UnmanagedCallersOnly, boolean ABI, and inherited activation IL shapes in generator tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

copilot `copilot-cli` or other AIs were used to author this trimmable-type-map

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants