From 34fdd148b3f307559e46fcfa9f9f2b7c2f6f1a08 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Thu, 21 Jan 2021 13:48:22 +0300 Subject: [PATCH] Optimize Interlocked.Exchange and Interlocked.CompareExchange for IntPtr --- .../System/Threading/Interlocked.CoreCLR.cs | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs index 4d7d844085929..e277312ccd22b 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs @@ -90,8 +90,15 @@ public static long Decrement(ref long location) => /// The value to which the parameter is set. /// The original value of . /// The address of location1 is a null pointer. - [MethodImpl(MethodImplOptions.InternalCall)] - public static extern IntPtr Exchange(ref IntPtr location1, IntPtr value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static IntPtr Exchange(ref IntPtr location1, IntPtr value) + { + if (IntPtr.Size == 4) + { + return (IntPtr)Interlocked.Exchange(ref Unsafe.As(ref location1), (int)value); + } + return (IntPtr)Interlocked.Exchange(ref Unsafe.As(ref location1), (long)value); + } // The below whole method reduces to a single call to Exchange(ref object, object) but // the JIT thinks that it will generate more native code than it actually does. @@ -162,8 +169,15 @@ public static T Exchange([NotNullIfNotNull("value")] ref T location1, T value /// The that is compared to the value at . /// The original value in . /// The address of is a null pointer. - [MethodImpl(MethodImplOptions.InternalCall)] - public static extern IntPtr CompareExchange(ref IntPtr location1, IntPtr value, IntPtr comparand); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static IntPtr CompareExchange(ref IntPtr location1, IntPtr value, IntPtr comparand) + { + if (IntPtr.Size == 4) + { + return (IntPtr)Interlocked.CompareExchange(ref Unsafe.As(ref location1), (int)value, (int)comparand); + } + return (IntPtr)Interlocked.CompareExchange(ref Unsafe.As(ref location1), (long)value, (long)comparand); + } // Note that getILIntrinsicImplementationForInterlocked() in vm\jitinterface.cpp replaces // the body of the following method with the the following IL: