[mono] AOT-compile marshalling wrappers for layout classes with class-typed fields#129710
Merged
pavelsavara merged 4 commits intoJun 24, 2026
Merged
Conversation
…-typed fields can_marshal_struct() in the AOT compiler did not handle MONO_TYPE_CLASS fields, so a [StructLayout] class whose fields are themselves marshalable layout classes (e.g. MINMAXINFO with two POINT fields) was considered not marshalable. Its StructureToPtr/PtrToStructure wrappers were therefore not emitted into the AOT image, and calling Marshal.StructureToPtr/PtrToStructure under full-AOT failed with 'Attempting to JIT compile method ... while running in aot-only mode'. Handle MONO_TYPE_CLASS the same way as MONO_TYPE_VALUETYPE by recursing into can_marshal_struct; the existing auto-layout check keeps non-layout class fields conservative. Re-enables the JIT/Regression/JitBlue/WPF_3226 test on Mono.
7 tasks
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates Mono’s AOT wrapper inclusion logic so sequential/explicit-layout classes with class-typed fields can be considered marshalable (enabling StructureToPtr/PtrToStructure wrappers to be emitted ahead-of-time), and re-enables a regression test on Mono.
Changes:
- Extend
can_marshal_struct()to handleMONO_TYPE_CLASSfields by recursing into the nested class. - Re-enable
WPF_3226regression coverage on Mono by removing the[ActiveIssue]skip.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/mono/mono/mini/aot-compiler.c | Adds MONO_TYPE_CLASS handling in can_marshal_struct() to allow nested layout classes to qualify for AOT marshalling wrappers. |
| src/tests/JIT/Regression/JitBlue/WPF_3226/CSharpRepro/WPF_3226.cs | Removes Mono-specific [ActiveIssue] skip so CI exercises the scenario again. |
pavelsavara
added a commit
that referenced
this pull request
Jun 22, 2026
Re-link the disabled Mono full-AOT tests from the #129508 tracking issue to the individual PRs that fix them (nullabletypes -> #129702, call05_large/small -> #129708, WPF_3226 -> #129710, b143840 -> #129713, UnitTest_GVM_TypeLoadException -> #129715). The tests stay disabled; Runtime_105619 keeps the #129508 link.
The new MONO_TYPE_CLASS handling recurses into class-typed fields, but unlike value types a reference-class field can point back to its declaring class (directly or indirectly). On a self-referential or cyclic [StructLayout] class this recursed without bound and overflowed the stack, crashing the AOT compiler (observed while AOT-compiling framework assemblies such as System.Net.Security and System.Private.CoreLib). Add a recursion-depth guard: such types cannot be marshalled as a flat struct anyway, so treat them as non-marshalable instead of overflowing.
This was referenced Jun 23, 2026
Open
Use the codebase's standard spelling 'marshalable'.
pavelsavara
added a commit
to pavelsavara/runtime
that referenced
this pull request
Jun 23, 2026
…ine jmp comment, fix marshalable typo Integrates the minor review follow-ups from dotnet#129708 and dotnet#129710.
lewing
approved these changes
Jun 23, 2026
Member
Author
|
/ba-g unrelated failures |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The Mono AOT compiler emits per-type
StructureToPtr/PtrToStructuremarshalling wrappers for[StructLayout]value types and sequential-layout classes, but only whencan_marshal_struct()considers the type marshalable. That helper inspects each instance field and rejects the type if it encounters a field type it doesn't explicitly allow.can_marshal_struct()had no case forMONO_TYPE_CLASS, so any layout class whose fields are themselves marshalable layout classes fell through to thedefault:branch and was treated as non-marshalable. A representative example is:Because
MINMAXINFOwas rejected, itsStructureToPtr/PtrToStructurewrappers were never emitted into the AOT image. The runtime marshals such a type just fine (it marshals the nested layout class as an embedded struct), so the call works under JIT, but under full-AOT the wrapper is generated on demand:Fix
Handle
MONO_TYPE_CLASSfields the same way asMONO_TYPE_VALUETYPEΓÇö recurse intocan_marshal_struct(). The existingmono_class_is_auto_layout()check at the top of the helper keeps the analysis conservative: non-layout class fields (e.g.object) still cause the type to be considered non-marshalable, while sequential/explicit-layout class fields recurse and are accepted when they are themselves marshalable.With the fix, the
MINMAXINFO/POINTStructureToPtr/PtrToStructurewrappers are present in the AOT image and the call succeeds under full-AOT.Testing
Re-enables the
JIT/Regression/JitBlue/WPF_3226test on Mono (the[ActiveIssue]annotation is removed so CI exercises the fix). Validated locally with an x64 Mono LLVM full-AOT build: the wrappers now appear in the AOT image and the test passes (it previously crashed with theExecutionEngineExceptionabove).Note
This change was authored with the assistance of GitHub Copilot.
Part of the MonoAOT LLVM 23 full-AOT regression set tracked by #129508. Built and tested together with the Emscripten 5.0.6 / LLVM 23 bump on #129396, where the re-enabled
WPF_3226test passes on theruntime-llvmAllSubsets_Mono_LLVMFULLAOT_RuntimeTestsleg.Contributes to #129508.