diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h
index bdedfa685b37e8..4adc4f3ece92fb 100644
--- a/src/coreclr/inc/corinfo.h
+++ b/src/coreclr/inc/corinfo.h
@@ -673,7 +673,8 @@ enum CorInfoCallConv
CORINFO_CALLCONV_HASTHIS = 0x20,
CORINFO_CALLCONV_EXPLICITTHIS=0x40,
CORINFO_CALLCONV_PARAMTYPE = 0x80, // Passed last. Same as CORINFO_GENERICS_CTXT_FROM_PARAMTYPEARG
- CORINFO_CALLCONV_ASYNCCALL = 0x100, // Is this a call to an async function?
+ CORINFO_CALLCONV_ASYNCCALL = 0x100, // Is this a call with async calling convention?
+
};
// Represents the calling conventions supported with the extensible calling convention syntax
diff --git a/src/coreclr/tools/Common/Compiler/AsyncMethodVariant.cs b/src/coreclr/tools/Common/Compiler/AsyncMethodVariant.cs
new file mode 100644
index 00000000000000..cca4984cacba12
--- /dev/null
+++ b/src/coreclr/tools/Common/Compiler/AsyncMethodVariant.cs
@@ -0,0 +1,90 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Diagnostics;
+using Internal.TypeSystem;
+using Internal.TypeSystem.Ecma;
+
+namespace ILCompiler
+{
+ ///
+ /// MethodDesc that represents async calling convention entrypoint of a Task-returning method.
+ ///
+ public partial class AsyncMethodVariant : MethodDelegator
+ {
+ private MethodSignature _asyncSignature;
+
+ public AsyncMethodVariant(EcmaMethod wrappedMethod)
+ : base(wrappedMethod)
+ {
+ Debug.Assert(wrappedMethod.Signature.ReturnsTaskOrValueTask());
+ }
+
+ public EcmaMethod Target => (EcmaMethod)_wrappedMethod;
+
+ public override MethodSignature Signature
+ {
+ get
+ {
+ return _asyncSignature ?? InitializeSignature();
+ }
+ }
+
+ private MethodSignature InitializeSignature()
+ {
+ var signature = _wrappedMethod.Signature;
+ Debug.Assert(!signature.IsAsyncCall);
+ Debug.Assert(signature.ReturnsTaskOrValueTask());
+ TypeDesc md = signature.ReturnType;
+ MethodSignatureBuilder builder = new MethodSignatureBuilder(signature);
+ builder.ReturnType = md.HasInstantiation ? md.Instantiation[0] : this.Context.GetWellKnownType(WellKnownType.Void);
+ builder.Flags = signature.Flags | MethodSignatureFlags.AsyncCall;
+ return (_asyncSignature = builder.ToSignature());
+ }
+
+ public override MethodDesc GetCanonMethodTarget(CanonicalFormKind kind)
+ {
+ // We should not be calling GetCanonMethodTarget on generic definitions of anything
+ // and this MethodDesc is a generic definition.
+ Debug.Assert(!HasInstantiation && !OwningType.HasInstantiation);
+ return this;
+ }
+
+ public override MethodDesc GetMethodDefinition()
+ {
+ return this;
+ }
+
+ public override MethodDesc GetTypicalMethodDefinition()
+ {
+ return this;
+ }
+
+ public override MethodDesc InstantiateSignature(Instantiation typeInstantiation, Instantiation methodInstantiation)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override string ToString() => $"Async variant: " + _wrappedMethod.ToString();
+
+ protected override int ClassCode => unchecked((int)0xd0fd1c1fu);
+
+ protected override int CompareToImpl(MethodDesc other, TypeSystemComparer comparer)
+ {
+ var asyncOther = (AsyncMethodVariant)other;
+ return comparer.Compare(_wrappedMethod, asyncOther._wrappedMethod);
+ }
+ }
+
+ public static class AsyncMethodVariantExtensions
+ {
+ ///
+ /// Returns true if this MethodDesc is an AsyncMethodVariant, which should not escape the jit interface.
+ ///
+ public static bool IsAsyncVariant(this MethodDesc method)
+ {
+ return method is AsyncMethodVariant;
+ }
+ }
+}
diff --git a/src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Async.cs b/src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Async.cs
new file mode 100644
index 00000000000000..ba594e7f474ea7
--- /dev/null
+++ b/src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.Async.cs
@@ -0,0 +1,44 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Internal.IL;
+using Internal.TypeSystem;
+using Internal.TypeSystem.Ecma;
+
+using Debug = System.Diagnostics.Debug;
+
+namespace ILCompiler
+{
+ public partial class CompilerTypeSystemContext
+ {
+ public MethodDesc GetAsyncVariantMethod(MethodDesc taskReturningMethod)
+ {
+ Debug.Assert(taskReturningMethod.Signature.ReturnsTaskOrValueTask());
+ MethodDesc asyncMetadataMethodDef = taskReturningMethod.GetTypicalMethodDefinition();
+ MethodDesc result = _asyncVariantImplHashtable.GetOrCreateValue((EcmaMethod)asyncMetadataMethodDef);
+
+ if (asyncMetadataMethodDef != taskReturningMethod)
+ {
+ TypeDesc owningType = taskReturningMethod.OwningType;
+ if (owningType.HasInstantiation)
+ result = GetMethodForInstantiatedType(result, (InstantiatedType)owningType);
+
+ if (taskReturningMethod.HasInstantiation)
+ result = GetInstantiatedMethod(result, taskReturningMethod.Instantiation);
+ }
+
+ return result;
+ }
+
+ private sealed class AsyncVariantImplHashtable : LockFreeReaderHashtable
+ {
+ protected override int GetKeyHashCode(EcmaMethod key) => key.GetHashCode();
+ protected override int GetValueHashCode(AsyncMethodVariant value) => value.Target.GetHashCode();
+ protected override bool CompareKeyToValue(EcmaMethod key, AsyncMethodVariant value) => key == value.Target;
+ protected override bool CompareValueToValue(AsyncMethodVariant value1, AsyncMethodVariant value2)
+ => value1.Target == value2.Target;
+ protected override AsyncMethodVariant CreateValueFromKey(EcmaMethod key) => new AsyncMethodVariant(key);
+ }
+ private AsyncVariantImplHashtable _asyncVariantImplHashtable = new AsyncVariantImplHashtable();
+ }
+}
diff --git a/src/coreclr/tools/Common/Compiler/MethodExtensions.cs b/src/coreclr/tools/Common/Compiler/MethodExtensions.cs
index 8943f7b3908a11..71c02d3834ec11 100644
--- a/src/coreclr/tools/Common/Compiler/MethodExtensions.cs
+++ b/src/coreclr/tools/Common/Compiler/MethodExtensions.cs
@@ -1,8 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System;
using ILCompiler.DependencyAnalysis;
-
using Internal.TypeSystem;
using Internal.TypeSystem.Ecma;
@@ -135,5 +135,23 @@ public static bool NotCallableWithoutOwningEEType(this MethodDesc method)
(owningType is not MetadataType mdType || !mdType.IsModuleType) && /* Compiler parks some instance methods on the type */
!method.IsSharedByGenericInstantiations; /* Current impl limitation; can be lifted */
}
+
+ public static bool ReturnsTaskOrValueTask(this MethodSignature method)
+ {
+ TypeDesc ret = method.ReturnType;
+
+ if (ret is MetadataType md
+ && md.Module == method.Context.SystemModule
+ && md.Namespace.SequenceEqual("System.Threading.Tasks"u8))
+ {
+ ReadOnlySpan name = md.Name;
+ if (name.SequenceEqual("Task"u8) || name.SequenceEqual("Task`1"u8)
+ || name.SequenceEqual("ValueTask"u8) || name.SequenceEqual("ValueTask`1"u8))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
}
}
diff --git a/src/coreclr/tools/Common/JitInterface/AsyncMethodDesc.cs b/src/coreclr/tools/Common/JitInterface/AsyncMethodDesc.cs
deleted file mode 100644
index b6584b5588eafb..00000000000000
--- a/src/coreclr/tools/Common/JitInterface/AsyncMethodDesc.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using System.Diagnostics;
-using Internal.TypeSystem;
-
-namespace Internal.JitInterface
-{
- ///
- /// Represents the async-callable (CORINFO_CALLCONV_ASYNCCALL) variant of a Task/ValueTask returning method.
- /// The wrapper should be short‑lived and only used while interacting with the JIT interface.
- ///
- internal sealed class AsyncMethodDesc : MethodDelegator, IJitHashableOnly
- {
- private readonly AsyncMethodDescFactory _factory;
- private readonly int _jitVisibleHashCode;
-
- public MethodDesc Target => _wrappedMethod;
-
- public AsyncMethodDesc(MethodDesc wrappedMethod, AsyncMethodDescFactory factory)
- : base(wrappedMethod)
- {
- Debug.Assert(wrappedMethod.IsTaskReturning());
- _factory = factory;
- // Salt with arbitrary constant so hash space differs from underlying method.
- _jitVisibleHashCode = HashCode.Combine(wrappedMethod.GetHashCode(), 0x51C0A54);
- }
-
- public override MethodDesc GetCanonMethodTarget(CanonicalFormKind kind)
- {
- MethodDesc realCanonTarget = _wrappedMethod.GetCanonMethodTarget(kind);
- if (realCanonTarget != _wrappedMethod)
- return _factory.GetAsyncMethod(realCanonTarget);
- return this;
- }
-
- public override MethodDesc GetMethodDefinition()
- {
- MethodDesc real = _wrappedMethod.GetMethodDefinition();
- if (real != _wrappedMethod)
- return _factory.GetAsyncMethod(real);
- return this;
- }
-
- public override MethodDesc GetTypicalMethodDefinition()
- {
- MethodDesc real = _wrappedMethod.GetTypicalMethodDefinition();
- if (real != _wrappedMethod)
- return _factory.GetAsyncMethod(real);
- return this;
- }
-
- public override MethodDesc InstantiateSignature(Instantiation typeInstantiation, Instantiation methodInstantiation)
- {
- MethodDesc real = _wrappedMethod.InstantiateSignature(typeInstantiation, methodInstantiation);
- if (real != _wrappedMethod)
- return _factory.GetAsyncMethod(real);
- return this;
- }
-
- public override MethodSignature Signature
- {
- get
- {
- MethodSignature wrappedSignature = _wrappedMethod.Signature;
- MetadataType md = (MetadataType)wrappedSignature.ReturnType;
- MethodSignatureBuilder builder = new MethodSignatureBuilder(wrappedSignature);
- builder.ReturnType = md.HasInstantiation ? md.Instantiation[0] : this.Context.GetWellKnownType(WellKnownType.Void);
- builder.Flags = wrappedSignature.Flags | MethodSignatureFlags.AsyncCallConv;
- return builder.ToSignature();
- }
- }
-
-#if !SUPPORT_JIT
- // Same pattern as UnboxingMethodDesc: these should not escape JIT hashing scope.
- protected override int ClassCode => throw new NotImplementedException();
- protected override int CompareToImpl(MethodDesc other, TypeSystemComparer comparer) => throw new NotImplementedException();
- protected override int ComputeHashCode() => _jitVisibleHashCode;
- int IJitHashableOnly.GetJitVisibleHashCode() => _jitVisibleHashCode;
-#else
- int IJitHashableOnly.GetJitVisibleHashCode() => _jitVisibleHashCode;
-#endif
- }
-
- internal static class AsyncMethodDescExtensions
- {
- ///
- /// Returns true if the method returns Task, Task<T>, ValueTask, or ValueTask<T>, otherwise false.
- ///
- public static bool IsTaskReturning(this MethodDesc method)
- {
- TypeDesc ret = method.GetTypicalMethodDefinition().Signature.ReturnType;
-
- if (ret is MetadataType md
- && md.Module == method.Context.SystemModule
- && md.Namespace.SequenceEqual("System.Threading.Tasks"u8))
- {
- ReadOnlySpan name = md.Name;
- if (name.SequenceEqual("Task"u8) || name.SequenceEqual("Task`1"u8)
- || name.SequenceEqual("ValueTask"u8) || name.SequenceEqual("ValueTask`1"u8))
- {
- return true;
- }
- }
- return false;
- }
- }
-}
diff --git a/src/coreclr/tools/Common/JitInterface/AsyncMethodDescFactory.cs b/src/coreclr/tools/Common/JitInterface/AsyncMethodDescFactory.cs
deleted file mode 100644
index 5494807192e078..00000000000000
--- a/src/coreclr/tools/Common/JitInterface/AsyncMethodDescFactory.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using Internal.TypeSystem;
-
-namespace Internal.JitInterface
-{
- internal class AsyncMethodDescFactory : Dictionary
- {
- public AsyncMethodDesc GetAsyncMethod(MethodDesc method)
- {
- if (!TryGetValue(method, out AsyncMethodDesc result))
- {
- result = new AsyncMethodDesc(method, this);
- Add(method, result);
- }
-
- return result;
- }
- }
-}
diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
index 4e574ed7641083..f987e7e637c3e0 100644
--- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
+++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
@@ -877,6 +877,7 @@ private void Get_CORINFO_SIG_INFO(MethodSignature signature, CORINFO_SIG_INFO* s
if (!signature.IsStatic) sig->callConv |= CorInfoCallConv.CORINFO_CALLCONV_HASTHIS;
if (signature.IsExplicitThis) sig->callConv |= CorInfoCallConv.CORINFO_CALLCONV_EXPLICITTHIS;
+ if (signature.IsAsyncCall) sig->callConv |= CorInfoCallConv.CORINFO_CALLCONV_ASYNCCALL;
TypeDesc returnType = signature.ReturnType;
diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs
index ff37fc2f9bc60b..c82c51c4e7d257 100644
--- a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs
+++ b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs
@@ -119,6 +119,7 @@ public unsafe struct CORINFO_SIG_INFO
private uint totalILArgs() { return (uint)(numArgs + (hasImplicitThis() ? 1 : 0)); }
private bool isVarArg() { return ((getCallConv() == CorInfoCallConv.CORINFO_CALLCONV_VARARG) || (getCallConv() == CorInfoCallConv.CORINFO_CALLCONV_NATIVEVARARG)); }
internal bool hasTypeArg() { return ((callConv & CorInfoCallConv.CORINFO_CALLCONV_PARAMTYPE) != 0); }
+ private bool isAsyncCall() { return ((callConv & CorInfoCallConv.CORINFO_CALLCONV_ASYNCCALL) != 0); }
};
//----------------------------------------------------------------------------
@@ -377,6 +378,7 @@ public enum CorInfoCallConv
CORINFO_CALLCONV_HASTHIS = 0x20,
CORINFO_CALLCONV_EXPLICITTHIS = 0x40,
CORINFO_CALLCONV_PARAMTYPE = 0x80, // Passed last. Same as CORINFO_GENERICS_CTXT_FROM_PARAMTYPEARG
+ CORINFO_CALLCONV_ASYNCCALL = 0x100, // Is this a call with async calling convention?
}
// Represents the calling conventions supported with the extensible calling convention syntax
diff --git a/src/coreclr/tools/Common/TypeSystem/Common/MethodDesc.cs b/src/coreclr/tools/Common/TypeSystem/Common/MethodDesc.cs
index 3f53e780d435e5..008371e25ecb58 100644
--- a/src/coreclr/tools/Common/TypeSystem/Common/MethodDesc.cs
+++ b/src/coreclr/tools/Common/TypeSystem/Common/MethodDesc.cs
@@ -23,7 +23,8 @@ public enum MethodSignatureFlags
Static = 0x0010,
ExplicitThis = 0x0020,
- AsyncCallConv = 0x0040,
+
+ AsyncCall = 0x0100,
}
public enum EmbeddedSignatureDataKind
@@ -139,11 +140,11 @@ public bool IsExplicitThis
}
}
- public bool IsAsyncCallConv
+ public bool IsAsyncCall
{
get
{
- return (_flags & MethodSignatureFlags.AsyncCallConv) != 0;
+ return (_flags & MethodSignatureFlags.AsyncCall) != 0;
}
}
diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaMethod.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaMethod.cs
index 09fb19a982fd79..f5ca2eb8710f0e 100644
--- a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaMethod.cs
+++ b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaMethod.cs
@@ -15,6 +15,7 @@ public sealed partial class EcmaMethod : MethodDesc, EcmaModule.IEntityHandleObj
{
private static class MethodFlags
{
+#pragma warning disable IDE0055 // Disable formatting to keep aligned
public const int BasicMetadataCache = 0x00001;
public const int Virtual = 0x00002;
public const int NewSlot = 0x00004;
@@ -28,11 +29,12 @@ private static class MethodFlags
public const int AggressiveOptimization = 0x00400;
public const int NoOptimization = 0x00800;
public const int RequireSecObject = 0x01000;
+ public const int Async = 0x02000;
- public const int AttributeMetadataCache = 0x02000;
- public const int Intrinsic = 0x04000;
- public const int UnmanagedCallersOnly = 0x08000;
- public const int Async = 0x10000;
+ public const int AttributeMetadataCache = 0x04000;
+ public const int Intrinsic = 0x08000;
+ public const int UnmanagedCallersOnly = 0x10000;
+#pragma warning restore IDE0055
};
private EcmaType _type;
diff --git a/src/coreclr/tools/Common/TypeSystem/RuntimeDetermined/MethodForRuntimeDeterminedType.cs b/src/coreclr/tools/Common/TypeSystem/RuntimeDetermined/MethodForRuntimeDeterminedType.cs
index 5f97f7645ea76e..9e6e2b974bd909 100644
--- a/src/coreclr/tools/Common/TypeSystem/RuntimeDetermined/MethodForRuntimeDeterminedType.cs
+++ b/src/coreclr/tools/Common/TypeSystem/RuntimeDetermined/MethodForRuntimeDeterminedType.cs
@@ -39,6 +39,7 @@ internal MethodForRuntimeDeterminedType(MethodDesc typicalMethodDef, RuntimeDete
public override ReadOnlySpan Name => _typicalMethodDef.Name;
public override MethodDesc GetTypicalMethodDefinition() => _typicalMethodDef;
public override Instantiation Instantiation => _typicalMethodDef.Instantiation;
+ public override bool IsAsync => _typicalMethodDef.IsAsync;
public override bool HasCustomAttribute(string attributeNamespace, string attributeName)
{
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodFixupSignature.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodFixupSignature.cs
index c3f3324e0c6ba4..a947bfda7c6016 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodFixupSignature.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodFixupSignature.cs
@@ -22,7 +22,7 @@ public class MethodFixupSignature : Signature
private readonly MethodWithToken _method;
public MethodFixupSignature(
- ReadyToRunFixupKind fixupKind,
+ ReadyToRunFixupKind fixupKind,
MethodWithToken method,
bool isInstantiatingStub)
{
@@ -111,7 +111,7 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
}
MethodWithToken method = _method;
-
+
if (factory.CompilationModuleGroup.VersionsWithMethodBody(method.Method))
{
if (method.Token.TokenType == CorTokenType.mdtMethodSpec)
@@ -154,6 +154,10 @@ public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilde
{
sb.Append(" [INST]"u8);
}
+ if (_method.Method.IsAsyncVariant())
+ {
+ sb.Append(" [ASYNC]"u8);
+ }
sb.Append(": "u8);
_method.AppendMangledName(nameMangler, sb);
}
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodWithGCInfo.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodWithGCInfo.cs
index 4b5f00c661c678..ae83abd5507695 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodWithGCInfo.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodWithGCInfo.cs
@@ -34,6 +34,7 @@ public class MethodWithGCInfo : ObjectNode, IMethodBodyNode, ISymbolDefinitionNo
public MethodWithGCInfo(MethodDesc methodDesc)
{
+ Debug.Assert(!methodDesc.IsUnboxingThunk());
GCInfoNode = new MethodGCInfoNode(this);
_fixups = new List();
_method = methodDesc;
@@ -323,7 +324,7 @@ public void InitializeFrameInfos(FrameInfo[] frameInfos)
else
{
// On x86, fake a single frame info representing the entire method
- _frameInfos = new FrameInfo[]
+ _frameInfos = new FrameInfo[]
{
new FrameInfo((FrameInfoFlags)0, startOffset: 0, endOffset: 0, blobData: Array.Empty())
};
@@ -396,6 +397,9 @@ public void InitializeNonRelocationDependencies(DependencyList dependencies)
public int Offset => 0;
public override bool IsShareable => throw new NotImplementedException();
+
+ public bool AsyncVariant => _method.IsAsyncVariant();
+
public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) => IsEmpty;
public override string ToString() => _method.ToString();
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunTableManager.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunTableManager.cs
index 93e3f3605cb03d..72363e7770d751 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunTableManager.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunTableManager.cs
@@ -112,7 +112,7 @@ public IEnumerable GetCompiledMethods(EcmaModule moduleToEnumerate,
int methodOnlyResult = comparer.Compare(x.Method, y.Method);
// Assert the two sorting techniques produce the same result unless there is a CustomSort applied
- Debug.Assert((nodeComparerResult == methodOnlyResult) ||
+ Debug.Assert((nodeComparerResult == methodOnlyResult) ||
((x is SortableDependencyNode sortableX && sortableX.CustomSort != Int32.MaxValue) ||
(y is SortableDependencyNode sortableY && sortableY.CustomSort != Int32.MaxValue)));
#endif
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IL/ReadyToRunILProvider.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IL/ReadyToRunILProvider.cs
index 6ea7cb2638fedf..d4b9987d6fae87 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IL/ReadyToRunILProvider.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IL/ReadyToRunILProvider.cs
@@ -165,6 +165,14 @@ public override MethodIL GetMethodIL(MethodDesc method)
return result;
}
+ if (method.IsAsync)
+ {
+ // We should not be creating any AsyncMethodVariants yet.
+ // This hasn't been implemented.
+ Debug.Assert(!method.IsAsyncVariant());
+ return null;
+ }
+
// Check to see if there is an override for the EcmaMethodIL. If there is not
// then simply return the EcmaMethodIL. In theory this could call
// CreateCrossModuleInlineableTokensForILBody, but we explicitly do not want
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj
index 5139e35de8b69d..f145cbeae61297 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj
@@ -55,11 +55,13 @@
+
+
@@ -354,12 +356,6 @@
JitInterface\UnboxingMethodDescFactory.cs
-
- JitInterface\AsyncMethodDesc.cs
-
-
- JitInterface\AsyncMethodDesc.cs
-
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
index 2bde41e031f496..6ec6baeded8a95 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
@@ -136,6 +136,7 @@ public class MethodWithToken
public MethodWithToken(MethodDesc method, ModuleToken token, TypeDesc constrainedType, bool unboxing, object context, TypeDesc devirtualizedMethodOwner = null)
{
Debug.Assert(!method.IsUnboxingThunk());
+ Debug.Assert(!method.IsAsyncVariant());
Method = method;
Token = token;
ConstrainedType = constrainedType;
@@ -349,6 +350,8 @@ public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
}
if (Unboxing)
sb.Append("; UNBOXING"u8);
+ if (Method.IsAsyncVariant())
+ sb.Append("; ASYNC"u8);
}
public override string ToString()
@@ -365,6 +368,8 @@ public override string ToString()
debuggingName.Append(Token.ToString());
if (Unboxing)
debuggingName.Append("; UNBOXING");
+ if (Method.IsAsyncVariant())
+ debuggingName.Append("; ASYNC");
return debuggingName.ToString();
}