[DRAFT] [net11.0] App size investigations. - #26291
Conversation
…ar after ILC Set the AssociatedSourceType field on the UnmanagedCallersOnly attributes the managed registrar emits, so the NativeAOT compiler (ILC) can drop a trampoline's native export when the associated type (the NSObject subclass declaring the exported method) can't be constructed. This is an app-size optimization for NativeAOT (issue #25631). The field is only emitted for NativeAOT + the trimmable-static registrar + PrepareAssemblies: * Only ILC understands the field; CoreCLR's attribute parser rejects any UnmanagedCallersOnly named argument it doesn't recognize ("Known custom attribute named argument not recognized.") at startup, so it must not be emitted for CoreCLR/Mono. * The trimmable-static registrar emits native glue (registrar.o) that references the trampoline symbols directly for the whole set of registered SDK types. ILLink keeps those types (so the glue is emitted), but ILC independently drops some trampoline exports, which would leave undefined symbols at native link time. The fix requires a post-ILC step that can reconcile the generated glue with the exports that survived ILC, which only PrepareAssemblies has. To make this work with the trimmable-static registrar, the native registrar-generating postprocessing pipeline is reordered to run *after* ILC instead of before (gated on trimmable-static + NativeAOT + PrepareAssemblies). This is possible because ILLink is skipped in this scenario (ILC consumes the prepared assemblies directly), so the postprocessing output no longer feeds ILC. After ILC, the registrar inspects ILC's output object file to determine which trampolines survived: * Trampolines ILC trimmed away are routed through the dlsym fallback (a runtime string reference) instead of a direct native symbol reference. Since ILC only trims a trampoline when the associated type can't be constructed, the trampoline is never actually invoked, so the fallback is never reached. * Classes whose trampolines were all trimmed away are skipped entirely (no @interface/@implementation is emitted), except base classes still referenced as a superclass of an emitted class (the whole base-class chain is kept). Additionally, a warning is emitted if any post-ILC postprocessing step modifies a managed assembly, since ILC has already consumed them and the change would be silently lost. Two spurious "modifications" are fixed to avoid false warnings: ManagedRegistrarStep.ProcessType now reports the actual modification state (during post-processing it only collects information, a read-only operation), and the NSObject.RegisterToggleRef stub (already applied before ILC) is no longer re-applied post-ILC. Fixes #25631 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2b6450f9-2ad9-4e89-823a-3cc6e2f33f53
…SSet<T> alive
The test verifies that a generic type referenced only from an optional protocol
member (Foundation.NSSet<T>) is trimmed away when using the trimmable static
registrar. It did so with:
typeof (NSObject).Assembly.GetType (NamespacePrefix + "Foundation.NSSet`1")
Since NamespacePrefix is a `const string = ""`, the argument is a compile-time
constant, so ILLink's intrinsic handling of Assembly.GetType(string) resolves it
and marks Foundation.NSSet`1 as kept - the test's own assertion was the sole
reason the type survived (confirmed via --dump-dependencies). The result was the
assertion failing with "NSSet<T> must be linked away, otherwise this test is
useless".
Fix it the same way the sibling RemovedAttributes test already does: copy the
name pieces into non-const locals and go through Helper.GetType, so ILLink can't
statically resolve the type name and keep it. With this change NSSet<T> is
trimmed and the test passes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2b6450f9-2ad9-4e89-823a-3cc6e2f33f53
…e-static When building for NativeAOT with the trimmable-static registrar on .NET 11+, enable the PrepareAssemblies/PostProcessAssemblies flow by default, so the native static registrar code is generated *after* ILC (_PostprocessAssembliesAfterIlc) and can drop the native code for UnmanagedCallersOnly trampolines ILC trimmed away (an app-size optimization built on the AssociatedSourceType support). Previously this flow only activated if the user explicitly set both PrepareAssemblies and PostProcessAssemblies. Setting only PrepareAssemblies wasn't enough: the static _PostprocessAssembliesAfterIlc gate is evaluated at import time and requires PostProcessAssemblies to already be 'true' there, but PostProcessAssemblies only defaults to $(PrepareAssemblies) later (at build time). So the gate saw an empty value and stayed off, the native registrar was generated before ILC, and it emitted direct references to trampolines ILC later trimmed away - undefined symbols at native link time. Setting both properties at evaluation time makes the gate (and _SkipILLink) see them and generates the registrar after ILC, where the existing survival-aware logic (skip classes whose trampolines were all trimmed; route the rest through the dlsym fallback) prevents the undefined symbols. This reduces the iOS trimmable-static NativeAOT SizeTestApp from 14.40 MB to 11.28 MB. Gated on .NET 11+ (the post-ILC reorder requires the .NET 11 ILC; see _SkipILLink), so there's no effect on .NET 10. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6aeeddfd-3bd8-4129-ad90-7292860c4b66
✅ API diff for current PR / commitNET (empty diffs)✅ API diff vs stableNET (empty diffs)ℹ️ Generator diffGenerator Diff: vsdrops (html) vsdrops (raw diff) gist (raw diff) - Please review changes) Pipeline on Agent |
🔥 [CI Build #1143cf4] Test results 🔥Test results❌ Tests failed on VSTS: test results 3 tests crashed, 11 tests failed, 160 tests passed. Failures❌ dotnettests tests (iOS)1 tests failed, 0 tests passed.Failed tests
Html Report (VSDrops) Download ❌ dotnettests tests (MacCatalyst)1 tests failed, 0 tests passed.Failed tests
Html Report (VSDrops) Download ❌ dotnettests tests (macOS)1 tests failed, 0 tests passed.Failed tests
Html Report (VSDrops) Download ❌ dotnettests tests (tvOS)1 tests failed, 0 tests passed.Failed tests
Html Report (VSDrops) Download ❌ linker tests (iOS)🔥 Failed catastrophically on VSTS: test results - linker_ios (no summary found). Html Report (VSDrops) Download ❌ linker tests (MacCatalyst)🔥 Failed catastrophically on VSTS: test results - linker_maccatalyst (no summary found). Html Report (VSDrops) Download ❌ linker tests (tvOS)4 tests failed, 27 tests passed.Failed tests
Html Report (VSDrops) Download ❌ monotouch tests (iOS)1 tests failed, 22 tests passed.Failed tests
Html Report (VSDrops) Download ❌ monotouch tests (MacCatalyst)🔥 Failed catastrophically on VSTS: test results - monotouch_maccatalyst (no summary found). Html Report (VSDrops) Download ❌ monotouch tests (macOS)1 tests failed, 17 tests passed.Failed tests
Html Report (VSDrops) Download ❌ monotouch tests (tvOS)1 tests failed, 22 tests passed.Failed tests
Html Report (VSDrops) Download Successes✅ assembly-processing: All 1 tests passed. Html Report (VSDrops) Download macOS tests✅ Tests on macOS Sonoma (14): All 5 tests passed. Html Report (VSDrops) Download Linux Build VerificationPipeline on Agent |
|
Do not review; this PR will not be merged.