Skip to content
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

Utilize the new ref readonly language feature #89736

Merged
merged 8 commits into from
Aug 2, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,8 @@ public static long Add(ref long location1, long value) =>
/// <summary>Returns a 64-bit signed value, loaded as an atomic operation.</summary>
/// <param name="location">The 64-bit value to be loaded.</param>
/// <returns>The loaded value.</returns>
public static long Read(ref long location) =>
CompareExchange(ref location, 0, 0);
public static long Read(ref readonly long location) =>
CompareExchange(ref Unsafe.AsRef(in location), 0, 0);
#endregion

#region MemoryBarrierProcessWide
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ private void CloseValue(char marker)

private bool WriteSeparator() => _isCommaNeeded ? WriteChar(',') : true;

private bool WriteChar(char source) => WriteChars(new ReadOnlySpan<char>(source));
private bool WriteChar(char source) => WriteChars(new ReadOnlySpan<char>(in source));

private bool WriteChars(ReadOnlySpan<char> chars)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ public abstract partial class ComWrappers
internal static IntPtr TaggedImplVftblPtr { get; } = CreateTaggedImplVftbl();
internal static IntPtr DefaultIReferenceTrackerTargetVftblPtr { get; } = CreateDefaultIReferenceTrackerTargetVftbl();

internal static Guid IID_IUnknown = new Guid(0x00000000, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
internal static Guid IID_IReferenceTrackerTarget = new Guid(0x64bd43f8, 0xbfee, 0x4ec4, 0xb7, 0xeb, 0x29, 0x35, 0x15, 0x8d, 0xae, 0x21);
internal static Guid IID_TaggedImpl = new Guid(0x5c13e51c, 0x4f32, 0x4726, 0xa3, 0xfd, 0xf3, 0xed, 0xd6, 0x3d, 0xa3, 0xa0);
internal static readonly Guid IID_IUnknown = new Guid(0x00000000, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
internal static readonly Guid IID_IReferenceTrackerTarget = new Guid(0x64bd43f8, 0xbfee, 0x4ec4, 0xb7, 0xeb, 0x29, 0x35, 0x15, 0x8d, 0xae, 0x21);
internal static readonly Guid IID_TaggedImpl = new Guid(0x5c13e51c, 0x4f32, 0x4726, 0xa3, 0xfd, 0xf3, 0xed, 0xd6, 0x3d, 0xa3, 0xa0);

private static readonly ConditionalWeakTable<object, NativeObjectWrapper> s_rcwTable = new ConditionalWeakTable<object, NativeObjectWrapper>();

Expand All @@ -46,7 +46,7 @@ public static unsafe bool TryGetComInstance(object obj, out IntPtr unknown)
return false;
}

return Marshal.QueryInterface(wrapper._externalComObject, ref IID_IUnknown, out unknown) == 0;
return Marshal.QueryInterface(wrapper._externalComObject, in IID_IUnknown, out unknown) == 0;
}

public static unsafe bool TryGetObject(IntPtr unknown, [NotNullWhen(true)] out object? obj)
Expand Down Expand Up @@ -675,7 +675,7 @@ public object GetOrRegisterObjectForComInstance(IntPtr externalComObject, Create
{
// It is possible the user has defined their own IUnknown impl so
// we fallback to the tagged interface approach to be sure.
if (0 != Marshal.QueryInterface(comObject, ref IID_TaggedImpl, out nint implMaybe))
if (0 != Marshal.QueryInterface(comObject, in IID_TaggedImpl, out nint implMaybe))
{
return null;
}
Expand Down Expand Up @@ -737,8 +737,7 @@ private unsafe bool TryGetOrCreateObjectForComInstanceInternal(
{
// The unwrapped object has a CCW in this context. Get the IUnknown for the externalComObject
// so we can see if it's the CCW for the unwrapped object in this context.
Guid iid = IID_IUnknown;
int hr = Marshal.QueryInterface(externalComObject, ref iid, out IntPtr externalIUnknown);
int hr = Marshal.QueryInterface(externalComObject, in IID_IUnknown, out IntPtr externalIUnknown);
Debug.Assert(hr == 0); // An external COM object that came from a ComWrappers instance
// will always be well-formed.
if (unwrappedWrapperInThisContext.ComIp == externalIUnknown)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public static unsafe byte[] ToByteArray(List<SslApplicationProtocol> application
byte[] buffer = new byte[sizeof(Sec_Application_Protocols) + protocolListSize];
int index = 0;

MemoryMarshal.Write(buffer.AsSpan(index), ref protocols);
MemoryMarshal.Write(buffer.AsSpan(index), in protocols);
index += sizeof(Sec_Application_Protocols);

for (int i = 0; i < applicationProtocols.Count; i++)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,13 @@ static T AssertNotNull<T>(T value, [CallerArgumentExpression(nameof(value))] str
uint hash1 = (5381 << 16) + 5381;
uint hash2 = BitOperations.RotateLeft(hash1, 5) + hash1;

MemoryMarshal.Write(asBytes, ref seed);
MemoryMarshal.Write(asBytes.Slice(4), ref hash2); // set hash2 := 0 (for Ordinal)
MemoryMarshal.Write(asBytes, in seed);
MemoryMarshal.Write(asBytes.Slice(4), in hash2); // set hash2 := 0 (for Ordinal)

hash1 = (BitOperations.RotateLeft(hash1, 5) + hash1) ^ (uint)seed;
hash1 = (BitOperations.RotateLeft(hash1, 5) + hash1);

MemoryMarshal.Write(asBytes.Slice(8), ref hash1); // set hash1 := 0 (for Ordinal)
MemoryMarshal.Write(asBytes.Slice(8), in hash1); // set hash1 := 0 (for Ordinal)
});

int ordinalHashCode = nonRandomizedOrdinal(candidate);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ void ICollection.CopyTo(Array array, int index)
/// <summary>Gets either a reference to a <typeparamref name="TValue"/> in the dictionary or a null reference if the key does not exist in the dictionary.</summary>
/// <param name="key">The key used for lookup.</param>
/// <returns>A reference to a <typeparamref name="TValue"/> in the dictionary or a null reference if the key does not exist in the dictionary.</returns>
/// <remarks>The null reference can be detected by calling <see cref="Unsafe.IsNullRef{T}(ref T)"/>.</remarks>
/// <remarks>The null reference can be detected by calling <see cref="Unsafe.IsNullRef"/>.</remarks>
public ref readonly TValue GetValueRefOrNullRef(TKey key)
{
if (key is null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ public void AddRangeDerivedSpan(string[] builderElements, string[] rangeElements

// AddRange
builder.AddRange(new ReadOnlySpan<string>(rangeElements));

// Assert
Assert.Equal(expectedResult, builder);
}
Expand All @@ -214,7 +214,7 @@ public void AddRangeDerivedImmutableArray(string[] builderElements, string[] ran

// AddRange
builder.AddRange(rangeElements.ToImmutableArray());

// Assert
Assert.Equal(expectedResult, builder);
}
Expand All @@ -226,7 +226,7 @@ public void AddRangeDerivedBuilder(string[] builderElements, string[] rangeEleme
// Initialize builder
var builderBase = new ImmutableArray<object>.Builder();
builderBase.AddRange(builderElements);

// Prepare another builder to add
var builder = new ImmutableArray<string>.Builder();
builder.AddRange(rangeElements);
Expand Down Expand Up @@ -1108,7 +1108,7 @@ public void ItemRef()
builder.Add(3);

ref readonly int safeRef = ref builder.ItemRef(1);
ref int unsafeRef = ref Unsafe.AsRef(safeRef);
ref int unsafeRef = ref Unsafe.AsRef(in safeRef);

Assert.Equal(2, builder.ItemRef(1));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2552,7 +2552,7 @@ public void ItemRef()
var array = new[] { 1, 2, 3 }.ToImmutableArray();

ref readonly int safeRef = ref array.ItemRef(1);
ref int unsafeRef = ref Unsafe.AsRef(safeRef);
ref int unsafeRef = ref Unsafe.AsRef(in safeRef);

Assert.Equal(2, array.ItemRef(1));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ public void RemoveRange()

mutable.RemoveRange(new double[] { 2.4, 3.6 });
Assert.Equal(new[] { 1.5, 4.7 }, mutable);

var absComparer = new DelegateEqualityComparer<double>(equals: (x, y) => Math.Abs(x) == Math.Abs(y));
mutable.RemoveRange(new double[] { -1.5 }, absComparer);
Assert.Equal(new[] { 4.7 }, mutable);
Expand Down Expand Up @@ -431,7 +431,7 @@ public void ItemRef()
var builder = new ImmutableList<int>.Builder(list);

ref readonly int safeRef = ref builder.ItemRef(1);
ref int unsafeRef = ref Unsafe.AsRef(safeRef);
ref int unsafeRef = ref Unsafe.AsRef(in safeRef);

Assert.Equal(2, builder.ItemRef(1));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,7 @@ public void ItemRef()
ImmutableList<int> list = new[] { 1, 2, 3 }.ToImmutableList();

ref readonly int safeRef = ref list.ItemRef(1);
ref int unsafeRef = ref Unsafe.AsRef(safeRef);
ref int unsafeRef = ref Unsafe.AsRef(in safeRef);

Assert.Equal(2, list.ItemRef(1));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ public void PeekRef()
.Enqueue(3);

ref readonly int safeRef = ref queue.PeekRef();
ref int unsafeRef = ref Unsafe.AsRef(safeRef);
ref int unsafeRef = ref Unsafe.AsRef(in safeRef);

Assert.Equal(1, queue.PeekRef());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ public void ValueRef()
}.ToImmutableSortedDictionary().ToBuilder();

ref readonly int safeRef = ref builder.ValueRef("a");
ref int unsafeRef = ref Unsafe.AsRef(safeRef);
ref int unsafeRef = ref Unsafe.AsRef(in safeRef);

Assert.Equal(1, builder.ValueRef("a"));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ public void ValueRef()
}.ToImmutableSortedDictionary();

ref readonly int safeRef = ref dictionary.ValueRef("a");
ref int unsafeRef = ref Unsafe.AsRef(safeRef);
ref int unsafeRef = ref Unsafe.AsRef(in safeRef);

Assert.Equal(1, dictionary.ValueRef("a"));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public void ItemRef()
var builder = new ImmutableSortedSet<int>.Builder(array);

ref readonly int safeRef = ref builder.ItemRef(1);
ref int unsafeRef = ref Unsafe.AsRef(safeRef);
ref int unsafeRef = ref Unsafe.AsRef(in safeRef);

Assert.Equal(2, builder.ItemRef(1));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ public void ItemRef()
var array = new[] { 1, 2, 3 }.ToImmutableSortedSet();

ref readonly int safeRef = ref array.ItemRef(1);
ref int unsafeRef = ref Unsafe.AsRef(safeRef);
ref int unsafeRef = ref Unsafe.AsRef(in safeRef);

Assert.Equal(2, array.ItemRef(1));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ public void PeekRef()
.Push(3);

ref readonly int safeRef = ref stack.PeekRef();
ref int unsafeRef = ref Unsafe.AsRef(safeRef);
ref int unsafeRef = ref Unsafe.AsRef(in safeRef);

Assert.Equal(3, stack.PeekRef());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,13 +303,13 @@ static string GenerateCollidingStringCandidate(int seed)
uint hash1 = (5381 << 16) + 5381;
uint hash2 = BitOperations.RotateLeft(hash1, 5) + hash1;

MemoryMarshal.Write(asBytes, ref seed);
MemoryMarshal.Write(asBytes.Slice(4), ref hash2); // set hash2 := 0 (for Ordinal)
MemoryMarshal.Write(asBytes, in seed);
MemoryMarshal.Write(asBytes.Slice(4), in hash2); // set hash2 := 0 (for Ordinal)

hash1 = (BitOperations.RotateLeft(hash1, 5) + hash1) ^ (uint)seed;
hash1 = (BitOperations.RotateLeft(hash1, 5) + hash1);

MemoryMarshal.Write(asBytes.Slice(8), ref hash1); // set hash1 := 0 (for Ordinal)
MemoryMarshal.Write(asBytes.Slice(8), in hash1); // set hash1 := 0 (for Ordinal)
});
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// We need to target netstandard2.0, so keep using ref for MemoryMarshal.Write
// CS9191: The 'ref' modifier for argument 2 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
#pragma warning disable CS9191

namespace System.Data.OleDb
{
/// <summary>
Expand Down
4 changes: 4 additions & 0 deletions src/libraries/System.Data.OleDb/src/SafeHandles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
using System.Runtime.Versioning;
using static System.Data.Common.UnsafeNativeMethods;

// We need to target netstandard2.0, so keep using ref for MemoryMarshal.Write
// CS9191: The 'ref' modifier for argument 2 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
#pragma warning disable CS9191

namespace System.Data.OleDb
{
internal sealed class DualCoTaskMem : SafeHandle
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
using System.Runtime.Versioning;
using System.Text;

// We need to target netstandard2.0, so keep using ref for MemoryMarshal.Write
// CS9191: The 'ref' modifier for argument 2 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
#pragma warning disable CS9191

namespace WbemClient_v1 { }
namespace WbemUtilities_v1 { }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

using System.Runtime.InteropServices;

// We need to target netstandard2.0, so keep using ref for MemoryMarshal.Write
// CS9191: The 'ref' modifier for argument 2 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
#pragma warning disable CS9191

namespace System.Management
{

Expand Down
6 changes: 3 additions & 3 deletions src/libraries/System.Memory/ref/System.Memory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ public static partial class MemoryMarshal
public static System.ReadOnlySpan<TTo> Cast<TFrom, TTo>(System.ReadOnlySpan<TFrom> span) where TFrom : struct where TTo : struct { throw null; }
public static System.Span<TTo> Cast<TFrom, TTo>(System.Span<TFrom> span) where TFrom : struct where TTo : struct { throw null; }
public static System.Memory<T> CreateFromPinnedArray<T>(T[]? array, int start, int length) { throw null; }
public static System.ReadOnlySpan<T> CreateReadOnlySpan<T>(scoped ref T reference, int length) { throw null; }
public static System.ReadOnlySpan<T> CreateReadOnlySpan<T>(scoped ref readonly T reference, int length) { throw null; }
[System.CLSCompliant(false)]
public static unsafe ReadOnlySpan<byte> CreateReadOnlySpanFromNullTerminated(byte* value) { throw null; }
[System.CLSCompliant(false)]
Expand All @@ -710,8 +710,8 @@ public static partial class MemoryMarshal
public static bool TryGetMemoryManager<T, TManager>(System.ReadOnlyMemory<T> memory, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TManager? manager, out int start, out int length) where TManager : System.Buffers.MemoryManager<T> { throw null; }
public static bool TryGetString(System.ReadOnlyMemory<char> memory, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out string? text, out int start, out int length) { throw null; }
public static bool TryRead<T>(System.ReadOnlySpan<byte> source, out T value) where T : struct { throw null; }
public static bool TryWrite<T>(System.Span<byte> destination, ref T value) where T : struct { throw null; }
public static void Write<T>(System.Span<byte> destination, ref T value) where T : struct { }
public static bool TryWrite<T>(System.Span<byte> destination, in T value) where T : struct { throw null; }
public static void Write<T>(System.Span<byte> destination, in T value) where T : struct { }
}
}
namespace System.Text
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public readonly long Length
if (_length < 0)
{
// Cast-away readonly to initialize lazy field
Unsafe.AsRef(_length) = Sequence.Length;
Unsafe.AsRef(in _length) = Sequence.Length;
}
return _length;
}
Expand Down
Loading
Loading