Uh oh!
There was an error while loading. Please reload this page.
Share ObjectiveCMarshal reference-tracking logic between CoreCLR and NativeAOT - #128961
Conversation
Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
AaronRobinsonMSFT
commented
Jun 4, 2026
@copilot Please fold the cDAC changes into version 1. There is no backwards compat concerns here. We can change version 1 without issue. |
Addressed in 0edf747. I folded the ObjectiveCMarshal cDAC changes into version c1, removed the c2 registration/implementation, and updated the CoreCLR data descriptor contract entry back to c1. |
Co-authored-by: AaronRobinsonMSFT <30635565+AaronRobinsonMSFT@users.noreply.github.com>
Co-authored-by: AaronRobinsonMSFT <30635565+AaronRobinsonMSFT@users.noreply.github.com>
Uh oh!
There was an error while loading. Please reload this page.
Add tests exercising the ConditionalWeakTable-based GetTaggedMemory path: - ObjectNotInTable: CWT exists but object not tracked - NullMemory: object tracked but memory pointer is null - HasMemory: object tracked with valid tagged memory Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…bjC stubs - Use m_Array directly instead of GetGCSafeDataPtr() per review feedback - Update Mono ObjectiveCMarshal stubs to match shared API changes Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…al methods Extract the unsafe MethodTable check into a partial method on each runtime (CoreCLR, NativeAOT, Mono stub) so the shared ObjectiveCMarshal.cs no longer requires an unsafe context for the validation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
In DAC mode, m_Array yields a host address, but PTR_KIND requires a target address. GetDataPtr() computes the correct target address via dac_cast<PTR_BYTE>(this) + offset. This was broken by PR #128961 which changed from GetDataPtr() to m_Array, breaking debugger inspection of exception stack traces, ConditionalWeakTable lookups, and stack frame helper arrays in DAC mode. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Fixes failing OSX cDac test. I think this is a regression from #128961. This pull request updates the handling of pointer types in managed code to better align with how .NET expresses raw pointers. The main change is to allow fields typed as `IntPtr`/`UIntPtr` (reported as `"nint"`/`"nuint"`) to be treated as pointers by the contract reader, improving compatibility and correctness when reading pointer-sized fields. Improvements to pointer type handling: * Updated `AssertPointerType` in `TargetFieldExtensions.cs` to accept `"nint"` and `"nuint"` as valid pointer type names, in addition to `"pointer"`, enabling proper handling of managed fields typed as `IntPtr`/`UIntPtr`. Test and contract descriptor alignment: * Modified the test contract for the `_memory` field in `ObjectiveCMarshalTests.cs` to explicitly set its type as `"nint"`, ensuring that the pointer read path is validated against the real managed contract descriptor. --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…d NativeAOT (#128961) `ObjectiveCMarshal` had divergent CoreCLR and NativeAOT implementations for tagged reference-tracking memory. This change moves CoreCLR to the same `ConditionalWeakTable<object, ObjcTrackingInformation>` model used by NativeAOT and updates diagnostics contracts accordingly. - **Description** - **CoreCLR managed ObjectiveCMarshal now owns tagged memory** - Added CoreCLR-side `s_objects` CWT and `ObjcTrackingInformation` lifecycle logic in `ObjectiveCMarshal.CoreCLR.cs`. - Unified `CreateReferenceTrackingHandle` / `GetOrCreateReferenceTrackingMemory` flow to use managed CWT-backed memory for both runtimes. - `Initialize` now passes the CWT instance to native for unmanaged lookup during GC callbacks. - **CoreCLR native Objective-C interop path no longer uses syncblk tagged storage** - Removed Objective-C-specific syncblk tagged-memory allocation/retrieval path from `interoplibinterface_objc.cpp`. - Replaced with unmanaged CWT lookup (`ConditionalWeakTableObject::TryGetValue`) to resolve tagged memory from managed state. - Split QCall responsibilities so native only allocates the ref-counted handle (`ObjCMarshal_AllocateReferenceTrackingHandle`). - **Unmanaged CWT accessor usage enabled in runtime path** - Exposed `ConditionalWeakTable` native lookup helpers for this suspended-runtime callback scenario and clarified constraints in comments. - **cDAC ObjectiveCMarshal contract folded into version `c1`** - Replaced `ObjectiveCMarshal_1` implementation to read tagged memory via `ObjectiveCMarshal.s_objects` and CWT entries. ```c++ // CoreCLR native callback path now resolves tagged memory from managed CWT state. CONDITIONAL_WEAK_TABLE_REF trackingTable = (CONDITIONAL_WEAK_TABLE_REF)ObjectFromHandle(g_ObjectiveCTrackingInfoTable); OBJECTREF trackingInfoObj = NULL; if (!trackingTable->TryGetValue(object, &trackingInfoObj)) return false; OBJC_TRACKING_INFO_REF trackingInfo = (OBJC_TRACKING_INFO_REF)trackingInfoObj; void* taggedLocal = (void*)trackingInfo->_memory; ``` --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: AaronRobinsonMSFT <30635565+AaronRobinsonMSFT@users.noreply.github.com> Co-authored-by: Aaron R Robinson <arobins@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
In DAC mode, m_Array yields a host address, but PTR_KIND requires a target address. GetDataPtr() computes the correct target address via dac_cast<PTR_BYTE>(this) + offset. This was broken by PR #128961 which changed from GetDataPtr() to m_Array, breaking debugger inspection of exception stack traces, ConditionalWeakTable lookups, and stack frame helper arrays in DAC mode. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Fixes failing OSX cDac test. I think this is a regression from #128961. This pull request updates the handling of pointer types in managed code to better align with how .NET expresses raw pointers. The main change is to allow fields typed as `IntPtr`/`UIntPtr` (reported as `"nint"`/`"nuint"`) to be treated as pointers by the contract reader, improving compatibility and correctness when reading pointer-sized fields. Improvements to pointer type handling: * Updated `AssertPointerType` in `TargetFieldExtensions.cs` to accept `"nint"` and `"nuint"` as valid pointer type names, in addition to `"pointer"`, enabling proper handling of managed fields typed as `IntPtr`/`UIntPtr`. Test and contract descriptor alignment: * Modified the test contract for the `_memory` field in `ObjectiveCMarshalTests.cs` to explicitly set its type as `"nint"`, ensuring that the pointer read path is validated against the real managed contract descriptor. --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
ObjectiveCMarshalhad divergent CoreCLR and NativeAOT implementations for tagged reference-tracking memory. This change moves CoreCLR to the sameConditionalWeakTable<object, ObjcTrackingInformation>model used by NativeAOT and updates diagnostics contracts accordingly.s_objectsCWT andObjcTrackingInformationlifecycle logic inObjectiveCMarshal.CoreCLR.cs.CreateReferenceTrackingHandle/GetOrCreateReferenceTrackingMemoryflow to use managed CWT-backed memory for both runtimes.Initializenow passes the CWT instance to native for unmanaged lookup during GC callbacks.interoplibinterface_objc.cpp.ConditionalWeakTableObject::TryGetValue) to resolve tagged memory from managed state.ObjCMarshal_AllocateReferenceTrackingHandle).ConditionalWeakTablenative lookup helpers for this suspended-runtime callback scenario and clarified constraints in comments.c1ObjectiveCMarshal_1implementation to read tagged memory viaObjectiveCMarshal.s_objectsand CWT entries.