Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
b7bb968
Set target method desc for resumption stubs
jakobbotsch Oct 1, 2025
d5d0864
Add JIT-EE boilerplate
jakobbotsch Oct 1, 2025
d7277fb
Add debug information for runtime async information
jakobbotsch Oct 1, 2025
6addd0e
Update managed view
jakobbotsch Oct 1, 2025
6a5bf19
Remove TODOs
jakobbotsch Oct 1, 2025
262260a
Leaf transition
jakobbotsch Oct 1, 2025
4e2a829
Comment
jakobbotsch Oct 1, 2025
820afa9
Delete unused enum
jakobbotsch Oct 1, 2025
3621eae
Restore comment
jakobbotsch Oct 1, 2025
f597424
Fix osx build
jakobbotsch Oct 1, 2025
6bb6cee
Fix GCC build
jakobbotsch Oct 1, 2025
f580e3f
Change sentinel value, fix contract
jakobbotsch Oct 2, 2025
55b9522
Bump R2R
jakobbotsch Oct 2, 2025
c9c64be
Clean up
jakobbotsch Oct 2, 2025
db77446
Expose async debug info accessor APIs
jakobbotsch Oct 2, 2025
c808390
Missed bumping R2R version for naot
jakobbotsch Oct 2, 2025
3ec5160
Fix reverse mapping to IL local nums
jakobbotsch Oct 2, 2025
bb12c77
Fix monotonicity for async vars
jakobbotsch Oct 2, 2025
bf3364b
Code style
jakobbotsch Oct 2, 2025
b49f38f
Fix JIT-EE prompt tools from Egor's instructions, allow use of experi…
jakobbotsch Oct 2, 2025
d1bf49f
Address feedback, make comment less misleading
jakobbotsch Oct 3, 2025
579714e
Add AsyncContinuationVarInfo.GCIndex
jakobbotsch Oct 6, 2025
c056793
Publish NextContinuation in TLS
jakobbotsch Oct 8, 2025
9679f91
Rename ThunkTask -> RuntimeAsyncTask
jakobbotsch Oct 8, 2025
abd7d8b
testing
rcj1 Oct 8, 2025
7a34475
Merge branch 'main' of github.com:dotnet/runtime into jit-async-diagn…
jakobbotsch Oct 9, 2025
e839409
Report native offsets instead
jakobbotsch Oct 9, 2025
d8ad0c1
Run jit-format
jakobbotsch Oct 9, 2025
9fdd8a7
Print reported async debug info, always report it
jakobbotsch Oct 9, 2025
1da796e
exception tostring
rcj1 Oct 10, 2025
818b708
async2 test stuff
rcj1 Oct 10, 2025
eb2cf4e
merge
rcj1 Oct 13, 2025
69e02db
Store target IPs in AsyncResumeILStubResolver
jakobbotsch Oct 14, 2025
68c245b
Fix bug
jakobbotsch Oct 14, 2025
e6770f7
wip
rcj1 Oct 14, 2025
53ea16d
Merge branch 'jit-async-diagnostics' into dev/rachel/asyncv2-exceptio…
rcj1 Oct 14, 2025
99b76f4
wip
rcj1 Oct 14, 2025
dfe3020
wip
rcj1 Oct 14, 2025
12a21c8
wip
rcj1 Oct 14, 2025
2031f08
Remove BBF_INTERNAL from rethrow BB to avoid broken mappings
jakobbotsch Oct 15, 2025
25385be
Merge branch 'jit-async-diagnostics' into dev/rachel/asyncv2-exceptio…
rcj1 Oct 15, 2025
8cf7c08
unit tests
rcj1 Oct 16, 2025
79f5c7b
merge
rcj1 Nov 7, 2025
4c35cc3
wip
rcj1 Nov 7, 2025
6226c60
wip
rcj1 Nov 8, 2025
e493a60
merge and fix
rcj1 Nov 9, 2025
c439232
merge
rcj1 Dec 11, 2025
f787585
fix
rcj1 Dec 11, 2025
5f32166
fix
rcj1 Dec 12, 2025
a33a738
ee
rcj1 Dec 15, 2025
bb5ce5b
aot test
rcj1 Dec 17, 2025
3b086e7
Merge branch 'main', remote-tracking branch 'origin' into dev/rachel/…
rcj1 Dec 17, 2025
4699d90
Revert "fix"
rcj1 Dec 17, 2025
82a9d45
nativeaot exceptions
rcj1 Dec 18, 2025
b5c4a9f
merge
rcj1 Dec 18, 2025
df8d178
ilc emit async stacktrace data
rcj1 Dec 19, 2025
ed85064
reduce diff etc
rcj1 Dec 24, 2025
54cc8c9
Dedup asm
am11 Dec 24, 2025
7e28e0b
fb
rcj1 Dec 24, 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
1 change: 1 addition & 0 deletions docs/design/coreclr/botr/readytorun-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,7 @@ enum ReadyToRunHelper
READYTORUN_HELPER_FailFast = 0x24,
READYTORUN_HELPER_ThrowNullRef = 0x25,
READYTORUN_HELPER_ThrowDivZero = 0x26,
READYTORUN_HELPER_ThrowExact = 0x27,

// Write barriers
READYTORUN_HELPER_WriteBarrier = 0x30,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ internal enum ContinuationFlags
ContinueOnCapturedTaskScheduler = 64,
}

internal enum RhEHFrameType
{
RH_EH_RUNTIME_ASYNC_FRAME = 4,
}

// Keep in sync with CORINFO_AsyncResumeInfo in corinfo.h
internal unsafe struct ResumeInfo
{
Expand Down Expand Up @@ -226,6 +231,14 @@ public void CaptureContexts()

[ThreadStatic]
private static RuntimeAsyncAwaitState t_runtimeAsyncAwaitState;
#if !NATIVEAOT

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "AsyncHelpers_AddContinuationToExInternal")]
private static unsafe partial void AddContinuationToExInternal(void* diagnosticIP, ObjectHandleOnStack ex);

internal static unsafe void AddContinuationToExInternal(void* diagnosticIP, Exception e)
=> AddContinuationToExInternal(diagnosticIP, ObjectHandleOnStack.Create(ref e));
#endif

private static unsafe Continuation AllocContinuation(Continuation prevContinuation, MethodTable* contMT)
{
Expand Down Expand Up @@ -434,6 +447,7 @@ internal void HandleSuspended()
}
}

[StackTraceHidden]
private unsafe void DispatchContinuations()
{
ExecutionAndSyncBlockStore contexts = default;
Expand Down Expand Up @@ -467,7 +481,7 @@ private unsafe void DispatchContinuations()
}
catch (Exception ex)
{
Continuation? handlerContinuation = UnwindToPossibleHandler(asyncDispatcherInfo.NextContinuation);
Continuation? handlerContinuation = UnwindToPossibleHandler(asyncDispatcherInfo.NextContinuation, ex);
if (handlerContinuation == null)
{
// Tail of AsyncTaskMethodBuilderT.SetException
Expand Down Expand Up @@ -518,10 +532,34 @@ private unsafe void DispatchContinuations()

private ref byte GetResultStorage() => ref Unsafe.As<T?, byte>(ref m_result);

private static Continuation? UnwindToPossibleHandler(Continuation? continuation)
private static unsafe Continuation? UnwindToPossibleHandler(Continuation? continuation, Exception ex)
{
while (true)
{
if (continuation != null && continuation.ResumeInfo != null && continuation.ResumeInfo->DiagnosticIP != null)
#if !NATIVEAOT
AddContinuationToExInternal(continuation.ResumeInfo->DiagnosticIP, ex);
#else
{
IntPtr ip = (IntPtr)continuation.ResumeInfo->DiagnosticIP;
int flags = (int)RhEHFrameType.RH_EH_RUNTIME_ASYNC_FRAME;
IntPtr pAppendStackFrame = (IntPtr)InternalCalls.RhpGetClasslibFunctionFromCodeAddress(ip,
ClassLibFunctionId.AppendExceptionStackFrame);

if (pAppendStackFrame != IntPtr.Zero)
{
try
{
((delegate*<object, IntPtr, int, void>)pAppendStackFrame)(ex, ip, flags);
}
catch
{
// disallow all exceptions leaking out of callbacks
}
}
}

#endif
if (continuation == null || (continuation.Flags & ContinuationFlags.HasException) != 0)
return continuation;

Expand Down Expand Up @@ -767,12 +805,14 @@ private static void CaptureContinuationContext(ref object continuationContext, r
flags |= ContinuationFlags.ContinueOnThreadPool;
}

[StackTraceHidden]
internal static T CompletedTaskResult<T>(Task<T> task)
{
TaskAwaiter.ValidateEnd(task);
return task.ResultOnSuccess;
}

[StackTraceHidden]
internal static void CompletedTask(Task task)
{
TaskAwaiter.ValidateEnd(task);
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/inc/readytorun.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ enum ReadyToRunHelper
READYTORUN_HELPER_FailFast = 0x24,
READYTORUN_HELPER_ThrowNullRef = 0x25,
READYTORUN_HELPER_ThrowDivZero = 0x26,
READYTORUN_HELPER_ThrowExact = 0x27,

// Write barriers
READYTORUN_HELPER_WriteBarrier = 0x30,
Expand Down
4 changes: 3 additions & 1 deletion src/coreclr/nativeaot/Runtime/StackFrameIterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ EXTERN_C CODE_LOCATION RhpCallFilterFunclet2;
EXTERN_C CODE_LOCATION RhpThrowEx2;
EXTERN_C CODE_LOCATION RhpThrowHwEx2;
EXTERN_C CODE_LOCATION RhpRethrow2;
EXTERN_C CODE_LOCATION RhpThrowExact2;
#endif // !defined(FEATURE_PORTABLE_HELPERS)

// Addresses of functions in the DAC won't match their runtime counterparts so we
Expand Down Expand Up @@ -2241,7 +2242,8 @@ StackFrameIterator::ReturnAddressCategory StackFrameIterator::CategorizeUnadjust

if (EQUALS_RETURN_ADDRESS(returnAddress, RhpThrowEx2) ||
EQUALS_RETURN_ADDRESS(returnAddress, RhpThrowHwEx2) ||
EQUALS_RETURN_ADDRESS(returnAddress, RhpRethrow2))
EQUALS_RETURN_ADDRESS(returnAddress, RhpRethrow2) ||
EQUALS_RETURN_ADDRESS(returnAddress, RhpThrowExact2))
{
return InThrowSiteThunk;
}
Expand Down
25 changes: 24 additions & 1 deletion src/coreclr/nativeaot/Runtime/amd64/ExceptionHandling.S
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,24 @@ ALTERNATE_ENTRY RhpThrowHwEx2
NESTED_END RhpThrowHwEx, _TEXT


//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// RhpThrowExact
//
// SUMMARY: Similar to RhpThrowEx, except that it sets the rethrow flag
//
// INPUT: RDI: exception object
//
// OUTPUT:
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
NESTED_ENTRY RhpThrowExact, _TEXT, NoHandler

mov r8d, 4 // r8d = ExKind.RethrowFlag
jmp LOCAL_LABEL(RhpThrowExImpl)

NESTED_END RhpThrowExact, _TEXT

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// RhpThrowEx
Expand All @@ -89,6 +107,10 @@ NESTED_END RhpThrowHwEx, _TEXT
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
NESTED_ENTRY RhpThrowEx, _TEXT, NoHandler

mov r8d, 1 // r8d = ExKind.Throw

LOCAL_LABEL(RhpThrowExImpl):

STACKSIZEOF_ExInfo = ((SIZEOF__ExInfo + 15) & (~ 15))
rsp_offsetof_Context = STACKSIZEOF_ExInfo

Expand Down Expand Up @@ -136,7 +158,7 @@ NESTED_ENTRY RhpThrowEx, _TEXT, NoHandler
mov [rsi + OFFSETOF__ExInfo__m_exception], rdx // init the exception object to null
mov byte ptr [rsi + OFFSETOF__ExInfo__m_passNumber], 1 // init to the first pass
mov dword ptr [rsi + OFFSETOF__ExInfo__m_idxCurClause], 0xFFFFFFFF
mov byte ptr [rsi + OFFSETOF__ExInfo__m_kind], 1 // ExKind.Throw
mov byte ptr [rsi + OFFSETOF__ExInfo__m_kind], r8b // ExKind (from r8b)

// link the ExInfo into the thread's ExInfo chain
mov rdx, [rax + OFFSETOF__Thread__m_pExInfoStackHead]
Expand All @@ -152,6 +174,7 @@ NESTED_ENTRY RhpThrowEx, _TEXT, NoHandler
call EXTERNAL_C_FUNC(RhThrowEx)

ALTERNATE_ENTRY RhpThrowEx2
ALTERNATE_ENTRY RhpThrowExact2

// no return
int 3
Expand Down
27 changes: 25 additions & 2 deletions src/coreclr/nativeaot/Runtime/amd64/ExceptionHandling.asm
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,24 @@ ALTERNATE_ENTRY RhpThrowHwEx2

NESTED_END RhpThrowHwEx, _TEXT

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; RhpThrowExact
;;
;; SUMMARY: Similar to RhpThrowEx, except that it sets the rethrow flag
;;
;; INPUT: RCX: exception object
;;
;; OUTPUT:
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
NESTED_ENTRY RhpThrowExact, _TEXT

mov r9d, 4 ;; r9d = ExKind.RethrowFlag
jmp RhpThrowExImpl

NESTED_END RhpThrowExact, _TEXT

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; RhpThrowEx
Expand All @@ -116,6 +134,10 @@ NESTED_END RhpThrowHwEx, _TEXT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
NESTED_ENTRY RhpThrowEx, _TEXT

mov r9d, 1 ;; r9d = ExKind.Throw

ALTERNATE_ENTRY RhpThrowExImpl

SIZEOF_XmmSaves equ SIZEOF__PAL_LIMITED_CONTEXT - OFFSETOF__PAL_LIMITED_CONTEXT__Xmm6
STACKSIZEOF_ExInfo equ ((SIZEOF__ExInfo + 15) AND (NOT 15))

Expand Down Expand Up @@ -172,7 +194,7 @@ NESTED_ENTRY RhpThrowEx, _TEXT
;; address could have been hijacked when we were in that C# code and we must remove the hijack and
;; reflect the correct return address in our exception context record. The other throw helpers don't
;; need this because they cannot be tail-called from C#.
INLINE_THREAD_UNHIJACK rax, r9, rdx ;; trashes R9, RDX
INLINE_THREAD_UNHIJACK rax, r10, rdx ;; trashes R10, RDX (use r10 instead of r9 to preserve ExKind)
mov rdx, [rbx] ;; rdx <- return address
mov [rsp + rsp_offsetof_Context + OFFSETOF__PAL_LIMITED_CONTEXT__IP], rdx ;; set 'faulting' IP after unhijack

Expand All @@ -181,7 +203,7 @@ NESTED_ENTRY RhpThrowEx, _TEXT
mov [rdx + OFFSETOF__ExInfo__m_exception], r8 ;; init the exception object to null
mov byte ptr [rdx + OFFSETOF__ExInfo__m_passNumber], 1 ;; init to the first pass
mov dword ptr [rdx + OFFSETOF__ExInfo__m_idxCurClause], 0FFFFFFFFh
mov byte ptr [rdx + OFFSETOF__ExInfo__m_kind], 1 ;; ExKind.Throw
mov byte ptr [rdx + OFFSETOF__ExInfo__m_kind], r9b ;; ExKind (from r9b)

;; link the ExInfo into the thread's ExInfo chain
mov r8, [rax + OFFSETOF__Thread__m_pExInfoStackHead]
Expand All @@ -197,6 +219,7 @@ NESTED_ENTRY RhpThrowEx, _TEXT
call RhThrowEx

ALTERNATE_ENTRY RhpThrowEx2
ALTERNATE_ENTRY RhpThrowExact2

;; no return
int 3
Expand Down
27 changes: 25 additions & 2 deletions src/coreclr/nativeaot/Runtime/arm/ExceptionHandling.S
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,24 @@ GLOBAL_LABEL RhpThrowHwEx2
NESTED_END RhpThrowHwEx


//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// RhpThrowExact
//
// SUMMARY: Similar to RhpThrowEx, except that it sets the rethrow flag
//
// INPUT: R0: exception object
//
// OUTPUT:
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
NESTED_ENTRY RhpThrowExact, _TEXT, NoHandler

mov r5, #4 // r5 = ExKind.RethrowFlag
b LOCAL_LABEL(RhpThrowExImpl)

NESTED_END RhpThrowExact, _TEXT

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// RhpThrowEx
Expand All @@ -90,6 +108,10 @@ NESTED_END RhpThrowHwEx
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
NESTED_ENTRY RhpThrowEx, _TEXT, NoHandler

mov r5, #1 // r5 = ExKind.Throw

LOCAL_LABEL(RhpThrowExImpl):

// Setup a PAL_LIMITED_CONTEXT on the stack {
PROLOG_VPUSH {d8-d15}
PROLOG_PUSH "{r0,lr}" // Reserve space for SP and store LR
Expand Down Expand Up @@ -158,9 +180,9 @@ LOCAL_LABEL(NotHiJacked):
str r3, [r1, #OFFSETOF__ExInfo__m_exception] // init the exception object to null
mov r3, #1
strb r3, [r1, #OFFSETOF__ExInfo__m_passNumber] // init to the first pass
strb r3, [r1, #OFFSETOF__ExInfo__m_kind]
strb r5, [r1, #OFFSETOF__ExInfo__m_kind] // ExKind (from r5)
mov r3, #0xFFFFFFFF
str r3, [r1, #OFFSETOF__ExInfo__m_idxCurClause] // ExKind.Throw
str r3, [r1, #OFFSETOF__ExInfo__m_idxCurClause]

// link the ExInfo into the thread's ExInfo chain
ldr r3, [r0, #OFFSETOF__Thread__m_pExInfoStackHead]
Expand All @@ -177,6 +199,7 @@ LOCAL_LABEL(NotHiJacked):
bl C_FUNC(RhThrowEx)

GLOBAL_LABEL RhpThrowEx2
GLOBAL_LABEL RhpThrowExact2

// no return
EMIT_BREAKPOINT
Expand Down
26 changes: 23 additions & 3 deletions src/coreclr/nativeaot/Runtime/arm64/ExceptionHandling.S
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,23 @@

NESTED_END RhpThrowHwEx, _TEXT

//
// RhpThrowExact
//
// SUMMARY: Similar to RhpThrowEx, except that it sets the rethrow flag
//
// INPUT: X0: exception object
//
// OUTPUT:
//

NESTED_ENTRY RhpThrowExact, _TEXT, NoHandler

mov w4, #4 // w4 = ExKind.RethrowFlag
b LOCAL_LABEL(RhpThrowExImpl)

NESTED_END RhpThrowExact, _TEXT

//
// RhpThrowEx
//
Expand All @@ -262,6 +279,10 @@

NESTED_ENTRY RhpThrowEx, _TEXT, NoHandler

mov w4, #1 // w4 = ExKind.Throw

LOCAL_LABEL(RhpThrowExImpl):

ALLOC_THROW_FRAME SOFTWARE_EXCEPTION

GetThreadX2
Expand Down Expand Up @@ -316,8 +337,7 @@ LOCAL_LABEL(NotHijacked):
strb w3, [x1, #OFFSETOF__ExInfo__m_passNumber] // pExInfo->m_passNumber = 1
mov w3, #0xFFFFFFFF
str w3, [x1, #OFFSETOF__ExInfo__m_idxCurClause] // pExInfo->m_idxCurClause = MaxTryRegionIdx
mov w3, #1
strb w3, [x1, #OFFSETOF__ExInfo__m_kind] // pExInfo->m_kind = ExKind.Throw
strb w4, [x1, #OFFSETOF__ExInfo__m_kind] // pExInfo->m_kind = ExKind (from w4)

// link the ExInfo into the thread's ExInfo chain
ldr x3, [x2, #OFFSETOF__Thread__m_pExInfoStackHead]
Expand All @@ -333,12 +353,12 @@ LOCAL_LABEL(NotHijacked):
bl C_FUNC(RhThrowEx)

ALTERNATE_ENTRY RhpThrowEx2
ALTERNATE_ENTRY RhpThrowExact2

// no return
EMIT_BREAKPOINT
NESTED_END RhpThrowEx, _TEXT


//
// void FASTCALL RhpRethrow()
//
Expand Down
Loading
Loading