Skip to content

[mono][aot] Fix recursive struct wrapper normalization - #135438

Open
pavelsavara wants to merge 1 commit into
dotnet:mainfrom
pavelsavara:mono-aot-recursive-struct-wrapper-2
Open

pavelsavara wants to merge 1 commit into
dotnet:mainfrom
pavelsavara:mono-aot-recursive-struct-wrapper-2

Conversation

@pavelsavara

Copy link
Copy Markdown
Member

Summary

Reintroduces the Mono AOT wrapper-normalization fix from #135029 after its
revert in #135371, with a corrected regression test.

mono-aot-cross recursively normalizes value-type fields and generic type
arguments when it builds gsharedvt wrapper signatures. A valid type such as:

struct GenericFieldBox<T>
{
    public object Value;
}

struct SelfRecursive
{
    public GenericFieldBox<SelfRecursive> Value;
}

makes get_wrapper_shared_vtype() and get_wrapper_shared_type_full() call
each other until the native stack overflows.

The fix carries a stack-allocated chain of value types currently being
normalized. Re-entering a type, or reaching the bounded depth for a generic
shape that grows at every level, uses the existing "keep the original type"
fallback.

What changed since #135029

The original product fix was not the source of the cross-platform CI failures.
The original test also declared mutually recursive generic value types:

struct A { GenericFieldBox<B> Value; }
struct B { GenericFieldBox<A> Value; }

CoreCLR rejects that metadata with TypeLoadException while loading
System.Runtime.Tests, before xUnit test discovery. This caused #135348 on
WASI, Firefox, Android, and iOS.

This PR removes that invalid mutual shape. The test uses only the valid
self-recursive shape that reproduces the Mono AOT compiler failure. Its helper
types are private.

Validation

  • .\build.cmd -bl -os browser -subset mono+libs -c Debug /p:RuntimeFlavor=Mono
    • Passed, 0 warnings/errors.
  • Preserved reverted-main mono-aot-cross compiling the exact modified
    System.Runtime.Tests.dll
    • Failed with 0xC00000FD native stack overflow, as expected.
  • Patched mono-aot-cross compiling the same assembly
    • Passed; 28,452/29,246 methods compiled.
  • Mono browser interpreter, Chrome:
    System.Tests.ValueTypeTests
    • Passed, 23/23; XHarness exit 0.
  • Clean Release Mono/browser build in a separate worktree
    • Passed, 0 warnings/errors.
  • Mono browser AOT, Chrome:
    System.Tests.ValueTypeTests
    • AOT-compiled 80 assemblies; passed 23/23; XHarness exit 0.
  • Original source-only Blazor reproduction from Blazor WASM AOT Compilation Failure #132071:
    • App assembly passed (109/110 methods compiled).
    • Dedup aot-instances.dll passed (14,712/14,747 methods compiled).
  • Standalone CoreCLR metadata probes:

Resolves #132071

Note

This PR description was drafted with GitHub Copilot.

get_wrapper_shared_vtype() normalizes each value type field while
get_wrapper_shared_type_full() normalizes generic type arguments. A struct
containing a generic struct instantiated over itself makes the two functions
recurse until mono-aot-cross overflows its native stack.

Track the value types currently being normalized. If a type is reached again,
or an ever-growing generic shape reaches a bounded depth, keep the original
type using the existing non-shared fallback.

The regression test uses only the valid self-recursive shape. In particular,
it does not reintroduce the mutually recursive generic value types from
dotnet#135029 that caused TypeLoadException during test assembly loading.

Fixes dotnet#132071

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
13 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@pavelsavara
pavelsavara requested a review from lewing October 8, 2026 18:04
pavelsavara added a commit that referenced this pull request Oct 8, 2026
Remove the mutually recursive generic value types added by the original test.
CoreCLR rejects that metadata while loading System.Runtime.Tests, before test
discovery, which caused #135348 across unrelated CI legs.

Keep the valid self-recursive shape that reproduces the Mono AOT compiler stack
overflow and make its helper types private. This matches the corrected test in
#135438.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Blazor WASM AOT Compilation Failure

1 participant