forked from dotnet/runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Optimize Interlocked.Exchange and Interlocked.CompareExchange for IntPtr
- Loading branch information
Showing
1 changed file
with
18 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -90,8 +90,15 @@ public static partial class Interlocked | |
/// <param name="value">The value to which the <paramref name="location1"/> parameter is set.</param> | ||
/// <returns>The original value of <paramref name="location1"/>.</returns> | ||
/// <exception cref="NullReferenceException">The address of location1 is a null pointer.</exception> | ||
[MethodImpl(MethodImplOptions.InternalCall)] | ||
public static extern IntPtr Exchange(ref IntPtr location1, IntPtr value); | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
public static IntPtr Exchange(ref IntPtr location1, IntPtr value) | ||
{ | ||
if (IntPtr.Size == 4) | ||
This comment has been minimized.
Sorry, something went wrong.
jkotas
|
||
{ | ||
return (IntPtr)Interlocked.Exchange(ref Unsafe.As<IntPtr, int>(ref location1), (int)value); | ||
} | ||
return (IntPtr)Interlocked.Exchange(ref Unsafe.As<IntPtr, long>(ref location1), (long)value); | ||
} | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
|
||
// 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 partial class Interlocked | |
/// <param name="comparand">The <see cref="IntPtr"/> that is compared to the value at <paramref name="location1"/>.</param> | ||
/// <returns>The original value in <paramref name="location1"/>.</returns> | ||
/// <exception cref="NullReferenceException">The address of <paramref name="location1"/> is a null pointer.</exception> | ||
[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<IntPtr, int>(ref location1), (int)value, (int)comparand); | ||
} | ||
return (IntPtr)Interlocked.CompareExchange(ref Unsafe.As<IntPtr, long>(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: | ||
|
Also delete the unmanaged FCall.