Skip to content

JIT: Treat the indicator variable as transition-preserved - #131731

Merged
jakobbotsch merged 9 commits into
dotnet:mainfrom
jakobbotsch:fix-inline-indicator-enc
Aug 3, 2026
Merged

JIT: Treat the indicator variable as transition-preserved#131731
jakobbotsch merged 9 commits into
dotnet:mainfrom
jakobbotsch:fix-inline-indicator-enc

Conversation

@jakobbotsch

@jakobbotsch jakobbotsch commented Aug 3, 2026

Copy link
Copy Markdown
Member

In OSR functions we recomputed this from the async continuation argument (which itself is transition-preserved). That approach is not sufficient for EnC. Instead just preserve the state across EnC/OSR transitions in the same way as other state.

To simplify the remapping/local allocation logic this also changes the indicator to consistently be a TYP_I_IMPL local, with all definitions of it writing that size. The arguments passed to the helper calls remain TYP_INT since they are bools in the managed signatures. We use TYP_INT typed local nodes for the indicator variable for these (allowed in JIT IR and used by optNarrowTree/IV widening also).

In OSR functions we recomputed this from the async continuation argument
(which itself is transition-preserved). That approach is not sufficient
for EnC. Instead just preserve the state across EnC/OSR transitions in
the same way as other state.
Copilot AI review requested due to automatic review settings August 3, 2026 10:46
@github-actions github-actions Bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Aug 3, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 6 pipeline(s).
10 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates async OSR/EnC handling so the async “resumed?” indicator local is treated like other transition-preserved state: it gets a stable stack slot in the preserved area and its tier0-frame offset is communicated via PatchpointInfo for OSR compilations.

Changes:

  • Adds PatchpointInfo support for a resumed-indicator stack offset and plumbs it through OSR patchpoint generation and OSR local offset resolution.
  • Allocates lvaResumedIndicator as part of the async preserved-area locals and includes it in EnC preserved-area size verification across xarch/arm.
  • Simplifies OSR async context setup by removing the OSR-specific recomputation of the indicator from the continuation argument.

Reviewed changes

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

Show a summary per file
File Description
src/coreclr/jit/lclvars.cpp Ensures the resumed-indicator local is stack-allocated as part of async preserved-area locals and excluded from later offset assignment passes.
src/coreclr/jit/compiler.h Moves lvaResumedIndicator alongside other async preserved locals in the Compiler state.
src/coreclr/jit/compiler.cpp Records and consumes the resumed-indicator tier0-frame offset via PatchpointInfo for OSR local remapping.
src/coreclr/jit/codegenxarch.cpp Accounts for resumed-indicator in EnC preserved-area sizing assertions on x64.
src/coreclr/jit/codegenarmarch.cpp Accounts for resumed-indicator in EnC preserved-area sizing assertions on arm64 (GC info encoder path).
src/coreclr/jit/codegenarm64.cpp Includes resumed-indicator stack home in funclet prolog/epilog size accounting (non-OSR).
src/coreclr/jit/codegenarm.cpp Includes resumed-indicator in funclet prolog/epilog size accounting (arm32).
src/coreclr/jit/async.cpp Creates the resumed-indicator local as pointer-sized and removes OSR-only recomputation from continuation arg.
src/coreclr/inc/patchpointinfo.h Adds a new resumed-indicator offset field + accessors to the shared OSR patchpoint info.
Suppressed comments (1)

src/coreclr/jit/async.cpp:380

  • Same issue as in SaveAsyncContexts: lvaResumedIndicator has lvType = TYP_I_IMPL, so using gtNewLclVarNode(lvaResumedIndicator, TYP_INT) will trip the gtNewLclvNode type assert in DEBUG builds. Load as TYP_I_IMPL and cast to TYP_INT for the restoreContexts call argument.
    restoreCall->gtArgs.PushFront(this, NewCallArg::Primitive(gtNewLclVarNode(lvaResumedIndicator, TYP_INT)));

Comment thread src/coreclr/jit/async.cpp
Copilot AI review requested due to automatic review settings August 3, 2026 10:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

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

Suppressed comments (1)

src/coreclr/jit/async.cpp:78

  • lvaResumedIndicator is now declared as TYP_I_IMPL, but several downstream parts of the async transformation still treat it as a byte/boolean flag. In particular, AsyncTransformation::StoreResumedDef only does a full-width store when the local is TYP_UBYTE; with TYP_I_IMPL it falls back to a TYP_UBYTE field store (byte write) into a pointer-sized local. That leaves the upper bytes undefined and makes the value representation dependent on prior zero-init, which is brittle for OSR/EnC transitions and any future TYP_I_IMPL uses.

Either keep the local as TYP_UBYTE and explicitly force a pointer-sized stack home for the transition-preserved slot, or update the async transformation (and related address-def sizing logic) to store/load the indicator consistently as native-int (e.g., store 1 as TYP_I_IMPL when the local is TYP_I_IMPL).


    lvaGetDesc(lvaResumedIndicator)->lvType               = TYP_I_IMPL;
    lvaGetDesc(lvaAsyncThreadObjectVar)->lvType           = TYP_REF;
    lvaGetDesc(lvaAsyncExecutionContextVar)->lvType       = TYP_REF;
    lvaGetDesc(lvaAsyncSynchronizationContextVar)->lvType = TYP_REF;

Copilot AI review requested due to automatic review settings August 3, 2026 11:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

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

Comment thread src/coreclr/jit/async.cpp
Copilot AI review requested due to automatic review settings August 3, 2026 12:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

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

Suppressed comments (1)

src/coreclr/jit/lclvars.cpp:5864

  • This comment says we "allocate 8 bytes" for the resumed indicator, but the actual allocation uses TARGET_POINTER_SIZE (4 bytes on x86, 8 bytes on 64-bit). The comment should describe the pointer-sized intent to avoid confusion when reading x86 EnC frame layout changes.
        // The indicator is actually a bool, but we allocate 8 bytes for it to
        // simplify EnC remapping.
        stkOffs = lvaAllocLocalAndSetVirtualOffset(lvaResumedIndicator, TARGET_POINTER_SIZE, stkOffs);

Comment thread src/coreclr/jit/codegenarm64.cpp
Copilot AI review requested due to automatic review settings August 3, 2026 13:17
Comment thread src/coreclr/inc/jiteeversionguid.h
Comment thread src/coreclr/inc/readytoruninstructionset.h

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.

Suppressed comments (4)

src/coreclr/inc/readytoruninstructionset.h:106

  • This introduces an otherwise unrelated whitespace-only change (extra blank line) in the enum; please remove it to keep the PR focused and avoid diff noise.
    READYTORUN_INSTRUCTION_Zicond=94,

};

src/coreclr/jit/lclvars.cpp:5863

  • The lvaAllocAsyncContexts header comment is now stale: the routine also allocates the resumed-indicator slot. Please update the comment so it matches the current behavior.
    if (lvaResumedIndicator != BAD_VAR_NUM)
    {
        stkOffs = lvaAllocLocalAndSetVirtualOffset(lvaResumedIndicator, lvaLclStackHomeSize(lvaResumedIndicator), stkOffs);
    }

src/coreclr/jit/codegenxarch.cpp:8382

  • The EnC preserved-area comment immediately above is now incomplete: the code also preserves the async resumed-indicator slot. Please update the comment to match the frame header layout.
        if (m_compiler->lvaResumedIndicator != BAD_VAR_NUM)
        {
            preservedAreaSize += TARGET_POINTER_SIZE;

            assert(m_compiler->lvaGetCallerSPRelativeOffset(m_compiler->lvaResumedIndicator) == -preservedAreaSize);
        }

src/coreclr/jit/codegenarmarch.cpp:3936

  • The EnC preserved-area comment immediately above is now incomplete: the code also preserves the async resumed-indicator slot. Please update the comment to match the frame header layout.
        if (m_compiler->lvaResumedIndicator != BAD_VAR_NUM)
        {
            preservedAreaSize += TARGET_POINTER_SIZE;

            assert(m_compiler->lvaGetCallerSPRelativeOffset(m_compiler->lvaResumedIndicator) == -preservedAreaSize);
        }

Copilot AI review requested due to automatic review settings August 3, 2026 13:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/coreclr/inc/readytoruninstructionset.h:106

  • Remove the extra blank line at the end of the enum; it looks like accidental whitespace-only churn unrelated to the JIT/async change and can cause avoidable merge conflicts.
    READYTORUN_INSTRUCTION_Cssc=93,
    READYTORUN_INSTRUCTION_Zicond=94,

};

src/coreclr/jit/lclvars.cpp:5864

  • The header comment for lvaAllocAsyncContexts is now out of sync with the implementation: it also allocates the resumed indicator slot. Updating the comment will help keep the frame-layout invariants clear (especially around EnC).
    if (lvaResumedIndicator != BAD_VAR_NUM)
    {
        stkOffs =
            lvaAllocLocalAndSetVirtualOffset(lvaResumedIndicator, lvaLclStackHomeSize(lvaResumedIndicator), stkOffs);
    }

@jakobbotsch
jakobbotsch marked this pull request as ready for review August 3, 2026 18:03
@jakobbotsch

Copy link
Copy Markdown
Member Author

cc @dotnet/jit-contrib PTAL @AndyAyersMS

@jakobbotsch
jakobbotsch requested a review from AndyAyersMS August 3, 2026 18:03
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 6 pipeline(s).
10 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@jakobbotsch
jakobbotsch merged commit c159290 into dotnet:main Aug 3, 2026
125 checks passed
@jakobbotsch
jakobbotsch deleted the fix-inline-indicator-enc branch August 3, 2026 23:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants