You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
JIT: Move Thread sync and exec context save/restore to happen around runtime async bodies (#121448)
This fixes an issue where there was a behavioral difference between
async1 and async2 for async to sync runtime async calls. Before this PR
the JIT would always save and restore contexts around awaits of
task-returning methods, regardless of whether they were implemented as
runtime async functions or not. That does not match async1: in async1,
the context save and restore happens around the body in each async
method. The former logic was an optimization, but the optimization is
only correct for runtime async to runtime async calls.
We cannot in general know if a callee is implemented by runtime async or
not, so we have to move the context save/restore to happen around the
body of all runtime async methods.
An example test program that saw the behavioral difference before is the
following:
```csharp
using System;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
static void Main()
{
Foo().GetAwaiter().GetResult();
}
static async Task Foo()
{
SynchronizationContext.SetSynchronizationContext(new MySyncCtx(123));
Console.WriteLine(((MySyncCtx)SynchronizationContext.Current).Arg);
await Bar();
Console.WriteLine(((MySyncCtx)SynchronizationContext.Current).Arg);
}
static Task Bar()
{
SynchronizationContext.SetSynchronizationContext(new MySyncCtx(124));
return Task.CompletedTask;
}
class MySyncCtx(int arg) : SynchronizationContext
{
public int Arg => arg;
}
}
```
Async1: 123 124
Runtime async before: 123 123
Runtime async after: 123 124
Copy file name to clipboardExpand all lines: src/coreclr/inc/corinfo.h
+1Lines changed: 1 addition & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -722,6 +722,7 @@ enum CorInfoOptions
722
722
CORINFO_GENERICS_CTXT_FROM_METHODDESC |
723
723
CORINFO_GENERICS_CTXT_FROM_METHODTABLE),
724
724
CORINFO_GENERICS_CTXT_KEEP_ALIVE = 0x00000100, // Keep the generics context alive throughout the method even if there is no explicit use, and report its location to the CLR
725
+
CORINFO_ASYNC_SAVE_CONTEXTS = 0x00000200, // Runtime async method must save and restore contexts
0 commit comments