Skip to content

Share allocation helpers between CoreCLR and NativeAOT #115339

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 44 commits into from
Jun 3, 2025

Conversation

filipnavara
Copy link
Member

@filipnavara filipnavara commented May 6, 2025

Share assembly version of allocation helpers between CoreCLR and NativeAOT. This allows better code reuse and removes the last usage of helper method frames in the CoreCLR runtime, cleanup is expected to be done separetely.

The slow paths on CoreCLR differ from NativeAOT in few details. They don't expect the GC_ALLOC_FINALIZE, GC_ALLOC_ALIGN8 and GC_ALLOC_ALIGN8_BIAS flags to be passed the correct values and if they are not present then they get inferred from the method table. This means that helpers like RhpNewFinalizable stay exclusive to NativeAOT and remain unused on CoreCLR. This is done intentionally so we can have a single slow path (RhpNew for objects, RhpNewArray for arrays) that can be assigned to any JIT helper. The slow path is used when allocation tracking is enabled or for other diagnostic options.

CoreCLR stores the per-thread allocation context in separate TLS variable, while NativeAOT track it as part of the main per-thread information. We abstract it by introducing INLINE_GET_ALLOC_CONTEXT macro that returns the pointer to ee_alloc_context structure.

FastAllocateString helper in CoreCLR has a changed signature to take the string method table as the first parameter. This mimics the same idea as used by NativeAOT where we can use slow array allocation helper and fast string allocation helper interchangably.

Platform specific notes:

  • linux-x86 didn't have the helpers implemented; the implementation is added and passed some smoke tests.
  • linux-riscv64 implementation was heavily rewritten. The main change is to establish function frame and move arguments into non-volatile registers. We support platform versions without TLS descriptor and this ensures that we only save minimum number of registers to stack to enable INLINE_GET_ALLOC_CONTEXT doing function call that trashes volatile registers.
  • linux-arm helpers for Align8/Misalign cases were enhanced to include padding with "free object" in the fast path.

Contributes to #95695

@filipnavara
Copy link
Member Author

filipnavara commented May 7, 2025

@jkotas I'd appreciate if you could take a look, only the second commit onwards (f3b968c as of this writing). Just want some opinion to avoid veering off in a completely wrong direction and wasting time on it. No need to do some in-depth review, there are still lots of things to clean up.

@jkotas
Copy link
Member

jkotas commented May 7, 2025

The general shape LGTM. Thank you!

@filipnavara filipnavara removed the NO-REVIEW Experimental/testing PR, do NOT review it label May 15, 2025
@filipnavara filipnavara marked this pull request as ready for review May 15, 2025 06:03
@filipnavara
Copy link
Member Author

This is now ready for some initial review pass.

@filipnavara
Copy link
Member Author

cc @tomeksowi can we run the RISC-V bot on this?
cc @LuckyXu-HF any change you could test the LA64 changes?

@LuckyXu-HF
Copy link
Contributor

cc @LuckyXu-HF any change you could test the LA64 changes?

Of course. It will take some time to fully build the NativeAOT testcases, so the results will come out later.
cc @shushanhf @Jabyn1031

@filipnavara filipnavara requested a review from a team May 15, 2025 16:24
@am11
Copy link
Member

am11 commented Jun 2, 2025

@filipnavara
Copy link
Member Author

Smoke tests passed with 3ac08ee.

Thanks for testing! I run it locally before pushing it but this is more comprehensive check.

Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

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

LGTM otherwise!


[RuntimeImport(RuntimeLibrary, "RhpNewVariableSizeObject")]
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern unsafe object RhpNewVariableSizeObject(MethodTable* pEEType, int length, uint flags);
Copy link
Member

Choose a reason for hiding this comment

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

The implementation of RhpNewVariableSizeObject does not expect the extra flags argument.

  • On x86, it is going to result into stack imbalance
  • On arm, we do not pass the flags through, so it is not going to allocate 8-byte aligned array when needed

I think we may want to replace the calls to this with calls to RhAllocateNewArray instead.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch, probably worth re-running /azp run runtime-nativeaot-outerloop.

Copy link
Member Author

Choose a reason for hiding this comment

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

I changed it to use RhAllocateNewArray. Alternative was to change to (misnamed) RhpNewArrayFastAlign8 / RhpNewVariableSizeObject with no flags parameter. Then again, it is a code path slated for a cleanup in the follow-up.

@MichalStrehovsky
Copy link
Member

/azp run runtime-nativeaot-outerloop

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@am11
Copy link
Member

am11 commented Jun 3, 2025

@filipnavara any chance #116276 is exclusive to this PR?

@filipnavara
Copy link
Member Author

filipnavara commented Jun 3, 2025

@filipnavara any chance #116276 is exclusive to this PR?

Cannot rule anything out but I don't see any connection. It's NativeAOT outerloop which is not run as often as other tests.

(Will look at the Helix artifacts later to see if anything sticks out.)

@am11
Copy link
Member

am11 commented Jun 3, 2025

Found one hit on main: https://dev.azure.com/dnceng-public/public/_build/results?buildId=1056334&view=ms.vss-test-web.build-test-results-tab&runId=28475296&resultId=119279&paneView=debug

image

@jkotas, it can randomly fail for any test using merged test executor (not specific to "Runtime_108612").

Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

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

None of the NativeAOT outer loop failures look related.

Thank you - great work!

@jkotas
Copy link
Member

jkotas commented Jun 3, 2025

/ba-g unrelated infrastructure issue (failure to list devices)

@jkotas jkotas merged commit c630f27 into dotnet:main Jun 3, 2025
112 of 119 checks passed
@filipnavara
Copy link
Member Author

Thanks for the patience with reviewing this.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-VM-coreclr community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.