Pin blittable layout classes in NativeAOT marshalling#130279
Conversation
NativeAOT's ILC always copied blittable layout classes passed by value into a separate native struct, honoring In/Out flags that default to In-only. This broke pointer identity, implicit [In,Out] write-back, and [Out] semantics for blittable layout classes. Fold pinning support into LayoutClassPtrMarshaller: when marshalling a non-byref, non-return blittable layout class argument CLR->native, pin the managed object and pass an interior pointer directly to native code, mirroring CoreCLR's ILBlittablePtrMarshaller. Byref, field, reverse, return, and non-blittable scenarios continue to copy through the struct marshalling thunks. Re-enables the previously-disabled LayoutClass interop tests (dotnet#81673). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR updates NativeAOT’s marshalling for blittable layout classes passed by value so they can be pinned and passed to native code via an interior pointer (instead of always copying into a temporary native struct), and re-enables the corresponding interop tests that were previously disabled for NativeAOT.
Changes:
- Re-enable
Interop/LayoutClasstests on NativeAOT by removing theActiveIssue(#81673)skips. - Add a pinning-based forward-argument path to
LayoutClassPtrMarshallerfor blittable layout classes, and skip copy-back/cleanup in that path.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/tests/Interop/LayoutClass/LayoutClassTest.cs | Removes the NativeAOT-specific ActiveIssue(#81673) skips to re-enable LayoutClass interop coverage. |
| src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs | Implements pinning-based CLR→native marshalling for blittable layout class arguments (forward, non-byref, non-return) and bypasses copy-back/cleanup in that mode. |
|
/azp run runtime-nativeaot-outerloop |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
(I'm looking at these long-known interop bugs because libgit2/libgit2sharp#2082 (comment) came to my attention. If we do generate marshalling for something and the marshalling doesn't work like CoreCLR, it's an annoying bug. They're trying to switch to LibraryImport but they have trouble doing so and they may not be the only ones - they didn't file a bug, just assumed this is the "normal native AOT experience"; it isn't). |
|
/ba-g timeout in a networking test that looks like another manifestation of #126867 |
Fixes #81673.
NativeAOT's ILC always copied blittable layout classes passed by value into a separate native struct, honoring In/Out flags that default to In-only. This broke pointer identity, implicit [In,Out] write-back, and [Out] semantics for blittable layout classes.
Fold pinning support into LayoutClassPtrMarshaller: when marshalling a non-byref, non-return blittable layout class argument CLR->native, pin the managed object and pass an interior pointer directly to native code, mirroring CoreCLR's ILBlittablePtrMarshaller. Byref, field, reverse, return, and non-blittable scenarios continue to copy through the struct marshalling thunks.
Re-enables the previously-disabled LayoutClass interop tests (#81673).