Emit Async Methods in crossgen2 - #124203

Merged
jtschuster merged 101 commits into
dotnet:mainfrom
jtschuster:runtime16
Mar 10, 2026
Merged

Emit Async Methods in crossgen2#124203
jtschuster merged 101 commits into
dotnet:mainfrom
jtschuster:runtime16

Conversation

@jtschuster

@jtschusterjtschuster commented Feb 9, 2026

Copy link
Copy Markdown
Member

Emit async methods, and their resumption stubs into ReadyToRun images. Also compiles and emits async thunks for task-returning methods.

Signatures for async methods are emitted in the InstanceMethod table, with an additional ENCODE_METHOD_SIG_AsyncVariant (0x100) flag.

Resumption stubs are encoded as precode fixups for the async method with the "signature" being the RVA of the start point of the code. When the fixups are resolved, a DynamicMethodDesc / ILStub is created to represent the resumption and enable GC and unwind info to be resolved. Async methods which do not await and do not need resumption stubs won't have a resumption stub fixup.

The resumption stub MethodDescs are created following the existing pattern for ILStubs, but set the code to the R2R code rather than a precode thunk.

@jtschuster

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr crossgen2

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

CopilotAI 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

This PR adds initial support for emitting and consuming runtime-async-related methods in crossgen2 ReadyToRun (R2R) images, including new signature flags and runtime-side lookup/GC-walk plumbing for async variants and resumption stubs.

Changes:

  • Enables runtime-async=on feature flagging for selected source and test projects, and adds a dedicated CI leg to run R2R + runtime-async library tests.
  • Extends R2R method signature encoding/decoding to represent async variants and resumption stubs, and updates crossgen2 tooling/readers to surface these modifiers.
  • Adds runtime support for locating and registering resumption stub entrypoints so stack walking/GC can associate R2R resumption stubs with a MethodDesc.

Reviewed changes

Copilot reviewed 35 out of 36 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
src/libraries/Directory.Build.targetsEnables preview features + runtime-async=on for source projects when UseRuntimeAsync=true.
eng/testing/tests.targetsAdjusts runtime-async enablement for tests and adds TestRuntimeAsync override knob.
eng/pipelines/coreclr/crossgen2.ymlAdds a new CI test matrix leg for R2R + runtime-async libraries testing.
src/coreclr/inc/corcompile.hAdds ENCODE_METHOD_SIG_ResumptionStub flag for method signature encoding.
src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.csAdds managed enum flag READYTORUN_METHOD_SIG_ResumptionStub.
src/coreclr/vm/zapsig.cppReads new ResumptionStub flag during method sig decode (currently unused in logic).
src/coreclr/vm/stackwalk.cppRelaxes a debug assert for unwind table registration to accommodate async R2R scenarios.
src/coreclr/vm/readytoruninfo.hDeclares runtime API to look up resumption stub entrypoints for async variants.
src/coreclr/vm/readytoruninfo.cppImplements resumption stub lookup and registers R2R-backed stub MethodDesc for GC stack walks.
src/coreclr/vm/method.hppExtends async lookup enum and dynamic IL stub types to represent R2R resumption stubs.
src/coreclr/vm/methodtable.cppAdds an AsyncResumptionStub lookup path (currently duplicative of the existing slow path).
src/coreclr/vm/ilstubcache.hDeclares helper to create a DynamicMethodDesc wrapper around precompiled (R2R) stub code.
src/coreclr/vm/ilstubcache.cppImplements creation of an R2R-backed IL-stub MethodDesc with native entrypoint set directly.
src/coreclr/vm/jitinterface.cppTweaks READYTORUN_HELPER handling (includes an unexpected printf).
src/coreclr/inc/readytorunhelpers.hAdds mapping for READYTORUN_HELPER_ThrowExact.
src/coreclr/inc/readytorun.hClarifies formatting/commenting for async continuation helpers.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.csShows [RESUME] in method display and improves BadImageFormatException message.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.csTracks async/resume modifiers when parsing instance method + PGO sections.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.csStores/display method modifiers (async/resume) in signature string.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/PgoInfoKey.csIncludes modifiers in PGO key signature string generation.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csprojAdds AsyncMethodVariant.Mangling.cs to the build.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/IL/ReadyToRunILProvider.csBroadens IL provisioning to handle async variants and resumption stubs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunTableManager.csCategorizes async variants/resumption stubs with instantiated methods for table emission.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.csAvoids inlining async call/thunk methods and force-adds required async metadata references once.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.csMinor whitespace/style fix.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.csEmits ResumptionStub flag and hashes resumption stubs with their async variant method signature.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ModuleTokenResolver.csAdjusts method token resolution and adds field token resolution helper.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodFixupSignature.csEnsures async variants/resumption stubs aren’t incorrectly optimized as ordinary defs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/InstanceEntryPointTableNode.csHandles async variants/resumption stubs in instantiated entrypoint table emission.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/InliningInfoNode.csSkips emitting inlining info for async thunks and avoids work for methods with no inlinees.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ExceptionInfoLookupTableNode.csSkips EH-info table processing for resumption stubs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TypeFixupSignature.csAdjusts GC map encoding size computation (currently incorrect for non-64-bit pointer sizes).
src/coreclr/tools/Common/TypeSystem/IL/Stubs/AsyncResumptionStub.csUpdates diagnostic naming and hashing; marks token generation on emit.
src/coreclr/tools/Common/TypeSystem/IL/InstantiatedMethodIL.csRelaxes a Debug.Assert to accommodate non-standard owning method relationships.
src/coreclr/tools/Common/JitInterface/CorInfoImpl.csEnables READYTORUN path to provide an async resumption stub and relaxes a debug assert for async variants.
src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Async.csTracks continuation types as valid types.
src/coreclr/tools/Common/Compiler/AsyncMethodVariant.csTreats resumption stubs as async thunks for compilation decisions.
Comments suppressed due to low confidence (1)

src/coreclr/vm/jitinterface.cpp:14153

  • Avoid calling printf from the VM here. This will write to stdout in production and can interfere with host output; it also bypasses existing logging/diagnostics patterns already present in this block (STRESS_LOG + _ASSERTE). Please remove the printf and rely on the existing logging/assertion mechanisms (or route through the runtime logging infrastructure if an additional message is needed).
 result = (size_t)GetEEFuncEntryPoint(DelayLoad_Helper_Obj);
break;
case READYTORUN_HELPER_DelayLoad_Helper_ObjObj:

Comment threadsrc/coreclr/vm/methodtable.cpp Outdated
Comment threadsrc/coreclr/vm/zapsig.cpp
Comment threadsrc/coreclr/tools/Common/JitInterface/CorInfoImpl.cs Outdated
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings February 9, 2026 23:41
jtschusterand others added 2 commits March 8, 2026 17:46
1. ARM Thumb bit (emit.cpp): Add codeDelta to emitRecordRelocationWithAddlDelta
for CORINFO_AsyncResumeInfo.Resume and DiagnosticIP. On ARM32,
CorInfoReloc::DIRECT maps to IMAGE_REL_BASED_HIGHLOW which doesn't add the
Thumb bit, causing SIGILL when DispatchContinuations calls the resume stub.
2. Tiered compilation init (ilstubcache.cpp): Call
DetermineAndSetIsEligibleForTieredCompilation() on the MethodDescChunk in
CreateR2RBackedILStub. Without this, GC stack walks through R2R-backed IL
stubs assert on IsEligibleForTieredCompilation().
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings March 9, 2026 01:01

CopilotAI 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 39 out of 40 changed files in this pull request and generated no new comments.

@jtschuster

Copy link
Copy Markdown
MemberAuthor

Looks like all failures are unrelated

@davidwrightondavidwrighton 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.

I see a need for minor changes only.

Comment threadsrc/coreclr/jit/async.cpp
Add comment why we don't emit async methods in composite or ARM32
Use runtime check to avoid setting entrypoint for async helpers in non-r2r scenarios

@jakobbotschjakobbotsch 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.

JIT changes LGTM

@jtschuster
jtschuster merged commit 65b2bc1 into dotnet:mainMar 10, 2026
170 of 172 checks passed
kotlarmilos added a commit to kotlarmilos/runtime that referenced this pull request Mar 11, 2026
…tion in async methods
Add a TypeDesc case to GetModuleTokenForType to handle InstantiatedType
and other non-EcmaType TypeDesc variants by delegating to the existing
ModuleTokenResolver.GetModuleTokenForType.
Fixes a regression from dotnet#124203 where async resumption stubs referencing
generic type instantiations (e.g., CallStruct1M0<T>) crash with
NotImplementedException on Apple simulator CoreCLR RuntimeTests.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
kotlarmilos added a commit that referenced this pull request Mar 12, 2026
…tion in async methods (#125444)
Fixes a regression introduced in #124203 where crossgen2 crashes with
`NotImplementedException: Unsupported token resolution for
Internal.TypeSystem.InstantiatedType` when compiling async methods that
reference generic type instantiations (e.g., `CallStruct1M0<T>`) on
Apple mobile platforms.
## Problem
The `GetModuleTokenForType` local function in `HandleToModuleToken`
handles `SignatureMethodVariable`, `ParameterizedType`, and `EcmaType`,
but does not handle `InstantiatedType`. When async resumption stubs
resolve tokens for instantiated generic types, the code falls through to
the `default` case and throws.
Affected jobs in `runtime-extra-platforms` pipeline:
- `iossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
- `iossimulator-x64 Release AllSubsets_CoreCLR_RuntimeTests`
- `tvossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
**Failed build:**
https://dev.azure.com/dnceng-public/public/_build/results?buildId=1329675&view=results
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI pushed a commit that referenced this pull request Mar 13, 2026
Emit async methods and resumption stubs in crossgen2 ReadyToRun images
Add support for compiling and emitting runtime-async methods, their
async thunks, and resumption stubs into ReadyToRun (R2R) images
produced by crossgen2.
Async method signatures are emitted in the InstanceMethod table with a
new ENCODE_METHOD_SIG_AsyncVariant (0x100) flag. Resumption stubs are
encoded as precode fixups using a new READYTORUN_FIXUP_ResumptionStubEntryPoint
(0x38) fixup kind, where the "signature" is the RVA of the stub code.
At fixup resolution time, a DynamicMethodDesc/ILStub is created to
represent the resumption and provide GC and unwind info. Async methods
that do not await skip resumption stub emission.
Key changes:
- Add ResumptionStubEntryPointSignature node and fixup support
- Implement getAsyncResumptionStub and getFunctionEntryPoint in
crossgen2's CorInfoImpl to enable the JIT to emit async calls
- Set R2R entrypoints on JIT-synthesized async helper calls
(context capture/restore) via SetCallEntrypointForR2R
- Extend ReadyToRunILProvider to handle AsyncMethodVariant and
AsyncResumptionStub IL bodies, including cross-module token
rewriting through ManifestModuleWrappedMethodIL
- Route async variants and resumption stubs through the instance
entrypoint table and inlining info emission
- Fix PEObjectWriter ARM64 page-relative relocations to support
non-zero addends (needed for resumption stub code deltas)
- Fix GC pointer map encoding for types whose size is not
pointer-aligned (off-by-one in encodedGCRefMap allocation)
- Mark CEE_JMP as unsupported in R2R (incorrect indirection cell setup)
- Disable hot/cold splitting for async methods (runtime limitation)
- Disable async method emission in composite mode and ARM32
(known issues tracked in #125337 and #125338)
- Extend crossgen2 CI pipeline to arm64 (linux, osx, windows)
- Update r2rdump/ReadyToRunReader to discover resumption stubs
- Update ReadyToRun format documentation with new fixup kinds and
method signature flag
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI pushed a commit that referenced this pull request Mar 13, 2026
…tion in async methods (#125444)
Fixes a regression introduced in #124203 where crossgen2 crashes with
`NotImplementedException: Unsupported token resolution for
Internal.TypeSystem.InstantiatedType` when compiling async methods that
reference generic type instantiations (e.g., `CallStruct1M0<T>`) on
Apple mobile platforms.
## Problem
The `GetModuleTokenForType` local function in `HandleToModuleToken`
handles `SignatureMethodVariable`, `ParameterizedType`, and `EcmaType`,
but does not handle `InstantiatedType`. When async resumption stubs
resolve tokens for instantiated generic types, the code falls through to
the `default` case and throws.
Affected jobs in `runtime-extra-platforms` pipeline:
- `iossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
- `iossimulator-x64 Release AllSubsets_CoreCLR_RuntimeTests`
- `tvossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
**Failed build:**
https://dev.azure.com/dnceng-public/public/_build/results?buildId=1329675&view=results
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jtschuster added a commit to jtschuster/runtime that referenced this pull request Apr 2, 2026
Add 5 new tests covering key runtime-async crossgen2 PRs:
- RuntimeAsyncMethodEmission (dotnet#124203): Validates [ASYNC] variant
entries for Task/ValueTask-returning methods
- RuntimeAsyncContinuationLayout (dotnet#123643): Validates ContinuationLayout
and ResumptionStubEntryPoint fixups for methods with GC refs across awaits
- RuntimeAsyncDevirtualize (dotnet#125420): Validates async virtual method
devirtualization produces [ASYNC] entries for sealed/interface dispatch
- RuntimeAsyncNoYield (dotnet#124203): Validates async methods without await
still produce [ASYNC] variants
- RuntimeAsyncCrossModule (dotnet#121679): Validates MutableModule async
references work with cross-module inlining of runtime-async methods
Infrastructure changes:
- Add Roslyn feature flag support (runtime-async=on) to R2RTestCaseCompiler
- Add R2RExpectations for async variants, resumption stubs,
continuation layouts, and arbitrary fixup kinds
- Add MainExtraSourceResourceNames to R2RTestCase for shared source files
- Add null guard for method.Fixups in CheckFixupKinds
All 9 tests pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 10, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Specific Continuation types for each method need to be encoded in the ready to run image.

6 participants

@jtschuster@jkotas@jakobbotsch@davidwrighton@MichalStrehovsky
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Emit Async Methods in crossgen2 - #124203

Merged
jtschuster merged 101 commits into
dotnet:mainfrom
jtschuster:runtime16
Mar 10, 2026
Merged

Emit Async Methods in crossgen2#124203
jtschuster merged 101 commits into
dotnet:mainfrom
jtschuster:runtime16

Conversation

@jtschuster

@jtschusterjtschuster commented Feb 9, 2026

Copy link
Copy Markdown
Member

Emit async methods, and their resumption stubs into ReadyToRun images. Also compiles and emits async thunks for task-returning methods.

Signatures for async methods are emitted in the InstanceMethod table, with an additional ENCODE_METHOD_SIG_AsyncVariant (0x100) flag.

Resumption stubs are encoded as precode fixups for the async method with the "signature" being the RVA of the start point of the code. When the fixups are resolved, a DynamicMethodDesc / ILStub is created to represent the resumption and enable GC and unwind info to be resolved. Async methods which do not await and do not need resumption stubs won't have a resumption stub fixup.

The resumption stub MethodDescs are created following the existing pattern for ILStubs, but set the code to the R2R code rather than a precode thunk.

@jtschuster

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr crossgen2

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

CopilotAI 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

This PR adds initial support for emitting and consuming runtime-async-related methods in crossgen2 ReadyToRun (R2R) images, including new signature flags and runtime-side lookup/GC-walk plumbing for async variants and resumption stubs.

Changes:

  • Enables runtime-async=on feature flagging for selected source and test projects, and adds a dedicated CI leg to run R2R + runtime-async library tests.
  • Extends R2R method signature encoding/decoding to represent async variants and resumption stubs, and updates crossgen2 tooling/readers to surface these modifiers.
  • Adds runtime support for locating and registering resumption stub entrypoints so stack walking/GC can associate R2R resumption stubs with a MethodDesc.

Reviewed changes

Copilot reviewed 35 out of 36 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
src/libraries/Directory.Build.targetsEnables preview features + runtime-async=on for source projects when UseRuntimeAsync=true.
eng/testing/tests.targetsAdjusts runtime-async enablement for tests and adds TestRuntimeAsync override knob.
eng/pipelines/coreclr/crossgen2.ymlAdds a new CI test matrix leg for R2R + runtime-async libraries testing.
src/coreclr/inc/corcompile.hAdds ENCODE_METHOD_SIG_ResumptionStub flag for method signature encoding.
src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.csAdds managed enum flag READYTORUN_METHOD_SIG_ResumptionStub.
src/coreclr/vm/zapsig.cppReads new ResumptionStub flag during method sig decode (currently unused in logic).
src/coreclr/vm/stackwalk.cppRelaxes a debug assert for unwind table registration to accommodate async R2R scenarios.
src/coreclr/vm/readytoruninfo.hDeclares runtime API to look up resumption stub entrypoints for async variants.
src/coreclr/vm/readytoruninfo.cppImplements resumption stub lookup and registers R2R-backed stub MethodDesc for GC stack walks.
src/coreclr/vm/method.hppExtends async lookup enum and dynamic IL stub types to represent R2R resumption stubs.
src/coreclr/vm/methodtable.cppAdds an AsyncResumptionStub lookup path (currently duplicative of the existing slow path).
src/coreclr/vm/ilstubcache.hDeclares helper to create a DynamicMethodDesc wrapper around precompiled (R2R) stub code.
src/coreclr/vm/ilstubcache.cppImplements creation of an R2R-backed IL-stub MethodDesc with native entrypoint set directly.
src/coreclr/vm/jitinterface.cppTweaks READYTORUN_HELPER handling (includes an unexpected printf).
src/coreclr/inc/readytorunhelpers.hAdds mapping for READYTORUN_HELPER_ThrowExact.
src/coreclr/inc/readytorun.hClarifies formatting/commenting for async continuation helpers.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.csShows [RESUME] in method display and improves BadImageFormatException message.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.csTracks async/resume modifiers when parsing instance method + PGO sections.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.csStores/display method modifiers (async/resume) in signature string.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/PgoInfoKey.csIncludes modifiers in PGO key signature string generation.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csprojAdds AsyncMethodVariant.Mangling.cs to the build.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/IL/ReadyToRunILProvider.csBroadens IL provisioning to handle async variants and resumption stubs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunTableManager.csCategorizes async variants/resumption stubs with instantiated methods for table emission.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.csAvoids inlining async call/thunk methods and force-adds required async metadata references once.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.csMinor whitespace/style fix.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.csEmits ResumptionStub flag and hashes resumption stubs with their async variant method signature.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ModuleTokenResolver.csAdjusts method token resolution and adds field token resolution helper.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodFixupSignature.csEnsures async variants/resumption stubs aren’t incorrectly optimized as ordinary defs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/InstanceEntryPointTableNode.csHandles async variants/resumption stubs in instantiated entrypoint table emission.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/InliningInfoNode.csSkips emitting inlining info for async thunks and avoids work for methods with no inlinees.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ExceptionInfoLookupTableNode.csSkips EH-info table processing for resumption stubs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TypeFixupSignature.csAdjusts GC map encoding size computation (currently incorrect for non-64-bit pointer sizes).
src/coreclr/tools/Common/TypeSystem/IL/Stubs/AsyncResumptionStub.csUpdates diagnostic naming and hashing; marks token generation on emit.
src/coreclr/tools/Common/TypeSystem/IL/InstantiatedMethodIL.csRelaxes a Debug.Assert to accommodate non-standard owning method relationships.
src/coreclr/tools/Common/JitInterface/CorInfoImpl.csEnables READYTORUN path to provide an async resumption stub and relaxes a debug assert for async variants.
src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Async.csTracks continuation types as valid types.
src/coreclr/tools/Common/Compiler/AsyncMethodVariant.csTreats resumption stubs as async thunks for compilation decisions.
Comments suppressed due to low confidence (1)

src/coreclr/vm/jitinterface.cpp:14153

  • Avoid calling printf from the VM here. This will write to stdout in production and can interfere with host output; it also bypasses existing logging/diagnostics patterns already present in this block (STRESS_LOG + _ASSERTE). Please remove the printf and rely on the existing logging/assertion mechanisms (or route through the runtime logging infrastructure if an additional message is needed).
 result = (size_t)GetEEFuncEntryPoint(DelayLoad_Helper_Obj);
break;
case READYTORUN_HELPER_DelayLoad_Helper_ObjObj:

Comment threadsrc/coreclr/vm/methodtable.cpp Outdated
Comment threadsrc/coreclr/vm/zapsig.cpp
Comment threadsrc/coreclr/tools/Common/JitInterface/CorInfoImpl.cs Outdated
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings February 9, 2026 23:41
jtschusterand others added 2 commits March 8, 2026 17:46
1. ARM Thumb bit (emit.cpp): Add codeDelta to emitRecordRelocationWithAddlDelta
for CORINFO_AsyncResumeInfo.Resume and DiagnosticIP. On ARM32,
CorInfoReloc::DIRECT maps to IMAGE_REL_BASED_HIGHLOW which doesn't add the
Thumb bit, causing SIGILL when DispatchContinuations calls the resume stub.
2. Tiered compilation init (ilstubcache.cpp): Call
DetermineAndSetIsEligibleForTieredCompilation() on the MethodDescChunk in
CreateR2RBackedILStub. Without this, GC stack walks through R2R-backed IL
stubs assert on IsEligibleForTieredCompilation().
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings March 9, 2026 01:01

CopilotAI 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 39 out of 40 changed files in this pull request and generated no new comments.

@jtschuster

Copy link
Copy Markdown
MemberAuthor

Looks like all failures are unrelated

@davidwrightondavidwrighton 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.

I see a need for minor changes only.

Comment threadsrc/coreclr/jit/async.cpp
Add comment why we don't emit async methods in composite or ARM32
Use runtime check to avoid setting entrypoint for async helpers in non-r2r scenarios

@jakobbotschjakobbotsch 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.

JIT changes LGTM

@jtschuster
jtschuster merged commit 65b2bc1 into dotnet:mainMar 10, 2026
170 of 172 checks passed
kotlarmilos added a commit to kotlarmilos/runtime that referenced this pull request Mar 11, 2026
…tion in async methods
Add a TypeDesc case to GetModuleTokenForType to handle InstantiatedType
and other non-EcmaType TypeDesc variants by delegating to the existing
ModuleTokenResolver.GetModuleTokenForType.
Fixes a regression from dotnet#124203 where async resumption stubs referencing
generic type instantiations (e.g., CallStruct1M0<T>) crash with
NotImplementedException on Apple simulator CoreCLR RuntimeTests.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
kotlarmilos added a commit that referenced this pull request Mar 12, 2026
…tion in async methods (#125444)
Fixes a regression introduced in #124203 where crossgen2 crashes with
`NotImplementedException: Unsupported token resolution for
Internal.TypeSystem.InstantiatedType` when compiling async methods that
reference generic type instantiations (e.g., `CallStruct1M0<T>`) on
Apple mobile platforms.
## Problem
The `GetModuleTokenForType` local function in `HandleToModuleToken`
handles `SignatureMethodVariable`, `ParameterizedType`, and `EcmaType`,
but does not handle `InstantiatedType`. When async resumption stubs
resolve tokens for instantiated generic types, the code falls through to
the `default` case and throws.
Affected jobs in `runtime-extra-platforms` pipeline:
- `iossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
- `iossimulator-x64 Release AllSubsets_CoreCLR_RuntimeTests`
- `tvossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
**Failed build:**
https://dev.azure.com/dnceng-public/public/_build/results?buildId=1329675&view=results
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI pushed a commit that referenced this pull request Mar 13, 2026
Emit async methods and resumption stubs in crossgen2 ReadyToRun images
Add support for compiling and emitting runtime-async methods, their
async thunks, and resumption stubs into ReadyToRun (R2R) images
produced by crossgen2.
Async method signatures are emitted in the InstanceMethod table with a
new ENCODE_METHOD_SIG_AsyncVariant (0x100) flag. Resumption stubs are
encoded as precode fixups using a new READYTORUN_FIXUP_ResumptionStubEntryPoint
(0x38) fixup kind, where the "signature" is the RVA of the stub code.
At fixup resolution time, a DynamicMethodDesc/ILStub is created to
represent the resumption and provide GC and unwind info. Async methods
that do not await skip resumption stub emission.
Key changes:
- Add ResumptionStubEntryPointSignature node and fixup support
- Implement getAsyncResumptionStub and getFunctionEntryPoint in
crossgen2's CorInfoImpl to enable the JIT to emit async calls
- Set R2R entrypoints on JIT-synthesized async helper calls
(context capture/restore) via SetCallEntrypointForR2R
- Extend ReadyToRunILProvider to handle AsyncMethodVariant and
AsyncResumptionStub IL bodies, including cross-module token
rewriting through ManifestModuleWrappedMethodIL
- Route async variants and resumption stubs through the instance
entrypoint table and inlining info emission
- Fix PEObjectWriter ARM64 page-relative relocations to support
non-zero addends (needed for resumption stub code deltas)
- Fix GC pointer map encoding for types whose size is not
pointer-aligned (off-by-one in encodedGCRefMap allocation)
- Mark CEE_JMP as unsupported in R2R (incorrect indirection cell setup)
- Disable hot/cold splitting for async methods (runtime limitation)
- Disable async method emission in composite mode and ARM32
(known issues tracked in #125337 and #125338)
- Extend crossgen2 CI pipeline to arm64 (linux, osx, windows)
- Update r2rdump/ReadyToRunReader to discover resumption stubs
- Update ReadyToRun format documentation with new fixup kinds and
method signature flag
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI pushed a commit that referenced this pull request Mar 13, 2026
…tion in async methods (#125444)
Fixes a regression introduced in #124203 where crossgen2 crashes with
`NotImplementedException: Unsupported token resolution for
Internal.TypeSystem.InstantiatedType` when compiling async methods that
reference generic type instantiations (e.g., `CallStruct1M0<T>`) on
Apple mobile platforms.
## Problem
The `GetModuleTokenForType` local function in `HandleToModuleToken`
handles `SignatureMethodVariable`, `ParameterizedType`, and `EcmaType`,
but does not handle `InstantiatedType`. When async resumption stubs
resolve tokens for instantiated generic types, the code falls through to
the `default` case and throws.
Affected jobs in `runtime-extra-platforms` pipeline:
- `iossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
- `iossimulator-x64 Release AllSubsets_CoreCLR_RuntimeTests`
- `tvossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
**Failed build:**
https://dev.azure.com/dnceng-public/public/_build/results?buildId=1329675&view=results
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jtschuster added a commit to jtschuster/runtime that referenced this pull request Apr 2, 2026
Add 5 new tests covering key runtime-async crossgen2 PRs:
- RuntimeAsyncMethodEmission (dotnet#124203): Validates [ASYNC] variant
entries for Task/ValueTask-returning methods
- RuntimeAsyncContinuationLayout (dotnet#123643): Validates ContinuationLayout
and ResumptionStubEntryPoint fixups for methods with GC refs across awaits
- RuntimeAsyncDevirtualize (dotnet#125420): Validates async virtual method
devirtualization produces [ASYNC] entries for sealed/interface dispatch
- RuntimeAsyncNoYield (dotnet#124203): Validates async methods without await
still produce [ASYNC] variants
- RuntimeAsyncCrossModule (dotnet#121679): Validates MutableModule async
references work with cross-module inlining of runtime-async methods
Infrastructure changes:
- Add Roslyn feature flag support (runtime-async=on) to R2RTestCaseCompiler
- Add R2RExpectations for async variants, resumption stubs,
continuation layouts, and arbitrary fixup kinds
- Add MainExtraSourceResourceNames to R2RTestCase for shared source files
- Add null guard for method.Fixups in CheckFixupKinds
All 9 tests pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 10, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Specific Continuation types for each method need to be encoded in the ready to run image.

6 participants

@jtschuster@jkotas@jakobbotsch@davidwrighton@MichalStrehovsky
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Emit Async Methods in crossgen2 - #124203

Merged
jtschuster merged 101 commits into
dotnet:mainfrom
jtschuster:runtime16
Mar 10, 2026
Merged

Emit Async Methods in crossgen2#124203
jtschuster merged 101 commits into
dotnet:mainfrom
jtschuster:runtime16

Conversation

@jtschuster

@jtschusterjtschuster commented Feb 9, 2026

Copy link
Copy Markdown
Member

Emit async methods, and their resumption stubs into ReadyToRun images. Also compiles and emits async thunks for task-returning methods.

Signatures for async methods are emitted in the InstanceMethod table, with an additional ENCODE_METHOD_SIG_AsyncVariant (0x100) flag.

Resumption stubs are encoded as precode fixups for the async method with the "signature" being the RVA of the start point of the code. When the fixups are resolved, a DynamicMethodDesc / ILStub is created to represent the resumption and enable GC and unwind info to be resolved. Async methods which do not await and do not need resumption stubs won't have a resumption stub fixup.

The resumption stub MethodDescs are created following the existing pattern for ILStubs, but set the code to the R2R code rather than a precode thunk.

@jtschuster

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr crossgen2

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

CopilotAI 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

This PR adds initial support for emitting and consuming runtime-async-related methods in crossgen2 ReadyToRun (R2R) images, including new signature flags and runtime-side lookup/GC-walk plumbing for async variants and resumption stubs.

Changes:

  • Enables runtime-async=on feature flagging for selected source and test projects, and adds a dedicated CI leg to run R2R + runtime-async library tests.
  • Extends R2R method signature encoding/decoding to represent async variants and resumption stubs, and updates crossgen2 tooling/readers to surface these modifiers.
  • Adds runtime support for locating and registering resumption stub entrypoints so stack walking/GC can associate R2R resumption stubs with a MethodDesc.

Reviewed changes

Copilot reviewed 35 out of 36 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
src/libraries/Directory.Build.targetsEnables preview features + runtime-async=on for source projects when UseRuntimeAsync=true.
eng/testing/tests.targetsAdjusts runtime-async enablement for tests and adds TestRuntimeAsync override knob.
eng/pipelines/coreclr/crossgen2.ymlAdds a new CI test matrix leg for R2R + runtime-async libraries testing.
src/coreclr/inc/corcompile.hAdds ENCODE_METHOD_SIG_ResumptionStub flag for method signature encoding.
src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.csAdds managed enum flag READYTORUN_METHOD_SIG_ResumptionStub.
src/coreclr/vm/zapsig.cppReads new ResumptionStub flag during method sig decode (currently unused in logic).
src/coreclr/vm/stackwalk.cppRelaxes a debug assert for unwind table registration to accommodate async R2R scenarios.
src/coreclr/vm/readytoruninfo.hDeclares runtime API to look up resumption stub entrypoints for async variants.
src/coreclr/vm/readytoruninfo.cppImplements resumption stub lookup and registers R2R-backed stub MethodDesc for GC stack walks.
src/coreclr/vm/method.hppExtends async lookup enum and dynamic IL stub types to represent R2R resumption stubs.
src/coreclr/vm/methodtable.cppAdds an AsyncResumptionStub lookup path (currently duplicative of the existing slow path).
src/coreclr/vm/ilstubcache.hDeclares helper to create a DynamicMethodDesc wrapper around precompiled (R2R) stub code.
src/coreclr/vm/ilstubcache.cppImplements creation of an R2R-backed IL-stub MethodDesc with native entrypoint set directly.
src/coreclr/vm/jitinterface.cppTweaks READYTORUN_HELPER handling (includes an unexpected printf).
src/coreclr/inc/readytorunhelpers.hAdds mapping for READYTORUN_HELPER_ThrowExact.
src/coreclr/inc/readytorun.hClarifies formatting/commenting for async continuation helpers.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.csShows [RESUME] in method display and improves BadImageFormatException message.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.csTracks async/resume modifiers when parsing instance method + PGO sections.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.csStores/display method modifiers (async/resume) in signature string.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/PgoInfoKey.csIncludes modifiers in PGO key signature string generation.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csprojAdds AsyncMethodVariant.Mangling.cs to the build.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/IL/ReadyToRunILProvider.csBroadens IL provisioning to handle async variants and resumption stubs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunTableManager.csCategorizes async variants/resumption stubs with instantiated methods for table emission.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.csAvoids inlining async call/thunk methods and force-adds required async metadata references once.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.csMinor whitespace/style fix.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.csEmits ResumptionStub flag and hashes resumption stubs with their async variant method signature.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ModuleTokenResolver.csAdjusts method token resolution and adds field token resolution helper.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodFixupSignature.csEnsures async variants/resumption stubs aren’t incorrectly optimized as ordinary defs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/InstanceEntryPointTableNode.csHandles async variants/resumption stubs in instantiated entrypoint table emission.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/InliningInfoNode.csSkips emitting inlining info for async thunks and avoids work for methods with no inlinees.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ExceptionInfoLookupTableNode.csSkips EH-info table processing for resumption stubs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TypeFixupSignature.csAdjusts GC map encoding size computation (currently incorrect for non-64-bit pointer sizes).
src/coreclr/tools/Common/TypeSystem/IL/Stubs/AsyncResumptionStub.csUpdates diagnostic naming and hashing; marks token generation on emit.
src/coreclr/tools/Common/TypeSystem/IL/InstantiatedMethodIL.csRelaxes a Debug.Assert to accommodate non-standard owning method relationships.
src/coreclr/tools/Common/JitInterface/CorInfoImpl.csEnables READYTORUN path to provide an async resumption stub and relaxes a debug assert for async variants.
src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Async.csTracks continuation types as valid types.
src/coreclr/tools/Common/Compiler/AsyncMethodVariant.csTreats resumption stubs as async thunks for compilation decisions.
Comments suppressed due to low confidence (1)

src/coreclr/vm/jitinterface.cpp:14153

  • Avoid calling printf from the VM here. This will write to stdout in production and can interfere with host output; it also bypasses existing logging/diagnostics patterns already present in this block (STRESS_LOG + _ASSERTE). Please remove the printf and rely on the existing logging/assertion mechanisms (or route through the runtime logging infrastructure if an additional message is needed).
 result = (size_t)GetEEFuncEntryPoint(DelayLoad_Helper_Obj);
break;
case READYTORUN_HELPER_DelayLoad_Helper_ObjObj:

Comment threadsrc/coreclr/vm/methodtable.cpp Outdated
Comment threadsrc/coreclr/vm/zapsig.cpp
Comment threadsrc/coreclr/tools/Common/JitInterface/CorInfoImpl.cs Outdated
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings February 9, 2026 23:41
jtschusterand others added 2 commits March 8, 2026 17:46
1. ARM Thumb bit (emit.cpp): Add codeDelta to emitRecordRelocationWithAddlDelta
for CORINFO_AsyncResumeInfo.Resume and DiagnosticIP. On ARM32,
CorInfoReloc::DIRECT maps to IMAGE_REL_BASED_HIGHLOW which doesn't add the
Thumb bit, causing SIGILL when DispatchContinuations calls the resume stub.
2. Tiered compilation init (ilstubcache.cpp): Call
DetermineAndSetIsEligibleForTieredCompilation() on the MethodDescChunk in
CreateR2RBackedILStub. Without this, GC stack walks through R2R-backed IL
stubs assert on IsEligibleForTieredCompilation().
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings March 9, 2026 01:01

CopilotAI 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 39 out of 40 changed files in this pull request and generated no new comments.

@jtschuster

Copy link
Copy Markdown
MemberAuthor

Looks like all failures are unrelated

@davidwrightondavidwrighton 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.

I see a need for minor changes only.

Comment threadsrc/coreclr/jit/async.cpp
Add comment why we don't emit async methods in composite or ARM32
Use runtime check to avoid setting entrypoint for async helpers in non-r2r scenarios

@jakobbotschjakobbotsch 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.

JIT changes LGTM

@jtschuster
jtschuster merged commit 65b2bc1 into dotnet:mainMar 10, 2026
170 of 172 checks passed
kotlarmilos added a commit to kotlarmilos/runtime that referenced this pull request Mar 11, 2026
…tion in async methods
Add a TypeDesc case to GetModuleTokenForType to handle InstantiatedType
and other non-EcmaType TypeDesc variants by delegating to the existing
ModuleTokenResolver.GetModuleTokenForType.
Fixes a regression from dotnet#124203 where async resumption stubs referencing
generic type instantiations (e.g., CallStruct1M0<T>) crash with
NotImplementedException on Apple simulator CoreCLR RuntimeTests.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
kotlarmilos added a commit that referenced this pull request Mar 12, 2026
…tion in async methods (#125444)
Fixes a regression introduced in #124203 where crossgen2 crashes with
`NotImplementedException: Unsupported token resolution for
Internal.TypeSystem.InstantiatedType` when compiling async methods that
reference generic type instantiations (e.g., `CallStruct1M0<T>`) on
Apple mobile platforms.
## Problem
The `GetModuleTokenForType` local function in `HandleToModuleToken`
handles `SignatureMethodVariable`, `ParameterizedType`, and `EcmaType`,
but does not handle `InstantiatedType`. When async resumption stubs
resolve tokens for instantiated generic types, the code falls through to
the `default` case and throws.
Affected jobs in `runtime-extra-platforms` pipeline:
- `iossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
- `iossimulator-x64 Release AllSubsets_CoreCLR_RuntimeTests`
- `tvossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
**Failed build:**
https://dev.azure.com/dnceng-public/public/_build/results?buildId=1329675&view=results
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI pushed a commit that referenced this pull request Mar 13, 2026
Emit async methods and resumption stubs in crossgen2 ReadyToRun images
Add support for compiling and emitting runtime-async methods, their
async thunks, and resumption stubs into ReadyToRun (R2R) images
produced by crossgen2.
Async method signatures are emitted in the InstanceMethod table with a
new ENCODE_METHOD_SIG_AsyncVariant (0x100) flag. Resumption stubs are
encoded as precode fixups using a new READYTORUN_FIXUP_ResumptionStubEntryPoint
(0x38) fixup kind, where the "signature" is the RVA of the stub code.
At fixup resolution time, a DynamicMethodDesc/ILStub is created to
represent the resumption and provide GC and unwind info. Async methods
that do not await skip resumption stub emission.
Key changes:
- Add ResumptionStubEntryPointSignature node and fixup support
- Implement getAsyncResumptionStub and getFunctionEntryPoint in
crossgen2's CorInfoImpl to enable the JIT to emit async calls
- Set R2R entrypoints on JIT-synthesized async helper calls
(context capture/restore) via SetCallEntrypointForR2R
- Extend ReadyToRunILProvider to handle AsyncMethodVariant and
AsyncResumptionStub IL bodies, including cross-module token
rewriting through ManifestModuleWrappedMethodIL
- Route async variants and resumption stubs through the instance
entrypoint table and inlining info emission
- Fix PEObjectWriter ARM64 page-relative relocations to support
non-zero addends (needed for resumption stub code deltas)
- Fix GC pointer map encoding for types whose size is not
pointer-aligned (off-by-one in encodedGCRefMap allocation)
- Mark CEE_JMP as unsupported in R2R (incorrect indirection cell setup)
- Disable hot/cold splitting for async methods (runtime limitation)
- Disable async method emission in composite mode and ARM32
(known issues tracked in #125337 and #125338)
- Extend crossgen2 CI pipeline to arm64 (linux, osx, windows)
- Update r2rdump/ReadyToRunReader to discover resumption stubs
- Update ReadyToRun format documentation with new fixup kinds and
method signature flag
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI pushed a commit that referenced this pull request Mar 13, 2026
…tion in async methods (#125444)
Fixes a regression introduced in #124203 where crossgen2 crashes with
`NotImplementedException: Unsupported token resolution for
Internal.TypeSystem.InstantiatedType` when compiling async methods that
reference generic type instantiations (e.g., `CallStruct1M0<T>`) on
Apple mobile platforms.
## Problem
The `GetModuleTokenForType` local function in `HandleToModuleToken`
handles `SignatureMethodVariable`, `ParameterizedType`, and `EcmaType`,
but does not handle `InstantiatedType`. When async resumption stubs
resolve tokens for instantiated generic types, the code falls through to
the `default` case and throws.
Affected jobs in `runtime-extra-platforms` pipeline:
- `iossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
- `iossimulator-x64 Release AllSubsets_CoreCLR_RuntimeTests`
- `tvossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
**Failed build:**
https://dev.azure.com/dnceng-public/public/_build/results?buildId=1329675&view=results
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jtschuster added a commit to jtschuster/runtime that referenced this pull request Apr 2, 2026
Add 5 new tests covering key runtime-async crossgen2 PRs:
- RuntimeAsyncMethodEmission (dotnet#124203): Validates [ASYNC] variant
entries for Task/ValueTask-returning methods
- RuntimeAsyncContinuationLayout (dotnet#123643): Validates ContinuationLayout
and ResumptionStubEntryPoint fixups for methods with GC refs across awaits
- RuntimeAsyncDevirtualize (dotnet#125420): Validates async virtual method
devirtualization produces [ASYNC] entries for sealed/interface dispatch
- RuntimeAsyncNoYield (dotnet#124203): Validates async methods without await
still produce [ASYNC] variants
- RuntimeAsyncCrossModule (dotnet#121679): Validates MutableModule async
references work with cross-module inlining of runtime-async methods
Infrastructure changes:
- Add Roslyn feature flag support (runtime-async=on) to R2RTestCaseCompiler
- Add R2RExpectations for async variants, resumption stubs,
continuation layouts, and arbitrary fixup kinds
- Add MainExtraSourceResourceNames to R2RTestCase for shared source files
- Add null guard for method.Fixups in CheckFixupKinds
All 9 tests pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 10, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Specific Continuation types for each method need to be encoded in the ready to run image.

6 participants

@jtschuster@jkotas@jakobbotsch@davidwrighton@MichalStrehovsky
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Emit Async Methods in crossgen2 - #124203

Merged
jtschuster merged 101 commits into
dotnet:mainfrom
jtschuster:runtime16
Mar 10, 2026
Merged

Emit Async Methods in crossgen2#124203
jtschuster merged 101 commits into
dotnet:mainfrom
jtschuster:runtime16

Conversation

@jtschuster

@jtschusterjtschuster commented Feb 9, 2026

Copy link
Copy Markdown
Member

Emit async methods, and their resumption stubs into ReadyToRun images. Also compiles and emits async thunks for task-returning methods.

Signatures for async methods are emitted in the InstanceMethod table, with an additional ENCODE_METHOD_SIG_AsyncVariant (0x100) flag.

Resumption stubs are encoded as precode fixups for the async method with the "signature" being the RVA of the start point of the code. When the fixups are resolved, a DynamicMethodDesc / ILStub is created to represent the resumption and enable GC and unwind info to be resolved. Async methods which do not await and do not need resumption stubs won't have a resumption stub fixup.

The resumption stub MethodDescs are created following the existing pattern for ILStubs, but set the code to the R2R code rather than a precode thunk.

@jtschuster

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr crossgen2

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

CopilotAI 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

This PR adds initial support for emitting and consuming runtime-async-related methods in crossgen2 ReadyToRun (R2R) images, including new signature flags and runtime-side lookup/GC-walk plumbing for async variants and resumption stubs.

Changes:

  • Enables runtime-async=on feature flagging for selected source and test projects, and adds a dedicated CI leg to run R2R + runtime-async library tests.
  • Extends R2R method signature encoding/decoding to represent async variants and resumption stubs, and updates crossgen2 tooling/readers to surface these modifiers.
  • Adds runtime support for locating and registering resumption stub entrypoints so stack walking/GC can associate R2R resumption stubs with a MethodDesc.

Reviewed changes

Copilot reviewed 35 out of 36 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
src/libraries/Directory.Build.targetsEnables preview features + runtime-async=on for source projects when UseRuntimeAsync=true.
eng/testing/tests.targetsAdjusts runtime-async enablement for tests and adds TestRuntimeAsync override knob.
eng/pipelines/coreclr/crossgen2.ymlAdds a new CI test matrix leg for R2R + runtime-async libraries testing.
src/coreclr/inc/corcompile.hAdds ENCODE_METHOD_SIG_ResumptionStub flag for method signature encoding.
src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.csAdds managed enum flag READYTORUN_METHOD_SIG_ResumptionStub.
src/coreclr/vm/zapsig.cppReads new ResumptionStub flag during method sig decode (currently unused in logic).
src/coreclr/vm/stackwalk.cppRelaxes a debug assert for unwind table registration to accommodate async R2R scenarios.
src/coreclr/vm/readytoruninfo.hDeclares runtime API to look up resumption stub entrypoints for async variants.
src/coreclr/vm/readytoruninfo.cppImplements resumption stub lookup and registers R2R-backed stub MethodDesc for GC stack walks.
src/coreclr/vm/method.hppExtends async lookup enum and dynamic IL stub types to represent R2R resumption stubs.
src/coreclr/vm/methodtable.cppAdds an AsyncResumptionStub lookup path (currently duplicative of the existing slow path).
src/coreclr/vm/ilstubcache.hDeclares helper to create a DynamicMethodDesc wrapper around precompiled (R2R) stub code.
src/coreclr/vm/ilstubcache.cppImplements creation of an R2R-backed IL-stub MethodDesc with native entrypoint set directly.
src/coreclr/vm/jitinterface.cppTweaks READYTORUN_HELPER handling (includes an unexpected printf).
src/coreclr/inc/readytorunhelpers.hAdds mapping for READYTORUN_HELPER_ThrowExact.
src/coreclr/inc/readytorun.hClarifies formatting/commenting for async continuation helpers.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.csShows [RESUME] in method display and improves BadImageFormatException message.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.csTracks async/resume modifiers when parsing instance method + PGO sections.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.csStores/display method modifiers (async/resume) in signature string.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/PgoInfoKey.csIncludes modifiers in PGO key signature string generation.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csprojAdds AsyncMethodVariant.Mangling.cs to the build.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/IL/ReadyToRunILProvider.csBroadens IL provisioning to handle async variants and resumption stubs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunTableManager.csCategorizes async variants/resumption stubs with instantiated methods for table emission.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.csAvoids inlining async call/thunk methods and force-adds required async metadata references once.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.csMinor whitespace/style fix.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.csEmits ResumptionStub flag and hashes resumption stubs with their async variant method signature.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ModuleTokenResolver.csAdjusts method token resolution and adds field token resolution helper.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodFixupSignature.csEnsures async variants/resumption stubs aren’t incorrectly optimized as ordinary defs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/InstanceEntryPointTableNode.csHandles async variants/resumption stubs in instantiated entrypoint table emission.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/InliningInfoNode.csSkips emitting inlining info for async thunks and avoids work for methods with no inlinees.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ExceptionInfoLookupTableNode.csSkips EH-info table processing for resumption stubs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TypeFixupSignature.csAdjusts GC map encoding size computation (currently incorrect for non-64-bit pointer sizes).
src/coreclr/tools/Common/TypeSystem/IL/Stubs/AsyncResumptionStub.csUpdates diagnostic naming and hashing; marks token generation on emit.
src/coreclr/tools/Common/TypeSystem/IL/InstantiatedMethodIL.csRelaxes a Debug.Assert to accommodate non-standard owning method relationships.
src/coreclr/tools/Common/JitInterface/CorInfoImpl.csEnables READYTORUN path to provide an async resumption stub and relaxes a debug assert for async variants.
src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Async.csTracks continuation types as valid types.
src/coreclr/tools/Common/Compiler/AsyncMethodVariant.csTreats resumption stubs as async thunks for compilation decisions.
Comments suppressed due to low confidence (1)

src/coreclr/vm/jitinterface.cpp:14153

  • Avoid calling printf from the VM here. This will write to stdout in production and can interfere with host output; it also bypasses existing logging/diagnostics patterns already present in this block (STRESS_LOG + _ASSERTE). Please remove the printf and rely on the existing logging/assertion mechanisms (or route through the runtime logging infrastructure if an additional message is needed).
 result = (size_t)GetEEFuncEntryPoint(DelayLoad_Helper_Obj);
break;
case READYTORUN_HELPER_DelayLoad_Helper_ObjObj:

Comment threadsrc/coreclr/vm/methodtable.cpp Outdated
Comment threadsrc/coreclr/vm/zapsig.cpp
Comment threadsrc/coreclr/tools/Common/JitInterface/CorInfoImpl.cs Outdated
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings February 9, 2026 23:41
jtschusterand others added 2 commits March 8, 2026 17:46
1. ARM Thumb bit (emit.cpp): Add codeDelta to emitRecordRelocationWithAddlDelta
for CORINFO_AsyncResumeInfo.Resume and DiagnosticIP. On ARM32,
CorInfoReloc::DIRECT maps to IMAGE_REL_BASED_HIGHLOW which doesn't add the
Thumb bit, causing SIGILL when DispatchContinuations calls the resume stub.
2. Tiered compilation init (ilstubcache.cpp): Call
DetermineAndSetIsEligibleForTieredCompilation() on the MethodDescChunk in
CreateR2RBackedILStub. Without this, GC stack walks through R2R-backed IL
stubs assert on IsEligibleForTieredCompilation().
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings March 9, 2026 01:01

CopilotAI 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 39 out of 40 changed files in this pull request and generated no new comments.

@jtschuster

Copy link
Copy Markdown
MemberAuthor

Looks like all failures are unrelated

@davidwrightondavidwrighton 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.

I see a need for minor changes only.

Comment threadsrc/coreclr/jit/async.cpp
Add comment why we don't emit async methods in composite or ARM32
Use runtime check to avoid setting entrypoint for async helpers in non-r2r scenarios

@jakobbotschjakobbotsch 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.

JIT changes LGTM

@jtschuster
jtschuster merged commit 65b2bc1 into dotnet:mainMar 10, 2026
170 of 172 checks passed
kotlarmilos added a commit to kotlarmilos/runtime that referenced this pull request Mar 11, 2026
…tion in async methods
Add a TypeDesc case to GetModuleTokenForType to handle InstantiatedType
and other non-EcmaType TypeDesc variants by delegating to the existing
ModuleTokenResolver.GetModuleTokenForType.
Fixes a regression from dotnet#124203 where async resumption stubs referencing
generic type instantiations (e.g., CallStruct1M0<T>) crash with
NotImplementedException on Apple simulator CoreCLR RuntimeTests.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
kotlarmilos added a commit that referenced this pull request Mar 12, 2026
…tion in async methods (#125444)
Fixes a regression introduced in #124203 where crossgen2 crashes with
`NotImplementedException: Unsupported token resolution for
Internal.TypeSystem.InstantiatedType` when compiling async methods that
reference generic type instantiations (e.g., `CallStruct1M0<T>`) on
Apple mobile platforms.
## Problem
The `GetModuleTokenForType` local function in `HandleToModuleToken`
handles `SignatureMethodVariable`, `ParameterizedType`, and `EcmaType`,
but does not handle `InstantiatedType`. When async resumption stubs
resolve tokens for instantiated generic types, the code falls through to
the `default` case and throws.
Affected jobs in `runtime-extra-platforms` pipeline:
- `iossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
- `iossimulator-x64 Release AllSubsets_CoreCLR_RuntimeTests`
- `tvossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
**Failed build:**
https://dev.azure.com/dnceng-public/public/_build/results?buildId=1329675&view=results
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI pushed a commit that referenced this pull request Mar 13, 2026
Emit async methods and resumption stubs in crossgen2 ReadyToRun images
Add support for compiling and emitting runtime-async methods, their
async thunks, and resumption stubs into ReadyToRun (R2R) images
produced by crossgen2.
Async method signatures are emitted in the InstanceMethod table with a
new ENCODE_METHOD_SIG_AsyncVariant (0x100) flag. Resumption stubs are
encoded as precode fixups using a new READYTORUN_FIXUP_ResumptionStubEntryPoint
(0x38) fixup kind, where the "signature" is the RVA of the stub code.
At fixup resolution time, a DynamicMethodDesc/ILStub is created to
represent the resumption and provide GC and unwind info. Async methods
that do not await skip resumption stub emission.
Key changes:
- Add ResumptionStubEntryPointSignature node and fixup support
- Implement getAsyncResumptionStub and getFunctionEntryPoint in
crossgen2's CorInfoImpl to enable the JIT to emit async calls
- Set R2R entrypoints on JIT-synthesized async helper calls
(context capture/restore) via SetCallEntrypointForR2R
- Extend ReadyToRunILProvider to handle AsyncMethodVariant and
AsyncResumptionStub IL bodies, including cross-module token
rewriting through ManifestModuleWrappedMethodIL
- Route async variants and resumption stubs through the instance
entrypoint table and inlining info emission
- Fix PEObjectWriter ARM64 page-relative relocations to support
non-zero addends (needed for resumption stub code deltas)
- Fix GC pointer map encoding for types whose size is not
pointer-aligned (off-by-one in encodedGCRefMap allocation)
- Mark CEE_JMP as unsupported in R2R (incorrect indirection cell setup)
- Disable hot/cold splitting for async methods (runtime limitation)
- Disable async method emission in composite mode and ARM32
(known issues tracked in #125337 and #125338)
- Extend crossgen2 CI pipeline to arm64 (linux, osx, windows)
- Update r2rdump/ReadyToRunReader to discover resumption stubs
- Update ReadyToRun format documentation with new fixup kinds and
method signature flag
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI pushed a commit that referenced this pull request Mar 13, 2026
…tion in async methods (#125444)
Fixes a regression introduced in #124203 where crossgen2 crashes with
`NotImplementedException: Unsupported token resolution for
Internal.TypeSystem.InstantiatedType` when compiling async methods that
reference generic type instantiations (e.g., `CallStruct1M0<T>`) on
Apple mobile platforms.
## Problem
The `GetModuleTokenForType` local function in `HandleToModuleToken`
handles `SignatureMethodVariable`, `ParameterizedType`, and `EcmaType`,
but does not handle `InstantiatedType`. When async resumption stubs
resolve tokens for instantiated generic types, the code falls through to
the `default` case and throws.
Affected jobs in `runtime-extra-platforms` pipeline:
- `iossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
- `iossimulator-x64 Release AllSubsets_CoreCLR_RuntimeTests`
- `tvossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
**Failed build:**
https://dev.azure.com/dnceng-public/public/_build/results?buildId=1329675&view=results
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jtschuster added a commit to jtschuster/runtime that referenced this pull request Apr 2, 2026
Add 5 new tests covering key runtime-async crossgen2 PRs:
- RuntimeAsyncMethodEmission (dotnet#124203): Validates [ASYNC] variant
entries for Task/ValueTask-returning methods
- RuntimeAsyncContinuationLayout (dotnet#123643): Validates ContinuationLayout
and ResumptionStubEntryPoint fixups for methods with GC refs across awaits
- RuntimeAsyncDevirtualize (dotnet#125420): Validates async virtual method
devirtualization produces [ASYNC] entries for sealed/interface dispatch
- RuntimeAsyncNoYield (dotnet#124203): Validates async methods without await
still produce [ASYNC] variants
- RuntimeAsyncCrossModule (dotnet#121679): Validates MutableModule async
references work with cross-module inlining of runtime-async methods
Infrastructure changes:
- Add Roslyn feature flag support (runtime-async=on) to R2RTestCaseCompiler
- Add R2RExpectations for async variants, resumption stubs,
continuation layouts, and arbitrary fixup kinds
- Add MainExtraSourceResourceNames to R2RTestCase for shared source files
- Add null guard for method.Fixups in CheckFixupKinds
All 9 tests pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 10, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Specific Continuation types for each method need to be encoded in the ready to run image.

6 participants

@jtschuster@jkotas@jakobbotsch@davidwrighton@MichalStrehovsky
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Emit Async Methods in crossgen2 - #124203

Merged
jtschuster merged 101 commits into
dotnet:mainfrom
jtschuster:runtime16
Mar 10, 2026
Merged

Emit Async Methods in crossgen2#124203
jtschuster merged 101 commits into
dotnet:mainfrom
jtschuster:runtime16

Conversation

@jtschuster

@jtschusterjtschuster commented Feb 9, 2026

Copy link
Copy Markdown
Member

Emit async methods, and their resumption stubs into ReadyToRun images. Also compiles and emits async thunks for task-returning methods.

Signatures for async methods are emitted in the InstanceMethod table, with an additional ENCODE_METHOD_SIG_AsyncVariant (0x100) flag.

Resumption stubs are encoded as precode fixups for the async method with the "signature" being the RVA of the start point of the code. When the fixups are resolved, a DynamicMethodDesc / ILStub is created to represent the resumption and enable GC and unwind info to be resolved. Async methods which do not await and do not need resumption stubs won't have a resumption stub fixup.

The resumption stub MethodDescs are created following the existing pattern for ILStubs, but set the code to the R2R code rather than a precode thunk.

@jtschuster

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr crossgen2

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

CopilotAI 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

This PR adds initial support for emitting and consuming runtime-async-related methods in crossgen2 ReadyToRun (R2R) images, including new signature flags and runtime-side lookup/GC-walk plumbing for async variants and resumption stubs.

Changes:

  • Enables runtime-async=on feature flagging for selected source and test projects, and adds a dedicated CI leg to run R2R + runtime-async library tests.
  • Extends R2R method signature encoding/decoding to represent async variants and resumption stubs, and updates crossgen2 tooling/readers to surface these modifiers.
  • Adds runtime support for locating and registering resumption stub entrypoints so stack walking/GC can associate R2R resumption stubs with a MethodDesc.

Reviewed changes

Copilot reviewed 35 out of 36 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
src/libraries/Directory.Build.targetsEnables preview features + runtime-async=on for source projects when UseRuntimeAsync=true.
eng/testing/tests.targetsAdjusts runtime-async enablement for tests and adds TestRuntimeAsync override knob.
eng/pipelines/coreclr/crossgen2.ymlAdds a new CI test matrix leg for R2R + runtime-async libraries testing.
src/coreclr/inc/corcompile.hAdds ENCODE_METHOD_SIG_ResumptionStub flag for method signature encoding.
src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.csAdds managed enum flag READYTORUN_METHOD_SIG_ResumptionStub.
src/coreclr/vm/zapsig.cppReads new ResumptionStub flag during method sig decode (currently unused in logic).
src/coreclr/vm/stackwalk.cppRelaxes a debug assert for unwind table registration to accommodate async R2R scenarios.
src/coreclr/vm/readytoruninfo.hDeclares runtime API to look up resumption stub entrypoints for async variants.
src/coreclr/vm/readytoruninfo.cppImplements resumption stub lookup and registers R2R-backed stub MethodDesc for GC stack walks.
src/coreclr/vm/method.hppExtends async lookup enum and dynamic IL stub types to represent R2R resumption stubs.
src/coreclr/vm/methodtable.cppAdds an AsyncResumptionStub lookup path (currently duplicative of the existing slow path).
src/coreclr/vm/ilstubcache.hDeclares helper to create a DynamicMethodDesc wrapper around precompiled (R2R) stub code.
src/coreclr/vm/ilstubcache.cppImplements creation of an R2R-backed IL-stub MethodDesc with native entrypoint set directly.
src/coreclr/vm/jitinterface.cppTweaks READYTORUN_HELPER handling (includes an unexpected printf).
src/coreclr/inc/readytorunhelpers.hAdds mapping for READYTORUN_HELPER_ThrowExact.
src/coreclr/inc/readytorun.hClarifies formatting/commenting for async continuation helpers.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.csShows [RESUME] in method display and improves BadImageFormatException message.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.csTracks async/resume modifiers when parsing instance method + PGO sections.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.csStores/display method modifiers (async/resume) in signature string.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/PgoInfoKey.csIncludes modifiers in PGO key signature string generation.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csprojAdds AsyncMethodVariant.Mangling.cs to the build.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/IL/ReadyToRunILProvider.csBroadens IL provisioning to handle async variants and resumption stubs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunTableManager.csCategorizes async variants/resumption stubs with instantiated methods for table emission.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.csAvoids inlining async call/thunk methods and force-adds required async metadata references once.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.csMinor whitespace/style fix.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.csEmits ResumptionStub flag and hashes resumption stubs with their async variant method signature.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ModuleTokenResolver.csAdjusts method token resolution and adds field token resolution helper.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodFixupSignature.csEnsures async variants/resumption stubs aren’t incorrectly optimized as ordinary defs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/InstanceEntryPointTableNode.csHandles async variants/resumption stubs in instantiated entrypoint table emission.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/InliningInfoNode.csSkips emitting inlining info for async thunks and avoids work for methods with no inlinees.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ExceptionInfoLookupTableNode.csSkips EH-info table processing for resumption stubs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TypeFixupSignature.csAdjusts GC map encoding size computation (currently incorrect for non-64-bit pointer sizes).
src/coreclr/tools/Common/TypeSystem/IL/Stubs/AsyncResumptionStub.csUpdates diagnostic naming and hashing; marks token generation on emit.
src/coreclr/tools/Common/TypeSystem/IL/InstantiatedMethodIL.csRelaxes a Debug.Assert to accommodate non-standard owning method relationships.
src/coreclr/tools/Common/JitInterface/CorInfoImpl.csEnables READYTORUN path to provide an async resumption stub and relaxes a debug assert for async variants.
src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Async.csTracks continuation types as valid types.
src/coreclr/tools/Common/Compiler/AsyncMethodVariant.csTreats resumption stubs as async thunks for compilation decisions.
Comments suppressed due to low confidence (1)

src/coreclr/vm/jitinterface.cpp:14153

  • Avoid calling printf from the VM here. This will write to stdout in production and can interfere with host output; it also bypasses existing logging/diagnostics patterns already present in this block (STRESS_LOG + _ASSERTE). Please remove the printf and rely on the existing logging/assertion mechanisms (or route through the runtime logging infrastructure if an additional message is needed).
 result = (size_t)GetEEFuncEntryPoint(DelayLoad_Helper_Obj);
break;
case READYTORUN_HELPER_DelayLoad_Helper_ObjObj:

Comment threadsrc/coreclr/vm/methodtable.cpp Outdated
Comment threadsrc/coreclr/vm/zapsig.cpp
Comment threadsrc/coreclr/tools/Common/JitInterface/CorInfoImpl.cs Outdated
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings February 9, 2026 23:41
jtschusterand others added 2 commits March 8, 2026 17:46
1. ARM Thumb bit (emit.cpp): Add codeDelta to emitRecordRelocationWithAddlDelta
for CORINFO_AsyncResumeInfo.Resume and DiagnosticIP. On ARM32,
CorInfoReloc::DIRECT maps to IMAGE_REL_BASED_HIGHLOW which doesn't add the
Thumb bit, causing SIGILL when DispatchContinuations calls the resume stub.
2. Tiered compilation init (ilstubcache.cpp): Call
DetermineAndSetIsEligibleForTieredCompilation() on the MethodDescChunk in
CreateR2RBackedILStub. Without this, GC stack walks through R2R-backed IL
stubs assert on IsEligibleForTieredCompilation().
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings March 9, 2026 01:01

CopilotAI 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 39 out of 40 changed files in this pull request and generated no new comments.

@jtschuster

Copy link
Copy Markdown
MemberAuthor

Looks like all failures are unrelated

@davidwrightondavidwrighton 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.

I see a need for minor changes only.

Comment threadsrc/coreclr/jit/async.cpp
Add comment why we don't emit async methods in composite or ARM32
Use runtime check to avoid setting entrypoint for async helpers in non-r2r scenarios

@jakobbotschjakobbotsch 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.

JIT changes LGTM

@jtschuster
jtschuster merged commit 65b2bc1 into dotnet:mainMar 10, 2026
170 of 172 checks passed
kotlarmilos added a commit to kotlarmilos/runtime that referenced this pull request Mar 11, 2026
…tion in async methods
Add a TypeDesc case to GetModuleTokenForType to handle InstantiatedType
and other non-EcmaType TypeDesc variants by delegating to the existing
ModuleTokenResolver.GetModuleTokenForType.
Fixes a regression from dotnet#124203 where async resumption stubs referencing
generic type instantiations (e.g., CallStruct1M0<T>) crash with
NotImplementedException on Apple simulator CoreCLR RuntimeTests.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
kotlarmilos added a commit that referenced this pull request Mar 12, 2026
…tion in async methods (#125444)
Fixes a regression introduced in #124203 where crossgen2 crashes with
`NotImplementedException: Unsupported token resolution for
Internal.TypeSystem.InstantiatedType` when compiling async methods that
reference generic type instantiations (e.g., `CallStruct1M0<T>`) on
Apple mobile platforms.
## Problem
The `GetModuleTokenForType` local function in `HandleToModuleToken`
handles `SignatureMethodVariable`, `ParameterizedType`, and `EcmaType`,
but does not handle `InstantiatedType`. When async resumption stubs
resolve tokens for instantiated generic types, the code falls through to
the `default` case and throws.
Affected jobs in `runtime-extra-platforms` pipeline:
- `iossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
- `iossimulator-x64 Release AllSubsets_CoreCLR_RuntimeTests`
- `tvossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
**Failed build:**
https://dev.azure.com/dnceng-public/public/_build/results?buildId=1329675&view=results
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI pushed a commit that referenced this pull request Mar 13, 2026
Emit async methods and resumption stubs in crossgen2 ReadyToRun images
Add support for compiling and emitting runtime-async methods, their
async thunks, and resumption stubs into ReadyToRun (R2R) images
produced by crossgen2.
Async method signatures are emitted in the InstanceMethod table with a
new ENCODE_METHOD_SIG_AsyncVariant (0x100) flag. Resumption stubs are
encoded as precode fixups using a new READYTORUN_FIXUP_ResumptionStubEntryPoint
(0x38) fixup kind, where the "signature" is the RVA of the stub code.
At fixup resolution time, a DynamicMethodDesc/ILStub is created to
represent the resumption and provide GC and unwind info. Async methods
that do not await skip resumption stub emission.
Key changes:
- Add ResumptionStubEntryPointSignature node and fixup support
- Implement getAsyncResumptionStub and getFunctionEntryPoint in
crossgen2's CorInfoImpl to enable the JIT to emit async calls
- Set R2R entrypoints on JIT-synthesized async helper calls
(context capture/restore) via SetCallEntrypointForR2R
- Extend ReadyToRunILProvider to handle AsyncMethodVariant and
AsyncResumptionStub IL bodies, including cross-module token
rewriting through ManifestModuleWrappedMethodIL
- Route async variants and resumption stubs through the instance
entrypoint table and inlining info emission
- Fix PEObjectWriter ARM64 page-relative relocations to support
non-zero addends (needed for resumption stub code deltas)
- Fix GC pointer map encoding for types whose size is not
pointer-aligned (off-by-one in encodedGCRefMap allocation)
- Mark CEE_JMP as unsupported in R2R (incorrect indirection cell setup)
- Disable hot/cold splitting for async methods (runtime limitation)
- Disable async method emission in composite mode and ARM32
(known issues tracked in #125337 and #125338)
- Extend crossgen2 CI pipeline to arm64 (linux, osx, windows)
- Update r2rdump/ReadyToRunReader to discover resumption stubs
- Update ReadyToRun format documentation with new fixup kinds and
method signature flag
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI pushed a commit that referenced this pull request Mar 13, 2026
…tion in async methods (#125444)
Fixes a regression introduced in #124203 where crossgen2 crashes with
`NotImplementedException: Unsupported token resolution for
Internal.TypeSystem.InstantiatedType` when compiling async methods that
reference generic type instantiations (e.g., `CallStruct1M0<T>`) on
Apple mobile platforms.
## Problem
The `GetModuleTokenForType` local function in `HandleToModuleToken`
handles `SignatureMethodVariable`, `ParameterizedType`, and `EcmaType`,
but does not handle `InstantiatedType`. When async resumption stubs
resolve tokens for instantiated generic types, the code falls through to
the `default` case and throws.
Affected jobs in `runtime-extra-platforms` pipeline:
- `iossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
- `iossimulator-x64 Release AllSubsets_CoreCLR_RuntimeTests`
- `tvossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
**Failed build:**
https://dev.azure.com/dnceng-public/public/_build/results?buildId=1329675&view=results
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jtschuster added a commit to jtschuster/runtime that referenced this pull request Apr 2, 2026
Add 5 new tests covering key runtime-async crossgen2 PRs:
- RuntimeAsyncMethodEmission (dotnet#124203): Validates [ASYNC] variant
entries for Task/ValueTask-returning methods
- RuntimeAsyncContinuationLayout (dotnet#123643): Validates ContinuationLayout
and ResumptionStubEntryPoint fixups for methods with GC refs across awaits
- RuntimeAsyncDevirtualize (dotnet#125420): Validates async virtual method
devirtualization produces [ASYNC] entries for sealed/interface dispatch
- RuntimeAsyncNoYield (dotnet#124203): Validates async methods without await
still produce [ASYNC] variants
- RuntimeAsyncCrossModule (dotnet#121679): Validates MutableModule async
references work with cross-module inlining of runtime-async methods
Infrastructure changes:
- Add Roslyn feature flag support (runtime-async=on) to R2RTestCaseCompiler
- Add R2RExpectations for async variants, resumption stubs,
continuation layouts, and arbitrary fixup kinds
- Add MainExtraSourceResourceNames to R2RTestCase for shared source files
- Add null guard for method.Fixups in CheckFixupKinds
All 9 tests pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 10, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Specific Continuation types for each method need to be encoded in the ready to run image.

6 participants

@jtschuster@jkotas@jakobbotsch@davidwrighton@MichalStrehovsky
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Emit Async Methods in crossgen2 - #124203

Merged
jtschuster merged 101 commits into
dotnet:mainfrom
jtschuster:runtime16
Mar 10, 2026
Merged

Emit Async Methods in crossgen2#124203
jtschuster merged 101 commits into
dotnet:mainfrom
jtschuster:runtime16

Conversation

@jtschuster

@jtschusterjtschuster commented Feb 9, 2026

Copy link
Copy Markdown
Member

Emit async methods, and their resumption stubs into ReadyToRun images. Also compiles and emits async thunks for task-returning methods.

Signatures for async methods are emitted in the InstanceMethod table, with an additional ENCODE_METHOD_SIG_AsyncVariant (0x100) flag.

Resumption stubs are encoded as precode fixups for the async method with the "signature" being the RVA of the start point of the code. When the fixups are resolved, a DynamicMethodDesc / ILStub is created to represent the resumption and enable GC and unwind info to be resolved. Async methods which do not await and do not need resumption stubs won't have a resumption stub fixup.

The resumption stub MethodDescs are created following the existing pattern for ILStubs, but set the code to the R2R code rather than a precode thunk.

@jtschuster

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr crossgen2

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

CopilotAI 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

This PR adds initial support for emitting and consuming runtime-async-related methods in crossgen2 ReadyToRun (R2R) images, including new signature flags and runtime-side lookup/GC-walk plumbing for async variants and resumption stubs.

Changes:

  • Enables runtime-async=on feature flagging for selected source and test projects, and adds a dedicated CI leg to run R2R + runtime-async library tests.
  • Extends R2R method signature encoding/decoding to represent async variants and resumption stubs, and updates crossgen2 tooling/readers to surface these modifiers.
  • Adds runtime support for locating and registering resumption stub entrypoints so stack walking/GC can associate R2R resumption stubs with a MethodDesc.

Reviewed changes

Copilot reviewed 35 out of 36 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
src/libraries/Directory.Build.targetsEnables preview features + runtime-async=on for source projects when UseRuntimeAsync=true.
eng/testing/tests.targetsAdjusts runtime-async enablement for tests and adds TestRuntimeAsync override knob.
eng/pipelines/coreclr/crossgen2.ymlAdds a new CI test matrix leg for R2R + runtime-async libraries testing.
src/coreclr/inc/corcompile.hAdds ENCODE_METHOD_SIG_ResumptionStub flag for method signature encoding.
src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.csAdds managed enum flag READYTORUN_METHOD_SIG_ResumptionStub.
src/coreclr/vm/zapsig.cppReads new ResumptionStub flag during method sig decode (currently unused in logic).
src/coreclr/vm/stackwalk.cppRelaxes a debug assert for unwind table registration to accommodate async R2R scenarios.
src/coreclr/vm/readytoruninfo.hDeclares runtime API to look up resumption stub entrypoints for async variants.
src/coreclr/vm/readytoruninfo.cppImplements resumption stub lookup and registers R2R-backed stub MethodDesc for GC stack walks.
src/coreclr/vm/method.hppExtends async lookup enum and dynamic IL stub types to represent R2R resumption stubs.
src/coreclr/vm/methodtable.cppAdds an AsyncResumptionStub lookup path (currently duplicative of the existing slow path).
src/coreclr/vm/ilstubcache.hDeclares helper to create a DynamicMethodDesc wrapper around precompiled (R2R) stub code.
src/coreclr/vm/ilstubcache.cppImplements creation of an R2R-backed IL-stub MethodDesc with native entrypoint set directly.
src/coreclr/vm/jitinterface.cppTweaks READYTORUN_HELPER handling (includes an unexpected printf).
src/coreclr/inc/readytorunhelpers.hAdds mapping for READYTORUN_HELPER_ThrowExact.
src/coreclr/inc/readytorun.hClarifies formatting/commenting for async continuation helpers.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.csShows [RESUME] in method display and improves BadImageFormatException message.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.csTracks async/resume modifiers when parsing instance method + PGO sections.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.csStores/display method modifiers (async/resume) in signature string.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/PgoInfoKey.csIncludes modifiers in PGO key signature string generation.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csprojAdds AsyncMethodVariant.Mangling.cs to the build.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/IL/ReadyToRunILProvider.csBroadens IL provisioning to handle async variants and resumption stubs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunTableManager.csCategorizes async variants/resumption stubs with instantiated methods for table emission.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.csAvoids inlining async call/thunk methods and force-adds required async metadata references once.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.csMinor whitespace/style fix.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.csEmits ResumptionStub flag and hashes resumption stubs with their async variant method signature.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ModuleTokenResolver.csAdjusts method token resolution and adds field token resolution helper.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodFixupSignature.csEnsures async variants/resumption stubs aren’t incorrectly optimized as ordinary defs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/InstanceEntryPointTableNode.csHandles async variants/resumption stubs in instantiated entrypoint table emission.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/InliningInfoNode.csSkips emitting inlining info for async thunks and avoids work for methods with no inlinees.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ExceptionInfoLookupTableNode.csSkips EH-info table processing for resumption stubs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TypeFixupSignature.csAdjusts GC map encoding size computation (currently incorrect for non-64-bit pointer sizes).
src/coreclr/tools/Common/TypeSystem/IL/Stubs/AsyncResumptionStub.csUpdates diagnostic naming and hashing; marks token generation on emit.
src/coreclr/tools/Common/TypeSystem/IL/InstantiatedMethodIL.csRelaxes a Debug.Assert to accommodate non-standard owning method relationships.
src/coreclr/tools/Common/JitInterface/CorInfoImpl.csEnables READYTORUN path to provide an async resumption stub and relaxes a debug assert for async variants.
src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Async.csTracks continuation types as valid types.
src/coreclr/tools/Common/Compiler/AsyncMethodVariant.csTreats resumption stubs as async thunks for compilation decisions.
Comments suppressed due to low confidence (1)

src/coreclr/vm/jitinterface.cpp:14153

  • Avoid calling printf from the VM here. This will write to stdout in production and can interfere with host output; it also bypasses existing logging/diagnostics patterns already present in this block (STRESS_LOG + _ASSERTE). Please remove the printf and rely on the existing logging/assertion mechanisms (or route through the runtime logging infrastructure if an additional message is needed).
 result = (size_t)GetEEFuncEntryPoint(DelayLoad_Helper_Obj);
break;
case READYTORUN_HELPER_DelayLoad_Helper_ObjObj:

Comment threadsrc/coreclr/vm/methodtable.cpp Outdated
Comment threadsrc/coreclr/vm/zapsig.cpp
Comment threadsrc/coreclr/tools/Common/JitInterface/CorInfoImpl.cs Outdated
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings February 9, 2026 23:41
jtschusterand others added 2 commits March 8, 2026 17:46
1. ARM Thumb bit (emit.cpp): Add codeDelta to emitRecordRelocationWithAddlDelta
for CORINFO_AsyncResumeInfo.Resume and DiagnosticIP. On ARM32,
CorInfoReloc::DIRECT maps to IMAGE_REL_BASED_HIGHLOW which doesn't add the
Thumb bit, causing SIGILL when DispatchContinuations calls the resume stub.
2. Tiered compilation init (ilstubcache.cpp): Call
DetermineAndSetIsEligibleForTieredCompilation() on the MethodDescChunk in
CreateR2RBackedILStub. Without this, GC stack walks through R2R-backed IL
stubs assert on IsEligibleForTieredCompilation().
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings March 9, 2026 01:01

CopilotAI 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 39 out of 40 changed files in this pull request and generated no new comments.

@jtschuster

Copy link
Copy Markdown
MemberAuthor

Looks like all failures are unrelated

@davidwrightondavidwrighton 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.

I see a need for minor changes only.

Comment threadsrc/coreclr/jit/async.cpp
Add comment why we don't emit async methods in composite or ARM32
Use runtime check to avoid setting entrypoint for async helpers in non-r2r scenarios

@jakobbotschjakobbotsch 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.

JIT changes LGTM

@jtschuster
jtschuster merged commit 65b2bc1 into dotnet:mainMar 10, 2026
170 of 172 checks passed
kotlarmilos added a commit to kotlarmilos/runtime that referenced this pull request Mar 11, 2026
…tion in async methods
Add a TypeDesc case to GetModuleTokenForType to handle InstantiatedType
and other non-EcmaType TypeDesc variants by delegating to the existing
ModuleTokenResolver.GetModuleTokenForType.
Fixes a regression from dotnet#124203 where async resumption stubs referencing
generic type instantiations (e.g., CallStruct1M0<T>) crash with
NotImplementedException on Apple simulator CoreCLR RuntimeTests.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
kotlarmilos added a commit that referenced this pull request Mar 12, 2026
…tion in async methods (#125444)
Fixes a regression introduced in #124203 where crossgen2 crashes with
`NotImplementedException: Unsupported token resolution for
Internal.TypeSystem.InstantiatedType` when compiling async methods that
reference generic type instantiations (e.g., `CallStruct1M0<T>`) on
Apple mobile platforms.
## Problem
The `GetModuleTokenForType` local function in `HandleToModuleToken`
handles `SignatureMethodVariable`, `ParameterizedType`, and `EcmaType`,
but does not handle `InstantiatedType`. When async resumption stubs
resolve tokens for instantiated generic types, the code falls through to
the `default` case and throws.
Affected jobs in `runtime-extra-platforms` pipeline:
- `iossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
- `iossimulator-x64 Release AllSubsets_CoreCLR_RuntimeTests`
- `tvossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
**Failed build:**
https://dev.azure.com/dnceng-public/public/_build/results?buildId=1329675&view=results
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI pushed a commit that referenced this pull request Mar 13, 2026
Emit async methods and resumption stubs in crossgen2 ReadyToRun images
Add support for compiling and emitting runtime-async methods, their
async thunks, and resumption stubs into ReadyToRun (R2R) images
produced by crossgen2.
Async method signatures are emitted in the InstanceMethod table with a
new ENCODE_METHOD_SIG_AsyncVariant (0x100) flag. Resumption stubs are
encoded as precode fixups using a new READYTORUN_FIXUP_ResumptionStubEntryPoint
(0x38) fixup kind, where the "signature" is the RVA of the stub code.
At fixup resolution time, a DynamicMethodDesc/ILStub is created to
represent the resumption and provide GC and unwind info. Async methods
that do not await skip resumption stub emission.
Key changes:
- Add ResumptionStubEntryPointSignature node and fixup support
- Implement getAsyncResumptionStub and getFunctionEntryPoint in
crossgen2's CorInfoImpl to enable the JIT to emit async calls
- Set R2R entrypoints on JIT-synthesized async helper calls
(context capture/restore) via SetCallEntrypointForR2R
- Extend ReadyToRunILProvider to handle AsyncMethodVariant and
AsyncResumptionStub IL bodies, including cross-module token
rewriting through ManifestModuleWrappedMethodIL
- Route async variants and resumption stubs through the instance
entrypoint table and inlining info emission
- Fix PEObjectWriter ARM64 page-relative relocations to support
non-zero addends (needed for resumption stub code deltas)
- Fix GC pointer map encoding for types whose size is not
pointer-aligned (off-by-one in encodedGCRefMap allocation)
- Mark CEE_JMP as unsupported in R2R (incorrect indirection cell setup)
- Disable hot/cold splitting for async methods (runtime limitation)
- Disable async method emission in composite mode and ARM32
(known issues tracked in #125337 and #125338)
- Extend crossgen2 CI pipeline to arm64 (linux, osx, windows)
- Update r2rdump/ReadyToRunReader to discover resumption stubs
- Update ReadyToRun format documentation with new fixup kinds and
method signature flag
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI pushed a commit that referenced this pull request Mar 13, 2026
…tion in async methods (#125444)
Fixes a regression introduced in #124203 where crossgen2 crashes with
`NotImplementedException: Unsupported token resolution for
Internal.TypeSystem.InstantiatedType` when compiling async methods that
reference generic type instantiations (e.g., `CallStruct1M0<T>`) on
Apple mobile platforms.
## Problem
The `GetModuleTokenForType` local function in `HandleToModuleToken`
handles `SignatureMethodVariable`, `ParameterizedType`, and `EcmaType`,
but does not handle `InstantiatedType`. When async resumption stubs
resolve tokens for instantiated generic types, the code falls through to
the `default` case and throws.
Affected jobs in `runtime-extra-platforms` pipeline:
- `iossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
- `iossimulator-x64 Release AllSubsets_CoreCLR_RuntimeTests`
- `tvossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
**Failed build:**
https://dev.azure.com/dnceng-public/public/_build/results?buildId=1329675&view=results
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jtschuster added a commit to jtschuster/runtime that referenced this pull request Apr 2, 2026
Add 5 new tests covering key runtime-async crossgen2 PRs:
- RuntimeAsyncMethodEmission (dotnet#124203): Validates [ASYNC] variant
entries for Task/ValueTask-returning methods
- RuntimeAsyncContinuationLayout (dotnet#123643): Validates ContinuationLayout
and ResumptionStubEntryPoint fixups for methods with GC refs across awaits
- RuntimeAsyncDevirtualize (dotnet#125420): Validates async virtual method
devirtualization produces [ASYNC] entries for sealed/interface dispatch
- RuntimeAsyncNoYield (dotnet#124203): Validates async methods without await
still produce [ASYNC] variants
- RuntimeAsyncCrossModule (dotnet#121679): Validates MutableModule async
references work with cross-module inlining of runtime-async methods
Infrastructure changes:
- Add Roslyn feature flag support (runtime-async=on) to R2RTestCaseCompiler
- Add R2RExpectations for async variants, resumption stubs,
continuation layouts, and arbitrary fixup kinds
- Add MainExtraSourceResourceNames to R2RTestCase for shared source files
- Add null guard for method.Fixups in CheckFixupKinds
All 9 tests pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 10, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Specific Continuation types for each method need to be encoded in the ready to run image.

6 participants

@jtschuster@jkotas@jakobbotsch@davidwrighton@MichalStrehovsky
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Emit Async Methods in crossgen2 - #124203

Merged
jtschuster merged 101 commits into
dotnet:mainfrom
jtschuster:runtime16
Mar 10, 2026
Merged

Emit Async Methods in crossgen2#124203
jtschuster merged 101 commits into
dotnet:mainfrom
jtschuster:runtime16

Conversation

@jtschuster

@jtschusterjtschuster commented Feb 9, 2026

Copy link
Copy Markdown
Member

Emit async methods, and their resumption stubs into ReadyToRun images. Also compiles and emits async thunks for task-returning methods.

Signatures for async methods are emitted in the InstanceMethod table, with an additional ENCODE_METHOD_SIG_AsyncVariant (0x100) flag.

Resumption stubs are encoded as precode fixups for the async method with the "signature" being the RVA of the start point of the code. When the fixups are resolved, a DynamicMethodDesc / ILStub is created to represent the resumption and enable GC and unwind info to be resolved. Async methods which do not await and do not need resumption stubs won't have a resumption stub fixup.

The resumption stub MethodDescs are created following the existing pattern for ILStubs, but set the code to the R2R code rather than a precode thunk.

@jtschuster

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr crossgen2

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

CopilotAI 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

This PR adds initial support for emitting and consuming runtime-async-related methods in crossgen2 ReadyToRun (R2R) images, including new signature flags and runtime-side lookup/GC-walk plumbing for async variants and resumption stubs.

Changes:

  • Enables runtime-async=on feature flagging for selected source and test projects, and adds a dedicated CI leg to run R2R + runtime-async library tests.
  • Extends R2R method signature encoding/decoding to represent async variants and resumption stubs, and updates crossgen2 tooling/readers to surface these modifiers.
  • Adds runtime support for locating and registering resumption stub entrypoints so stack walking/GC can associate R2R resumption stubs with a MethodDesc.

Reviewed changes

Copilot reviewed 35 out of 36 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
src/libraries/Directory.Build.targetsEnables preview features + runtime-async=on for source projects when UseRuntimeAsync=true.
eng/testing/tests.targetsAdjusts runtime-async enablement for tests and adds TestRuntimeAsync override knob.
eng/pipelines/coreclr/crossgen2.ymlAdds a new CI test matrix leg for R2R + runtime-async libraries testing.
src/coreclr/inc/corcompile.hAdds ENCODE_METHOD_SIG_ResumptionStub flag for method signature encoding.
src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.csAdds managed enum flag READYTORUN_METHOD_SIG_ResumptionStub.
src/coreclr/vm/zapsig.cppReads new ResumptionStub flag during method sig decode (currently unused in logic).
src/coreclr/vm/stackwalk.cppRelaxes a debug assert for unwind table registration to accommodate async R2R scenarios.
src/coreclr/vm/readytoruninfo.hDeclares runtime API to look up resumption stub entrypoints for async variants.
src/coreclr/vm/readytoruninfo.cppImplements resumption stub lookup and registers R2R-backed stub MethodDesc for GC stack walks.
src/coreclr/vm/method.hppExtends async lookup enum and dynamic IL stub types to represent R2R resumption stubs.
src/coreclr/vm/methodtable.cppAdds an AsyncResumptionStub lookup path (currently duplicative of the existing slow path).
src/coreclr/vm/ilstubcache.hDeclares helper to create a DynamicMethodDesc wrapper around precompiled (R2R) stub code.
src/coreclr/vm/ilstubcache.cppImplements creation of an R2R-backed IL-stub MethodDesc with native entrypoint set directly.
src/coreclr/vm/jitinterface.cppTweaks READYTORUN_HELPER handling (includes an unexpected printf).
src/coreclr/inc/readytorunhelpers.hAdds mapping for READYTORUN_HELPER_ThrowExact.
src/coreclr/inc/readytorun.hClarifies formatting/commenting for async continuation helpers.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.csShows [RESUME] in method display and improves BadImageFormatException message.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.csTracks async/resume modifiers when parsing instance method + PGO sections.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.csStores/display method modifiers (async/resume) in signature string.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/PgoInfoKey.csIncludes modifiers in PGO key signature string generation.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csprojAdds AsyncMethodVariant.Mangling.cs to the build.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/IL/ReadyToRunILProvider.csBroadens IL provisioning to handle async variants and resumption stubs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunTableManager.csCategorizes async variants/resumption stubs with instantiated methods for table emission.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.csAvoids inlining async call/thunk methods and force-adds required async metadata references once.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.csMinor whitespace/style fix.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.csEmits ResumptionStub flag and hashes resumption stubs with their async variant method signature.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ModuleTokenResolver.csAdjusts method token resolution and adds field token resolution helper.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodFixupSignature.csEnsures async variants/resumption stubs aren’t incorrectly optimized as ordinary defs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/InstanceEntryPointTableNode.csHandles async variants/resumption stubs in instantiated entrypoint table emission.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/InliningInfoNode.csSkips emitting inlining info for async thunks and avoids work for methods with no inlinees.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ExceptionInfoLookupTableNode.csSkips EH-info table processing for resumption stubs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TypeFixupSignature.csAdjusts GC map encoding size computation (currently incorrect for non-64-bit pointer sizes).
src/coreclr/tools/Common/TypeSystem/IL/Stubs/AsyncResumptionStub.csUpdates diagnostic naming and hashing; marks token generation on emit.
src/coreclr/tools/Common/TypeSystem/IL/InstantiatedMethodIL.csRelaxes a Debug.Assert to accommodate non-standard owning method relationships.
src/coreclr/tools/Common/JitInterface/CorInfoImpl.csEnables READYTORUN path to provide an async resumption stub and relaxes a debug assert for async variants.
src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Async.csTracks continuation types as valid types.
src/coreclr/tools/Common/Compiler/AsyncMethodVariant.csTreats resumption stubs as async thunks for compilation decisions.
Comments suppressed due to low confidence (1)

src/coreclr/vm/jitinterface.cpp:14153

  • Avoid calling printf from the VM here. This will write to stdout in production and can interfere with host output; it also bypasses existing logging/diagnostics patterns already present in this block (STRESS_LOG + _ASSERTE). Please remove the printf and rely on the existing logging/assertion mechanisms (or route through the runtime logging infrastructure if an additional message is needed).
 result = (size_t)GetEEFuncEntryPoint(DelayLoad_Helper_Obj);
break;
case READYTORUN_HELPER_DelayLoad_Helper_ObjObj:

Comment threadsrc/coreclr/vm/methodtable.cpp Outdated
Comment threadsrc/coreclr/vm/zapsig.cpp
Comment threadsrc/coreclr/tools/Common/JitInterface/CorInfoImpl.cs Outdated
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings February 9, 2026 23:41
jtschusterand others added 2 commits March 8, 2026 17:46
1. ARM Thumb bit (emit.cpp): Add codeDelta to emitRecordRelocationWithAddlDelta
for CORINFO_AsyncResumeInfo.Resume and DiagnosticIP. On ARM32,
CorInfoReloc::DIRECT maps to IMAGE_REL_BASED_HIGHLOW which doesn't add the
Thumb bit, causing SIGILL when DispatchContinuations calls the resume stub.
2. Tiered compilation init (ilstubcache.cpp): Call
DetermineAndSetIsEligibleForTieredCompilation() on the MethodDescChunk in
CreateR2RBackedILStub. Without this, GC stack walks through R2R-backed IL
stubs assert on IsEligibleForTieredCompilation().
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings March 9, 2026 01:01

CopilotAI 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 39 out of 40 changed files in this pull request and generated no new comments.

@jtschuster

Copy link
Copy Markdown
MemberAuthor

Looks like all failures are unrelated

@davidwrightondavidwrighton 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.

I see a need for minor changes only.

Comment threadsrc/coreclr/jit/async.cpp
Add comment why we don't emit async methods in composite or ARM32
Use runtime check to avoid setting entrypoint for async helpers in non-r2r scenarios

@jakobbotschjakobbotsch 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.

JIT changes LGTM

@jtschuster
jtschuster merged commit 65b2bc1 into dotnet:mainMar 10, 2026
170 of 172 checks passed
kotlarmilos added a commit to kotlarmilos/runtime that referenced this pull request Mar 11, 2026
…tion in async methods
Add a TypeDesc case to GetModuleTokenForType to handle InstantiatedType
and other non-EcmaType TypeDesc variants by delegating to the existing
ModuleTokenResolver.GetModuleTokenForType.
Fixes a regression from dotnet#124203 where async resumption stubs referencing
generic type instantiations (e.g., CallStruct1M0<T>) crash with
NotImplementedException on Apple simulator CoreCLR RuntimeTests.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
kotlarmilos added a commit that referenced this pull request Mar 12, 2026
…tion in async methods (#125444)
Fixes a regression introduced in #124203 where crossgen2 crashes with
`NotImplementedException: Unsupported token resolution for
Internal.TypeSystem.InstantiatedType` when compiling async methods that
reference generic type instantiations (e.g., `CallStruct1M0<T>`) on
Apple mobile platforms.
## Problem
The `GetModuleTokenForType` local function in `HandleToModuleToken`
handles `SignatureMethodVariable`, `ParameterizedType`, and `EcmaType`,
but does not handle `InstantiatedType`. When async resumption stubs
resolve tokens for instantiated generic types, the code falls through to
the `default` case and throws.
Affected jobs in `runtime-extra-platforms` pipeline:
- `iossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
- `iossimulator-x64 Release AllSubsets_CoreCLR_RuntimeTests`
- `tvossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
**Failed build:**
https://dev.azure.com/dnceng-public/public/_build/results?buildId=1329675&view=results
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI pushed a commit that referenced this pull request Mar 13, 2026
Emit async methods and resumption stubs in crossgen2 ReadyToRun images
Add support for compiling and emitting runtime-async methods, their
async thunks, and resumption stubs into ReadyToRun (R2R) images
produced by crossgen2.
Async method signatures are emitted in the InstanceMethod table with a
new ENCODE_METHOD_SIG_AsyncVariant (0x100) flag. Resumption stubs are
encoded as precode fixups using a new READYTORUN_FIXUP_ResumptionStubEntryPoint
(0x38) fixup kind, where the "signature" is the RVA of the stub code.
At fixup resolution time, a DynamicMethodDesc/ILStub is created to
represent the resumption and provide GC and unwind info. Async methods
that do not await skip resumption stub emission.
Key changes:
- Add ResumptionStubEntryPointSignature node and fixup support
- Implement getAsyncResumptionStub and getFunctionEntryPoint in
crossgen2's CorInfoImpl to enable the JIT to emit async calls
- Set R2R entrypoints on JIT-synthesized async helper calls
(context capture/restore) via SetCallEntrypointForR2R
- Extend ReadyToRunILProvider to handle AsyncMethodVariant and
AsyncResumptionStub IL bodies, including cross-module token
rewriting through ManifestModuleWrappedMethodIL
- Route async variants and resumption stubs through the instance
entrypoint table and inlining info emission
- Fix PEObjectWriter ARM64 page-relative relocations to support
non-zero addends (needed for resumption stub code deltas)
- Fix GC pointer map encoding for types whose size is not
pointer-aligned (off-by-one in encodedGCRefMap allocation)
- Mark CEE_JMP as unsupported in R2R (incorrect indirection cell setup)
- Disable hot/cold splitting for async methods (runtime limitation)
- Disable async method emission in composite mode and ARM32
(known issues tracked in #125337 and #125338)
- Extend crossgen2 CI pipeline to arm64 (linux, osx, windows)
- Update r2rdump/ReadyToRunReader to discover resumption stubs
- Update ReadyToRun format documentation with new fixup kinds and
method signature flag
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI pushed a commit that referenced this pull request Mar 13, 2026
…tion in async methods (#125444)
Fixes a regression introduced in #124203 where crossgen2 crashes with
`NotImplementedException: Unsupported token resolution for
Internal.TypeSystem.InstantiatedType` when compiling async methods that
reference generic type instantiations (e.g., `CallStruct1M0<T>`) on
Apple mobile platforms.
## Problem
The `GetModuleTokenForType` local function in `HandleToModuleToken`
handles `SignatureMethodVariable`, `ParameterizedType`, and `EcmaType`,
but does not handle `InstantiatedType`. When async resumption stubs
resolve tokens for instantiated generic types, the code falls through to
the `default` case and throws.
Affected jobs in `runtime-extra-platforms` pipeline:
- `iossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
- `iossimulator-x64 Release AllSubsets_CoreCLR_RuntimeTests`
- `tvossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
**Failed build:**
https://dev.azure.com/dnceng-public/public/_build/results?buildId=1329675&view=results
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jtschuster added a commit to jtschuster/runtime that referenced this pull request Apr 2, 2026
Add 5 new tests covering key runtime-async crossgen2 PRs:
- RuntimeAsyncMethodEmission (dotnet#124203): Validates [ASYNC] variant
entries for Task/ValueTask-returning methods
- RuntimeAsyncContinuationLayout (dotnet#123643): Validates ContinuationLayout
and ResumptionStubEntryPoint fixups for methods with GC refs across awaits
- RuntimeAsyncDevirtualize (dotnet#125420): Validates async virtual method
devirtualization produces [ASYNC] entries for sealed/interface dispatch
- RuntimeAsyncNoYield (dotnet#124203): Validates async methods without await
still produce [ASYNC] variants
- RuntimeAsyncCrossModule (dotnet#121679): Validates MutableModule async
references work with cross-module inlining of runtime-async methods
Infrastructure changes:
- Add Roslyn feature flag support (runtime-async=on) to R2RTestCaseCompiler
- Add R2RExpectations for async variants, resumption stubs,
continuation layouts, and arbitrary fixup kinds
- Add MainExtraSourceResourceNames to R2RTestCase for shared source files
- Add null guard for method.Fixups in CheckFixupKinds
All 9 tests pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 10, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Specific Continuation types for each method need to be encoded in the ready to run image.

6 participants

@jtschuster@jkotas@jakobbotsch@davidwrighton@MichalStrehovsky
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Emit Async Methods in crossgen2 - #124203

Merged
jtschuster merged 101 commits into
dotnet:mainfrom
jtschuster:runtime16
Mar 10, 2026
Merged

Emit Async Methods in crossgen2#124203
jtschuster merged 101 commits into
dotnet:mainfrom
jtschuster:runtime16

Conversation

@jtschuster

@jtschusterjtschuster commented Feb 9, 2026

Copy link
Copy Markdown
Member

Emit async methods, and their resumption stubs into ReadyToRun images. Also compiles and emits async thunks for task-returning methods.

Signatures for async methods are emitted in the InstanceMethod table, with an additional ENCODE_METHOD_SIG_AsyncVariant (0x100) flag.

Resumption stubs are encoded as precode fixups for the async method with the "signature" being the RVA of the start point of the code. When the fixups are resolved, a DynamicMethodDesc / ILStub is created to represent the resumption and enable GC and unwind info to be resolved. Async methods which do not await and do not need resumption stubs won't have a resumption stub fixup.

The resumption stub MethodDescs are created following the existing pattern for ILStubs, but set the code to the R2R code rather than a precode thunk.

@jtschuster

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr crossgen2

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

CopilotAI 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

This PR adds initial support for emitting and consuming runtime-async-related methods in crossgen2 ReadyToRun (R2R) images, including new signature flags and runtime-side lookup/GC-walk plumbing for async variants and resumption stubs.

Changes:

  • Enables runtime-async=on feature flagging for selected source and test projects, and adds a dedicated CI leg to run R2R + runtime-async library tests.
  • Extends R2R method signature encoding/decoding to represent async variants and resumption stubs, and updates crossgen2 tooling/readers to surface these modifiers.
  • Adds runtime support for locating and registering resumption stub entrypoints so stack walking/GC can associate R2R resumption stubs with a MethodDesc.

Reviewed changes

Copilot reviewed 35 out of 36 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
src/libraries/Directory.Build.targetsEnables preview features + runtime-async=on for source projects when UseRuntimeAsync=true.
eng/testing/tests.targetsAdjusts runtime-async enablement for tests and adds TestRuntimeAsync override knob.
eng/pipelines/coreclr/crossgen2.ymlAdds a new CI test matrix leg for R2R + runtime-async libraries testing.
src/coreclr/inc/corcompile.hAdds ENCODE_METHOD_SIG_ResumptionStub flag for method signature encoding.
src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.csAdds managed enum flag READYTORUN_METHOD_SIG_ResumptionStub.
src/coreclr/vm/zapsig.cppReads new ResumptionStub flag during method sig decode (currently unused in logic).
src/coreclr/vm/stackwalk.cppRelaxes a debug assert for unwind table registration to accommodate async R2R scenarios.
src/coreclr/vm/readytoruninfo.hDeclares runtime API to look up resumption stub entrypoints for async variants.
src/coreclr/vm/readytoruninfo.cppImplements resumption stub lookup and registers R2R-backed stub MethodDesc for GC stack walks.
src/coreclr/vm/method.hppExtends async lookup enum and dynamic IL stub types to represent R2R resumption stubs.
src/coreclr/vm/methodtable.cppAdds an AsyncResumptionStub lookup path (currently duplicative of the existing slow path).
src/coreclr/vm/ilstubcache.hDeclares helper to create a DynamicMethodDesc wrapper around precompiled (R2R) stub code.
src/coreclr/vm/ilstubcache.cppImplements creation of an R2R-backed IL-stub MethodDesc with native entrypoint set directly.
src/coreclr/vm/jitinterface.cppTweaks READYTORUN_HELPER handling (includes an unexpected printf).
src/coreclr/inc/readytorunhelpers.hAdds mapping for READYTORUN_HELPER_ThrowExact.
src/coreclr/inc/readytorun.hClarifies formatting/commenting for async continuation helpers.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.csShows [RESUME] in method display and improves BadImageFormatException message.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.csTracks async/resume modifiers when parsing instance method + PGO sections.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.csStores/display method modifiers (async/resume) in signature string.
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/PgoInfoKey.csIncludes modifiers in PGO key signature string generation.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csprojAdds AsyncMethodVariant.Mangling.cs to the build.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/IL/ReadyToRunILProvider.csBroadens IL provisioning to handle async variants and resumption stubs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunTableManager.csCategorizes async variants/resumption stubs with instantiated methods for table emission.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.csAvoids inlining async call/thunk methods and force-adds required async metadata references once.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.csMinor whitespace/style fix.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.csEmits ResumptionStub flag and hashes resumption stubs with their async variant method signature.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ModuleTokenResolver.csAdjusts method token resolution and adds field token resolution helper.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodFixupSignature.csEnsures async variants/resumption stubs aren’t incorrectly optimized as ordinary defs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/InstanceEntryPointTableNode.csHandles async variants/resumption stubs in instantiated entrypoint table emission.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/InliningInfoNode.csSkips emitting inlining info for async thunks and avoids work for methods with no inlinees.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ExceptionInfoLookupTableNode.csSkips EH-info table processing for resumption stubs.
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TypeFixupSignature.csAdjusts GC map encoding size computation (currently incorrect for non-64-bit pointer sizes).
src/coreclr/tools/Common/TypeSystem/IL/Stubs/AsyncResumptionStub.csUpdates diagnostic naming and hashing; marks token generation on emit.
src/coreclr/tools/Common/TypeSystem/IL/InstantiatedMethodIL.csRelaxes a Debug.Assert to accommodate non-standard owning method relationships.
src/coreclr/tools/Common/JitInterface/CorInfoImpl.csEnables READYTORUN path to provide an async resumption stub and relaxes a debug assert for async variants.
src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Async.csTracks continuation types as valid types.
src/coreclr/tools/Common/Compiler/AsyncMethodVariant.csTreats resumption stubs as async thunks for compilation decisions.
Comments suppressed due to low confidence (1)

src/coreclr/vm/jitinterface.cpp:14153

  • Avoid calling printf from the VM here. This will write to stdout in production and can interfere with host output; it also bypasses existing logging/diagnostics patterns already present in this block (STRESS_LOG + _ASSERTE). Please remove the printf and rely on the existing logging/assertion mechanisms (or route through the runtime logging infrastructure if an additional message is needed).
 result = (size_t)GetEEFuncEntryPoint(DelayLoad_Helper_Obj);
break;
case READYTORUN_HELPER_DelayLoad_Helper_ObjObj:

Comment threadsrc/coreclr/vm/methodtable.cpp Outdated
Comment threadsrc/coreclr/vm/zapsig.cpp
Comment threadsrc/coreclr/tools/Common/JitInterface/CorInfoImpl.cs Outdated
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings February 9, 2026 23:41
jtschusterand others added 2 commits March 8, 2026 17:46
1. ARM Thumb bit (emit.cpp): Add codeDelta to emitRecordRelocationWithAddlDelta
for CORINFO_AsyncResumeInfo.Resume and DiagnosticIP. On ARM32,
CorInfoReloc::DIRECT maps to IMAGE_REL_BASED_HIGHLOW which doesn't add the
Thumb bit, causing SIGILL when DispatchContinuations calls the resume stub.
2. Tiered compilation init (ilstubcache.cpp): Call
DetermineAndSetIsEligibleForTieredCompilation() on the MethodDescChunk in
CreateR2RBackedILStub. Without this, GC stack walks through R2R-backed IL
stubs assert on IsEligibleForTieredCompilation().
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings March 9, 2026 01:01

CopilotAI 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 39 out of 40 changed files in this pull request and generated no new comments.

@jtschuster

Copy link
Copy Markdown
MemberAuthor

Looks like all failures are unrelated

@davidwrightondavidwrighton 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.

I see a need for minor changes only.

Comment threadsrc/coreclr/jit/async.cpp
Add comment why we don't emit async methods in composite or ARM32
Use runtime check to avoid setting entrypoint for async helpers in non-r2r scenarios

@jakobbotschjakobbotsch 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.

JIT changes LGTM

@jtschuster
jtschuster merged commit 65b2bc1 into dotnet:mainMar 10, 2026
170 of 172 checks passed
kotlarmilos added a commit to kotlarmilos/runtime that referenced this pull request Mar 11, 2026
…tion in async methods
Add a TypeDesc case to GetModuleTokenForType to handle InstantiatedType
and other non-EcmaType TypeDesc variants by delegating to the existing
ModuleTokenResolver.GetModuleTokenForType.
Fixes a regression from dotnet#124203 where async resumption stubs referencing
generic type instantiations (e.g., CallStruct1M0<T>) crash with
NotImplementedException on Apple simulator CoreCLR RuntimeTests.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
kotlarmilos added a commit that referenced this pull request Mar 12, 2026
…tion in async methods (#125444)
Fixes a regression introduced in #124203 where crossgen2 crashes with
`NotImplementedException: Unsupported token resolution for
Internal.TypeSystem.InstantiatedType` when compiling async methods that
reference generic type instantiations (e.g., `CallStruct1M0<T>`) on
Apple mobile platforms.
## Problem
The `GetModuleTokenForType` local function in `HandleToModuleToken`
handles `SignatureMethodVariable`, `ParameterizedType`, and `EcmaType`,
but does not handle `InstantiatedType`. When async resumption stubs
resolve tokens for instantiated generic types, the code falls through to
the `default` case and throws.
Affected jobs in `runtime-extra-platforms` pipeline:
- `iossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
- `iossimulator-x64 Release AllSubsets_CoreCLR_RuntimeTests`
- `tvossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
**Failed build:**
https://dev.azure.com/dnceng-public/public/_build/results?buildId=1329675&view=results
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI pushed a commit that referenced this pull request Mar 13, 2026
Emit async methods and resumption stubs in crossgen2 ReadyToRun images
Add support for compiling and emitting runtime-async methods, their
async thunks, and resumption stubs into ReadyToRun (R2R) images
produced by crossgen2.
Async method signatures are emitted in the InstanceMethod table with a
new ENCODE_METHOD_SIG_AsyncVariant (0x100) flag. Resumption stubs are
encoded as precode fixups using a new READYTORUN_FIXUP_ResumptionStubEntryPoint
(0x38) fixup kind, where the "signature" is the RVA of the stub code.
At fixup resolution time, a DynamicMethodDesc/ILStub is created to
represent the resumption and provide GC and unwind info. Async methods
that do not await skip resumption stub emission.
Key changes:
- Add ResumptionStubEntryPointSignature node and fixup support
- Implement getAsyncResumptionStub and getFunctionEntryPoint in
crossgen2's CorInfoImpl to enable the JIT to emit async calls
- Set R2R entrypoints on JIT-synthesized async helper calls
(context capture/restore) via SetCallEntrypointForR2R
- Extend ReadyToRunILProvider to handle AsyncMethodVariant and
AsyncResumptionStub IL bodies, including cross-module token
rewriting through ManifestModuleWrappedMethodIL
- Route async variants and resumption stubs through the instance
entrypoint table and inlining info emission
- Fix PEObjectWriter ARM64 page-relative relocations to support
non-zero addends (needed for resumption stub code deltas)
- Fix GC pointer map encoding for types whose size is not
pointer-aligned (off-by-one in encodedGCRefMap allocation)
- Mark CEE_JMP as unsupported in R2R (incorrect indirection cell setup)
- Disable hot/cold splitting for async methods (runtime limitation)
- Disable async method emission in composite mode and ARM32
(known issues tracked in #125337 and #125338)
- Extend crossgen2 CI pipeline to arm64 (linux, osx, windows)
- Update r2rdump/ReadyToRunReader to discover resumption stubs
- Update ReadyToRun format documentation with new fixup kinds and
method signature flag
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI pushed a commit that referenced this pull request Mar 13, 2026
…tion in async methods (#125444)
Fixes a regression introduced in #124203 where crossgen2 crashes with
`NotImplementedException: Unsupported token resolution for
Internal.TypeSystem.InstantiatedType` when compiling async methods that
reference generic type instantiations (e.g., `CallStruct1M0<T>`) on
Apple mobile platforms.
## Problem
The `GetModuleTokenForType` local function in `HandleToModuleToken`
handles `SignatureMethodVariable`, `ParameterizedType`, and `EcmaType`,
but does not handle `InstantiatedType`. When async resumption stubs
resolve tokens for instantiated generic types, the code falls through to
the `default` case and throws.
Affected jobs in `runtime-extra-platforms` pipeline:
- `iossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
- `iossimulator-x64 Release AllSubsets_CoreCLR_RuntimeTests`
- `tvossimulator-arm64 Release AllSubsets_CoreCLR_RuntimeTests`
**Failed build:**
https://dev.azure.com/dnceng-public/public/_build/results?buildId=1329675&view=results
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jtschuster added a commit to jtschuster/runtime that referenced this pull request Apr 2, 2026
Add 5 new tests covering key runtime-async crossgen2 PRs:
- RuntimeAsyncMethodEmission (dotnet#124203): Validates [ASYNC] variant
entries for Task/ValueTask-returning methods
- RuntimeAsyncContinuationLayout (dotnet#123643): Validates ContinuationLayout
and ResumptionStubEntryPoint fixups for methods with GC refs across awaits
- RuntimeAsyncDevirtualize (dotnet#125420): Validates async virtual method
devirtualization produces [ASYNC] entries for sealed/interface dispatch
- RuntimeAsyncNoYield (dotnet#124203): Validates async methods without await
still produce [ASYNC] variants
- RuntimeAsyncCrossModule (dotnet#121679): Validates MutableModule async
references work with cross-module inlining of runtime-async methods
Infrastructure changes:
- Add Roslyn feature flag support (runtime-async=on) to R2RTestCaseCompiler
- Add R2RExpectations for async variants, resumption stubs,
continuation layouts, and arbitrary fixup kinds
- Add MainExtraSourceResourceNames to R2RTestCase for shared source files
- Add null guard for method.Fixups in CheckFixupKinds
All 9 tests pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 10, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Specific Continuation types for each method need to be encoded in the ready to run image.

6 participants

@jtschuster@jkotas@jakobbotsch@davidwrighton@MichalStrehovsky