Skip to content

[mono] Fix gc descriptor for large static valuetypes - #136625

Merged
BrzVlad merged 1 commit into
dotnet:mainfrom
BrzVlad:fix-static-vt-bitmap
Nov 2, 2026
Merged

BrzVlad merged 1 commit into
dotnet:mainfrom
BrzVlad:fix-static-vt-bitmap

Conversation

@BrzVlad

@BrzVlad BrzVlad commented Oct 29, 2026

Copy link
Copy Markdown
Member

compute_class_bitmap has the role of initializing the incoming bitmap, by setting bits for slots containing refs for the class in question. If the passed bitmap is not large enough to hold bits for all slots, it allocates a new bitmap which will be returned. compute_class_bitmap also receives a position argument to offset the bit setting in the received bitmap. All non-static field offsets include also the expected object header size (of 2 slots). If you need to set ref bits for a valuetype field inside a class having its bitmap computed, then you pass the bitmap owned by this parent class and the position where the bitmap needs to be initialized, position which needs to subtract MONO_OBJECT_HEADER_BITS to revert the standard field offset.

Consider the bitmap initialization for the StaticData class from the testcase. It will allocate a bitmap able to hold all static data for the class, in our case only one field, therefore sizeof(LargeValue) / sizeof(void*) bits. The current offset to store the bits is 0. It will then recursively delegate the initialization of the bitmap section for the LargeValue to the instance field specific part, passing the -MONO_OBJECT_HEADER_BITS offset. The max_size that we compute for this class includes the object header, so it can therefore exceed the initial bitmap size. This would hit the realloc path which the caller doesn't expect, ending up with improperly initialized ref bitmaps.

Fixes #136602

`compute_class_bitmap` has the role of initializing the incoming bitmap, by setting bits for slots containing refs for the class in question. If the passed bitmap is not large enough to hold bits for all slots, it allocates a new bitmap which will be returned. `compute_class_bitmap` also receives a position argument to offset the bit setting in the received bitmap. All non-static field offsets include also the expected object header size (of 2 slots). If you need to set ref bits for a valuetype field inside a class having its bitmap computed, then you pass the bitmap owned by this parent class and the position where the bitmap needs to be initialized, position which need to subtract MONO_OBJECT_HEADER_BITS to revert the standard field offset.

Consider the bitmap initialization for the class `StaticData` class from the testcase. It will allocate a bitmap able to hold all static data for the class, in our case only one field, therefore `sizeof(LargeValue) / sizeof(void*)` bits. The current offset to store the bits is 0. It will then recursively delegate the initialization of the bitmap section for the `LargeValue` to the instance field specific part, passing the -MONO_OBJECT_HEADER_BITS offset. The `max_size` that we compute for this class includes the object header, so it can therefore exceed the initial bitmap size. This would hit the realloc path which the caller doesn't expect, ending up with improperly initialized ref bitmaps.
@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.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @BrzVlad
See info in area-owners.md if you want to be subscribed.

@BrzVlad
BrzVlad merged commit 42854c1 into dotnet:main Nov 2, 2026
123 of 126 checks passed
@BrzVlad

BrzVlad commented Nov 2, 2026

Copy link
Copy Markdown
Member Author

/backport to release/11.0

@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Started backporting to release/11.0 (link to workflow run)

@BrzVlad

BrzVlad commented Nov 2, 2026

Copy link
Copy Markdown
Member Author

/backport to release/10.0

@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0 (link to workflow run)

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.

[mono][wasm] References in a large static readonly struct are not kept valid across a GC (browser-wasm)

2 participants