Skip to content

Skip save/restore of contexts in task-returning thunks; mark thunk infrastructure NonVersionable#129894

Draft
jakobbotsch wants to merge 4 commits into
dotnet:mainfrom
jakobbotsch:skip-context-save-restore-in-thunks
Draft

Skip save/restore of contexts in task-returning thunks; mark thunk infrastructure NonVersionable#129894
jakobbotsch wants to merge 4 commits into
dotnet:mainfrom
jakobbotsch:skip-context-save-restore-in-thunks

Conversation

@jakobbotsch

@jakobbotsch jakobbotsch commented Jun 26, 2026

Copy link
Copy Markdown
Member

We do not need to save/restore contexts in task-returning thunks since that already happens in the JIT generated code for async functions.

Needs to wait for the bug fix in #129890.

Also make the types and methods used in the thunks NonVersionable for more efficient handling by crossgen2. Bump R2R version, and at the same time take the opportunity to rename various internal functions:

  • Rename FinalizeTaskReturningThunk and FinalizeValueTaskReturningThunk to CreateRuntimeAsyncTask and CreateRuntimeAsyncValueTask respectively
  • All await helpers that do not check for completion and that always suspend immediately have been renamed to Suspend and TransparentSuspend
  • TransparentAwaitWithResult overloads have been renamed to TransparentAwait

Fix #122512

We do not need to save/restore contexts in task-returning thunks since
that already happens in the JIT generated code for async functions.

Also make the types and methods used in the thunks `NonVersionable` so
they can be inlined by crossgen2. Bump R2R version and also rename some
async members that were poorly named.
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates the CoreCLR runtime-async thunk contract (the members referenced from task-returning thunks and ReadyToRun images) by renaming key AsyncHelpers entrypoints, removing thunk-side context save/restore, and bumping the ReadyToRun major version to reflect the contract change.

Changes:

  • Renames the thunk finalization entrypoints from Finalize*ReturningThunk to CreateRuntimeAsync* and updates both VM-generated and crossgen2-generated thunk IL to call the new methods.
  • Removes AsyncHelpers.CompletedTask* helpers and their binder entries.
  • Bumps ReadyToRun major/minimum version to 25 and updates managed/native module header constants accordingly.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/coreclr/vm/corelib.h Updates CoreLibBinder method IDs for renamed runtime-async thunk entrypoints; removes binder entries for deleted CompletedTask* helpers.
src/coreclr/vm/asyncthunks.cpp Updates VM IL stub emission to call the renamed CreateRuntimeAsync* methods when the wrapped async method suspends.
src/coreclr/tools/Common/TypeSystem/IL/Stubs/AsyncThunks.cs Updates crossgen2 thunk IL emitter to call the renamed CreateRuntimeAsync* methods.
src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs Bumps managed ReadyToRun major version constant to 25.
src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.CoreCLR.cs Removes root context save/restore from RuntimeAsyncAwaitState used by thunks; introduces dispatch-only context save/restore and renames thunk-entry methods.
src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h Bumps native ReadyToRun major version constant to 25.
src/coreclr/inc/readytorun.h Bumps ReadyToRun major/minimum to 25 and documents the version 25 change rationale.

Comment on lines +1287 to 1291
private static Task<T?> CreateRuntimeAsyncTask<T>(ref RuntimeAsyncAwaitState state)
{
RuntimeAsyncTask<T?> result = new();
FinalizeRuntimeAsyncTask(ref state, result!);
return result;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think it's ok for these to not be NonVersionable, RuntimeAsyncStackState and RuntimeAsyncAwaitState are more important since they are used even for synchronously finishing tasks.

[BypassReadyToRun]
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.Async)]
private static unsafe void TransparentAwaitValueTask(ValueTask valueTask)
private static unsafe void Suspend(IValueTaskSource source, short token, bool continueOnCapturedContext)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

No functional changes in these, just renaming and reordering.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

(Decided to remove the reordering from this PR to make the diff easier.)

Copilot AI review requested due to automatic review settings June 26, 2026 15:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.CoreCLR.cs:1320

  • TaskFromException helpers are also invoked by the task-returning thunks (see asyncthunks.cpp / AsyncThunks.cs). If the goal is to make thunk infrastructure NonVersionable for crossgen2 efficiency, these should likely be annotated as well (and similarly the adjacent ValueTaskFromException overloads, which are also thunk helpers but are outside the changed-line window for a separate inline comment here).
        private static Task<T?> TaskFromException<T>(Exception ex)
        {
            Task<T?> task = new();
            bool successfullySet = ex is OperationCanceledException oce ?
                task.TrySetCanceled(oce.CancellationToken, oce) :

Comment thread src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
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.

Names of types and methods that are part of the runtime-async contract should be updated according to framework guidelines.

2 participants