[bcl][jit] implement Interlocked.Exchange<T> in terms of object (mono/mono#17341)
* [bcl][jit] implement Interlocked.Exchange<T> in terms of object
Exchange<T> is supposed to be picked up as an intrinsic. But if it isn't,
since T has a class constraint, call the `Exchange (ref object, ref object, ref
object)` overload instead.
This works around a limitation in the JIT:
https://github.com/mono/mono/blob/mono/mono@
82a07273c22b996b08fa88ee2e6632d782ac2242/mono/mini/mini-trampolines.c#L704-L713
if we're in the common call trampoline, and the caller is generic method and
the callee is a generic method, if we're using generic sharing for the caller,
but there's no generic jit info for the callee, we will not patch the call
site.
In this case we had Exchange<T> calling Exchange_T<T>
where the callee is an icall (and evidently didn't have generic jit info).
So every time we called Exchange<T>, we would go through the trampoline when
trying to call Exchange_T<T> without patching the call site.
Addresses part of https://github.com/mono/mono/issues/17334
* Bump Mono
* Also drop CompareExchange_T<T>
* Sprinkle some Unsafe magic.
Mark the non-icall methods that we expect the JIT to treet as intrinsics with [Intrinsic]
* aot-runtime doesn't need Volatile.Read<T>/Write<T> code
Both of those methods are implemented as calls to the object overload of Volatile.Read/Write
Commit migrated from https://github.com/mono/mono/commit/
f017835ac11371038aec3ea66c513c8234d73187