From 64f84f6d80d3f03ec909cb178ab8de3e384dd74d Mon Sep 17 00:00:00 2001 From: Andy Gocke Date: Fri, 28 Mar 2025 11:41:08 -0700 Subject: [PATCH] WIP --- .gitignore | 3 -- NuGet.config | 2 +- buildroslynnugets.cmd | 34 ------------------- eng/Versions.props | 7 ++-- .../CompilerServices/RuntimeFeature.cs | 19 ++++++++++- .../System.Runtime/ref/System.Runtime.cs | 2 ++ src/tests/Directory.Build.props | 5 +++ src/tests/async/Directory.Build.props | 9 +++++ .../RuntimeAsyncMethodGenerationAttribute.cs | 6 ++++ src/tests/async/awaitingnotasync.cs | 7 ++-- src/tests/async/collectible-alc.cs | 6 ++-- src/tests/async/collectible-alc.csproj | 1 + src/tests/async/cse-array-index-byref.cs | 3 +- src/tests/async/eh-microbench.cs | 10 ++++-- src/tests/async/fibonacci-with-yields.cs | 5 +-- src/tests/async/fibonacci-with-yields.csproj | 1 + .../fibonacci-with-yields_struct_return.cs | 4 +-- ...fibonacci-with-yields_struct_return.csproj | 1 + src/tests/async/fibonacci-without-yields.cs | 4 +-- .../async/fibonacci-without-yields.csproj | 1 + src/tests/async/gc-roots-scan.cs | 3 +- src/tests/async/implement.cs | 9 ++--- src/tests/async/mincallcost-microbench.cs | 29 ++++++++++------ src/tests/async/object.cs | 3 +- src/tests/async/objects-captured.cs | 3 +- src/tests/async/override.cs | 9 +++-- src/tests/async/pgo.cs | 12 +++---- src/tests/async/pinvoke.cs | 2 +- src/tests/async/returns.cs | 10 +++--- src/tests/async/shared-generic.cs | 17 ++++++---- src/tests/async/simple-eh.cs | 5 +-- src/tests/async/struct.cs | 11 ++---- .../taskbased-asyncfibonacci-with-yields.cs | 2 ++ ...taskbased-asyncfibonacci-without-yields.cs | 2 ++ src/tests/async/valuetask.cs | 2 +- ...luetaskbased-asyncfibonacci-with-yields.cs | 2 ++ ...taskbased-asyncfibonacci-without-yields.cs | 2 ++ src/tests/async/varying-yields.cs | 28 ++++++++------- src/tests/async/void.cs | 3 +- src/tests/async/with-yields.cs | 5 +-- src/tests/async/without-yields.cs | 5 +-- 41 files changed, 169 insertions(+), 125 deletions(-) delete mode 100644 buildroslynnugets.cmd create mode 100644 src/tests/async/Directory.Build.props create mode 100644 src/tests/async/RuntimeAsyncMethodGenerationAttribute.cs diff --git a/.gitignore b/.gitignore index 0c35f3bd6918..88e4f6ab632a 100644 --- a/.gitignore +++ b/.gitignore @@ -11,9 +11,6 @@ syntax: glob .packages .tools -# nuget packages for custom roslyn -roslynpackages - # User-specific files *.suo *.user diff --git a/NuGet.config b/NuGet.config index f05e91436c2e..335f51a80849 100644 --- a/NuGet.config +++ b/NuGet.config @@ -19,7 +19,7 @@ - + diff --git a/buildroslynnugets.cmd b/buildroslynnugets.cmd deleted file mode 100644 index 983551b3c297..000000000000 --- a/buildroslynnugets.cmd +++ /dev/null @@ -1,34 +0,0 @@ -setlocal ENABLEEXTENSIONS -pushd %~dp0 -set ASYNC_ROSLYN_COMMIT=22232ae7939c97984d1158f4f371b0d89ea3db08 -set ASYNC_SUFFIX=async-13 -set ASYNC_ROSLYN_BRANCH=demos/async2-experiment1 - -cd .. -if not exist async-roslyn-repo git clone -b %ASYNC_ROSLYN_BRANCH% -o async_roslyn_remote https://github.com/dotnet/roslyn.git async-roslyn-repo - -pushd async-roslyn-repo - -git fetch async_roslyn_remote %ASYNC_ROSLYN_BRANCH% -rem when updating this, make sure to update the ASYNC_SUFFIX above and the versions.props file -git checkout %ASYNC_ROSLYN_COMMIT% - -call restore.cmd -call build.cmd -c release - -call dotnet pack src\NuGet\Microsoft.Net.Compilers.Toolset\AnyCpu\Microsoft.Net.Compilers.Toolset.Package.csproj --version-suffix %ASYNC_SUFFIX% -call dotnet pack src\Workspaces\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.Workspaces.csproj --version-suffix %ASYNC_SUFFIX% -call dotnet pack src\Compilers\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.csproj --version-suffix %ASYNC_SUFFIX% -call dotnet pack src\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj --version-suffix %ASYNC_SUFFIX% -call dotnet pack src\Workspaces\Core\Portable\Microsoft.CodeAnalysis.Workspaces.csproj --version-suffix %ASYNC_SUFFIX% - -pushd %~dp0 - -md roslynpackages - -copy ..\async-roslyn-repo\artifacts\packages\Release\Shipping\Microsoft.Net.Compilers.Toolset.4.14.0-%ASYNC_SUFFIX%.nupkg roslynpackages -copy ..\async-roslyn-repo\artifacts\packages\Release\Shipping\Microsoft.CodeAnalysis.Workspaces.Common.4.14.0-%ASYNC_SUFFIX%.nupkg roslynpackages -copy ..\async-roslyn-repo\artifacts\packages\Release\Shipping\Microsoft.CodeAnalysis.CSharp.Workspaces.4.14.0-%ASYNC_SUFFIX%.nupkg roslynpackages -copy ..\async-roslyn-repo\artifacts\packages\Release\Shipping\Microsoft.CodeAnalysis.CSharp.4.14.0-%ASYNC_SUFFIX%.nupkg roslynpackages -copy ..\async-roslyn-repo\artifacts\packages\Release\Shipping\Microsoft.CodeAnalysis.Common.4.14.0-%ASYNC_SUFFIX%.nupkg roslynpackages - diff --git a/eng/Versions.props b/eng/Versions.props index 4f21ee086e5c..7688e6ef3bda 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -44,9 +44,10 @@ Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure they do not break the local dev experience. --> - 4.14.0-async-13 - 4.14.0-async-13 - 4.14.0-async-13 + + 4.13.0-3.24611.10 + $(MicrosoftCodeAnalysisCSharpVersion) + $(MicrosoftCodeAnalysisCSharpVersion) + 4.14.0-3.25170.6 + + true diff --git a/src/tests/async/Directory.Build.props b/src/tests/async/Directory.Build.props new file mode 100644 index 000000000000..06c34511cb11 --- /dev/null +++ b/src/tests/async/Directory.Build.props @@ -0,0 +1,9 @@ + + + + $(Features);runtime-async=on + + + + + \ No newline at end of file diff --git a/src/tests/async/RuntimeAsyncMethodGenerationAttribute.cs b/src/tests/async/RuntimeAsyncMethodGenerationAttribute.cs new file mode 100644 index 000000000000..2ae84c6fcccd --- /dev/null +++ b/src/tests/async/RuntimeAsyncMethodGenerationAttribute.cs @@ -0,0 +1,6 @@ +namespace System.Runtime.CompilerServices; +[AttributeUsage(AttributeTargets.Method)] +public class RuntimeAsyncMethodGenerationAttribute(bool runtimeAsync) : Attribute +{ + public bool RuntimeAsync { get; } = runtimeAsync; +} \ No newline at end of file diff --git a/src/tests/async/awaitingnotasync.cs b/src/tests/async/awaitingnotasync.cs index 9f4b1732313c..bf8ad8c9cc12 100644 --- a/src/tests/async/awaitingnotasync.cs +++ b/src/tests/async/awaitingnotasync.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Threading.Tasks; using Xunit; @@ -14,6 +13,7 @@ public static void TestEntryPoint() AsyncEntryPoint().Wait(); } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] private static async Task GetTask(T arg) { await Task.Yield(); @@ -21,6 +21,7 @@ private static async Task GetTask(T arg) } // TODO: switch every other scenario to use ValueTask + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] private static async ValueTask GetValueTask(T arg) { await Task.Yield(); @@ -33,13 +34,13 @@ private static async ValueTask GetValueTask(T arg) private static T sIdentity(T arg) => arg; - private static async2 Task AsyncEntryPoint() + private static async Task AsyncEntryPoint() { // static field sField = GetTask(5); Assert.Equal(5, await sField); - // property + // property Assert.Equal(6, await sProp); // generic identity diff --git a/src/tests/async/collectible-alc.cs b/src/tests/async/collectible-alc.cs index eb7e43309db2..0feb988d4ac4 100644 --- a/src/tests/async/collectible-alc.cs +++ b/src/tests/async/collectible-alc.cs @@ -17,7 +17,7 @@ public static void TestEntryPoint() AsyncEntryPoint().Wait(); } - private static async2 Task AsyncEntryPoint() + private static async Task AsyncEntryPoint() { WeakReference wr = await CallFooAsyncAndUnload(); @@ -31,7 +31,7 @@ private static async2 Task AsyncEntryPoint() } [MethodImpl(MethodImplOptions.NoInlining)] - private static async2 Task CallFooAsyncAndUnload() + private static async Task CallFooAsyncAndUnload() { TaskCompletionSource tcs = new(); (Task task, WeakReference wr) = CallFooAsyncInCollectibleALC(tcs.Task); @@ -63,7 +63,7 @@ private static (Task, WeakReference) CallFooAsyncInCollectibleALC(Task t } // Task[] to work around a compiler bug - private static async2 Task FooAsync(Task[] t) + private static async Task FooAsync(Task[] t) { await t[0]; return "done"; diff --git a/src/tests/async/collectible-alc.csproj b/src/tests/async/collectible-alc.csproj index 3b3ebe1336c1..97ccb4252e97 100644 --- a/src/tests/async/collectible-alc.csproj +++ b/src/tests/async/collectible-alc.csproj @@ -3,6 +3,7 @@ True True + $(Features);runtime-async diff --git a/src/tests/async/cse-array-index-byref.cs b/src/tests/async/cse-array-index-byref.cs index be99722a054b..d208c4e7a12c 100644 --- a/src/tests/async/cse-array-index-byref.cs +++ b/src/tests/async/cse-array-index-byref.cs @@ -16,13 +16,14 @@ public static void TestEntryPoint() Assert.Equal(199_990_000, arr[0]); } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] private static async Task AsyncTestEntryPoint(int[] arr, int index) { await HoistedByref(arr, index); } [MethodImpl(MethodImplOptions.NoInlining)] - private static async2 Task HoistedByref(int[] arr, int index) + private static async Task HoistedByref(int[] arr, int index) { for (int i = 0; i < 20000; i++) { diff --git a/src/tests/async/eh-microbench.cs b/src/tests/async/eh-microbench.cs index 994e443cf9e3..2eefa61570a8 100644 --- a/src/tests/async/eh-microbench.cs +++ b/src/tests/async/eh-microbench.cs @@ -24,6 +24,7 @@ public static int Main() return 100; } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] public static async Task AsyncEntry() { if (!GCSettings.IsServerGC) @@ -68,6 +69,7 @@ public static async Task AsyncEntry() await RunBench(yieldFrequency, depth, finallyRate, throwOrReturn, "ValueTask"); } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] private static async Task RunBench(int yieldCount, int depth, int finallyRate, bool throwOrReturn, string type) { @@ -104,7 +106,7 @@ public Benchmark(int yieldCount, int depth, int finallyRate, bool throwOrReturn) _throwOrReturn = throwOrReturn; } - public async2 Task Run(string type) + public async Task Run(string type) { if (type == "Async2") return await RunAsync2(_depth); @@ -117,6 +119,7 @@ public async2 Task Run(string type) return 0; } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] public async Task RunTask(int depth) { int liveState1 = depth * 3 + _yieldCount; @@ -182,6 +185,7 @@ public async Task RunTask(int depth) return result; } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] public async ValueTask RunValueTask(int depth) { int liveState1 = depth * 3 + _yieldCount; @@ -267,7 +271,7 @@ public class FakeThread // This case is used to test the impact of save/restore of the sync and execution context on performance // The intent here is to measure what the performance impact of maintaining the current async semantics with // the new implementation. - public async2 Task RunAsync2WithContextSaveRestore(int depth) + public async Task RunAsync2WithContextSaveRestore(int depth) { FakeThread thread = CurrentThread; if (thread == null) @@ -361,7 +365,7 @@ public async2 Task RunAsync2WithContextSaveRestore(int depth) } } - public async2 Task RunAsync2(int depth) + public async Task RunAsync2(int depth) { int liveState1 = depth * 3 + _yieldCount; int liveState2 = depth; diff --git a/src/tests/async/fibonacci-with-yields.cs b/src/tests/async/fibonacci-with-yields.cs index a51a834fbdd7..814b96eda0b9 100644 --- a/src/tests/async/fibonacci-with-yields.cs +++ b/src/tests/async/fibonacci-with-yields.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Runtime.CompilerServices; using System.Threading.Tasks; using System.Diagnostics; using Xunit; @@ -22,7 +23,7 @@ public static void Test() System.Console.WriteLine("allocated: " + allocated); } - public static async2 Task AsyncEntry() + public static async Task AsyncEntry() { for (int i = 0; i < iterations; i++) { @@ -34,7 +35,7 @@ public static async2 Task AsyncEntry() } } - static async2 Task Fib(int i) + static async Task Fib(int i) { if (i <= 1) { diff --git a/src/tests/async/fibonacci-with-yields.csproj b/src/tests/async/fibonacci-with-yields.csproj index de6d5e08882e..b769f499427a 100644 --- a/src/tests/async/fibonacci-with-yields.csproj +++ b/src/tests/async/fibonacci-with-yields.csproj @@ -1,6 +1,7 @@ True + $(Features);runtime-async diff --git a/src/tests/async/fibonacci-with-yields_struct_return.cs b/src/tests/async/fibonacci-with-yields_struct_return.cs index eee23a2c1624..5b1de2e017b0 100644 --- a/src/tests/async/fibonacci-with-yields_struct_return.cs +++ b/src/tests/async/fibonacci-with-yields_struct_return.cs @@ -34,7 +34,7 @@ public struct MyInt public MyInt(int i) => this.i = i; } - public static async2 Task AsyncEntry() + public static async Task AsyncEntry() { for (int i = 0; i < iterations; i++) { @@ -46,7 +46,7 @@ public static async2 Task AsyncEntry() } } - static async2 Task Fib(MyInt n) + static async Task Fib(MyInt n) { int i = n.i; if (i <= 1) diff --git a/src/tests/async/fibonacci-with-yields_struct_return.csproj b/src/tests/async/fibonacci-with-yields_struct_return.csproj index de6d5e08882e..b769f499427a 100644 --- a/src/tests/async/fibonacci-with-yields_struct_return.csproj +++ b/src/tests/async/fibonacci-with-yields_struct_return.csproj @@ -1,6 +1,7 @@ True + $(Features);runtime-async diff --git a/src/tests/async/fibonacci-without-yields.cs b/src/tests/async/fibonacci-without-yields.cs index 77ff71e8d1ee..2ef1c507e231 100644 --- a/src/tests/async/fibonacci-without-yields.cs +++ b/src/tests/async/fibonacci-without-yields.cs @@ -22,7 +22,7 @@ public static void Test() System.Console.WriteLine("allocated: " + allocated); } - public static async2 Task AsyncEntry() + public static async Task AsyncEntry() { for (int i = 0; i < iterations; i++) { @@ -34,7 +34,7 @@ public static async2 Task AsyncEntry() } } - static async2 Task Fib(int i) + static async Task Fib(int i) { if (i <= 1) { diff --git a/src/tests/async/fibonacci-without-yields.csproj b/src/tests/async/fibonacci-without-yields.csproj index de6d5e08882e..b769f499427a 100644 --- a/src/tests/async/fibonacci-without-yields.csproj +++ b/src/tests/async/fibonacci-without-yields.csproj @@ -1,6 +1,7 @@ True + $(Features);runtime-async diff --git a/src/tests/async/gc-roots-scan.cs b/src/tests/async/gc-roots-scan.cs index fffe874af38e..b50e862d17f2 100644 --- a/src/tests/async/gc-roots-scan.cs +++ b/src/tests/async/gc-roots-scan.cs @@ -11,6 +11,7 @@ public class Async2RootReporting private static TaskCompletionSource cs; + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] static async Task Recursive1(int n) { Task cTask = cs.Task; @@ -50,7 +51,7 @@ static async Task Recursive1(int n) return result; } - static async2 Task Recursive2(int n) + static async Task Recursive2(int n) { Task cTask = cs.Task; diff --git a/src/tests/async/implement.cs b/src/tests/async/implement.cs index bb8607541d1d..9607d582cd04 100644 --- a/src/tests/async/implement.cs +++ b/src/tests/async/implement.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using System.Runtime.CompilerServices; using System.Threading.Tasks; using Xunit; @@ -10,11 +9,12 @@ public class Async2Implement { interface IBase1 { - public async2 Task M1(); + public Task M1(); } class Derived1 : IBase1 { + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] public async Task M1() { await Task.Yield(); @@ -24,7 +24,7 @@ public async Task M1() class Derived1a : IBase1 { - public async2 Task M1() + public async Task M1() { await Task.Yield(); return 3; @@ -38,7 +38,7 @@ interface IBase2 class Derived2 : IBase2 { - public async2 Task M1() + public async Task M1() { await Task.Yield(); return 12; @@ -47,6 +47,7 @@ public async2 Task M1() class Derived2a : IBase2 { + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] public async Task M1() { await Task.Yield(); diff --git a/src/tests/async/mincallcost-microbench.cs b/src/tests/async/mincallcost-microbench.cs index 122994d8061c..900aad4ba45b 100644 --- a/src/tests/async/mincallcost-microbench.cs +++ b/src/tests/async/mincallcost-microbench.cs @@ -24,6 +24,7 @@ public static int Main() return 100; } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] public static async Task AsyncEntry() { if (!GCSettings.IsServerGC) @@ -66,6 +67,7 @@ public static async Task AsyncEntry() static double time = 10.0; static bool printResult = false; + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] private static async Task RunBench(string type) { if (printResult) @@ -85,6 +87,7 @@ private static async Task RunBench(string type) Console.WriteLine("Result = {0}", (long)avg); } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] private static async Task Run(string type) { if (type == "AsyncCallingAsync") @@ -114,6 +117,7 @@ private static async Task Run(string type) } #pragma warning disable CS1998 + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] private static async Task AsyncCallingAsync() { Stopwatch timer = Stopwatch.StartNew(); @@ -131,6 +135,7 @@ private static async Task AsyncCallingAsync() return numIters * 10; } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] private static async Task AsyncCallingValueTaskAsync() { Stopwatch timer = Stopwatch.StartNew(); @@ -148,6 +153,7 @@ private static async Task AsyncCallingValueTaskAsync() return numIters * 10; } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] private static async Task AsyncCallingAsync2() { Stopwatch timer = Stopwatch.StartNew(); @@ -165,7 +171,7 @@ private static async Task AsyncCallingAsync2() return numIters * 10; } - private static async2 Task Async2CallingAsync() + private static async Task Async2CallingAsync() { Stopwatch timer = Stopwatch.StartNew(); @@ -182,7 +188,7 @@ private static async2 Task Async2CallingAsync() return numIters * 10; } - private static async2 Task Async2CallingValueTaskAsync() + private static async Task Async2CallingValueTaskAsync() { Stopwatch timer = Stopwatch.StartNew(); @@ -199,7 +205,7 @@ private static async2 Task Async2CallingValueTaskAsync() return numIters * 10; } - private static async2 Task Async2CallingAsync2() + private static async Task Async2CallingAsync2() { Stopwatch timer = Stopwatch.StartNew(); @@ -216,7 +222,7 @@ private static async2 Task Async2CallingAsync2() return numIters * 10; } - private static async2 Task Async2CallingAsync2NoInlining() + private static async Task Async2CallingAsync2NoInlining() { Stopwatch timer = Stopwatch.StartNew(); @@ -233,7 +239,7 @@ private static async2 Task Async2CallingAsync2NoInlining() return numIters * 10; } - private static async2 Task Async2CallingAsync2WithContextSave() + private static async Task Async2CallingAsync2WithContextSave() { FakeThread thread = CurrentThread; if (thread == null) @@ -274,6 +280,7 @@ public class FakeThread public static FakeThread CurrentThread; + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] private static async Task AsyncCallingYield() { Stopwatch timer = Stopwatch.StartNew(); @@ -291,7 +298,7 @@ private static async Task AsyncCallingYield() return numIters * 10; } - private static async2 Task Async2CallingYield() + private static async Task Async2CallingYield() { Stopwatch timer = Stopwatch.StartNew(); @@ -325,6 +332,7 @@ private static long Sync2CallingSync() return numIters * 10; } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] private static async Task EmptyAsync() { // Add some work that forces the method to be a real async method @@ -333,6 +341,7 @@ private static async Task EmptyAsync() return; } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] private static async ValueTask EmptyValueTaskAsync() { // Add some work that forces the method to be a real async method @@ -341,7 +350,7 @@ private static async ValueTask EmptyValueTaskAsync() return; } - private static async2 Task EmptyAsync2() + private static async Task EmptyAsync2() { // Add some work that forces the method to be a real async method if (time == 0) @@ -350,7 +359,7 @@ private static async2 Task EmptyAsync2() } [MethodImpl(MethodImplOptions.NoInlining)] - private static async2 Task EmptyAsync2NoInlining() + private static async Task EmptyAsync2NoInlining() { // Add some work that forces the method to be a real async method if (time == 0) @@ -358,8 +367,8 @@ private static async2 Task EmptyAsync2NoInlining() return; } - // This simulates async2 capturing the same amount of state that existing async needs to capture to handle the current semantics around async locals and synchronizationcontext - private static async2 Task EmptyAsync2WithContextSave() + // This simulates async capturing the same amount of state that existing async needs to capture to handle the current semantics around async locals and synchronizationcontext + private static async Task EmptyAsync2WithContextSave() { FakeThread thread = CurrentThread; FakeExecContext? previousExecutionCtx = thread._execContext; diff --git a/src/tests/async/object.cs b/src/tests/async/object.cs index fb62588652ae..7ebec6207edf 100644 --- a/src/tests/async/object.cs +++ b/src/tests/async/object.cs @@ -14,13 +14,14 @@ public static int TestEntryPoint() return (int)AsyncTestEntryPoint(100).Result; } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] private static async Task AsyncTestEntryPoint(int arg) { return await ObjMethod(arg); } [MethodImpl(MethodImplOptions.NoInlining)] - private static async2 Task ObjMethod(int arg) + private static async Task ObjMethod(int arg) { await Task.Yield(); return arg; diff --git a/src/tests/async/objects-captured.cs b/src/tests/async/objects-captured.cs index 197d29f0383d..b5c252298ed2 100644 --- a/src/tests/async/objects-captured.cs +++ b/src/tests/async/objects-captured.cs @@ -8,7 +8,7 @@ public class Async2ObjectsWithYields { - internal static async2 Task A(object n) + internal static async Task A(object n) { // use string equality so that JIT would not think of hoisting "(int)n" // also to produce some amout of garbage @@ -21,6 +21,7 @@ internal static async2 Task A(object n) return 0; } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] private static async Task AsyncEntry() { object result = 0; diff --git a/src/tests/async/override.cs b/src/tests/async/override.cs index 4ee5d1446b83..d55d961880ad 100644 --- a/src/tests/async/override.cs +++ b/src/tests/async/override.cs @@ -10,7 +10,7 @@ public class Async2Override { class Base { - public virtual async2 Task M1() + public virtual async Task M1() { await Task.Yield(); return 1; @@ -19,6 +19,7 @@ public virtual async2 Task M1() class Derived1 : Base { + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] public override async Task M1() { await Task.Yield(); @@ -28,7 +29,7 @@ public override async Task M1() class Derived2 : Derived1 { - public override async2 Task M1() + public override async Task M1() { await Task.Yield(); return 3; @@ -38,6 +39,7 @@ public override async2 Task M1() class Base1 { + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] public virtual async Task M1() { await Task.Yield(); @@ -47,7 +49,7 @@ public virtual async Task M1() class Derived11 : Base1 { - public override async2 Task M1() + public override async Task M1() { await Task.Yield(); return 12; @@ -56,6 +58,7 @@ public override async2 Task M1() class Derived12 : Derived11 { + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] public override async Task M1() { await Task.Yield(); diff --git a/src/tests/async/pgo.cs b/src/tests/async/pgo.cs index 6e3f14caa7ba..ba5589c07d91 100644 --- a/src/tests/async/pgo.cs +++ b/src/tests/async/pgo.cs @@ -17,7 +17,7 @@ public static void EntryPoint() AsyncEntryPoint().Wait(); } - internal static async2 Task AsyncEntryPoint() + internal static async Task AsyncEntryPoint() { int[] arr = Enumerable.Range(0, 100_000).ToArray(); @@ -36,20 +36,20 @@ internal static async2 Task AsyncEntryPoint() private class AggregateSum : I { #pragma warning disable CS1998 - public async2 Task Aggregate(int a, int b) => a + b; + public async Task Aggregate(int a, int b) => a + b; } - + public interface I { public Task Aggregate(T seed, T val); } - + [MethodImpl(MethodImplOptions.NoInlining)] - public static async2 Task AggregateDelegateAsync(T[] arr, I aggregate, T seed) + public static async Task AggregateDelegateAsync(T[] arr, I aggregate, T seed) { foreach (T val in arr) seed = await aggregate.Aggregate(seed, val); - + return seed; } } diff --git a/src/tests/async/pinvoke.cs b/src/tests/async/pinvoke.cs index df04091cbaf2..bbe9e939ad7f 100644 --- a/src/tests/async/pinvoke.cs +++ b/src/tests/async/pinvoke.cs @@ -14,7 +14,7 @@ public static void TestEntryPoint() AsyncEntryPoint().Wait(); } - private static async2 Task AsyncEntryPoint() + private static async Task AsyncEntryPoint() { unsafe { diff --git a/src/tests/async/returns.cs b/src/tests/async/returns.cs index 174a66c479a1..3df7a8a65899 100644 --- a/src/tests/async/returns.cs +++ b/src/tests/async/returns.cs @@ -15,7 +15,7 @@ public static void TestEntryPoint() } [MethodImpl(MethodImplOptions.NoInlining)] - private static async2 Task Returns(C c) + private static async Task Returns(C c) { for (int i = 0; i < 20000; i++) { @@ -58,28 +58,28 @@ private static void AssertEqual(T expected, T actual) } [MethodImpl(MethodImplOptions.NoInlining)] - private static async2 Task> ReturnsStruct() + private static async Task> ReturnsStruct() { await Task.Yield(); return new S { A = 42, B = 4242, C = 424242, D = 42424242 }; } [MethodImpl(MethodImplOptions.NoInlining)] - private static async2 Task> ReturnsStructGC() + private static async Task> ReturnsStructGC() { await Task.Yield(); return new S { A = "A", B = "B", C = "C", D = "D" }; } [MethodImpl(MethodImplOptions.NoInlining)] - private static async2 Task> ReturnsBytes() + private static async Task> ReturnsBytes() { await Task.Yield(); return new S { A = 4, B = 40, C = 42, D = 45 }; } [MethodImpl(MethodImplOptions.NoInlining)] - private static async2 Task ReturnsString() + private static async Task ReturnsString() { await Task.Yield(); return "a string!"; diff --git a/src/tests/async/shared-generic.cs b/src/tests/async/shared-generic.cs index bacaafcb320c..419eca104c72 100644 --- a/src/tests/async/shared-generic.cs +++ b/src/tests/async/shared-generic.cs @@ -53,6 +53,7 @@ public static void TestEntryPoint() Async2EntryPoint?>(typeof(S1?), null).Wait(); } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] private static async Task Async1EntryPoint(Type t, T value) { await new GenericClass().InstanceMethod(t); @@ -67,7 +68,7 @@ private static async Task Async1EntryPoint(Type t, T value) Assert.Equal(value, await GenericClass.StaticReturnMethodTypeAsync1(value)); } - private static async2 Task Async2EntryPoint(Type t, T value) + private static async Task Async2EntryPoint(Type t, T value) { await new GenericClass().InstanceMethod(t); await GenericClass.StaticMethod(t); @@ -86,7 +87,7 @@ public class GenericClass { // 'this' is context [MethodImpl(MethodImplOptions.NoInlining)] - public async2 Task InstanceMethod(Type t) + public async Task InstanceMethod(Type t) { Assert.Equal(typeof(T), t); await Task.Yield(); @@ -95,7 +96,7 @@ public async2 Task InstanceMethod(Type t) // Class context [MethodImpl(MethodImplOptions.NoInlining)] - public static async2 Task StaticMethod(Type t) + public static async Task StaticMethod(Type t) { Assert.Equal(typeof(T), t); await Task.Yield(); @@ -104,7 +105,7 @@ public static async2 Task StaticMethod(Type t) // Method context [MethodImpl(MethodImplOptions.NoInlining)] - public static async2 Task StaticMethod(Type t, Type tm) + public static async Task StaticMethod(Type t, Type tm) { Assert.Equal(typeof(T), t); Assert.Equal(typeof(TM), tm); @@ -115,6 +116,7 @@ public static async2 Task StaticMethod(Type t, Type tm) // Class context [MethodImpl(MethodImplOptions.NoInlining)] + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] public static async Task StaticMethodAsync1(Type t) { Assert.Equal(typeof(T), t); @@ -124,6 +126,7 @@ public static async Task StaticMethodAsync1(Type t) // Method context [MethodImpl(MethodImplOptions.NoInlining)] + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] public static async Task StaticMethodAsync1(Type t, Type tm) { Assert.Equal(typeof(T), t); @@ -133,24 +136,26 @@ public static async Task StaticMethodAsync1(Type t, Type tm) Assert.Equal(typeof(TM), tm); } - public static async2 Task StaticReturnClassType(T value) + public static async Task StaticReturnClassType(T value) { await Task.Yield(); return value; } - public static async2 Task StaticReturnMethodType(TM value) + public static async Task StaticReturnMethodType(TM value) { await Task.Yield(); return value; } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] public static async Task StaticReturnClassTypeAsync1(T value) { await Task.Yield(); return value; } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] public static async Task StaticReturnMethodTypeAsync1(TM value) { await Task.Yield(); diff --git a/src/tests/async/simple-eh.cs b/src/tests/async/simple-eh.cs index 8d70af66efc5..04b19f132c42 100644 --- a/src/tests/async/simple-eh.cs +++ b/src/tests/async/simple-eh.cs @@ -18,13 +18,14 @@ public static void Test() Task.Run(AsyncEntry).Wait(); } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] public static async Task AsyncEntry() { int result = await Handler(); Assert.Equal(42, result); } - public static async2 Task Handler() + public static async Task Handler() { try { @@ -37,7 +38,7 @@ public static async2 Task Handler() } [MethodImpl(MethodImplOptions.NoInlining)] - public static async2 Task Throw(int value) + public static async Task Throw(int value) { await Task.Yield(); throw new IntegerException(value); diff --git a/src/tests/async/struct.cs b/src/tests/async/struct.cs index cc2923b89ece..a6cc74f409e1 100644 --- a/src/tests/async/struct.cs +++ b/src/tests/async/struct.cs @@ -24,13 +24,6 @@ private static async Task Async() AssertEqual(100, s.Value); } - private static async2 Task Async2() - { - S s = new S(100); - await s.Test(); - AssertEqual(100, s.Value); - } - [MethodImpl(MethodImplOptions.NoInlining)] private static void AssertEqual(int expected, int val) { @@ -43,7 +36,7 @@ private struct S public S(int value) => Value = value; - public async2 Task Test() + public async Task Test() { AssertEqual(100, Value); Value++; @@ -54,7 +47,7 @@ public async2 Task Test() AssertEqual(102, Value); } - private async2 Task InstanceCall() + private async Task InstanceCall() { AssertEqual(101, Value); Value++; diff --git a/src/tests/async/taskbased-asyncfibonacci-with-yields.cs b/src/tests/async/taskbased-asyncfibonacci-with-yields.cs index 4829e029636d..2465903d710a 100644 --- a/src/tests/async/taskbased-asyncfibonacci-with-yields.cs +++ b/src/tests/async/taskbased-asyncfibonacci-with-yields.cs @@ -23,6 +23,7 @@ public static int Main() return 100; } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] public static async Task AsyncEntry() { for (int i = 0; i < iterations; i++) @@ -35,6 +36,7 @@ public static async Task AsyncEntry() } } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] static async Task Fib(int i) { if (i <= 1) diff --git a/src/tests/async/taskbased-asyncfibonacci-without-yields.cs b/src/tests/async/taskbased-asyncfibonacci-without-yields.cs index e3e9c7ff21f8..2f8ddb5f0665 100644 --- a/src/tests/async/taskbased-asyncfibonacci-without-yields.cs +++ b/src/tests/async/taskbased-asyncfibonacci-without-yields.cs @@ -23,6 +23,7 @@ public static int Main() return 100; } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] public static async Task AsyncEntry() { for (int i = 0; i < iterations; i++) @@ -35,6 +36,7 @@ public static async Task AsyncEntry() } } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] static async Task Fib(int i) { if (i <= 1) diff --git a/src/tests/async/valuetask.cs b/src/tests/async/valuetask.cs index deff530e9f5d..4740181e2739 100644 --- a/src/tests/async/valuetask.cs +++ b/src/tests/async/valuetask.cs @@ -19,7 +19,7 @@ private static ValueTask AsyncTestEntryPoint(int arg) return M1(arg); } - private static async2 ValueTask M1(int arg) + private static async ValueTask M1(int arg) { await Task.Yield(); return arg; diff --git a/src/tests/async/valuetaskbased-asyncfibonacci-with-yields.cs b/src/tests/async/valuetaskbased-asyncfibonacci-with-yields.cs index ac48372814ef..f34cc93b1d6b 100644 --- a/src/tests/async/valuetaskbased-asyncfibonacci-with-yields.cs +++ b/src/tests/async/valuetaskbased-asyncfibonacci-with-yields.cs @@ -23,6 +23,7 @@ public static int Main() return 100; } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] public static async ValueTask AsyncEntry() { for (int i = 0; i < iterations; i++) @@ -35,6 +36,7 @@ public static async ValueTask AsyncEntry() } } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] static async ValueTask Fib(int i) { if (i <= 1) diff --git a/src/tests/async/valuetaskbased-asyncfibonacci-without-yields.cs b/src/tests/async/valuetaskbased-asyncfibonacci-without-yields.cs index 1e3aab57ec7d..64d57c46f8ee 100644 --- a/src/tests/async/valuetaskbased-asyncfibonacci-without-yields.cs +++ b/src/tests/async/valuetaskbased-asyncfibonacci-without-yields.cs @@ -23,6 +23,7 @@ public static int Main() return 100; } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] public static async ValueTask AsyncEntry() { for (int i = 0; i < iterations; i++) @@ -35,6 +36,7 @@ public static async ValueTask AsyncEntry() } } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] static async ValueTask Fib(int i) { if (i <= 1) diff --git a/src/tests/async/varying-yields.cs b/src/tests/async/varying-yields.cs index 6edc30e8118d..6194d1890d83 100644 --- a/src/tests/async/varying-yields.cs +++ b/src/tests/async/varying-yields.cs @@ -22,6 +22,7 @@ public static void TestEntryPoint() Task.Run(AsyncEntry).Wait(); } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] public static async Task AsyncEntry() { if (!GCSettings.IsServerGC) @@ -76,13 +77,14 @@ private class Benchmark public Benchmark(double yieldProbability) => _yieldProbability = yieldProbability; -public #if ASYNC1_TASK - async Task + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] + public async Task #elif ASYNC1_VALUETASK - async ValueTask + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] + public async ValueTask #else - async2 Task + public async Task #endif Run(int depth) { @@ -98,13 +100,14 @@ async2 Task return result; } -private #if ASYNC1_TASK - async Task + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] + private async Task #elif ASYNC1_VALUETASK - async ValueTask + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] + private async ValueTask #else - async2 Task + private async Task #endif Loop() { @@ -124,13 +127,14 @@ async2 Task return numIters; } -private #if ASYNC1_TASK - async Task + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] + private async Task #elif ASYNC1_VALUETASK - async ValueTask + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] + private async ValueTask #else - async2 Task + private async Task #endif DoYields() { diff --git a/src/tests/async/void.cs b/src/tests/async/void.cs index 8271887731a1..566dbd8e7ccc 100644 --- a/src/tests/async/void.cs +++ b/src/tests/async/void.cs @@ -16,13 +16,14 @@ public static void TestEntryPoint() Assert.Equal(199_990_000, arr[0]); } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] private static async Task AsyncTestEntryPoint(int[] arr, int index) { await HoistedByref(arr, index); } [MethodImpl(MethodImplOptions.NoInlining)] - private static async2 Task HoistedByref(int[] arr, int index) + private static async Task HoistedByref(int[] arr, int index) { for (int i = 0; i < 20000; i++) { diff --git a/src/tests/async/with-yields.cs b/src/tests/async/with-yields.cs index 2f53a60f7c4f..7c382b671092 100644 --- a/src/tests/async/with-yields.cs +++ b/src/tests/async/with-yields.cs @@ -8,7 +8,7 @@ public class Async2FibonacceWithYields { - internal static async2 Task B(int n) + internal static async Task B(int n) { int num = 1; await Task.Yield(); @@ -22,7 +22,7 @@ internal static async2 Task B(int n) return num; } - internal static async2 Task A(int n) + internal static async Task A(int n) { int num = n; for (int num2 = 0; num2 < n; num2++) @@ -33,6 +33,7 @@ internal static async2 Task A(int n) return num; } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] private static async Task AsyncEntry() { int result = 0; diff --git a/src/tests/async/without-yields.cs b/src/tests/async/without-yields.cs index ba1f2aeff0df..b0866fda6a79 100644 --- a/src/tests/async/without-yields.cs +++ b/src/tests/async/without-yields.cs @@ -11,12 +11,12 @@ public class Async2FibonacceWithoutYields //This async method lacks 'await' #pragma warning disable 1998 - internal static async2 Task B(int n) + internal static async Task B(int n) { return 100; } - internal static async2 Task A(int n) + internal static async Task A(int n) { int num = n; for (int num2 = 0; num2 < n; num2++) @@ -27,6 +27,7 @@ internal static async2 Task A(int n) return num; } + [System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)] private static async Task AsyncEntry() { int result = 0;