@@ -146,6 +146,28 @@ public ref byte GetResultStorageOrNull()
146146 }
147147 }
148148
149+ [ StructLayout ( LayoutKind . Explicit ) ]
150+ internal unsafe ref struct AsyncDispatcherInfo
151+ {
152+ // Dispatcher info for next dispatcher present on stack, or
153+ // null if none.
154+ [ FieldOffset ( 0 ) ]
155+ public AsyncDispatcherInfo * Next ;
156+
157+ // Next continuation the dispatcher will process.
158+ #if TARGET_64BIT
159+ [ FieldOffset ( 8 ) ]
160+ #else
161+ [ FieldOffset ( 4 ) ]
162+ #endif
163+ public Continuation ? NextContinuation ;
164+
165+ // Information about current task dispatching, to be used for async
166+ // stackwalking.
167+ [ ThreadStatic ]
168+ internal static unsafe AsyncDispatcherInfo * t_current ; // Debugger depends on the exact name of this field.
169+ }
170+
149171 public static partial class AsyncHelpers
150172 {
151173#if FEATURE_INTERPRETER
@@ -417,19 +439,19 @@ private unsafe void DispatchContinuations()
417439 ExecutionAndSyncBlockStore contexts = default ;
418440 contexts . Push ( ) ;
419441
420- RuntimeAsyncTaskCore . DispatcherInfo dispatcherInfo ;
421- dispatcherInfo . Next = RuntimeAsyncTaskCore . t_dispatcherInfo ;
422- dispatcherInfo . NextContinuation = MoveContinuationState ( ) ;
423- RuntimeAsyncTaskCore . t_dispatcherInfo = & dispatcherInfo ;
442+ AsyncDispatcherInfo asyncDispatcherInfo ;
443+ asyncDispatcherInfo . Next = AsyncDispatcherInfo . t_current ;
444+ asyncDispatcherInfo . NextContinuation = MoveContinuationState ( ) ;
445+ AsyncDispatcherInfo . t_current = & asyncDispatcherInfo ;
424446
425447 while ( true )
426448 {
427- Debug . Assert ( dispatcherInfo . NextContinuation != null ) ;
449+ Debug . Assert ( asyncDispatcherInfo . NextContinuation != null ) ;
428450 try
429451 {
430- Continuation curContinuation = dispatcherInfo . NextContinuation ;
452+ Continuation curContinuation = asyncDispatcherInfo . NextContinuation ;
431453 Continuation ? nextContinuation = curContinuation . Next ;
432- dispatcherInfo . NextContinuation = nextContinuation ;
454+ asyncDispatcherInfo . NextContinuation = nextContinuation ;
433455
434456 ref byte resultLoc = ref nextContinuation != null ? ref nextContinuation . GetResultStorageOrNull ( ) : ref GetResultStorage ( ) ;
435457 Continuation ? newContinuation = curContinuation . ResumeInfo ->Resume ( curContinuation , ref resultLoc ) ;
@@ -439,13 +461,13 @@ private unsafe void DispatchContinuations()
439461 newContinuation . Next = nextContinuation ;
440462 HandleSuspended ( ) ;
441463 contexts . Pop ( ) ;
442- RuntimeAsyncTaskCore . t_dispatcherInfo = dispatcherInfo . Next ;
464+ AsyncDispatcherInfo . t_current = asyncDispatcherInfo . Next ;
443465 return ;
444466 }
445467 }
446468 catch ( Exception ex )
447469 {
448- Continuation ? handlerContinuation = UnwindToPossibleHandler ( dispatcherInfo . NextContinuation ) ;
470+ Continuation ? handlerContinuation = UnwindToPossibleHandler ( asyncDispatcherInfo . NextContinuation ) ;
449471 if ( handlerContinuation == null )
450472 {
451473 // Tail of AsyncTaskMethodBuilderT.SetException
@@ -455,7 +477,7 @@ private unsafe void DispatchContinuations()
455477
456478 contexts . Pop ( ) ;
457479
458- RuntimeAsyncTaskCore . t_dispatcherInfo = dispatcherInfo . Next ;
480+ AsyncDispatcherInfo . t_current = asyncDispatcherInfo . Next ;
459481
460482 if ( ! successfullySet )
461483 {
@@ -466,16 +488,16 @@ private unsafe void DispatchContinuations()
466488 }
467489
468490 handlerContinuation . SetException ( ex ) ;
469- dispatcherInfo . NextContinuation = handlerContinuation ;
491+ asyncDispatcherInfo . NextContinuation = handlerContinuation ;
470492 }
471493
472- if ( dispatcherInfo . NextContinuation == null )
494+ if ( asyncDispatcherInfo . NextContinuation == null )
473495 {
474496 bool successfullySet = TrySetResult ( m_result ) ;
475497
476498 contexts . Pop ( ) ;
477499
478- RuntimeAsyncTaskCore . t_dispatcherInfo = dispatcherInfo . Next ;
500+ AsyncDispatcherInfo . t_current = asyncDispatcherInfo . Next ;
479501
480502 if ( ! successfullySet )
481503 {
@@ -485,10 +507,10 @@ private unsafe void DispatchContinuations()
485507 return ;
486508 }
487509
488- if ( QueueContinuationFollowUpActionIfNecessary ( dispatcherInfo . NextContinuation ) )
510+ if ( QueueContinuationFollowUpActionIfNecessary ( asyncDispatcherInfo . NextContinuation ) )
489511 {
490512 contexts . Pop ( ) ;
491- RuntimeAsyncTaskCore . t_dispatcherInfo = dispatcherInfo . Next ;
513+ AsyncDispatcherInfo . t_current = asyncDispatcherInfo . Next ;
492514 return ;
493515 }
494516 }
@@ -583,31 +605,6 @@ private bool QueueContinuationFollowUpActionIfNecessary(Continuation continuatio
583605 } ;
584606 }
585607
586- internal static class RuntimeAsyncTaskCore
587- {
588- [ StructLayout ( LayoutKind . Explicit ) ]
589- internal unsafe ref struct DispatcherInfo
590- {
591- // Dispatcher info for next dispatcher present on stack, or
592- // null if none.
593- [ FieldOffset ( 0 ) ]
594- public DispatcherInfo * Next ;
595-
596- // Next continuation the dispatcher will process.
597- #if TARGET_64BIT
598- [ FieldOffset ( 8 ) ]
599- #else
600- [ FieldOffset ( 4 ) ]
601- #endif
602- public Continuation ? NextContinuation ;
603- }
604-
605- // Information about current task dispatching, to be used for async
606- // stackwalking.
607- [ ThreadStatic ]
608- internal static unsafe DispatcherInfo * t_dispatcherInfo ;
609- }
610-
611608 // Change return type to RuntimeAsyncTask<T?> -- no benefit since this is used for Task returning thunks only
612609#pragma warning disable CA1859
613610 // When a Task-returning thunk gets a continuation result
0 commit comments