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(); }