diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.CoreCLR.cs index 19ea178f6bf1f9..79deaf08a0f6c7 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.CoreCLR.cs @@ -144,12 +144,20 @@ public ref byte GetResultStorageOrNull() public static partial class AsyncHelpers { - // This is the "magic" method on wich other "Await" methods are built. + // This is the "magic" method on which other "Await" methods are built. // Calling this from an Async method returns the continuation to the caller thus // explicitly initiates suspension. [Intrinsic] private static void AsyncSuspend(Continuation continuation) => throw new UnreachableException(); + // An intrinsic that provides access to continuations produced by Async calls. + // Calling this after an Async method call returns: + // * `null` if the call has completed synchronously, or + // * a continuation object if the call requires suspension. + // In this case the formal result of the call is undefined. + [Intrinsic] + 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. private struct RuntimeAsyncAwaitState diff --git a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs index acb629e66e3662..6d61edd19ebc4a 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs @@ -1610,9 +1610,6 @@ internal static void MulticastDebuggerTraceHelper(object o, int count) [Intrinsic] internal static IntPtr NextCallReturnAddress() => throw new UnreachableException(); // Unconditionally expanded intrinsic - - [Intrinsic] - internal static Continuation? AsyncCallContinuation() => throw new UnreachableException(); // Unconditionally expanded intrinsic } // class StubHelpers #if FEATURE_COMINTEROP diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index fe620f6f332b87..b9d49d5655f500 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -2265,7 +2265,7 @@ bool GenTreeCall::HasSideEffects(Compiler* compiler, bool ignoreExceptions, bool // those cases the JIT does not know (and does not need to know) which arg is // the async continuation. // -// The VM also uses the StubHelpers.AsyncCallContinuation() intrinsic in the +// The VM also uses the AsyncHelpers.AsyncCallContinuation() intrinsic in the // stubs discussed above. The JIT must take care in those cases to still mark // the preceding call as an async call; this is required for correct LSRA // behavior and GC reporting around the returned async continuation. This is diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 42dbb08ee7043f..f7915a7b98ef61 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -3323,7 +3323,7 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd, return new (this, GT_LABEL) GenTree(GT_LABEL, TYP_I_IMPL); } - if (ni == NI_System_StubHelpers_AsyncCallContinuation) + if (ni == NI_System_Runtime_CompilerServices_AsyncHelpers_AsyncCallContinuation) { GenTree* node = new (this, GT_ASYNC_CONTINUATION) GenTree(GT_ASYNC_CONTINUATION, TYP_REF); node->SetHasOrderingSideEffect(); @@ -10872,6 +10872,10 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) { result = NI_System_Runtime_CompilerServices_AsyncHelpers_Await; } + else if (strcmp(methodName, "AsyncCallContinuation") == 0) + { + result = NI_System_Runtime_CompilerServices_AsyncHelpers_AsyncCallContinuation; + } } else if (strcmp(className, "StaticsHelpers") == 0) { @@ -11129,10 +11133,6 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) { result = NI_System_StubHelpers_NextCallReturnAddress; } - else if (strcmp(methodName, "AsyncCallContinuation") == 0) - { - result = NI_System_StubHelpers_AsyncCallContinuation; - } } } else if (strcmp(namespaceName, "Text") == 0) diff --git a/src/coreclr/jit/namedintrinsiclist.h b/src/coreclr/jit/namedintrinsiclist.h index aa56003f25acc1..e0c346870de084 100644 --- a/src/coreclr/jit/namedintrinsiclist.h +++ b/src/coreclr/jit/namedintrinsiclist.h @@ -107,7 +107,6 @@ enum NamedIntrinsic : unsigned short NI_System_RuntimeType_get_TypeHandle, NI_System_StubHelpers_GetStubContext, NI_System_StubHelpers_NextCallReturnAddress, - NI_System_StubHelpers_AsyncCallContinuation, NI_Array_Address, NI_Array_Get, @@ -126,6 +125,7 @@ enum NamedIntrinsic : unsigned short NI_System_Runtime_CompilerServices_AsyncHelpers_AsyncSuspend, NI_System_Runtime_CompilerServices_AsyncHelpers_Await, + NI_System_Runtime_CompilerServices_AsyncHelpers_AsyncCallContinuation, NI_System_Runtime_CompilerServices_StaticsHelpers_VolatileReadAsByref, diff --git a/src/coreclr/vm/asyncthunks.cpp b/src/coreclr/vm/asyncthunks.cpp index 519daeefeed193..0f92fe053f734a 100644 --- a/src/coreclr/vm/asyncthunks.cpp +++ b/src/coreclr/vm/asyncthunks.cpp @@ -190,7 +190,7 @@ void MethodDesc::EmitTaskReturningThunk(MethodDesc* pAsyncOtherVariant, MetaSig& if (logicalResultLocal != UINT_MAX) pCode->EmitSTLOC(logicalResultLocal); - pCode->EmitCALL(METHOD__STUBHELPERS__ASYNC_CALL_CONTINUATION, 0, 1); + pCode->EmitCALL(METHOD__ASYNC_HELPERS__ASYNC_CALL_CONTINUATION, 0, 1); pCode->EmitBRFALSE(finishedLabel); pCode->EmitLEAVE(suspendedLabel); diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index e0cde61d373d8e..ecc8976103d7e5 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -747,8 +747,9 @@ DEFINE_METHOD(ASYNC_HELPERS, COMPLETED_TASK, CompletedTask, NoSi 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) -DEFINE_METHOD(ASYNC_HELPERS, CAPTURE_CONTEXTS, CaptureContexts, NoSig) -DEFINE_METHOD(ASYNC_HELPERS, RESTORE_CONTEXTS, RestoreContexts, NoSig) +DEFINE_METHOD(ASYNC_HELPERS, CAPTURE_CONTEXTS, CaptureContexts, NoSig) +DEFINE_METHOD(ASYNC_HELPERS, RESTORE_CONTEXTS, RestoreContexts, NoSig) +DEFINE_METHOD(ASYNC_HELPERS, ASYNC_CALL_CONTINUATION, AsyncCallContinuation, NoSig) #ifdef TARGET_BROWSER DEFINE_METHOD(ASYNC_HELPERS, HANDLE_ASYNC_ENTRYPOINT, HandleAsyncEntryPoint, SM_TaskOfInt_RetInt) @@ -1098,7 +1099,6 @@ DEFINE_METHOD(STUBHELPERS, VALIDATE_BYREF, Validate DEFINE_METHOD(STUBHELPERS, GET_STUB_CONTEXT, GetStubContext, SM_RetIntPtr) DEFINE_METHOD(STUBHELPERS, LOG_PINNED_ARGUMENT, LogPinnedArgument, SM_IntPtr_IntPtr_RetVoid) DEFINE_METHOD(STUBHELPERS, NEXT_CALL_RETURN_ADDRESS, NextCallReturnAddress, SM_RetIntPtr) -DEFINE_METHOD(STUBHELPERS, ASYNC_CALL_CONTINUATION, AsyncCallContinuation, SM_RetContinuation) DEFINE_METHOD(STUBHELPERS, SAFE_HANDLE_ADD_REF, SafeHandleAddRef, SM_SafeHandle_RefBool_RetIntPtr) DEFINE_METHOD(STUBHELPERS, SAFE_HANDLE_RELEASE, SafeHandleRelease, SM_SafeHandle_RetVoid) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 22707566d309a2..f6902fbc24f91e 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -14763,7 +14763,7 @@ CORINFO_METHOD_HANDLE CEEJitInfo::getAsyncResumptionStub(void** entryPoint) TypeHandle continuationTypeHnd = CoreLibBinder::GetClass(CLASS__CONTINUATION); DWORD newContinuationLoc = pCode->NewLocal(LocalDesc(continuationTypeHnd)); - pCode->EmitCALL(METHOD__STUBHELPERS__ASYNC_CALL_CONTINUATION, 0, 1); + pCode->EmitCALL(METHOD__ASYNC_HELPERS__ASYNC_CALL_CONTINUATION, 0, 1); pCode->EmitSTLOC(newContinuationLoc); if (!msig.IsReturnTypeVoid()) diff --git a/src/coreclr/vm/metasig.h b/src/coreclr/vm/metasig.h index 412b88665360d0..065690fd812428 100644 --- a/src/coreclr/vm/metasig.h +++ b/src/coreclr/vm/metasig.h @@ -619,7 +619,6 @@ DEFINE_METASIG(SM(PtrByte_RetStr, P(b), s)) DEFINE_METASIG(SM(Str_RetPtrByte, s, P(b))) DEFINE_METASIG(SM(PtrByte_RetVoid, P(b), v)) -DEFINE_METASIG_T(SM(RetContinuation, , C(CONTINUATION))) DEFINE_METASIG(GM(T_RetVoid, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, M(0), v)) DEFINE_METASIG_T(GM(RetTaskOfT, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, , GI(C(TASK_1), 1, M(0)))) DEFINE_METASIG_T(GM(RetValueTaskOfT, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, , GI(g(VALUETASK_1), 1, M(0))))