[bcl][jit] implement Interlocked.Exchange<T> in terms of object (mono/mono#17341)
authorAleksey Kliger (λgeek) <alklig@microsoft.com>
Wed, 16 Oct 2019 19:35:49 +0000 (15:35 -0400)
committerGitHub <noreply@github.com>
Wed, 16 Oct 2019 19:35:49 +0000 (15:35 -0400)
commit53c8c31687246f8f993b39673685f4e6a1e8e577
tree0dc111ebc4d426aa5824718bf7b18f6b471d1740
parent6979c3d675820717d1a2d38ddb4e84f8d65ebc98
[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
src/mono/configure.ac
src/mono/mono/metadata/icall-def-netcore.h
src/mono/mono/metadata/icall-def.h
src/mono/mono/mini/aot-compiler.c
src/mono/mono/mini/aot-runtime.c
src/mono/netcore/System.Private.CoreLib/src/System.Threading/Interlocked.cs