Skip to content

Use prototype roslyn compiler #3062

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: feature/async2-experiment
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ syntax: glob
.packages
.tools

# nuget packages for custom roslyn
roslynpackages

# User-specific files
*.suo
*.user
Expand Down
2 changes: 1 addition & 1 deletion NuGet.config
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<add key="dotnet-libraries-transport" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-libraries-transport/nuget/v3/index.json" />
<add key="dotnet10" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet10/nuget/v3/index.json" />
<add key="dotnet10-transport" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet10-transport/nuget/v3/index.json" />
<add key="async-compiler" value="roslynpackages" />
<add key="general-testing" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/general-testing/nuget/v3/index.json" />
</packageSources>
<auditSources>
<clear />
Expand Down
34 changes: 0 additions & 34 deletions buildroslynnugets.cmd

This file was deleted.

7 changes: 4 additions & 3 deletions eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -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.
-->
<MicrosoftCodeAnalysisCSharpVersion>4.14.0-async-13</MicrosoftCodeAnalysisCSharpVersion>
<MicrosoftCodeAnalysisVersion>4.14.0-async-13</MicrosoftCodeAnalysisVersion>
<MicrosoftNetCompilersToolsetVersion>4.14.0-async-13</MicrosoftNetCompilersToolsetVersion>

<MicrosoftCodeAnalysisCSharpVersion>4.13.0-3.24611.10</MicrosoftCodeAnalysisCSharpVersion>
<MicrosoftCodeAnalysisVersion>$(MicrosoftCodeAnalysisCSharpVersion)</MicrosoftCodeAnalysisVersion>
<MicrosoftNetCompilersToolsetVersion>$(MicrosoftCodeAnalysisCSharpVersion)</MicrosoftNetCompilersToolsetVersion>
</PropertyGroup>
<!--
For source generator support we need to target multiple versions of Roslyn in order to be able to run on older versions of Roslyn.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,31 @@ public static partial class RuntimeFeature
/// </summary>
public const string NumericIntPtr = nameof(NumericIntPtr);

/// <summary>
/// Indicates that this version of the runtime supports async methods.
/// </summary>
[RequiresPreviewFeatures]
public const string Async = nameof(Async);

/// <summary>
/// Checks whether a certain feature is supported by the Runtime.
/// </summary>
public static bool IsSupported(string feature)
{
return feature switch
{
PortablePdb or CovariantReturnsOfClasses or ByRefFields or ByRefLikeGenerics or UnmanagedSignatureCallingConvention or DefaultImplementationsOfInterfaces or VirtualStaticsInInterfaces or NumericIntPtr => true,
PortablePdb or
CovariantReturnsOfClasses or
ByRefFields or
ByRefLikeGenerics or
UnmanagedSignatureCallingConvention or
DefaultImplementationsOfInterfaces or
VirtualStaticsInInterfaces or
NumericIntPtr or
#pragma warning disable CA2252 // Using preview features
Async=> true,
#pragma warning restore CA2252 // Using preview features

nameof(IsDynamicCodeSupported) => IsDynamicCodeSupported,
nameof(IsDynamicCodeCompiled) => IsDynamicCodeCompiled,
_ => false,
Expand Down
2 changes: 2 additions & 0 deletions src/libraries/System.Runtime/ref/System.Runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13709,6 +13709,8 @@ public static partial class RuntimeFeature
public const string PortablePdb = "PortablePdb";
public const string UnmanagedSignatureCallingConvention = "UnmanagedSignatureCallingConvention";
public const string VirtualStaticsInInterfaces = "VirtualStaticsInInterfaces";
[System.Runtime.Versioning.RequiresPreviewFeaturesAttribute]
public const string Async = "Async";
[System.Diagnostics.CodeAnalysis.FeatureGuardAttribute(typeof(System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute))]
public static bool IsDynamicCodeCompiled { get { throw null; } }
[System.Diagnostics.CodeAnalysis.FeatureSwitchDefinitionAttribute("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported")]
Expand Down
5 changes: 5 additions & 0 deletions src/tests/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
<Import Project="$(MSBuildThisFileDirectory)\Common\dir.sdkbuild.props" Condition="'$(UsingMicrosoftNETSdk)' == 'true'" />
<Import Project="$(MSBuildThisFileDirectory)\Common\dir.common.props" Condition="'$(UsingMicrosoftNETSdk)' != 'true'" />

<PropertyGroup>
<!-- Override the compiler version with a private build that supports async2 -->
<MicrosoftNetCompilersToolsetVersion>4.14.0-3.25170.6</MicrosoftNetCompilersToolsetVersion>
</PropertyGroup>

<PropertyGroup>
<RunningOnUnix Condition="('$(RunningOnUnix)' == '') And ('$(MSBuildRuntimeType)' == 'Core') And ('$(OS)'!='Windows_NT')">true</RunningOnUnix>
</PropertyGroup>
Expand Down
9 changes: 9 additions & 0 deletions src/tests/async/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project>
<Import Project="../Directory.Build.props" />
<PropertyGroup>
<Features>$(Features);runtime-async=on</Features>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)RuntimeAsyncMethodGenerationAttribute.cs" />
</ItemGroup>
</Project>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think switching all tests to experimental compiler is good for runtimelab, but in main repo we might need to limit this to async folder.

I assume this will work in CI, right?

6 changes: 6 additions & 0 deletions src/tests/async/RuntimeAsyncMethodGenerationAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace System.Runtime.CompilerServices;
[AttributeUsage(AttributeTargets.Method)]
public class RuntimeAsyncMethodGenerationAttribute(bool runtimeAsync) : Attribute
{
public bool RuntimeAsync { get; } = runtimeAsync;
}
7 changes: 4 additions & 3 deletions src/tests/async/awaitingnotasync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -14,13 +13,15 @@ public static void TestEntryPoint()
AsyncEntryPoint().Wait();
}

[System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)]
private static async Task<T> GetTask<T>(T arg)
{
await Task.Yield();
return arg;
}

// TODO: switch every other scenario to use ValueTask
[System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)]
private static async ValueTask<T> GetValueTask<T>(T arg)
{
await Task.Yield();
Expand All @@ -33,13 +34,13 @@ private static async ValueTask<T> GetValueTask<T>(T arg)

private static T sIdentity<T>(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
Expand Down
6 changes: 3 additions & 3 deletions src/tests/async/collectible-alc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public static void TestEntryPoint()
AsyncEntryPoint().Wait();
}

private static async2 Task AsyncEntryPoint()
private static async Task AsyncEntryPoint()
{
WeakReference wr = await CallFooAsyncAndUnload();

Expand All @@ -31,7 +31,7 @@ private static async2 Task AsyncEntryPoint()
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static async2 Task<WeakReference> CallFooAsyncAndUnload()
private static async Task<WeakReference> CallFooAsyncAndUnload()
{
TaskCompletionSource tcs = new();
(Task<string> task, WeakReference wr) = CallFooAsyncInCollectibleALC(tcs.Task);
Expand Down Expand Up @@ -63,7 +63,7 @@ private static (Task<string>, WeakReference) CallFooAsyncInCollectibleALC(Task t
}

// Task[] to work around a compiler bug
private static async2 Task<string> FooAsync(Task[] t)
private static async Task<string> FooAsync(Task[] t)
{
await t[0];
return "done";
Expand Down
1 change: 1 addition & 0 deletions src/tests/async/collectible-alc.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<!-- For collectible ALC -->
<RequiresProcessIsolation>True</RequiresProcessIsolation>
<Optimize>True</Optimize>
<Features>$(Features);runtime-async</Features>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
Expand Down
3 changes: 2 additions & 1 deletion src/tests/async/cse-array-index-byref.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<int> HoistedByref(int[] arr, int index)
private static async Task<int> HoistedByref(int[] arr, int index)
{
for (int i = 0; i < 20000; i++)
{
Expand Down
10 changes: 7 additions & 3 deletions src/tests/async/eh-microbench.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public static int Main()
return 100;
}

[System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)]
public static async Task AsyncEntry()
{
if (!GCSettings.IsServerGC)
Expand Down Expand Up @@ -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)
{

Expand Down Expand Up @@ -104,7 +106,7 @@ public Benchmark(int yieldCount, int depth, int finallyRate, bool throwOrReturn)
_throwOrReturn = throwOrReturn;
}

public async2 Task<long> Run(string type)
public async Task<long> Run(string type)
{
if (type == "Async2")
return await RunAsync2(_depth);
Expand All @@ -117,6 +119,7 @@ public async2 Task<long> Run(string type)
return 0;
}

[System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)]
public async Task<long> RunTask(int depth)
{
int liveState1 = depth * 3 + _yieldCount;
Expand Down Expand Up @@ -182,6 +185,7 @@ public async Task<long> RunTask(int depth)
return result;
}

[System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)]
public async ValueTask<long> RunValueTask(int depth)
{
int liveState1 = depth * 3 + _yieldCount;
Expand Down Expand Up @@ -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<long> RunAsync2WithContextSaveRestore(int depth)
public async Task<long> RunAsync2WithContextSaveRestore(int depth)
{
FakeThread thread = CurrentThread;
if (thread == null)
Expand Down Expand Up @@ -361,7 +365,7 @@ public async2 Task<long> RunAsync2WithContextSaveRestore(int depth)
}
}

public async2 Task<long> RunAsync2(int depth)
public async Task<long> RunAsync2(int depth)
{
int liveState1 = depth * 3 + _yieldCount;
int liveState2 = depth;
Expand Down
5 changes: 3 additions & 2 deletions src/tests/async/fibonacci-with-yields.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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++)
{
Expand All @@ -34,7 +35,7 @@ public static async2 Task AsyncEntry()
}
}

static async2 Task<int> Fib(int i)
static async Task<int> Fib(int i)
{
if (i <= 1)
{
Expand Down
1 change: 1 addition & 0 deletions src/tests/async/fibonacci-with-yields.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Optimize>True</Optimize>
<Features>$(Features);runtime-async</Features>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
Expand Down
4 changes: 2 additions & 2 deletions src/tests/async/fibonacci-with-yields_struct_return.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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++)
{
Expand All @@ -46,7 +46,7 @@ public static async2 Task AsyncEntry()
}
}

static async2 Task<MyInt> Fib(MyInt n)
static async Task<MyInt> Fib(MyInt n)
{
int i = n.i;
if (i <= 1)
Expand Down
1 change: 1 addition & 0 deletions src/tests/async/fibonacci-with-yields_struct_return.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Optimize>True</Optimize>
<Features>$(Features);runtime-async</Features>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
Expand Down
4 changes: 2 additions & 2 deletions src/tests/async/fibonacci-without-yields.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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++)
{
Expand All @@ -34,7 +34,7 @@ public static async2 Task AsyncEntry()
}
}

static async2 Task<int> Fib(int i)
static async Task<int> Fib(int i)
{
if (i <= 1)
{
Expand Down
1 change: 1 addition & 0 deletions src/tests/async/fibonacci-without-yields.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Optimize>True</Optimize>
<Features>$(Features);runtime-async</Features>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
Expand Down
3 changes: 2 additions & 1 deletion src/tests/async/gc-roots-scan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class Async2RootReporting
private static TaskCompletionSource<int> cs;


[System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)]
static async Task<int> Recursive1(int n)
{
Task<int> cTask = cs.Task;
Expand Down Expand Up @@ -50,7 +51,7 @@ static async Task<int> Recursive1(int n)
return result;
}

static async2 Task<int> Recursive2(int n)
static async Task<int> Recursive2(int n)
{
Task<int> cTask = cs.Task;

Expand Down
Loading
Loading