Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
e7f430a
WIP
jakobbotsch Jul 15, 2025
3b85c95
JIT: Preparatory refactoring to support multiple defs per single node
jakobbotsch Jul 15, 2025
fba620a
Mitigate some TP diffs
jakobbotsch Jul 16, 2025
3939f24
Nit
jakobbotsch Jul 16, 2025
2e151fe
Merge branch 'multiple-defs-per-node' into restore-sync-context-field
jakobbotsch Jul 16, 2025
5fec55f
WIP
jakobbotsch Jul 16, 2025
b9483e7
Attempt at jump threading optimization
jakobbotsch Jul 16, 2025
8301152
Drop jump threading opt for now
jakobbotsch Jul 16, 2025
4a88fe8
Run jit-format
jakobbotsch Jul 16, 2025
c2b3e88
Clean up
jakobbotsch Jul 17, 2025
f9e62e1
Fix SPMI
jakobbotsch Jul 17, 2025
41158a3
Merge branch 'main' of github.com:dotnet/runtime into restore-sync-co…
jakobbotsch Jul 17, 2025
576d138
Fix build
jakobbotsch Jul 17, 2025
39549be
JIT: Fix unique successors in `BBswtDesc` in runtime async
jakobbotsch Jul 17, 2025
a38902b
Clean up
jakobbotsch Jul 17, 2025
f91aa6a
Expand test
jakobbotsch Jul 17, 2025
c786545
Nit
jakobbotsch Jul 17, 2025
aa31bfb
Fix release build
jakobbotsch Jul 17, 2025
9e3a686
Fix dangling pointer bug
jakobbotsch Jul 17, 2025
c78ca39
Update JIT-EE GUID
jakobbotsch Jul 17, 2025
24cd099
Redisable runtime async
jakobbotsch Jul 17, 2025
f40c255
Require AsyncSuspendedIndicator to be present when HasSuspensionIndic…
jakobbotsch Jul 21, 2025
2c073ab
Update async comments
jakobbotsch Jul 21, 2025
0741517
Assert NumPosts
jakobbotsch Jul 21, 2025
8066afb
Add another test that we capture the sync context from before the call
jakobbotsch Jul 21, 2025
ddd7584
Use sync context from before call as continuation context
jakobbotsch Jul 21, 2025
ce2f834
Reset continuation context handling for tailcalls:
jakobbotsch Jul 21, 2025
0405154
Add some more comments
jakobbotsch Jul 23, 2025
b1329a7
Run jit-format
jakobbotsch Jul 23, 2025
6510e37
Make SyncContext parameter the first one
jakobbotsch Jul 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -625,9 +625,8 @@ private static void RestoreContexts(bool suspended, ExecutionContext? previousEx
}
}

private static void CaptureContinuationContext(ref object context, ref CorInfoContinuationFlags flags)
private static void CaptureContinuationContext(ref object context, SynchronizationContext syncCtx, ref CorInfoContinuationFlags flags)
{
SynchronizationContext? syncCtx = Thread.CurrentThreadAssumedInitialized._synchronizationContext;
if (syncCtx != null && syncCtx.GetType() != typeof(SynchronizationContext))
{
flags |= CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_SYNCHRONIZATION_CONTEXT;
Expand Down
23 changes: 20 additions & 3 deletions src/coreclr/jit/async.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1330,7 +1330,7 @@ BasicBlock* AsyncTransformation::CreateSuspension(

if (layout.GCRefsCount > 0)
{
FillInGCPointersOnSuspension(layout, suspendBB);
FillInGCPointersOnSuspension(call, layout, suspendBB);
}

if (layout.DataSize > 0)
Expand Down Expand Up @@ -1410,10 +1410,13 @@ GenTreeCall* AsyncTransformation::CreateAllocContinuationCall(AsyncLiveness& lif
// parts that need to be stored.
//
// Parameters:
// call - The async call that is being transformed
// layout - Layout information
// suspendBB - Basic block to add IR to.
//
void AsyncTransformation::FillInGCPointersOnSuspension(const ContinuationLayout& layout, BasicBlock* suspendBB)
void AsyncTransformation::FillInGCPointersOnSuspension(GenTreeCall* call,
const ContinuationLayout& layout,
BasicBlock* suspendBB)
{
unsigned objectArrLclNum = GetGCDataArrayVar();

Expand Down Expand Up @@ -1502,14 +1505,20 @@ void AsyncTransformation::FillInGCPointersOnSuspension(const ContinuationLayout&

if (layout.ContinuationContextGCDataIndex != UINT_MAX)
{
const AsyncCallInfo& callInfo = call->GetAsyncInfo();
assert(callInfo.SaveAndRestoreSynchronizationContextField &&
(callInfo.SynchronizationContextLclNum != BAD_VAR_NUM));

// Insert call AsyncHelpers.CaptureContinuationContext(ref
// newContinuation.GCData[ContinuationContextGCDataIndex], ref newContinuation.Flags).
GenTree* contextElementPlaceholder = m_comp->gtNewZeroConNode(TYP_BYREF);
GenTree* syncContextPlaceholder = m_comp->gtNewNull();
GenTree* flagsPlaceholder = m_comp->gtNewZeroConNode(TYP_BYREF);
GenTreeCall* captureCall =
m_comp->gtNewCallNode(CT_USER_FUNC, m_asyncInfo->captureContinuationContextMethHnd, TYP_VOID);

captureCall->gtArgs.PushFront(m_comp, NewCallArg::Primitive(flagsPlaceholder));
captureCall->gtArgs.PushFront(m_comp, NewCallArg::Primitive(syncContextPlaceholder));
captureCall->gtArgs.PushFront(m_comp, NewCallArg::Primitive(contextElementPlaceholder));

m_comp->compCurBB = suspendBB;
Expand All @@ -1531,7 +1540,15 @@ void AsyncTransformation::FillInGCPointersOnSuspension(const ContinuationLayout&
use.ReplaceWith(contextElementOffset);
LIR::AsRange(suspendBB).Remove(contextElementPlaceholder);

// And now replace flagsPlaceholder with actual address of the flags
// Then do the sync context
gotUse = LIR::AsRange(suspendBB).TryGetUse(syncContextPlaceholder, &use);
assert(gotUse);
GenTree* syncContextLcl = m_comp->gtNewLclvNode(callInfo.SynchronizationContextLclNum, TYP_REF);
LIR::AsRange(suspendBB).InsertBefore(syncContextPlaceholder, syncContextLcl);
use.ReplaceWith(syncContextLcl);
LIR::AsRange(suspendBB).Remove(syncContextPlaceholder);

// And finally replace flagsPlaceholder with actual address of the flags
gotUse = LIR::AsRange(suspendBB).TryGetUse(flagsPlaceholder, &use);
assert(gotUse);

Expand Down
58 changes: 29 additions & 29 deletions src/coreclr/jit/async.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,37 +94,37 @@ class AsyncTransformation
GenTree* prevContinuation,
unsigned gcRefsCount,
unsigned int dataSize);
void FillInGCPointersOnSuspension(const ContinuationLayout& layout, BasicBlock* suspendBB);
void FillInDataOnSuspension(const jitstd::vector<LiveLocalInfo>& liveLocals, BasicBlock* suspendBB);
void CreateCheckAndSuspendAfterCall(BasicBlock* block,
GenTreeCall* call,
const CallDefinitionInfo& callDefInfo,
AsyncLiveness& life,
BasicBlock* suspendBB,
BasicBlock** remainder);
BasicBlock* CreateResumption(BasicBlock* block,
BasicBlock* remainder,
GenTreeCall* call,
const CallDefinitionInfo& callDefInfo,
unsigned stateNum,
const ContinuationLayout& layout);
void SetSuspendedIndicator(BasicBlock* block, BasicBlock* callBlock, GenTreeCall* call);
void RestoreFromDataOnResumption(unsigned resumeByteArrLclNum,
const jitstd::vector<LiveLocalInfo>& liveLocals,
BasicBlock* resumeBB);
void RestoreFromGCPointersOnResumption(unsigned resumeObjectArrLclNum,
const ContinuationLayout& layout,
BasicBlock* resumeBB);
BasicBlock* RethrowExceptionOnResumption(BasicBlock* block,
unsigned resumeObjectArrLclNum,
const ContinuationLayout& layout,
BasicBlock* resumeBB);
void CopyReturnValueOnResumption(GenTreeCall* call,
const CallDefinitionInfo& callDefInfo,
unsigned resumeByteArrLclNum,
void FillInGCPointersOnSuspension(GenTreeCall* call, const ContinuationLayout& layout, BasicBlock* suspendBB);
void FillInDataOnSuspension(const jitstd::vector<LiveLocalInfo>& liveLocals, BasicBlock* suspendBB);
void CreateCheckAndSuspendAfterCall(BasicBlock* block,
GenTreeCall* call,
const CallDefinitionInfo& callDefInfo,
AsyncLiveness& life,
BasicBlock* suspendBB,
BasicBlock** remainder);
BasicBlock* CreateResumption(BasicBlock* block,
BasicBlock* remainder,
GenTreeCall* call,
const CallDefinitionInfo& callDefInfo,
unsigned stateNum,
const ContinuationLayout& layout);
void SetSuspendedIndicator(BasicBlock* block, BasicBlock* callBlock, GenTreeCall* call);
void RestoreFromDataOnResumption(unsigned resumeByteArrLclNum,
const jitstd::vector<LiveLocalInfo>& liveLocals,
BasicBlock* resumeBB);
void RestoreFromGCPointersOnResumption(unsigned resumeObjectArrLclNum,
const ContinuationLayout& layout,
BasicBlock* resumeBB);
BasicBlock* RethrowExceptionOnResumption(BasicBlock* block,
unsigned resumeObjectArrLclNum,
const ContinuationLayout& layout,
BasicBlock* storeResultBB);
BasicBlock* resumeBB);
void CopyReturnValueOnResumption(GenTreeCall* call,
const CallDefinitionInfo& callDefInfo,
unsigned resumeByteArrLclNum,
unsigned resumeObjectArrLclNum,
const ContinuationLayout& layout,
BasicBlock* storeResultBB);

GenTreeIndir* LoadFromOffset(GenTree* base,
unsigned offset,
Expand Down