Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

namespace System.Runtime.CompilerServices
{
internal struct ExecutionAndSyncBlockStore
internal struct AsyncContextsSnapshot
{
// Store current ExecutionContext and SynchronizationContext as "previousXxx".
// This allows us to restore them and undo any Context changes made in stateMachine.MoveNext
Expand Down Expand Up @@ -199,7 +199,7 @@ public static partial class AsyncHelpers
private static Continuation? AsyncCallContinuation() => throw new UnreachableException();

// Used during suspensions to hold the continuation chain and on what we are waiting.
// Methods like FinalizeTaskReturningThunk will unlink the state and wrap into a Task.
// Methods like CreateAsyncMethodTask will unlink the state and wrap into a Task.
private struct RuntimeAsyncAwaitState
{
public Continuation? SentinelContinuation;
Expand Down Expand Up @@ -447,7 +447,7 @@ internal void HandleSuspended()
[StackTraceHidden]
private unsafe void DispatchContinuations()
{
ExecutionAndSyncBlockStore contexts = default;
AsyncContextsSnapshot contexts = default;
contexts.Push();

AsyncDispatcherInfo asyncDispatcherInfo;
Expand Down Expand Up @@ -629,30 +629,30 @@ private bool QueueContinuationFollowUpActionIfNecessary(Continuation continuatio
#pragma warning disable CA1859
// When a Task-returning thunk gets a continuation result
// it calls here to make a Task that awaits on the current async state.
private static Task<T?> FinalizeTaskReturningThunk<T>()
private static Task<T?> CreateAsyncMethodTask<T>()
{
RuntimeAsyncTask<T?> result = new();
result.HandleSuspended();
return result;
}

private static Task FinalizeTaskReturningThunk()
private static Task CreateAsyncMethodTask()
{
RuntimeAsyncTask<VoidTaskResult> result = new();
result.HandleSuspended();
return result;
}

private static ValueTask<T?> FinalizeValueTaskReturningThunk<T>()
private static ValueTask<T?> CreateAsyncMethodValueTask<T>()
{
// We only come to these methods in the expensive case (already
// suspended), so ValueTask optimization here is not relevant.
return new ValueTask<T?>(FinalizeTaskReturningThunk<T>());
return new ValueTask<T?>(CreateAsyncMethodTask<T>());
}

private static ValueTask FinalizeValueTaskReturningThunk()
private static ValueTask CreateAsyncMethodValueTask()
{
return new ValueTask(FinalizeTaskReturningThunk());
return new ValueTask(CreateAsyncMethodTask());
}

private static Task<T?> TaskFromException<T>(Exception ex)
Expand Down Expand Up @@ -788,14 +788,14 @@ private static void CaptureContinuationContext(ref object continuationContext, r
}

[StackTraceHidden]
internal static T CompletedTaskResult<T>(Task<T> task)
internal static T GetCompletedTaskResult<T>(Task<T> task)
{
TaskAwaiter.ValidateEnd(task);
return task.ResultOnSuccess;
}

[StackTraceHidden]
internal static void CompletedTask(Task task)
internal static void ValidateCompletedTask(Task task)
{
TaskAwaiter.ValidateEnd(task);
}
Expand Down
30 changes: 15 additions & 15 deletions src/coreclr/tools/Common/TypeSystem/IL/Stubs/AsyncThunks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static class AsyncThunkILEmitter
// Emits a thunk that wraps an async method to return a Task or ValueTask.
// The thunk calls the async method, and if it completes synchronously,
// it returns a completed Task/ValueTask. If the async method suspends,
// it calls FinalizeTaskReturningThunk/FinalizeValueTaskReturningThunk method to get the Task/ValueTask.
// it calls CreateAsyncMethodTask/CreateAsyncMethodValueTask method to get the Task/ValueTask.

// The emitted code matches method EmitTaskReturningThunk in CoreCLR VM.
public static MethodIL EmitTaskReturningThunk(MethodDesc taskReturningMethod, MethodDesc asyncMethod)
Expand All @@ -38,15 +38,15 @@ public static MethodIL EmitTaskReturningThunk(MethodDesc taskReturningMethod, Me

ILLocalVariable returnTaskLocal = emitter.NewLocal(returnType);

TypeDesc executionAndSyncBlockStoreType = context.SystemModule.GetKnownType("System.Runtime.CompilerServices"u8, "ExecutionAndSyncBlockStore"u8);
ILLocalVariable executionAndSyncBlockStoreLocal = emitter.NewLocal(executionAndSyncBlockStoreType);
TypeDesc asyncContextsSnapshotType = context.SystemModule.GetKnownType("System.Runtime.CompilerServices"u8, "AsyncContextsSnapshot"u8);
ILLocalVariable asyncContextsSnapshotLocal = emitter.NewLocal(asyncContextsSnapshotType);

ILCodeLabel returnTaskLabel = emitter.NewCodeLabel();
ILCodeLabel suspendedLabel = emitter.NewCodeLabel();
ILCodeLabel finishedLabel = emitter.NewCodeLabel();

codestream.EmitLdLoca(executionAndSyncBlockStoreLocal);
codestream.Emit(ILOpcode.call, emitter.NewToken(executionAndSyncBlockStoreType.GetKnownMethod("Push"u8, null)));
codestream.EmitLdLoca(asyncContextsSnapshotLocal);
codestream.Emit(ILOpcode.call, emitter.NewToken(asyncContextsSnapshotType.GetKnownMethod("Push"u8, null)));

ILExceptionRegionBuilder tryFinallyRegion = emitter.NewFinallyRegion();
{
Expand Down Expand Up @@ -188,36 +188,36 @@ public static MethodIL EmitTaskReturningThunk(MethodDesc taskReturningMethod, Me

codestream.EmitLabel(suspendedLabel);

MethodDesc finalizeTaskReturningThunkMd;
MethodDesc createAsyncMethodTaskMd;
if (logicalReturnType != null)
{
MethodSignature finalizeReturningThunkSignature = new MethodSignature(
MethodSignature createMethodTaskSignature = new MethodSignature(
MethodSignatureFlags.Static,
genericParameterCount: 1,
returnType: ((MetadataType)returnType.GetTypeDefinition()).MakeInstantiatedType(context.GetSignatureVariable(0, true)),
parameters: Array.Empty<TypeDesc>()
);

finalizeTaskReturningThunkMd = context.SystemModule
createAsyncMethodTaskMd = context.SystemModule
.GetKnownType("System.Runtime.CompilerServices"u8, "AsyncHelpers"u8)
.GetKnownMethod(isValueTask ? "FinalizeValueTaskReturningThunk"u8 : "FinalizeTaskReturningThunk"u8, finalizeReturningThunkSignature)
.GetKnownMethod(isValueTask ? "CreateAsyncMethodValueTask"u8 : "CreateAsyncMethodTask"u8, createMethodTaskSignature)
.MakeInstantiatedMethod(new Instantiation(logicalReturnType));
}
else
{
MethodSignature finalizeReturningThunkSignature = new MethodSignature(
MethodSignature createMethodTaskSignature = new MethodSignature(
MethodSignatureFlags.Static,
genericParameterCount: 0,
returnType: returnType,
parameters: Array.Empty<TypeDesc>()
);

finalizeTaskReturningThunkMd = context.SystemModule
createAsyncMethodTaskMd = context.SystemModule
.GetKnownType("System.Runtime.CompilerServices"u8, "AsyncHelpers"u8)
.GetKnownMethod(isValueTask ? "FinalizeValueTaskReturningThunk"u8 : "FinalizeTaskReturningThunk"u8, finalizeReturningThunkSignature);
.GetKnownMethod(isValueTask ? "CreateAsyncMethodValueTask"u8 : "CreateAsyncMethodTask"u8, createMethodTaskSignature);
}

codestream.Emit(ILOpcode.call, emitter.NewToken(finalizeTaskReturningThunkMd));
codestream.Emit(ILOpcode.call, emitter.NewToken(createAsyncMethodTaskMd));
codestream.EmitStLoc(returnTaskLocal);
codestream.Emit(ILOpcode.leave, returnTaskLabel);

Expand All @@ -227,8 +227,8 @@ public static MethodIL EmitTaskReturningThunk(MethodDesc taskReturningMethod, Me
{
codestream.BeginHandler(tryFinallyRegion);

codestream.EmitLdLoca(executionAndSyncBlockStoreLocal);
codestream.Emit(ILOpcode.call, emitter.NewToken(executionAndSyncBlockStoreType.GetKnownMethod("Pop"u8, null)));
codestream.EmitLdLoca(asyncContextsSnapshotLocal);
codestream.Emit(ILOpcode.call, emitter.NewToken(asyncContextsSnapshotType.GetKnownMethod("Pop"u8, null)));
codestream.Emit(ILOpcode.endfinally);
codestream.EndHandler(tryFinallyRegion);
}
Expand Down
44 changes: 22 additions & 22 deletions src/coreclr/vm/asyncthunks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ void MethodDesc::EmitTaskReturningThunk(MethodDesc* pAsyncCallVariant, MetaSig&

// Emits roughly the following code:
//
// ExecutionAndSyncBlockStore store = default;
// AsyncContextsSnapshot store = default;
// store.Push();
// try
// {
Expand All @@ -77,7 +77,7 @@ void MethodDesc::EmitTaskReturningThunk(MethodDesc* pAsyncCallVariant, MetaSig&
// if (StubHelpers.AsyncCallContinuation() == null)
// return Task.FromResult(result);
//
// return FinalizeTaskReturningThunk();
// return CreateAsyncMethodTask();
// }
// catch (Exception ex)
// {
Expand Down Expand Up @@ -105,15 +105,15 @@ void MethodDesc::EmitTaskReturningThunk(MethodDesc* pAsyncCallVariant, MetaSig&

LocalDesc returnLocalDesc(thTaskRet);
DWORD returnTaskLocal = pCode->NewLocal(returnLocalDesc);
LocalDesc executionAndSyncBlockStoreLocalDesc(CoreLibBinder::GetClass(CLASS__EXECUTIONANDSYNCBLOCKSTORE));
DWORD executionAndSyncBlockStoreLocal = pCode->NewLocal(executionAndSyncBlockStoreLocalDesc);
LocalDesc asyncContextsSnapshotLocalDesc(CoreLibBinder::GetClass(CLASS__ASYNCCONTEXTSSNAPSHOT));
DWORD asyncContextsSnapshotLocal = pCode->NewLocal(asyncContextsSnapshotLocalDesc);

ILCodeLabel* returnTaskLabel = pCode->NewCodeLabel();
ILCodeLabel* suspendedLabel = pCode->NewCodeLabel();
ILCodeLabel* finishedLabel = pCode->NewCodeLabel();

pCode->EmitLDLOCA(executionAndSyncBlockStoreLocal);
pCode->EmitCALL(pCode->GetToken(CoreLibBinder::GetMethod(METHOD__EXECUTIONANDSYNCBLOCKSTORE__PUSH)), 1, 0);
pCode->EmitLDLOCA(asyncContextsSnapshotLocal);
pCode->EmitCALL(pCode->GetToken(CoreLibBinder::GetMethod(METHOD__ASYNCCONTEXTSSNAPSHOT__PUSH)), 1, 0);

{
pCode->BeginTryBlock();
Expand Down Expand Up @@ -257,28 +257,28 @@ void MethodDesc::EmitTaskReturningThunk(MethodDesc* pAsyncCallVariant, MetaSig&

pCode->EmitLabel(suspendedLabel);

int finalizeTaskReturningThunkToken;
int createAsyncMethodTaskToken;
if (logicalResultLocal != UINT_MAX)
{
MethodDesc* md;
if (isValueTask)
md = CoreLibBinder::GetMethod(METHOD__ASYNC_HELPERS__FINALIZE_VALUETASK_RETURNING_THUNK_1);
md = CoreLibBinder::GetMethod(METHOD__ASYNC_HELPERS__CREATE_ASYNC_METHOD_VALUE_TASK_1);
else
md = CoreLibBinder::GetMethod(METHOD__ASYNC_HELPERS__FINALIZE_TASK_RETURNING_THUNK_1);
md = CoreLibBinder::GetMethod(METHOD__ASYNC_HELPERS__CREATE_ASYNC_METHOD_TASK_1);

md = FindOrCreateAssociatedMethodDesc(md, md->GetMethodTable(), FALSE, Instantiation(&thLogicalRetType, 1), FALSE);
finalizeTaskReturningThunkToken = GetTokenForGenericMethodCallWithAsyncReturnType(pCode, md);
createAsyncMethodTaskToken = GetTokenForGenericMethodCallWithAsyncReturnType(pCode, md);
}
else
{
MethodDesc* md;
if (isValueTask)
md = CoreLibBinder::GetMethod(METHOD__ASYNC_HELPERS__FINALIZE_VALUETASK_RETURNING_THUNK);
md = CoreLibBinder::GetMethod(METHOD__ASYNC_HELPERS__CREATE_ASYNC_METHOD_VALUE_TASK);
else
md = CoreLibBinder::GetMethod(METHOD__ASYNC_HELPERS__FINALIZE_TASK_RETURNING_THUNK);
finalizeTaskReturningThunkToken = pCode->GetToken(md);
md = CoreLibBinder::GetMethod(METHOD__ASYNC_HELPERS__CREATE_ASYNC_METHOD_TASK);
createAsyncMethodTaskToken = pCode->GetToken(md);
}
pCode->EmitCALL(finalizeTaskReturningThunkToken, 0, 1);
pCode->EmitCALL(createAsyncMethodTaskToken, 0, 1);
pCode->EmitSTLOC(returnTaskLocal);
pCode->EmitLEAVE(returnTaskLabel);

Expand All @@ -287,8 +287,8 @@ void MethodDesc::EmitTaskReturningThunk(MethodDesc* pAsyncCallVariant, MetaSig&
//
{
pCode->BeginFinallyBlock();
pCode->EmitLDLOCA(executionAndSyncBlockStoreLocal);
pCode->EmitCALL(pCode->GetToken(CoreLibBinder::GetMethod(METHOD__EXECUTIONANDSYNCBLOCKSTORE__POP)), 1, 0);
pCode->EmitLDLOCA(asyncContextsSnapshotLocal);
pCode->EmitCALL(pCode->GetToken(CoreLibBinder::GetMethod(METHOD__ASYNCCONTEXTSSNAPSHOT__POP)), 1, 0);
pCode->EmitENDFINALLY();
pCode->EndFinallyBlock();
}
Expand Down Expand Up @@ -444,7 +444,7 @@ void MethodDesc::EmitAsyncMethodThunk(MethodDesc* pTaskReturningVariant, MetaSig
// // Magic function which will suspend the current run of async methods
// AsyncHelpers.TransparentAwait(task);
// }
// return AsyncHelpers.CompletedTaskResult(task);
// return AsyncHelpers.GetCompletedTaskResult(task);
// }

// For ValueTask:
Expand Down Expand Up @@ -604,17 +604,17 @@ void MethodDesc::EmitAsyncMethodThunk(MethodDesc* pTaskReturningVariant, MetaSig
{
pMTTask = CoreLibBinder::GetClass(CLASS__TASK);

MethodDesc* pMDCompletedTask = CoreLibBinder::GetMethod(METHOD__ASYNC_HELPERS__COMPLETED_TASK);
completedTaskResultToken = pCode->GetToken(pMDCompletedTask);
MethodDesc* pMDValidateCompletedTask = CoreLibBinder::GetMethod(METHOD__ASYNC_HELPERS__VALIDATE_COMPLETED_TASK);
completedTaskResultToken = pCode->GetToken(pMDValidateCompletedTask);
}
else
{
MethodTable* pMTTaskOpen = CoreLibBinder::GetClass(CLASS__TASK_1);
pMTTask = ClassLoader::LoadGenericInstantiationThrowing(pMTTaskOpen->GetModule(), pMTTaskOpen->GetCl(), Instantiation(&thLogicalRetType, 1)).GetMethodTable();

MethodDesc* pMDCompletedTaskResult = CoreLibBinder::GetMethod(METHOD__ASYNC_HELPERS__COMPLETED_TASK_RESULT);
pMDCompletedTaskResult = FindOrCreateAssociatedMethodDesc(pMDCompletedTaskResult, pMDCompletedTaskResult->GetMethodTable(), FALSE, Instantiation(&thLogicalRetType, 1), FALSE);
completedTaskResultToken = GetTokenForGenericMethodCallWithAsyncReturnType(pCode, pMDCompletedTaskResult);
MethodDesc* pMDGetCompletedTaskResult = CoreLibBinder::GetMethod(METHOD__ASYNC_HELPERS__GET_COMPLETED_TASK_RESULT);
pMDGetCompletedTaskResult = FindOrCreateAssociatedMethodDesc(pMDGetCompletedTaskResult, pMDGetCompletedTaskResult->GetMethodTable(), FALSE, Instantiation(&thLogicalRetType, 1), FALSE);
completedTaskResultToken = GetTokenForGenericMethodCallWithAsyncReturnType(pCode, pMDGetCompletedTaskResult);
}

LocalDesc taskLocalDesc(pMTTask);
Expand Down
18 changes: 9 additions & 9 deletions src/coreclr/vm/corelib.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,9 +673,9 @@ DEFINE_CLASS(RESOURCE_MANAGER, Resources, ResourceManager)
DEFINE_CLASS(RTFIELD, Reflection, RtFieldInfo)
DEFINE_METHOD(RTFIELD, GET_FIELDESC, GetFieldDesc, IM_RetIntPtr)

DEFINE_CLASS(EXECUTIONANDSYNCBLOCKSTORE, CompilerServices, ExecutionAndSyncBlockStore)
DEFINE_METHOD(EXECUTIONANDSYNCBLOCKSTORE, PUSH, Push, NoSig)
DEFINE_METHOD(EXECUTIONANDSYNCBLOCKSTORE, POP, Pop, NoSig)
DEFINE_CLASS(ASYNCCONTEXTSSNAPSHOT, CompilerServices, AsyncContextsSnapshot)
DEFINE_METHOD(ASYNCCONTEXTSSNAPSHOT, PUSH, Push, NoSig)
DEFINE_METHOD(ASYNCCONTEXTSSNAPSHOT, POP, Pop, NoSig)

DEFINE_CLASS(RUNTIME_HELPERS, CompilerServices, RuntimeHelpers)
DEFINE_METHOD(RUNTIME_HELPERS, IS_BITWISE_EQUATABLE, IsBitwiseEquatable, NoSig)
Expand All @@ -696,19 +696,19 @@ DEFINE_METHOD(ASYNC_HELPERS, ALLOC_CONTINUATION, AllocContinuation,
DEFINE_METHOD(ASYNC_HELPERS, ALLOC_CONTINUATION_METHOD, AllocContinuationMethod, NoSig)
DEFINE_METHOD(ASYNC_HELPERS, ALLOC_CONTINUATION_CLASS, AllocContinuationClass, NoSig)

DEFINE_METHOD(ASYNC_HELPERS, FINALIZE_TASK_RETURNING_THUNK, FinalizeTaskReturningThunk, SM_RetTask)
DEFINE_METHOD(ASYNC_HELPERS, FINALIZE_TASK_RETURNING_THUNK_1, FinalizeTaskReturningThunk, GM_RetTaskOfT)
DEFINE_METHOD(ASYNC_HELPERS, FINALIZE_VALUETASK_RETURNING_THUNK, FinalizeValueTaskReturningThunk, SM_RetValueTask)
DEFINE_METHOD(ASYNC_HELPERS, FINALIZE_VALUETASK_RETURNING_THUNK_1, FinalizeValueTaskReturningThunk, GM_RetValueTaskOfT)
DEFINE_METHOD(ASYNC_HELPERS, CREATE_ASYNC_METHOD_TASK, CreateAsyncMethodTask, SM_RetTask)
DEFINE_METHOD(ASYNC_HELPERS, CREATE_ASYNC_METHOD_TASK_1, CreateAsyncMethodTask, GM_RetTaskOfT)
DEFINE_METHOD(ASYNC_HELPERS, CREATE_ASYNC_METHOD_VALUE_TASK, CreateAsyncMethodValueTask, SM_RetValueTask)
DEFINE_METHOD(ASYNC_HELPERS, CREATE_ASYNC_METHOD_VALUE_TASK_1, CreateAsyncMethodValueTask, GM_RetValueTaskOfT)

DEFINE_METHOD(ASYNC_HELPERS, TASK_FROM_EXCEPTION, TaskFromException, SM_Exception_RetTask)
DEFINE_METHOD(ASYNC_HELPERS, TASK_FROM_EXCEPTION_1, TaskFromException, GM_Exception_RetTaskOfT)
DEFINE_METHOD(ASYNC_HELPERS, VALUETASK_FROM_EXCEPTION, ValueTaskFromException, SM_Exception_RetValueTask)
DEFINE_METHOD(ASYNC_HELPERS, VALUETASK_FROM_EXCEPTION_1, ValueTaskFromException, GM_Exception_RetValueTaskOfT)

DEFINE_METHOD(ASYNC_HELPERS, TRANSPARENT_AWAIT, TransparentAwait, NoSig)
DEFINE_METHOD(ASYNC_HELPERS, COMPLETED_TASK_RESULT, CompletedTaskResult, NoSig)
DEFINE_METHOD(ASYNC_HELPERS, COMPLETED_TASK, CompletedTask, NoSig)
DEFINE_METHOD(ASYNC_HELPERS, GET_COMPLETED_TASK_RESULT, GetCompletedTaskResult, NoSig)
DEFINE_METHOD(ASYNC_HELPERS, VALIDATE_COMPLETED_TASK, ValidateCompletedTask, NoSig)
DEFINE_METHOD(ASYNC_HELPERS, CAPTURE_EXECUTION_CONTEXT, CaptureExecutionContext, NoSig)
DEFINE_METHOD(ASYNC_HELPERS, RESTORE_EXECUTION_CONTEXT, RestoreExecutionContext, NoSig)
DEFINE_METHOD(ASYNC_HELPERS, CAPTURE_CONTINUATION_CONTEXT, CaptureContinuationContext, NoSig)
Expand Down
Loading