-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Remove uses of FCThrow in interlocked helpers #96916
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 |
---|---|---|
|
@@ -48,27 +48,60 @@ public static long Decrement(ref long location) => | |
/// <returns>The original value of <paramref name="location1"/>.</returns> | ||
/// <exception cref="NullReferenceException">The address of location1 is a null pointer.</exception> | ||
[Intrinsic] | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public static int Exchange(ref int location1, int value) | ||
{ | ||
#if TARGET_X86 || TARGET_AMD64 || TARGET_ARM64 || TARGET_RISCV64 | ||
return Exchange(ref location1, value); // Must expand intrinsic | ||
#else | ||
if (Unsafe.IsNullRef(ref location1)) | ||
ThrowHelper.ThrowNullReferenceException(); | ||
return Exchange32(ref location1, value); | ||
#endif | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.InternalCall)] | ||
public static extern int Exchange(ref int location1, int value); | ||
private static extern int Exchange32(ref int location1, int value); | ||
|
||
/// <summary>Sets a 64-bit signed integer to a specified value and returns the original value, as an atomic operation.</summary> | ||
/// <param name="location1">The variable to set to the specified value.</param> | ||
/// <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> | ||
[Intrinsic] | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public static long Exchange(ref long location1, long value) | ||
{ | ||
#if TARGET_AMD64 || TARGET_ARM64 || TARGET_RISCV64 | ||
return Exchange(ref location1, value); // Must expand intrinsic | ||
#else | ||
if (Unsafe.IsNullRef(ref location1)) | ||
ThrowHelper.ThrowNullReferenceException(); | ||
return Exchange64(ref location1, value); | ||
#endif | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.InternalCall)] | ||
public static extern long Exchange(ref long location1, long value); | ||
private static extern long Exchange64(ref long location1, long value); | ||
|
||
/// <summary>Sets an object to the specified value and returns a reference to the original object, as an atomic operation.</summary> | ||
/// <param name="location1">The variable to set to the specified value.</param> | ||
/// <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> | ||
[Intrinsic] | ||
[MethodImpl(MethodImplOptions.InternalCall)] | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
[return: NotNullIfNotNull(nameof(location1))] | ||
public static extern object? Exchange([NotNullIfNotNull(nameof(value))] ref object? location1, object? value); | ||
public static object? Exchange([NotNullIfNotNull(nameof(value))] ref object? location1, object? value) | ||
{ | ||
if (Unsafe.IsNullRef(ref location1)) | ||
|
||
ThrowHelper.ThrowNullReferenceException(); | ||
return ExchangeObject(ref location1, value); | ||
} | ||
|
||
[return: NotNullIfNotNull(nameof(location1))] | ||
[MethodImpl(MethodImplOptions.InternalCall)] | ||
private static extern object? ExchangeObject([NotNullIfNotNull(nameof(value))] ref object? location1, object? 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. | ||
|
@@ -84,7 +117,7 @@ public static long Decrement(ref long location) => | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public static T Exchange<T>([NotNullIfNotNull(nameof(value))] ref T location1, T value) where T : class? => | ||
Unsafe.As<T>(Exchange(ref Unsafe.As<T, object?>(ref location1), value)); | ||
#endregion | ||
#endregion | ||
|
||
#region CompareExchange | ||
/// <summary>Compares two 32-bit signed integers for equality and, if they are equal, replaces the first value.</summary> | ||
|
@@ -94,8 +127,20 @@ public static T Exchange<T>([NotNullIfNotNull(nameof(value))] ref T location1, T | |
/// <returns>The original value in <paramref name="location1"/>.</returns> | ||
/// <exception cref="NullReferenceException">The address of <paramref name="location1"/> is a null pointer.</exception> | ||
[Intrinsic] | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public static int CompareExchange(ref int location1, int value, int comparand) | ||
{ | ||
#if TARGET_X86 || TARGET_AMD64 || TARGET_ARM64 || TARGET_RISCV64 | ||
return CompareExchange(ref location1, value, comparand); // Must expand intrinsic | ||
#else | ||
if (Unsafe.IsNullRef(ref location1)) | ||
ThrowHelper.ThrowNullReferenceException(); | ||
return CompareExchange32(ref location1, value, comparand); | ||
#endif | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.InternalCall)] | ||
public static extern int CompareExchange(ref int location1, int value, int comparand); | ||
private static extern int CompareExchange32(ref int location1, int value, int comparand); | ||
|
||
/// <summary>Compares two 64-bit signed integers for equality and, if they are equal, replaces the first value.</summary> | ||
/// <param name="location1">The destination, whose value is compared with <paramref name="comparand"/> and possibly replaced.</param> | ||
|
@@ -104,8 +149,20 @@ public static T Exchange<T>([NotNullIfNotNull(nameof(value))] ref T location1, T | |
/// <returns>The original value in <paramref name="location1"/>.</returns> | ||
/// <exception cref="NullReferenceException">The address of <paramref name="location1"/> is a null pointer.</exception> | ||
[Intrinsic] | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public static long CompareExchange(ref long location1, long value, long comparand) | ||
{ | ||
#if TARGET_AMD64 || TARGET_ARM64 || TARGET_RISCV64 | ||
return CompareExchange(ref location1, value, comparand); // Must expand intrinsic | ||
#else | ||
if (Unsafe.IsNullRef(ref location1)) | ||
ThrowHelper.ThrowNullReferenceException(); | ||
return CompareExchange64(ref location1, value, comparand); | ||
#endif | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.InternalCall)] | ||
public static extern long CompareExchange(ref long location1, long value, long comparand); | ||
private static extern long CompareExchange64(ref long location1, long value, long comparand); | ||
|
||
/// <summary>Compares two objects for reference equality and, if they are equal, replaces the first object.</summary> | ||
/// <param name="location1">The destination object that is compared by reference with <paramref name="comparand"/> and possibly replaced.</param> | ||
|
@@ -114,9 +171,18 @@ public static T Exchange<T>([NotNullIfNotNull(nameof(value))] ref T location1, T | |
/// <returns>The original value in <paramref name="location1"/>.</returns> | ||
/// <exception cref="NullReferenceException">The address of <paramref name="location1"/> is a null pointer.</exception> | ||
[Intrinsic] | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
[return: NotNullIfNotNull(nameof(location1))] | ||
public static object? CompareExchange(ref object? location1, object? value, object? comparand) | ||
{ | ||
if (Unsafe.IsNullRef(ref location1)) | ||
ThrowHelper.ThrowNullReferenceException(); | ||
return CompareExchangeObject(ref location1, value, comparand); | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.InternalCall)] | ||
[return: NotNullIfNotNull(nameof(location1))] | ||
public static extern object? CompareExchange(ref object? location1, object? value, object? comparand); | ||
private static extern object? CompareExchangeObject(ref object? location1, object? value, object? comparand); | ||
|
||
// Note that getILIntrinsicImplementationForInterlocked() in vm\jitinterface.cpp replaces | ||
// the body of the following method with the following IL: | ||
|
@@ -136,8 +202,8 @@ public static T Exchange<T>([NotNullIfNotNull(nameof(value))] ref T location1, T | |
/// <exception cref="NullReferenceException">The address of <paramref name="location1"/> is a null pointer.</exception> | ||
/// <typeparam name="T">The type to be used for <paramref name="location1"/>, <paramref name="value"/>, and <paramref name="comparand"/>. This type must be a reference type.</typeparam> | ||
[Intrinsic] | ||
[return: NotNullIfNotNull(nameof(location1))] | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
[return: NotNullIfNotNull(nameof(location1))] | ||
public static T CompareExchange<T>(ref T location1, T value, T comparand) where T : class? => | ||
Unsafe.As<T>(CompareExchange(ref Unsafe.As<T, object?>(ref location1), value, comparand)); | ||
#endregion | ||
|
@@ -160,12 +226,36 @@ public static long Add(ref long location1, long value) => | |
ExchangeAdd(ref location1, value) + value; | ||
|
||
[Intrinsic] | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
private static int ExchangeAdd(ref int location1, int value) | ||
{ | ||
#if TARGET_X86 || TARGET_AMD64 || TARGET_ARM64 || TARGET_RISCV64 | ||
return ExchangeAdd(ref location1, value); // Must expand intrinsic | ||
#else | ||
if (Unsafe.IsNullRef(ref location1)) | ||
ThrowHelper.ThrowNullReferenceException(); | ||
return ExchangeAdd32(ref location1, value); | ||
#endif | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.InternalCall)] | ||
private static extern int ExchangeAdd(ref int location1, int value); | ||
private static extern int ExchangeAdd32(ref int location1, int value); | ||
|
||
[Intrinsic] | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
private static long ExchangeAdd(ref long location1, long value) | ||
{ | ||
#if TARGET_AMD64 || TARGET_ARM64 || TARGET_RISCV64 | ||
return ExchangeAdd(ref location1, value); // Must expand intrinsic | ||
#else | ||
if (Unsafe.IsNullRef(ref location1)) | ||
ThrowHelper.ThrowNullReferenceException(); | ||
return ExchangeAdd64(ref location1, value); | ||
#endif | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.InternalCall)] | ||
private static extern long ExchangeAdd(ref long location1, long value); | ||
private static extern long ExchangeAdd64(ref long location1, long value); | ||
#endregion | ||
|
||
#region Read | ||
|
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.