Just out of curiosity: value types are generally copied, and the JIT compiler seems to use Microsoft\'s Fastcall calling convention when calling a method. This puts the firs
It is __clrcall, indeed similar to __fastcall. Two registers are used by the x86 jitter (ecx, edx). Four registers by the x64 jitter (ecx, edx, r8, r9), same as the native x64 calling convention. Large value types like Decimal and large structs are passed by reserving space on the caller's stack, copying the value into it and passing a pointer to this copy. The callee copies it again to its own stack frame.
This is expensive which is why Microsoft recommends that a struct should not be larger than 16 bytes. Intentionally passing a struct by ref to avoid the copy is a workaround, commonly done in C and C++ as well. At the cost of an extra pointer dereference.