Skip to content

Convert constructor invocations from the runtime to use UnmanagedCallersOnly#124920

Open
jkoritzinsky wants to merge 1 commit intodotnet:mainfrom
jkoritzinsky:chf-uco
Open

Convert constructor invocations from the runtime to use UnmanagedCallersOnly#124920
jkoritzinsky wants to merge 1 commit intodotnet:mainfrom
jkoritzinsky:chf-uco

Conversation

@jkoritzinsky
Copy link
Member

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_CALLSITE and PREPARE_NONVIRTUAL_CALLSITE_USING_METHODDESC , these pieces of infrastructure are removed as well.

…RE_NONVIRTUAL_CALLSITE_USING_METHODDESC to use UnmanagedCallersOnly
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @agocke
See info in area-owners.md if you want to be subscribed.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 new InitHelpers.CallClassConstructor [UnmanagedCallersOnly] entrypoint and UnmanagedCallersOnlyCaller.
  • Route default constructor invocations through a new RuntimeHelpers.CallDefaultConstructor [UnmanagedCallersOnly] entrypoint and UnmanagedCallersOnlyCaller.
  • 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.

Comment on lines 1319 to +1322
DEFINE_CLASS(INITHELPERS, CompilerServices, InitHelpers)
DEFINE_METHOD(INITHELPERS, INITCLASS, InitClass, NoSig)
DEFINE_METHOD(INITHELPERS, INITINSTANTIATEDCLASS, InitInstantiatedClass, NoSig)
DEFINE_METHOD(INITHELPERS, CALLCLASSCONSTRUCTOR, CallClassConstructor, NoSig)
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
InitClassSlow(pMT);
}


Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change

Copilot uses AI. Check for mistakes.
else
{
RuntimeHelpers.SetNextCallGenericContext(instantiatingArg);
cctor();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jakobbotsch Are you okay using this API outside of the async2 scenario?

Copy link
Member

@jakobbotsch jakobbotsch Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also think this can now be used and instead update the appropriate callers of CallDescrWorkerWithHandler with a TRUE instead of a the flag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

4 participants