[runtime] Replace stale object map entries when completing deferred registration - #26478
[runtime] Replace stale object map entries when completing deferred registration#26478rolfbjarne wants to merge 4 commits into
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the .NET for Apple platforms runtime and toolchain to make native-handle → managed-wrapper registration more robust in alloc/init edge cases (notably pointer reuse and deferred registration), while also introducing related build/linker/runtime improvements (trusted platform assemblies generation, runtimeconfig merging, and UI-thread-check control via a feature switch), plus new regression tests.
Changes:
- Fixes deferred
NSObjectregistration/handle transitions to avoid staleobject_mapentries and incorrect unregister behavior when native pointers are reused. - Reworks UI-thread-check behavior: removes the old “remove-uithread-checks” optimizer path and replaces it with an MSBuild property + ILLink feature switch/substitution approach.
- Adds/updates build-time/runtime infrastructure (TPA list generation, runtimeconfig.dev merge task) and expands coverage with new tests and expected baselines.
Reviewed changes
Copilot reviewed 1 out of 1 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| tools/linker/OptimizeGeneratedCode.cs | Removes EnsureUIThread optimizer. |
| tools/dotnet-linker/Steps/TrimmableRegistrarStep.cs | Emit lookup method conditionally. |
| tools/dotnet-linker/Steps/GenerateMainStep.cs | Populate TPA list for build. |
| tools/dotnet-linker/LinkerConfiguration.cs | Adds new linker config keys. |
| tools/dotnet-linker/DocumentionComments.cs | Adds name-only doc signature helper. |
| tools/dotnet-linker/AppBundleRewriter.cs | Avoid trimmer crash in DDA signatures. |
| tools/common/Target.cs | Emit TPA name array + escaping. |
| tools/common/StaticRegistrar.cs | Adds namespace validation call. |
| tools/common/Optimizations.cs | Deprecates remove-uithread-checks optimization path. |
| tools/common/ErrorHelper.tools.cs | Log warnings as warnings in MSBuild. |
| tools/common/Application.cs | Stores TPA generation state/list. |
| tools/api-tools/mono-api-html/MultiplexedFormatter.cs | Fix placeholder leakage in output. |
| tools/api-tools/mono-api-html-tests/mono-api-html-tests.csproj | New test project for mono-api-html. |
| tools/api-tools/mono-api-html-tests/ApiDiffTests.cs | Regression test for placeholder leakage. |
| tools/api-tools/api-tools.slnx | Adds slnx including new tests. |
| tests/xharness/Jenkins/TestVariationsFactory.cs | Fixes variations naming/selection. |
| tests/test-libraries/libtest.m | Adds native helpers for alloc/init scenarios. |
| tests/test-libraries/libtest.h | Exposes new native test helpers. |
| tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/MergeRuntimeConfigFilesTaskTest.cs | Tests runtimeconfig merge task. |
| tests/monotouch-test/ObjCRuntime/InitCallbackProbeTest.cs | Probe tests for init-time behavior. |
| tests/monotouch-test/ObjCRuntime/AllocInitRaceTest.cs | Deterministic alloc/init reuse regression. |
| tests/linker/link all/PreserveTest.cs | Updates preserved signature expectation. |
| tests/dotnet/UnitTests/Extensions.cs | Updates filtered-warning strings. |
| tests/dotnet/UnitTests/expected/TVOS-NativeAOT-TrimmableStatic-size.txt | Updates expected app size. |
| tests/dotnet/UnitTests/expected/TVOS-NativeAOT-size.txt | Updates expected app size. |
| tests/dotnet/UnitTests/expected/TVOS-MonoVM-size.txt | Updates expected app size. |
| tests/dotnet/UnitTests/expected/TVOS-MonoVM-preservedapis.txt | Updates expected preserved APIs. |
| tests/dotnet/UnitTests/expected/TVOS-MonoVM-interpreter-size.txt | Updates expected app size. |
| tests/dotnet/UnitTests/expected/TVOS-MonoVM-interpreter-preservedapis.txt | Updates expected preserved APIs. |
| tests/dotnet/UnitTests/expected/MacOSX-NativeAOT-TrimmableStatic-size.txt | Updates expected app size. |
| tests/dotnet/UnitTests/expected/MacOSX-NativeAOT-size.txt | Updates expected app size. |
| tests/dotnet/UnitTests/expected/MacOSX-CoreCLR-Interpreter-TrimmableStatic-size.txt | Updates expected app size. |
| tests/dotnet/UnitTests/expected/MacOSX-CoreCLR-Interpreter-size.txt | Updates expected app size. |
| tests/dotnet/UnitTests/expected/MacCatalyst-NativeAOT-TrimmableStatic-size.txt | Updates expected app size. |
| tests/dotnet/UnitTests/expected/MacCatalyst-NativeAOT-size.txt | Updates expected app size. |
| tests/dotnet/UnitTests/expected/MacCatalyst-MonoVM-size.txt | Updates expected app size. |
| tests/dotnet/UnitTests/expected/MacCatalyst-MonoVM-preservedapis.txt | Updates expected preserved APIs. |
| tests/dotnet/UnitTests/expected/MacCatalyst-MonoVM-interpreter-size.txt | Updates expected app size. |
| tests/dotnet/UnitTests/expected/MacCatalyst-MonoVM-interpreter-preservedapis.txt | Updates expected preserved APIs. |
| tests/dotnet/UnitTests/expected/iOS-NativeAOT-TrimmableStatic-size.txt | Updates expected app size. |
| tests/dotnet/UnitTests/expected/iOS-NativeAOT-size.txt | Updates expected app size. |
| tests/dotnet/UnitTests/expected/iOS-MonoVM-size.txt | Updates expected app size. |
| tests/dotnet/UnitTests/expected/iOS-MonoVM-preservedapis.txt | Updates expected preserved APIs. |
| tests/dotnet/UnitTests/expected/iOS-MonoVM-interpreter-size.txt | Updates expected app size. |
| tests/dotnet/UnitTests/expected/iOS-MonoVM-interpreter-preservedapis.txt | Updates expected preserved APIs. |
| tests/dotnet/UnitTests/EnsureUIThreadChecksTest.cs | New test for UI-thread-check switch. |
| tests/dotnet/EnsureUIThreadApp/tvOS/EnsureUIThreadApp.csproj | New app for UI-thread-check test. |
| tests/dotnet/EnsureUIThreadApp/shared.csproj | Shared test app settings. |
| tests/dotnet/EnsureUIThreadApp/macOS/EnsureUIThreadApp.csproj | New app for UI-thread-check test. |
| tests/dotnet/EnsureUIThreadApp/MacCatalyst/EnsureUIThreadApp.csproj | New app for UI-thread-check test. |
| tests/dotnet/EnsureUIThreadApp/iOS/EnsureUIThreadApp.csproj | New app for UI-thread-check test. |
| tests/dotnet/EnsureUIThreadApp/EnsureUIThreadApp.cs | References EnsureUIThread for linking. |
| tests/dotnet/EnsureUIThreadApp/Directory.Build.props | Imports test props. |
| tests/cecil-tests/Documentation.KnownFailures.txt | Updates known failures list. |
| tests/bindings-test/ApiDefinition.cs | Adds bindings for new test types. |
| tests/assembly-preparer/RelocateRegistrarTrampolinesTests.cs | Adds generic trampoline relocation coverage. |
| tests/assembly-preparer/PreserveSmartEnumConversionsTest.cs | Updates DDA signature expectation. |
| tests/assembly-preparer/PreserveBlockCodeHandlerTests.cs | Updates DDA signature expectation. |
| tests/assembly-preparer/OptimizeGeneratedCodeHandlerTests.cs | Removes/adjusts EnsureUIThread optimization tests. |
| tests/assembly-preparer/BaseClass.cs | Adds extra csproj injection parameter. |
| system-dependencies.sh | Adds retrying runtime download logic. |
| src/VideoToolbox/VTDefs.cs | Improves enum docs. |
| src/VideoSubscriberAccount/VSAccountProviderAuthenticationScheme.cs | Improves extension docs. |
| src/UIKit/UIApplication.cs | Moves UI-thread-check wiring to feature switch. |
| src/SceneKit/Defs.cs | Improves enum docs. |
| src/SafariServices/SSEnums.cs | Improves enum docs. |
| src/PdfKit/Enums.cs | Improves enum docs + adds missing member docs. |
| src/ObjCRuntime/TypeMaps.cs | Makes LookupUnmanagedFunction virtual default. |
| src/MapKit/MKEnums.cs | Fixes doc typo and removes noise. |
| src/ILLink.Substitutions.tvOS.xml | Adds feature switch + stubs EnsureUIThread. |
| src/ILLink.Substitutions.macOS.xml | Adds feature switch + stubs EnsureUIThread. |
| src/ILLink.Substitutions.MacCatalyst.xml | Adds feature switch + stubs EnsureUIThread. |
| src/ILLink.Substitutions.iOS.xml | Adds feature switch + stubs EnsureUIThread. |
| src/Foundation/NSObject2.cs | Deferred registration + ownership-aware unregister. |
| src/Foundation/Enum.cs | Improves enum/member docs. |
| src/EventKitUI/Defs.cs | Improves enum/member docs. |
| src/CoreVideo/CVEnums.cs | Improves enum/member docs. |
| src/CoreTelephony/CTEnums.cs | Adds enum member docs + new member doc. |
| src/CoreMotion/Defs.cs | Removes doc noise. |
| src/AVFoundation/Enums.cs | Improves enum/member docs. |
| src/AudioUnit/AUEnums.cs | Improves enum/member docs. |
| src/AppKit/NSApplication.cs | Moves UI-thread-check wiring to feature switch. |
| src/AppKit/Enums.cs | Improves enum/member docs. |
| scripts/changelog/README.md | Adds changelog tool README. |
| scripts/changelog/Program.cs | New changelog tool implementation. |
| scripts/changelog/fragment.mk | Adds script integration fragment. |
| scripts/changelog/changelog.csproj | Adds changelog tool project. |
| runtime/xamarin/main.h | Adds TPA/multi-RID runtime globals. |
| runtime/runtime.m | Uses build-time TPA list when present. |
| NuGet.config | Removes an old feed entry. |
| msbuild/Xamarin.Shared/Xamarin.Shared.targets | Includes .exe in assembly lists + inputs. |
| msbuild/Xamarin.MacDev.Tasks/Tasks/MergeRuntimeConfigFiles.cs | New task to merge runtimeconfig files. |
| msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs | Updates deprecation warning text. |
| msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx | Updates warnings + adds new errors. |
| macios/Localize/loc/zh-Hant/macios/tools/mtouch/Errors.resx.lcl | Localization change (generated file). |
| macios/Localize/loc/tr/macios/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx.lcl | Localization change (generated file). |
| macios/Localize/loc/ko/macios/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx.lcl | Localization change (generated file). |
| macios/Localize/loc/ja/macios/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx.lcl | Localization change (generated file). |
| eng/Version.Details.xml | Updates xharness dependency. |
| eng/Version.Details.props | Updates xharness dependency version. |
| dotnet/targets/Xamarin.Shared.Sdk.targets | New MSBuild properties/targets for features. |
| dotnet/targets/Xamarin.Shared.Sdk.props | Changes default registrar/prepare behavior. |
| docs/website/optimizations.md | Documents EnsureUIThread optimization change. |
| docs/building-apps/build-properties.md | Documents new MSBuild properties. |
| Directory.Build.props | Updates SystemSecurityCryptographyXml version. |
| .github/workflows/zizmor.yml | Updates zizmor action pin. |
| .github/workflows/maestro-changelog.yml | Switches to in-repo changelog tool. |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
|
✅ Applied expected app size files from gist. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
✅ 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 #ed317df] Test results 🚀Test results✅ All tests passed on VSTS: test results. 🎉 All 264 tests passed 🎉 Tests counts✅ 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 |
Addresses review feedback on PR #26424:
RegisterNSObject(..., onlyIfNeeded: true)previously bailed out onobject_map.ContainsKey(ptr)alone, without checking whether the existing entry's weakGCHandle.Targetwas still alive. If a native pointer was reused and the previous entry's target had already been collected (without the native object dying through the normal path), the stale entry would block registration of the new wrapper — leaving it unregistered and leaking the oldGCHandle.This change checks
existing.Target is not nullinstead of just key presence. A dead entry is now removed and its handle freed before the new object is registered, matching the behavior already used elsewhere (e.g.UnregisterNSObject(ptr, managed)andNativeObjectHasDied).🤖 Pull request created by Copilot