Convert constructor invocations from the runtime to use UnmanagedCallersOnly#124920
Convert constructor invocations from the runtime to use UnmanagedCallersOnly#124920jkoritzinsky wants to merge 1 commit intodotnet:mainfrom
Conversation
…RE_NONVIRTUAL_CALLSITE_USING_METHODDESC to use UnmanagedCallersOnly
|
Tagging subscribers to this area: @agocke |
There was a problem hiding this comment.
Pull request overview
This PR continues the migration away from MethodDescCallSite / CallDescrWorker-style VM-to-managed invocation, switching class constructor and default instance constructor calls over to the UnmanagedCallersOnly reverse P/Invoke pattern (per #123864). It also removes the now-unused CATCH_HANDLER_FOUND_NOTIFICATION_CALLSITE / PREPARE_NONVIRTUAL_CALLSITE_USING_METHODDESC infrastructure.
Changes:
- Route
MethodTable::RunClassInitEx(.cctor invocation) through a newInitHelpers.CallClassConstructor[UnmanagedCallersOnly]entrypoint andUnmanagedCallersOnlyCaller. - Route default constructor invocations through a new
RuntimeHelpers.CallDefaultConstructor[UnmanagedCallersOnly]entrypoint andUnmanagedCallersOnlyCaller. - Remove debugger notification dispatch flag and wrapper logic from
DispatchCallSimple/call helper macros.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/coreclr/vm/methodtable.cpp | Switches class constructor invocation to UnmanagedCallersOnlyCaller. |
| src/coreclr/vm/corelib.h | Adds CoreLib binder entries for the new UCO-managed helpers. |
| src/coreclr/vm/cominterfacemarshaler.cpp | Switches extensible RCW default ctor invocation to UCO path. |
| src/coreclr/vm/callhelpers.h | Removes catch-handler-found notification flag/macro; retains UCO caller helper. |
| src/coreclr/vm/callhelpers.cpp | Removes debugger wrapper dispatch path; switches default ctor helper to UCO path. |
| src/coreclr/System.Private.CoreLib/.../RuntimeHelpers.CoreCLR.cs | Adds [UnmanagedCallersOnly] method for default ctor invocation. |
| src/coreclr/System.Private.CoreLib/.../InitHelpers.cs | Adds [UnmanagedCallersOnly] method for class constructor invocation. |
| DEFINE_CLASS(INITHELPERS, CompilerServices, InitHelpers) | ||
| DEFINE_METHOD(INITHELPERS, INITCLASS, InitClass, NoSig) | ||
| DEFINE_METHOD(INITHELPERS, INITINSTANTIATEDCLASS, InitInstantiatedClass, NoSig) | ||
| DEFINE_METHOD(INITHELPERS, CALLCLASSCONSTRUCTOR, CallClassConstructor, NoSig) |
There was a problem hiding this comment.
New UnmanagedCallersOnly entrypoints (RuntimeHelpers.CallDefaultConstructor / InitHelpers.CallClassConstructor) require corresponding reverse thunk entries on portable-entrypoint platforms like WASM. As-is, GetUnmanagedCallersOnlyThunk will hit the "unknown thunk" portability assert if these methods are invoked on WASM because the generated reverse thunk map (src/coreclr/vm/wasm/callhelpers-reverse.cpp) doesn't include them. Please regenerate/update the callhelpers reverse thunk list to include these new UCO methods.
| InitClassSlow(pMT); | ||
| } | ||
|
|
||
|
|
There was a problem hiding this comment.
There is an extra blank line introduced before the UnmanagedCallersOnly method. Please remove the redundant empty line to keep formatting consistent with the surrounding methods in this file.
src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/InitHelpers.cs
Show resolved
Hide resolved
| else | ||
| { | ||
| RuntimeHelpers.SetNextCallGenericContext(instantiatingArg); | ||
| cctor(); |
There was a problem hiding this comment.
@jakobbotsch Are you okay using this API outside of the async2 scenario?
There was a problem hiding this comment.
It would need some changes I think. The JIT/interpreter only pay attention to this for calls that require instantiating args (sig->hasTypeArg() is true). I would expect it to be ignored for a calli like this one.
There was a problem hiding this comment.
I can change this to instead pass the argument explicity when needed if the JIT won't respect it
| pParam->pCallDescrData, | ||
| pParam->fCriticalCall); | ||
| } | ||
| PAL_EXCEPT_FILTER(AppDomainTransitionExceptionFilter) |
There was a problem hiding this comment.
This is the last use of AppDomainTransitionExceptionFilter. Please go through and remove mentions and the definition.
| @@ -502,7 +502,6 @@ enum EEToManagedCallFlags | |||
| enum DispatchCallSimpleFlags | |||
| { | |||
| DispatchCallSimple_CriticalCall = 0x0001, | |||
There was a problem hiding this comment.
I also think this can now be used and instead update the appropriate callers of CallDescrWorkerWithHandler with a TRUE instead of a the flag.
This PR moves the class constructor and instance constructor invocations from within the runtime to use the UnmanagedCallersOnly pattern established with #123864 to invoke the constructors.
Contributes to #123864.
As this PR removes all usages of
CATCH_HANDLER_FOUND_NOTIFICATION_CALLSITEandPREPARE_NONVIRTUAL_CALLSITE_USING_METHODDESC, these pieces of infrastructure are removed as well.