Convert constructor invocations from the runtime to use UnmanagedCallersOnly#124920
Convert constructor invocations from the runtime to use UnmanagedCallersOnly#124920jkoritzinsky wants to merge 12 commits 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. |
src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/InitHelpers.cs
Outdated
Show resolved
Hide resolved
src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/InitHelpers.cs
Show resolved
Hide resolved
src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/InitHelpers.cs
Outdated
Show resolved
Hide resolved
...coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs
Show resolved
Hide resolved
We would have to use reflection ( |
src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/InitHelpers.cs
Outdated
Show resolved
Hide resolved
Okay. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
src/coreclr/vm/excep.cpp:8286
- The comment at line 8285-8286, "since we are here because of a cross AD reraise of the original exception," is now stale. With the removal of
AppDomainTransitionExceptionFilterand the updated assertion at line 8281 (_ASSERTE((fIsThreadAbortException || fIsPreallocatedOOMExceptionForTA) && pUEWatsonBucketTracker->CapturedForThreadAbort())), theif (!fIsThreadAbortException)branch can only be reached in thefIsPreallocatedOOMExceptionForTAcase—not an AD transition. The comment should be updated to reflect the remaining scenario (preallocated OOM exception during thread abort).
if (!fIsThreadAbortException)
{
// The watson bucket tracker for the exceptiong being raised should be empty at this point
// since we are here because of a cross AD reraise of the original exception.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
| // preallocated exception. In such a case, if the IP does not exist, we will return NULL | ||
| // indicating that we couldnt find the Watson bucket tracker, since returning a tracker | ||
| // that does not have any bucketing details will be of no use to the caller. | ||
| // Incase of an OOM, we may not have an IP in the Watson bucket tracker. |
There was a problem hiding this comment.
Corrected spelling of 'Incase' to 'In case'.
| // Incase of an OOM, we may not have an IP in the Watson bucket tracker. | |
| // In case of an OOM, we may not have an IP in the Watson bucket tracker. |
|
|
||
| // Bucket details were captured during Reflection invocation | ||
| Wb_CapturedAtReflectionInvocation = 4 | ||
| Wb_CapturedAtReflectionInvocation = 2 |
There was a problem hiding this comment.
Wb_CapturedAtReflectionInvocation was previously 4 (bit 2) and is now renumbered to 2 (bit 1), which conflicts with the now-removed Wb_CapturedAtADTransition = 2. While Wb_CapturedAtADTransition has been deleted, the renumbering means this flag now occupies bit 1 instead of bit 2. Any serialized or persisted m_DebugFlags values (e.g., in crash dumps) will be misinterpreted. More critically, if m_DebugFlags is ever checked for a combined bitmask at existing call sites that have not been updated, the semantics will silently change. The value should remain 4 to preserve stable bit-flag semantics, or the removal of the gap should be explicitly justified.
| Wb_CapturedAtReflectionInvocation = 2 | |
| Wb_CapturedAtReflectionInvocation = 4 |
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.