Skip to content

Commit cdf3559

Browse files
jkoritzinskyCopilot
andcommitted
Remove obsolete native managed-invocation machinery
Delete MethodDescCallSite, CallDescrWorker and their argument-copying, return-value, architecture assembly, build, and EH identification closure after the reflection, custom-attribute, and func-eval migrations. Remove orphaned multicore-JIT diagnostic state and update VM-to-managed calling documentation. Preserve live field-access helpers, typed UCO calls, GC argument reporting, and calling-convention traits. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 84969d7 commit cdf3559

49 files changed

Lines changed: 73 additions & 2961 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/design/coreclr/botr/corelib.md

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -296,31 +296,35 @@ Then, you can use the `REF<T>` template to create a type name like `SAFEHANDLERE
296296

297297
# Calling into managed code from unmanaged code
298298

299-
Clearly there are places where the CLR must call into managed code from native. For this purpose, we have added a `MethodDescCallSite` class to handle a lot of plumbing for you. Conceptually, all you need to do is find the `MethodDesc*` for the method you want to call, find a managed object for the "this" pointer (if you're calling an instance method), pass in an array of arguments, and deal with the return value. Internally, you'll need to potentially toggle your thread's state to allow the GC to run in preemptive mode, etc.
299+
The VM calls CoreLib methods marked `[UnmanagedCallersOnly]` through `UnmanagedCallersOnlyCaller`. The binder identifies the entrypoint, and the helper transitions to preemptive GC mode before calling it through the platform's unmanaged ABI. The caller must keep managed references GC-protected and pass their addresses to the managed entrypoint. Instance or virtual dispatch is performed in a managed wrapper rather than by constructing a native argument stack.
300300

301-
Here's a simplified example. Note how this instance uses the binder described in the previous section to call `SafeHandle`'s virtual `ReleaseHandle` method.
301+
The `InvokeThrowing` variants append an exception-handle argument. The managed entrypoint catches exceptions and stores them through that argument; the native helper rethrows them after returning. For example, `Exception.CreateTargetInvocationException` returns its newly allocated object through an output argument:
302302

303303
```C++
304-
void SafeHandle::RunReleaseMethod(SafeHandle* psh)
304+
OBJECTREF CreateTargetInvocationException(OBJECTREF innerException)
305305
{
306-
CONTRACTL {
306+
CONTRACTL
307+
{
307308
THROWS;
308309
GC_TRIGGERS;
309310
MODE_COOPERATIVE;
310-
} CONTRACTL_END;
311-
312-
SAFEHANDLEREF sh(psh);
313-
314-
GCPROTECT_BEGIN(sh);
315-
316-
MethodDescCallSite releaseHandle(s_pReleaseHandleMethod, METHOD__SAFE_HANDLE__RELEASE_HANDLE, (OBJECTREF*)&sh, TypeHandle(), TRUE);
317-
318-
ARG_SLOT releaseArgs[] = { ObjToArgSlot(sh) };
319-
if (!(BOOL)releaseHandle.Call_RetBool(releaseArgs)) {
320-
MDA_TRIGGER_ASSISTANT(ReleaseHandleFailed, ReportViolation)(sh->GetTypeHandle(), sh->m_handle);
321311
}
312+
CONTRACTL_END;
322313

314+
struct
315+
{
316+
OBJECTREF inner;
317+
OBJECTREF result;
318+
} gc;
319+
gc.inner = innerException;
320+
gc.result = nullptr;
321+
322+
GCPROTECT_BEGIN(gc);
323+
UnmanagedCallersOnlyCaller caller{METHOD__EXCEPTION__CREATE_TARGET_INVOCATION_EXCEPTION};
324+
caller.InvokeThrowing(&gc.inner, &gc.result);
323325
GCPROTECT_END();
326+
327+
return gc.result;
324328
}
325329
```
326330

docs/design/coreclr/botr/guide-for-porting.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -336,9 +336,9 @@ Here is an annotated list of the stubs implemented for Unix on Arm64.
336336
call in interesting ways, manipulate/parse the "secret" arguments, or do
337337
other not quite compilable to standardized C concepts.
338338

339-
1. `CallDescrWorkerInternal` – Needed to support VM to managed function
340-
calls. Necessary for all applications as this is how the main method is
341-
called.
339+
1. VM-to-managed calls use `[UnmanagedCallersOnly]` entrypoints through the
340+
platform's unmanaged ABI. Ports must support the reverse P/Invoke
341+
transitions used by these entrypoints, including program startup.
342342

343343
2. `PInvokeImportThunk` – Needed to support saving off a set of arguments to
344344
a p/invoke so that the runtime can find the actual target. Also uses one

src/coreclr/debug/ee/controller.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7758,8 +7758,7 @@ TP_RESULT DebuggerStepper::TriggerPatch(DebuggerControllerPatch *patch,
77587758
}
77597759
else
77607760
{
7761-
// We're hitting this code path with MC++ assemblies
7762-
// that have an unmanaged entry point so the stub returns to CallDescrWorker.
7761+
// An interop stub can return to unmanaged code.
77637762
_ASSERTE(g_pEEInterface->GetNativeCodeMethodDesc(dac_cast<PCODE>(patch->address))->IsInteropStub());
77647763
}
77657764

src/coreclr/inc/clrconfigvalues.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,6 @@ RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableRiscV64Zicond, W("EnableRiscV64
728728
// **
729729
CONFIG_DWORD_INFO(INTERNAL_ActivatePatchSkip, W("ActivatePatchSkip"), 0, "Allows an assert when ActivatePatchSkip is called")
730730
CONFIG_DWORD_INFO(INTERNAL_AlwaysUseMetadataInterfaceMapLayout, W("AlwaysUseMetadataInterfaceMapLayout"), 0, "Used for debugging generic interface map layout.")
731-
CONFIG_DWORD_INFO(INTERNAL_AssertOnUnneededThis, W("AssertOnUnneededThis"), 0, "While the ConfigDWORD is unnecessary, the contained ASSERT should be kept. This may result in some work tracking down violating MethodDescCallSites.")
732731
CONFIG_DWORD_INFO(INTERNAL_AssertStacktrace, W("AssertStacktrace"), 1, "")
733732
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_DisableConfigCache, W("DisableConfigCache"), 0, "Used to disable the \"probabilistic\" config cache, which walks through the appropriate config registry keys on init and probabilistically keeps track of which exist.")
734733
CONFIG_STRING_INFO(INTERNAL_DumpOnClassLoad, W("DumpOnClassLoad"), "Dumps information about loaded class to log.")

src/coreclr/nativeaot/Common/src/Internal/Runtime/TransitionBlock.cs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,36 +8,31 @@
88

99
//
1010
#if TARGET_ARM
11-
#define CALLDESCR_ARGREGS // CallDescrWorker has ArgumentRegister parameter
12-
#define CALLDESCR_FPARGREGS // CallDescrWorker has FloatArgumentRegisters parameter
11+
#define CALLDESCR_FPARGREGS // Calling convention has floating-point argument registers
1312
#define ENREGISTERED_RETURNTYPE_MAXSIZE
1413
#define ENREGISTERED_RETURNTYPE_INTEGER_MAXSIZE
1514
#define FEATURE_HFA
1615
#elif TARGET_ARM64
17-
#define CALLDESCR_ARGREGS // CallDescrWorker has ArgumentRegister parameter
18-
#define CALLDESCR_FPARGREGS // CallDescrWorker has FloatArgumentRegisters parameter
16+
#define CALLDESCR_FPARGREGS // Calling convention has floating-point argument registers
1917
#define ENREGISTERED_RETURNTYPE_MAXSIZE
2018
#define ENREGISTERED_RETURNTYPE_INTEGER_MAXSIZE
2119
#define ENREGISTERED_PARAMTYPE_MAXSIZE
2220
#define FEATURE_HFA
2321
#elif TARGET_X86
2422
#define ENREGISTERED_RETURNTYPE_MAXSIZE
2523
#define ENREGISTERED_RETURNTYPE_INTEGER_MAXSIZE
26-
#define CALLDESCR_ARGREGS // CallDescrWorker has ArgumentRegister parameter
2724
#elif TARGET_AMD64
2825
#if TARGET_UNIX
2926
#define UNIX_AMD64_ABI
30-
#define CALLDESCR_ARGREGS // CallDescrWorker has ArgumentRegister parameter
3127
#else
3228
#endif
33-
#define CALLDESCR_FPARGREGS // CallDescrWorker has FloatArgumentRegisters parameter
29+
#define CALLDESCR_FPARGREGS // Calling convention has floating-point argument registers
3430
#define ENREGISTERED_RETURNTYPE_MAXSIZE
3531
#define ENREGISTERED_RETURNTYPE_INTEGER_MAXSIZE
3632
#define ENREGISTERED_PARAMTYPE_MAXSIZE
3733
#elif TARGET_WASM
3834
#elif TARGET_LOONGARCH64 || TARGET_RISCV64
39-
#define CALLDESCR_ARGREGS // CallDescrWorker has ArgumentRegister parameter
40-
#define CALLDESCR_FPARGREGS // CallDescrWorker has FloatArgumentRegisters parameter
35+
#define CALLDESCR_FPARGREGS // Calling convention has floating-point argument registers
4136
#define ENREGISTERED_RETURNTYPE_MAXSIZE
4237
#define ENREGISTERED_RETURNTYPE_INTEGER_MAXSIZE
4338
#define ENREGISTERED_PARAMTYPE_MAXSIZE
@@ -205,7 +200,7 @@ public static unsafe int GetOffsetOfEcx()
205200
return sizeof(IntPtr);
206201
}
207202
}
208-
// This struct isn't used by x86, but exists for compatibility with the definition of the CallDescrData struct
203+
// Floating-point arguments are stack-passed on x86; keep an empty placeholder for the shared ABI abstraction.
209204
[StructLayout(LayoutKind.Sequential)]
210205
internal struct FloatArgumentRegisters
211206
{

src/coreclr/vm/CMakeLists.txt

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,6 @@ elseif(CLR_CMAKE_TARGET_WIN32)
677677
${ARCH_SOURCES_DIR}/AllocSlow.asm
678678
${ARCH_SOURCES_DIR}/AsmHelpers.asm
679679
${ARCH_SOURCES_DIR}/CachedInterfaceDispatchCoreCLR.asm
680-
${ARCH_SOURCES_DIR}/CallDescrWorkerAMD64.asm
681680
${ARCH_SOURCES_DIR}/ComCallPreStub.asm
682681
${ARCH_SOURCES_DIR}/getstate.asm
683682
${ARCH_SOURCES_DIR}/JitHelpers_Fast.asm
@@ -721,7 +720,6 @@ elseif(CLR_CMAKE_TARGET_WIN32)
721720
set(VM_SOURCES_WKS_ARCH_ASM
722721
${ARCH_SOURCES_DIR}/AllocSlow.asm
723722
${ARCH_SOURCES_DIR}/AsmHelpers.asm
724-
${ARCH_SOURCES_DIR}/CallDescrWorkerARM64.asm
725723
${ARCH_SOURCES_DIR}/patchedcode.asm
726724
${ARCH_SOURCES_DIR}/PInvokeStubs.asm
727725
${RUNTIME_DIR}/${ARCH_SOURCES_DIR}/StubDispatch.asm
@@ -745,7 +743,6 @@ else()
745743
${ARCH_SOURCES_DIR}/AllocSlow.S
746744
${ARCH_SOURCES_DIR}/asmhelpers.S
747745
${ARCH_SOURCES_DIR}/CachedInterfaceDispatchCoreCLR.S
748-
${ARCH_SOURCES_DIR}/calldescrworkeramd64.S
749746
${ARCH_SOURCES_DIR}/externalmethodfixupthunk.S
750747
${ARCH_SOURCES_DIR}/getstate.S
751748
${ARCH_SOURCES_DIR}/jithelpers_fast.S
@@ -793,7 +790,6 @@ else()
793790
${ARCH_SOURCES_DIR}/AllocSlow.S
794791
${ARCH_SOURCES_DIR}/asmhelpers.S
795792
${ARCH_SOURCES_DIR}/CachedInterfaceDispatchCoreCLR.S
796-
${ARCH_SOURCES_DIR}/calldescrworkerarm64.S
797793
${ARCH_SOURCES_DIR}/patchedcode.S
798794
${ARCH_SOURCES_DIR}/pinvokestubs.S
799795
${RUNTIME_DIR}/${ARCH_SOURCES_DIR}/StubDispatch.S
@@ -806,7 +802,6 @@ else()
806802
set(VM_SOURCES_WKS_ARCH_ASM
807803
${ARCH_SOURCES_DIR}/AllocSlow.S
808804
${ARCH_SOURCES_DIR}/asmhelpers.S
809-
${ARCH_SOURCES_DIR}/calldescrworkerloongarch64.S
810805
${ARCH_SOURCES_DIR}/pinvokestubs.S
811806
${ARCH_SOURCES_DIR}/thunktemplates.S
812807
${RUNTIME_DIR}/${ARCH_SOURCES_DIR}/AllocFast.S
@@ -816,7 +811,6 @@ else()
816811
set(VM_SOURCES_WKS_ARCH_ASM
817812
${ARCH_SOURCES_DIR}/AllocSlow.S
818813
${ARCH_SOURCES_DIR}/asmhelpers.S
819-
${ARCH_SOURCES_DIR}/calldescrworkerriscv64.S
820814
${ARCH_SOURCES_DIR}/pinvokestubs.S
821815
${ARCH_SOURCES_DIR}/thunktemplates.S
822816
${RUNTIME_DIR}/${ARCH_SOURCES_DIR}/AllocFast.S
@@ -960,7 +954,6 @@ elseif(CLR_CMAKE_TARGET_ARCH_WASM)
960954
)
961955
set(VM_SOURCES_WKS_ARCH
962956
${RUNTIME_DIR}/${ARCH_SOURCES_DIR}/writebarriers.cpp
963-
${ARCH_SOURCES_DIR}/calldescrworkerwasm.cpp
964957
${ARCH_SOURCES_DIR}/profiler.cpp
965958
${ARCH_SOURCES_DIR}/helpers.cpp
966959
${ARCH_SOURCES_DIR}/dynamichelpers.cpp

src/coreclr/vm/amd64/CallDescrWorkerAMD64.asm

Lines changed: 0 additions & 108 deletions
This file was deleted.

src/coreclr/vm/amd64/asmconstants.h

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -469,33 +469,6 @@ ASMCONSTANTS_C_ASSERT(OFFSETOF__InlinedCallFrame__m_pCalleeSavedFP
469469
ASMCONSTANTS_C_ASSERT(OFFSETOF__InlinedCallFrame__m_pThread
470470
== offsetof(InlinedCallFrame, m_pThread));
471471

472-
#define CallDescrData__pSrc 0x00
473-
#define CallDescrData__numStackSlots 0x08
474-
#ifdef UNIX_AMD64_ABI
475-
#define CallDescrData__pArgumentRegisters 0x10
476-
#define CallDescrData__pFloatArgumentRegisters 0x18
477-
#define CallDescrData__fpReturnSize 0x20
478-
#define CallDescrData__pTarget 0x28
479-
#define CallDescrData__returnValue 0x30
480-
#else
481-
#define CallDescrData__dwRegTypeMap 0x10
482-
#define CallDescrData__fpReturnSize 0x18
483-
#define CallDescrData__pTarget 0x20
484-
#define CallDescrData__returnValue 0x28
485-
#endif
486-
487-
ASMCONSTANTS_C_ASSERT(CallDescrData__pSrc == offsetof(CallDescrData, pSrc))
488-
ASMCONSTANTS_C_ASSERT(CallDescrData__numStackSlots == offsetof(CallDescrData, numStackSlots))
489-
#ifdef UNIX_AMD64_ABI
490-
ASMCONSTANTS_C_ASSERT(CallDescrData__pArgumentRegisters == offsetof(CallDescrData, pArgumentRegisters))
491-
ASMCONSTANTS_C_ASSERT(CallDescrData__pFloatArgumentRegisters == offsetof(CallDescrData, pFloatArgumentRegisters))
492-
#else
493-
ASMCONSTANTS_C_ASSERT(CallDescrData__dwRegTypeMap == offsetof(CallDescrData, dwRegTypeMap))
494-
#endif
495-
ASMCONSTANTS_C_ASSERT(CallDescrData__fpReturnSize == offsetof(CallDescrData, fpReturnSize))
496-
ASMCONSTANTS_C_ASSERT(CallDescrData__pTarget == offsetof(CallDescrData, pTarget))
497-
ASMCONSTANTS_C_ASSERT(CallDescrData__returnValue == offsetof(CallDescrData, returnValue))
498-
499472
#ifdef UNIX_AMD64_ABI
500473
#define OFFSETOF__TransitionBlock__m_argumentRegisters 0x00
501474
ASMCONSTANTS_C_ASSERT(OFFSETOF__TransitionBlock__m_argumentRegisters == offsetof(TransitionBlock, m_argumentRegisters))

0 commit comments

Comments
 (0)