Skip to content

Commit cd847a6

Browse files
Use new JIT helpers for instantiating and continuation thunks (#121952)
Takes advantage of the new functionality added in #121799.
1 parent d23cb67 commit cd847a6

File tree

10 files changed

+33
-464
lines changed

10 files changed

+33
-464
lines changed

src/coreclr/jit/lower.cpp

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5864,12 +5864,6 @@ GenTree* Lowering::LowerAsyncContinuation(GenTree* asyncCont)
58645864
// 2. In the async transformation, ASYNC_CONTINUATION nodes are inserted
58655865
// after calls to async calls.
58665866
//
5867-
// In the former case, for NativeAOT nothing has marked the previous call
5868-
// as an "async" method. We need to do that here to ensure that the backend
5869-
// knows that the call has a non-standard calling convention that returns
5870-
// an additional GC ref. This requires additional GC tracking that we would
5871-
// otherwise not get.
5872-
//
58735867
GenTree* node = asyncCont;
58745868
while (true)
58755869
{
@@ -5878,13 +5872,7 @@ GenTree* Lowering::LowerAsyncContinuation(GenTree* asyncCont)
58785872

58795873
if (node->IsCall())
58805874
{
5881-
if (!node->AsCall()->IsAsync())
5882-
{
5883-
JITDUMP("Marking the call [%06u] before async continuation [%06u] as an async call\n",
5884-
Compiler::dspTreeID(node), Compiler::dspTreeID(asyncCont));
5885-
node->AsCall()->SetIsAsync(new (comp, CMK_Async) AsyncCallInfo);
5886-
}
5887-
5875+
assert(node->AsCall()->IsAsync());
58885876
BlockRange().Remove(asyncCont);
58895877
BlockRange().InsertAfter(node, asyncCont);
58905878
break;

src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -842,11 +842,6 @@ private void Get_CORINFO_SIG_INFO(MethodDesc method, CORINFO_SIG_INFO* sig, Meth
842842
if (method.IsIntrinsic)
843843
{
844844
// Some intrinsics will beg to differ about the hasHiddenParameter decision
845-
#if !READYTORUN
846-
if (_compilation.TypeSystemContext.IsSpecialUnboxingThunkTargetMethod(method))
847-
hasHiddenParameter = false;
848-
#endif
849-
850845
if (method.IsArrayAddressMethod())
851846
hasHiddenParameter = true;
852847
}

src/coreclr/tools/Common/TypeSystem/IL/Stubs/AsyncResumptionStub.Sorting.cs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,4 @@ protected override int CompareToImpl(MethodDesc other, TypeSystemComparer compar
1515
return comparer.Compare(_targetMethod, ((AsyncResumptionStub)other)._targetMethod);
1616
}
1717
}
18-
19-
internal sealed partial class ExplicitContinuationAsyncMethod : MethodDesc
20-
{
21-
protected override int ClassCode => 0xd076659;
22-
23-
protected override int CompareToImpl(MethodDesc other, TypeSystemComparer comparer)
24-
{
25-
return comparer.Compare(_wrappedMethod, ((ExplicitContinuationAsyncMethod)other)._wrappedMethod);
26-
}
27-
}
2818
}

src/coreclr/tools/Common/TypeSystem/IL/Stubs/AsyncResumptionStub.cs

Lines changed: 11 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,16 @@ public override MethodIL EmitIL()
6060
}
6161
}
6262

63-
if (Context.Target.Architecture != TargetArchitecture.X86)
63+
if (_targetMethod.RequiresInstArg())
6464
{
65-
if (_targetMethod.RequiresInstArg())
66-
{
67-
ilStream.EmitLdc(0);
68-
ilStream.Emit(ILOpcode.conv_i);
69-
}
70-
ilStream.EmitLdArg(0);
65+
ilStream.EmitLdc(0);
66+
ilStream.Emit(ILOpcode.conv_i);
67+
ilStream.Emit(ILOpcode.call, ilEmitter.NewToken(Context.GetCoreLibEntryPoint("System.Runtime.CompilerServices"u8, "RuntimeHelpers"u8, "SetNextCallGenericContext"u8, null)));
7168
}
7269

70+
ilStream.EmitLdArg(0);
71+
ilStream.Emit(ILOpcode.call, ilEmitter.NewToken(Context.GetCoreLibEntryPoint("System.Runtime.CompilerServices"u8, "RuntimeHelpers"u8, "SetNextCallAsyncContinuation"u8, null)));
72+
7373
foreach (var param in _targetMethod.Signature)
7474
{
7575
var local = ilEmitter.NewLocal(param);
@@ -78,24 +78,13 @@ public override MethodIL EmitIL()
7878
ilStream.EmitLdLoc(local);
7979
}
8080

81-
if (Context.Target.Architecture == TargetArchitecture.X86)
82-
{
83-
ilStream.EmitLdArg(0);
84-
if (_targetMethod.RequiresInstArg())
85-
{
86-
ilStream.EmitLdc(0);
87-
ilStream.Emit(ILOpcode.conv_i);
88-
}
89-
}
81+
ilStream.Emit(ILOpcode.call, ilEmitter.NewToken(_targetMethod));
9082

91-
MethodDesc resumingMethod = new ExplicitContinuationAsyncMethod(_targetMethod);
92-
ilStream.Emit(ILOpcode.call, ilEmitter.NewToken(resumingMethod));
93-
94-
bool returnsVoid = resumingMethod.Signature.ReturnType.IsVoid;
83+
bool returnsVoid = _targetMethod.Signature.ReturnType.IsVoid;
9584
ILLocalVariable resultLocal = default;
9685
if (!returnsVoid)
9786
{
98-
resultLocal = ilEmitter.NewLocal(resumingMethod.Signature.ReturnType);
87+
resultLocal = ilEmitter.NewLocal(_targetMethod.Signature.ReturnType);
9988
ilStream.EmitStLoc(resultLocal);
10089
}
10190

@@ -113,7 +102,7 @@ public override MethodIL EmitIL()
113102
ilStream.Emit(ILOpcode.brtrue, doneResult);
114103
ilStream.EmitLdArg(1);
115104
ilStream.EmitLdLoc(resultLocal);
116-
ilStream.Emit(ILOpcode.stobj, ilEmitter.NewToken(resumingMethod.Signature.ReturnType));
105+
ilStream.Emit(ILOpcode.stobj, ilEmitter.NewToken(_targetMethod.Signature.ReturnType));
117106
ilStream.EmitLabel(doneResult);
118107
}
119108
ilStream.EmitLdLoc(newContinuationLocal);
@@ -122,135 +111,4 @@ public override MethodIL EmitIL()
122111
return ilEmitter.Link(this);
123112
}
124113
}
125-
126-
/// <summary>
127-
/// A dummy method used to tell the jit that we want to explicitly pass the hidden Continuation parameter
128-
/// as well as the generic context parameter (if any) for async resumption methods.
129-
/// This method should be marked IsAsync=false and HasInstantiation=false. These are defaults
130-
/// for MethodDesc and so aren't explicitly set in the code below.
131-
/// </summary>
132-
internal sealed partial class ExplicitContinuationAsyncMethod : MethodDesc
133-
{
134-
private MethodSignature _signature;
135-
private readonly MethodDesc _wrappedMethod;
136-
private readonly MethodDesc _typicalDefinition;
137-
138-
public ExplicitContinuationAsyncMethod(MethodDesc target)
139-
{
140-
_wrappedMethod = target;
141-
142-
MethodDesc targetTypicalDefinition = target.GetTypicalMethodDefinition();
143-
if (targetTypicalDefinition != target)
144-
_typicalDefinition = new ExplicitContinuationAsyncMethod(targetTypicalDefinition);
145-
else
146-
_typicalDefinition = this;
147-
}
148-
149-
public MethodDesc Target => _wrappedMethod;
150-
151-
/// <summary>
152-
/// To explicitly pass the hidden parameters for async resumption methods,
153-
/// we need to add explicit Continuation and generic context parameters to the signature.
154-
/// </summary>
155-
private MethodSignature InitializeSignature()
156-
{
157-
// Async methods have an implicit Continuation parameter
158-
// The order of parameters depends on the architecture
159-
// non-x86: this?, genericCtx?, continuation, params...
160-
// x86: this?, params, continuation, genericCtx?
161-
// To make the jit pass arguments in this order, we can add the continuation parameter
162-
// at the end for x86 and at the beginning for other architectures.
163-
// The 'this' parameter and generic context parameter (if any) can be handled by the jit.
164-
165-
var parameters = new TypeDesc[_wrappedMethod.Signature.Length + 1 + (_wrappedMethod.RequiresInstArg() ? 1 : 0)];
166-
167-
TypeDesc continuation = Context.SystemModule.GetKnownType("System.Runtime.CompilerServices"u8, "Continuation"u8);
168-
if (Context.Target.Architecture == TargetArchitecture.X86)
169-
{
170-
int i = 0;
171-
for (; i < _wrappedMethod.Signature.Length; i++)
172-
{
173-
parameters[i] = _wrappedMethod.Signature[i];
174-
}
175-
parameters[i++] = continuation;
176-
if (_wrappedMethod.RequiresInstArg())
177-
{
178-
parameters[i] = Context.GetWellKnownType(WellKnownType.Void).MakePointerType();
179-
}
180-
}
181-
else
182-
{
183-
int i = 0;
184-
if (_wrappedMethod.RequiresInstArg())
185-
{
186-
parameters[i++] = Context.GetWellKnownType(WellKnownType.Void).MakePointerType();
187-
}
188-
parameters[i++] = continuation;
189-
foreach (var param in _wrappedMethod.Signature)
190-
{
191-
parameters[i++] = param;
192-
}
193-
}
194-
// Get the return type from the Task-returning variant
195-
TypeDesc returnType;
196-
if (_wrappedMethod is AsyncMethodVariant variant)
197-
{
198-
Debug.Assert(variant.Target.Signature.ReturnsTaskOrValueTask());
199-
if (variant.Target.Signature.ReturnType is { HasInstantiation: true } wrappedReturnType)
200-
{
201-
returnType = wrappedReturnType.Instantiation[0];
202-
}
203-
else
204-
{
205-
returnType = Context.GetWellKnownType(WellKnownType.Void);
206-
}
207-
}
208-
else
209-
{
210-
// AsyncExplicitImpl
211-
returnType = _wrappedMethod.Signature.ReturnType;
212-
}
213-
214-
return _signature = new MethodSignature(
215-
_wrappedMethod.Signature.Flags,
216-
0,
217-
returnType,
218-
parameters);
219-
}
220-
221-
public override bool HasCustomAttribute(string attributeNamespace, string attributeName) => throw new NotImplementedException();
222-
223-
public override MethodSignature Signature
224-
{
225-
get
226-
{
227-
if (_signature is null)
228-
return InitializeSignature();
229-
230-
return _signature;
231-
}
232-
}
233-
234-
public override string DiagnosticName => $"ExplicitContinuationAsyncMethod({_wrappedMethod.DiagnosticName})";
235-
236-
public override TypeDesc OwningType => _wrappedMethod.OwningType;
237-
238-
public override TypeSystemContext Context => _wrappedMethod.Context;
239-
240-
public override bool IsInternalCall => true;
241-
242-
public override MethodDesc GetTypicalMethodDefinition() => _typicalDefinition;
243-
}
244-
245-
public static class AsyncResumptionStubExtensions
246-
{
247-
public static bool IsExplicitContinuationAsyncMethod(this MethodDesc method)
248-
{
249-
return method is ExplicitContinuationAsyncMethod;
250-
}
251-
public static MethodDesc GetExplicitContinuationAsyncMethodTarget(this MethodDesc method)
252-
{
253-
return ((ExplicitContinuationAsyncMethod)method).Target;
254-
}
255-
}
256114
}

0 commit comments

Comments
 (0)