Skip to content

Using canonical All-pointers GC desc in more scenarios. - #83800

Merged
VSadov merged 10 commits into
dotnet:mainfrom
VSadov:allPtrs
Mar 23, 2023
Merged

Using canonical All-pointers GC desc in more scenarios.#83800
VSadov merged 10 commits into
dotnet:mainfrom
VSadov:allPtrs

Conversation

@VSadov

@VSadovVSadov commented Mar 23, 2023

Copy link
Copy Markdown
Member

Re: #82744 (comment)
Fixes: #83111

Turns out NativeAOT already emits optimized GC descs. That just follows from the implementation that builds complete pointer maps and scans them for series. Array-of-all-pointer-structs cases were not considered on some code paths though.

In the most general case CoreClr builds GC descs by appending GC descs of constituent parts - the base class and struct fields. It does use the compact "all-pointers" form, but only for object arrays.
With this change we detect most of the cases of all-pointers instances and use a compact 1-serie GC desc.

This is not a 100% match of the optimal GC descs produced by NativeAOT.
For example NativeAOT will naturally coalesce adjacent all-pointers structs in the middle of an instance into one contiguous GC serie. NativeAOT has more time and more motivation for this (the number of statically required method tables could be a lot higher than what is actually used at run time and using more compact forms reduces size).
For the JIT scenario, handling "all-pointers" seems good enough and also what we can do cheaply and allocation-free at JIT time.

@jkotas

Copy link
Copy Markdown
Member

Lots of failures...

@VSadov

Copy link
Copy Markdown
MemberAuthor

I realized that couple of changes are not necessary and reverted them right before staging the PR.
Possibly reverted too much :)

@VSadov

VSadov commented Mar 23, 2023

Copy link
Copy Markdown
MemberAuthor

I've tried collecting crude statistics of how often the optimizations make a difference in Libraries testcases.

It varies a lot, but in general I see:

  • 1-3% non-array cases get optimized to fewer series than otherwise.
    Object-derived classes are optimal anyways and complex types often contain ints and the like which break "all-pointers" case.
    Overall the hit rate does not seem like a lot, but it may be helping the array case and may become more interesting as inline arrays become more common as we may see more "all-pointers" structs.

  • ~10% array cases
    This is on top of about 50% of arrays that are object arrays and are already optimized. I think here the optimization is definitely worth it.


// ====================== GCDescOpt ==========================================================

[Fact]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test will need to be disabled for Mono

@jkotasjkotas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@VSadov

Copy link
Copy Markdown
MemberAuthor

Thanks!!

@VSadov
VSadov merged commit 6246ce3 into dotnet:mainMar 23, 2023
@VSadov
VSadov deleted the allPtrs branch March 23, 2023 19:27
@ghostghost locked as resolved and limited conversation to collaborators Apr 23, 2023
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Optimize GC series for cases where all instance fields could be represented as a single serie

2 participants

@VSadov@jkotas