diff --git a/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs index a93afa1efd507e..082e91bc719c93 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs @@ -677,7 +677,7 @@ internal static void UnregisterMemoryLoadChangeNotification(Action notification) /// If pinned is set to true, must not be a reference type or a type that contains object references. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] // forced to ensure no perf drop for small memory buffers (hot path) - public static T[] AllocateUninitializedArray(int length, bool pinned = false) // T[] rather than T?[] to match `new T[length]` behavior + public static unsafe T[] AllocateUninitializedArray(int length, bool pinned = false) // T[] rather than T?[] to match `new T[length]` behavior { if (!pinned) { @@ -689,10 +689,13 @@ public static T[] AllocateUninitializedArray(int length, bool pinned = false) // for debug builds we always want to call AllocateNewArray to detect AllocateNewArray bugs #if !DEBUG // small arrays are allocated using `new[]` as that is generally faster. - if (length < 2048 / Unsafe.SizeOf()) +#pragma warning disable 8500 // sizeof of managed types + if (length < 2048 / sizeof(T)) +#pragma warning restore 8500 { return new T[length]; } + #endif } else if (RuntimeHelpers.IsReferenceOrContainsReferences()) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/DependentHandle.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/DependentHandle.cs index a8ccb94aae2eb8..027c41ae7533e1 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/DependentHandle.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/DependentHandle.cs @@ -237,13 +237,12 @@ public void Dispose() [MethodImpl(MethodImplOptions.InternalCall)] private static extern object? InternalGetTarget(IntPtr dependentHandle); #else - private static unsafe object? InternalGetTarget(IntPtr dependentHandle) - { - // This optimization is the same that is used in GCHandle in RELEASE mode. - // This is not used in DEBUG builds as the runtime performs additional checks. - // The logic below is the inlined copy of ObjectFromHandle in the unmanaged runtime. - return Unsafe.As(ref *(IntPtr*)(nint)dependentHandle); - } + // This optimization is the same that is used in GCHandle in RELEASE mode. + // This is not used in DEBUG builds as the runtime performs additional checks. + // The logic below is the inlined copy of ObjectFromHandle in the unmanaged runtime. +#pragma warning disable 8500 // address of managed types + private static unsafe object? InternalGetTarget(IntPtr dependentHandle) => *(object*)dependentHandle; +#pragma warning restore 8500 #endif [MethodImpl(MethodImplOptions.InternalCall)] diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.CoreCLR.cs index b84be38d886fc6..c62d6aeb75fe42 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.CoreCLR.cs @@ -18,8 +18,9 @@ public partial struct GCHandle [MethodImpl(MethodImplOptions.InternalCall)] internal static extern object? InternalGet(IntPtr handle); #else - internal static unsafe object? InternalGet(IntPtr handle) => - Unsafe.As(ref *(IntPtr*)(nint)handle); +#pragma warning disable 8500 // address of managed types + internal static unsafe object? InternalGet(IntPtr handle) => *(object*)handle; +#pragma warning restore 8500 #endif [MethodImpl(MethodImplOptions.InternalCall)] diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs index 841f0cd145643b..ee9c669b6cb35e 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs @@ -15,7 +15,9 @@ internal static unsafe class CachedInterfaceDispatch private static unsafe IntPtr RhpCidResolve(IntPtr callerTransitionBlockParam, IntPtr pCell) { IntPtr locationOfThisPointer = callerTransitionBlockParam + TransitionBlock.GetThisOffset(); - object pObject = Unsafe.As(ref *(IntPtr*)locationOfThisPointer); +#pragma warning disable 8500 // address of managed types + object pObject = *(object*)locationOfThisPointer; +#pragma warning restore 8500 IntPtr dispatchResolveTarget = RhpCidResolve_Worker(pObject, pCell); return dispatchResolveTarget; } diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InteropServices/UnsafeGCHandle.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InteropServices/UnsafeGCHandle.cs index 2d4b13a92c5e28..cf95df4680444c 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InteropServices/UnsafeGCHandle.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InteropServices/UnsafeGCHandle.cs @@ -41,7 +41,9 @@ public unsafe object Target // The runtime performs additional checks in debug builds return InternalCalls.RhHandleGet(_handle); #else - return Unsafe.As(ref *(IntPtr*)_handle); +#pragma warning disable 8500 // address of managed types + return *(object*)_handle; +#pragma warning restore 8500 #endif } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.NativeAot.cs index 7e8441cdb90b8e..6153784b66fbf7 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.NativeAot.cs @@ -773,7 +773,9 @@ public static unsafe T[] AllocateUninitializedArray(int length, bool pinned = // for debug builds we always want to call AllocateNewArray to detect AllocateNewArray bugs #if !DEBUG // small arrays are allocated using `new[]` as that is generally faster. - if (length < 2048 / Unsafe.SizeOf()) +#pragma warning disable 8500 // sizeof of managed types + if (length < 2048 / sizeof(T)) +#pragma warning restore 8500 { return new T[length]; } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NativeAot.cs index ed85c17e1dc5fc..b263ee17e26482 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.NativeAot.cs @@ -305,8 +305,10 @@ ptr is string || // Compat note: CLR wouldn't bother with a range check. If someone does this, // they're likely taking dependency on some CLR implementation detail quirk. - if (checked(ofs + Unsafe.SizeOf()) > size) +#pragma warning disable 8500 // sizeof of managed types + if (checked(ofs + sizeof(T)) > size) throw new ArgumentOutOfRangeException(nameof(ofs)); +#pragma warning restore 8500 IntPtr nativeBytes = AllocCoTaskMem(size); NativeMemory.Clear((void*)nativeBytes, (nuint)size); @@ -384,8 +386,10 @@ ptr is string || // Compat note: CLR wouldn't bother with a range check. If someone does this, // they're likely taking dependency on some CLR implementation detail quirk. - if (checked(ofs + Unsafe.SizeOf()) > size) +#pragma warning disable 8500 // sizeof of managed types + if (checked(ofs + sizeof(T)) > size) throw new ArgumentOutOfRangeException(nameof(ofs)); +#pragma warning restore 8500 IntPtr nativeBytes = AllocCoTaskMem(size); NativeMemory.Clear((void*)nativeBytes, (nuint)size); diff --git a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/UnsafeIntrinsics.cs b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/UnsafeIntrinsics.cs index f25671773490bf..2b90323728049f 100644 --- a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/UnsafeIntrinsics.cs +++ b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/UnsafeIntrinsics.cs @@ -22,8 +22,6 @@ public static MethodIL EmitIL(MethodDesc method) { case "AsPointer": return new ILStubMethodIL(method, new byte[] { (byte)ILOpcode.ldarg_0, (byte)ILOpcode.conv_u, (byte)ILOpcode.ret }, Array.Empty(), null); - case "SizeOf": - return EmitSizeOf(method); case "As": case "AsRef": return new ILStubMethodIL(method, new byte[] { (byte)ILOpcode.ldarg_0, (byte)ILOpcode.ret }, Array.Empty(), null); @@ -98,19 +96,6 @@ public static MethodIL EmitIL(MethodDesc method) return null; } - private static MethodIL EmitSizeOf(MethodDesc method) - { - Debug.Assert(method.Signature.IsStatic && method.Signature.Length == 0); - - TypeSystemContext context = method.Context; - - ILEmitter emit = new ILEmitter(); - ILCodeStream codeStream = emit.NewCodeStream(); - codeStream.Emit(ILOpcode.sizeof_, emit.NewToken(context.GetSignatureVariable(0, method: true))); - codeStream.Emit(ILOpcode.ret); - return emit.Link(method); - } - private static MethodIL EmitAdd(MethodDesc method) { Debug.Assert(method.Signature.IsStatic && method.Signature.Length == 2); diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 9f97a8001cec5c..b5ff0a1c795939 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -694,7 +694,6 @@ DEFINE_METHOD(UNSAFE, BYREF_IS_NULL, IsNullRef, NoSig) DEFINE_METHOD(UNSAFE, BYREF_NULLREF, NullRef, NoSig) DEFINE_METHOD(UNSAFE, AS_REF_IN, AsRef, GM_RefT_RetRefT) DEFINE_METHOD(UNSAFE, AS_REF_POINTER, AsRef, GM_VoidPtr_RetRefT) -DEFINE_METHOD(UNSAFE, SIZEOF, SizeOf, NoSig) DEFINE_METHOD(UNSAFE, BYREF_AS, As, GM_RefTFrom_RetRefTTo) DEFINE_METHOD(UNSAFE, OBJECT_AS, As, GM_Obj_RetT) DEFINE_METHOD(UNSAFE, BYREF_ADD, Add, GM_RefT_Int_RetRefT) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 6d37ff818217fb..c1553c14f6c031 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -6789,24 +6789,6 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, return true; } - else if (tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__SIZEOF)->GetMemberDef()) - { - _ASSERTE(ftn->HasMethodInstantiation()); - Instantiation inst = ftn->GetMethodInstantiation(); - - _ASSERTE(ftn->GetNumGenericMethodArgs() == 1); - mdToken tokGenericArg = FindGenericMethodArgTypeSpec(CoreLibBinder::GetModule()->GetMDImport()); - - static const BYTE ilcode[] = - { - CEE_PREFIX1, (CEE_SIZEOF & 0xFF), (BYTE)(tokGenericArg), (BYTE)(tokGenericArg >> 8), (BYTE)(tokGenericArg >> 16), (BYTE)(tokGenericArg >> 24), - CEE_RET - }; - - setILIntrinsicMethodInfo(methInfo,const_cast(ilcode),sizeof(ilcode), 1); - - return true; - } else if (tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__BYREF_AS)->GetMemberDef() || tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__OBJECT_AS)->GetMemberDef() || tk == CoreLibBinder::GetMethod(METHOD__UNSAFE__AS_REF_POINTER)->GetMemberDef() || diff --git a/src/libraries/Microsoft.Extensions.Logging.EventSource/src/LoggingEventSource.cs b/src/libraries/Microsoft.Extensions.Logging.EventSource/src/LoggingEventSource.cs index 28f073d9ee0612..c9bc8c5c0aaaf4 100644 --- a/src/libraries/Microsoft.Extensions.Logging.EventSource/src/LoggingEventSource.cs +++ b/src/libraries/Microsoft.Extensions.Logging.EventSource/src/LoggingEventSource.cs @@ -516,7 +516,9 @@ private static unsafe void SetEventData(ref EventData eventData, ref T value, else { eventData.DataPointer = (IntPtr)Unsafe.AsPointer(ref value); - eventData.Size = Unsafe.SizeOf(); +#pragma warning disable 8500 // sizeof of managed types + eventData.Size = sizeof(T); +#pragma warning restore 8500 } } } diff --git a/src/libraries/System.Memory/src/System/Buffers/ArrayMemoryPool.cs b/src/libraries/System.Memory/src/System/Buffers/ArrayMemoryPool.cs index 88ae8b05de7e18..aa0fb4de26bc14 100644 --- a/src/libraries/System.Memory/src/System/Buffers/ArrayMemoryPool.cs +++ b/src/libraries/System.Memory/src/System/Buffers/ArrayMemoryPool.cs @@ -9,12 +9,14 @@ internal sealed partial class ArrayMemoryPool : MemoryPool { public sealed override int MaxBufferSize => Array.MaxLength; - public sealed override IMemoryOwner Rent(int minimumBufferSize = -1) + public sealed override unsafe IMemoryOwner Rent(int minimumBufferSize = -1) { +#pragma warning disable 8500 // sizeof of managed types if (minimumBufferSize == -1) - minimumBufferSize = 1 + (4095 / Unsafe.SizeOf()); + minimumBufferSize = 1 + (4095 / sizeof(T)); else if (((uint)minimumBufferSize) > Array.MaxLength) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.minimumBufferSize); +#pragma warning restore 8500 return new ArrayMemoryPoolBuffer(minimumBufferSize); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Array.cs b/src/libraries/System.Private.CoreLib/src/System/Array.cs index 2e9f5f2e6c8694..a937f69a2d83b9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Array.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Array.cs @@ -11,6 +11,8 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +#pragma warning disable 8500 // sizeof of managed types + namespace System { [Serializable] @@ -1308,7 +1310,7 @@ public static int IndexOf(T[] array, T value, int startIndex) return IndexOf(array, value, startIndex, array.Length - startIndex); } - public static int IndexOf(T[] array, T value, int startIndex, int count) + public static unsafe int IndexOf(T[] array, T value, int startIndex, int count) { if (array == null) { @@ -1327,7 +1329,7 @@ public static int IndexOf(T[] array, T value, int startIndex, int count) if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { int result = SpanHelpers.IndexOfValueType( ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(Unsafe.As(array)), startIndex), @@ -1335,7 +1337,7 @@ ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(Unsafe.As(array)) count); return (result >= 0 ? startIndex : 0) + result; } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { int result = SpanHelpers.IndexOfValueType( ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(Unsafe.As(array)), startIndex), @@ -1343,7 +1345,7 @@ ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(Unsafe.As(array) count); return (result >= 0 ? startIndex : 0) + result; } - else if (Unsafe.SizeOf() == sizeof(int)) + else if (sizeof(T) == sizeof(int)) { int result = SpanHelpers.IndexOfValueType( ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(Unsafe.As(array)), startIndex), @@ -1351,7 +1353,7 @@ ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(Unsafe.As(array)), count); return (result >= 0 ? startIndex : 0) + result; } - else if (Unsafe.SizeOf() == sizeof(long)) + else if (sizeof(T) == sizeof(long)) { int result = SpanHelpers.IndexOfValueType( ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(Unsafe.As(array)), startIndex), @@ -1534,7 +1536,7 @@ public static int LastIndexOf(T[] array, T value, int startIndex) return LastIndexOf(array, value, startIndex, (array.Length == 0) ? 0 : (startIndex + 1)); } - public static int LastIndexOf(T[] array, T value, int startIndex, int count) + public static unsafe int LastIndexOf(T[] array, T value, int startIndex, int count) { if (array == null) { @@ -1574,7 +1576,7 @@ public static int LastIndexOf(T[] array, T value, int startIndex, int count) if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { int endIndex = startIndex - count + 1; int result = SpanHelpers.LastIndexOfValueType( @@ -1584,7 +1586,7 @@ ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(Unsafe.As(array)) return (result >= 0 ? endIndex : 0) + result; } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { int endIndex = startIndex - count + 1; int result = SpanHelpers.LastIndexOfValueType( @@ -1594,7 +1596,7 @@ ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(Unsafe.As(array) return (result >= 0 ? endIndex : 0) + result; } - else if (Unsafe.SizeOf() == sizeof(int)) + else if (sizeof(T) == sizeof(int)) { int endIndex = startIndex - count + 1; int result = SpanHelpers.LastIndexOfValueType( @@ -1604,7 +1606,7 @@ ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(Unsafe.As(array)), return (result >= 0 ? endIndex : 0) + result; } - else if (Unsafe.SizeOf() == sizeof(long)) + else if (sizeof(T) == sizeof(long)) { int endIndex = startIndex - count + 1; int result = SpanHelpers.LastIndexOfValueType( diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffer.cs b/src/libraries/System.Private.CoreLib/src/System/Buffer.cs index 7ea4502c95fff8..52bfa1d39d5dbf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffer.cs @@ -348,15 +348,16 @@ internal static unsafe void _ZeroMemory(ref byte b, nuint byteLength) #if !MONO // Mono BulkMoveWithWriteBarrier is in terms of elements (not bytes) and takes a type handle. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void Memmove(ref T destination, ref T source, nuint elementCount) + internal static unsafe void Memmove(ref T destination, ref T source, nuint elementCount) { +#pragma warning disable 8500 // sizeof of managed types if (!RuntimeHelpers.IsReferenceOrContainsReferences()) { // Blittable memmove Memmove( ref Unsafe.As(ref destination), ref Unsafe.As(ref source), - elementCount * (nuint)Unsafe.SizeOf()); + elementCount * (nuint)sizeof(T)); } else { @@ -364,8 +365,9 @@ ref Unsafe.As(ref source), BulkMoveWithWriteBarrier( ref Unsafe.As(ref destination), ref Unsafe.As(ref source), - elementCount * (nuint)Unsafe.SizeOf()); + elementCount * (nuint)sizeof(T)); } +#pragma warning restore 8500 } // The maximum block size to for __BulkMoveWithWriteBarrier FCall. This is required to avoid GC starvation. diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs index 9206dde5e5fa6f..bffa23fc679632 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs @@ -459,13 +459,18 @@ public void Trim(int currentMilliseconds, int id, Utilities.MemoryPressure press { trimCount++; } - if (Unsafe.SizeOf() > StackModerateTypeSize) + unsafe { - trimCount++; - } - if (Unsafe.SizeOf() > StackLargeTypeSize) - { - trimCount++; +#pragma warning disable 8500 // sizeof of managed types + if (sizeof(T) > StackModerateTypeSize) + { + trimCount++; + } + if (sizeof(T) > StackLargeTypeSize) + { + trimCount++; + } +#pragma warning restore 8500 } break; diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs index 966a1b0ba4358b..cf481d8999649a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs @@ -449,7 +449,7 @@ private static void IntroSort(Span keys, int depthLimit) } } - private static int PickPivotAndPartition(Span keys) + private static unsafe int PickPivotAndPartition(Span keys) { Debug.Assert(keys.Length >= Array.IntrosortSizeThreshold); @@ -494,7 +494,9 @@ private static int PickPivotAndPartition(Span keys) { Swap(ref leftRef, ref nextToLastRef); } - return (int)((nint)Unsafe.ByteOffset(ref zeroRef, ref leftRef) / Unsafe.SizeOf()); +#pragma warning disable 8500 // sizeof of managed types + return (int)((nint)Unsafe.ByteOffset(ref zeroRef, ref leftRef) / sizeof(T)); +#pragma warning restore 8500 } private static void HeapSort(Span keys) diff --git a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyAsciiSearcher.cs b/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyAsciiSearcher.cs index c33807fd33a184..8d9e2794ad2db8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyAsciiSearcher.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IndexOfAnyValues/IndexOfAnyAsciiSearcher.cs @@ -8,6 +8,8 @@ using System.Runtime.Intrinsics.Arm; using System.Runtime.Intrinsics.X86; +#pragma warning disable 8500 // sizeof of managed types + namespace System.Buffers { internal static class IndexOfAnyAsciiSearcher @@ -585,17 +587,17 @@ private static Vector128 Shuffle(Vector128 vector, Vector128 i } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int ComputeFirstIndex(ref T searchSpace, ref T current, Vector128 result) + private static unsafe int ComputeFirstIndex(ref T searchSpace, ref T current, Vector128 result) where TNegator : struct, INegator { uint mask = TNegator.ExtractMask(result); int offsetInVector = BitOperations.TrailingZeroCount(mask); - return offsetInVector + (int)(Unsafe.ByteOffset(ref searchSpace, ref current) / Unsafe.SizeOf()); + return offsetInVector + (int)(Unsafe.ByteOffset(ref searchSpace, ref current) / sizeof(T)); } #pragma warning disable IDE0060 // https://github.com/dotnet/roslyn-analyzers/issues/6228 [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int ComputeFirstIndexOverlapped(ref T searchSpace, ref T current0, ref T current1, Vector128 result) + private static unsafe int ComputeFirstIndexOverlapped(ref T searchSpace, ref T current0, ref T current1, Vector128 result) where TNegator : struct, INegator { uint mask = TNegator.ExtractMask(result); @@ -606,21 +608,21 @@ private static int ComputeFirstIndexOverlapped(ref T searchSpace, r current0 = ref current1; offsetInVector -= Vector128.Count; } - return offsetInVector + (int)(Unsafe.ByteOffset(ref searchSpace, ref current0) / Unsafe.SizeOf()); + return offsetInVector + (int)(Unsafe.ByteOffset(ref searchSpace, ref current0) / sizeof(T)); } #pragma warning restore IDE0060 // https://github.com/dotnet/roslyn-analyzers/issues/6228 [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int ComputeLastIndex(ref T searchSpace, ref T current, Vector128 result) + private static unsafe int ComputeLastIndex(ref T searchSpace, ref T current, Vector128 result) where TNegator : struct, INegator { uint mask = TNegator.ExtractMask(result) & 0xFFFF; int offsetInVector = 31 - BitOperations.LeadingZeroCount(mask); - return offsetInVector + (int)(Unsafe.ByteOffset(ref searchSpace, ref current) / Unsafe.SizeOf()); + return offsetInVector + (int)(Unsafe.ByteOffset(ref searchSpace, ref current) / sizeof(T)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int ComputeLastIndexOverlapped(ref T searchSpace, ref T secondVector, Vector128 result) + private static unsafe int ComputeLastIndexOverlapped(ref T searchSpace, ref T secondVector, Vector128 result) where TNegator : struct, INegator { uint mask = TNegator.ExtractMask(result) & 0xFFFF; @@ -631,7 +633,7 @@ private static int ComputeLastIndexOverlapped(ref T searchSpace, re } // We matched within the second vector - return offsetInVector - Vector128.Count + (int)(Unsafe.ByteOffset(ref searchSpace, ref secondVector) / Unsafe.SizeOf()); + return offsetInVector - Vector128.Count + (int)(Unsafe.ByteOffset(ref searchSpace, ref secondVector) / sizeof(T)); } internal interface INegator diff --git a/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs b/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs index b218550bd2720a..835816e0f38a49 100644 --- a/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs @@ -10,6 +10,8 @@ using System.Runtime.InteropServices; using System.Runtime.Intrinsics; +#pragma warning disable 8500 // sizeof of managed types + namespace System { /// @@ -265,32 +267,32 @@ public static ReadOnlyMemory AsMemory(this string? text, Range range) /// The span to search. /// The value to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool Contains(this Span span, T value) where T : IEquatable? + public static unsafe bool Contains(this Span span, T value) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.ContainsValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { return SpanHelpers.ContainsValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } - else if (Unsafe.SizeOf() == sizeof(int)) + else if (sizeof(T) == sizeof(int)) { return SpanHelpers.ContainsValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } - else if (Unsafe.SizeOf() == sizeof(long)) + else if (sizeof(T) == sizeof(long)) { return SpanHelpers.ContainsValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -309,32 +311,32 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), /// The span to search. /// The value to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool Contains(this ReadOnlySpan span, T value) where T : IEquatable? + public static unsafe bool Contains(this ReadOnlySpan span, T value) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.ContainsValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { return SpanHelpers.ContainsValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } - else if (Unsafe.SizeOf() == sizeof(int)) + else if (sizeof(T) == sizeof(int)) { return SpanHelpers.ContainsValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } - else if (Unsafe.SizeOf() == sizeof(long)) + else if (sizeof(T) == sizeof(long)) { return SpanHelpers.ContainsValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -352,29 +354,29 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), /// The span to search. /// The value to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int IndexOf(this Span span, T value) where T : IEquatable? + public static unsafe int IndexOf(this Span span, T value) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) return SpanHelpers.IndexOfValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); - if (Unsafe.SizeOf() == sizeof(short)) + if (sizeof(T) == sizeof(short)) return SpanHelpers.IndexOfValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); - if (Unsafe.SizeOf() == sizeof(int)) + if (sizeof(T) == sizeof(int)) return SpanHelpers.IndexOfValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); - if (Unsafe.SizeOf() == sizeof(long)) + if (sizeof(T) == sizeof(long)) return SpanHelpers.IndexOfValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), @@ -390,18 +392,18 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), /// The span to search. /// The sequence to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int IndexOf(this Span span, ReadOnlySpan value) where T : IEquatable? + public static unsafe int IndexOf(this Span span, ReadOnlySpan value) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) return SpanHelpers.IndexOf( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As(ref MemoryMarshal.GetReference(value)), value.Length); - if (Unsafe.SizeOf() == sizeof(char)) + if (sizeof(T) == sizeof(char)) return SpanHelpers.IndexOf( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), span.Length, @@ -418,32 +420,32 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(value)), /// The span to search. /// The value to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int LastIndexOf(this Span span, T value) where T : IEquatable? + public static unsafe int LastIndexOf(this Span span, T value) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.LastIndexOfValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { return SpanHelpers.LastIndexOfValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } - else if (Unsafe.SizeOf() == sizeof(int)) + else if (sizeof(T) == sizeof(int)) { return SpanHelpers.LastIndexOfValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } - else if (Unsafe.SizeOf() == sizeof(long)) + else if (sizeof(T) == sizeof(long)) { return SpanHelpers.LastIndexOfValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -461,11 +463,11 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), /// The span to search. /// The sequence to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int LastIndexOf(this Span span, ReadOnlySpan value) where T : IEquatable? + public static unsafe int LastIndexOf(this Span span, ReadOnlySpan value) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.LastIndexOf( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -473,7 +475,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), ref Unsafe.As(ref MemoryMarshal.GetReference(value)), value.Length); } - else if (Unsafe.SizeOf() == sizeof(char)) + else if (sizeof(T) == sizeof(char)) { return SpanHelpers.LastIndexOf( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -554,25 +556,25 @@ public static int IndexOfAnyExcept(this Span span, IndexOfAnyValues val /// If all of the values are , returns -1. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int IndexOfAnyExcept(this ReadOnlySpan span, T value) where T : IEquatable? + public static unsafe int IndexOfAnyExcept(this ReadOnlySpan span, T value) where T : IEquatable? { if (SpanHelpers.CanVectorizeAndBenefit(span.Length)) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.IndexOfAnyExceptValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { return SpanHelpers.IndexOfAnyExceptValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } - else if (Unsafe.SizeOf() == sizeof(int)) + else if (sizeof(T) == sizeof(int)) { return SpanHelpers.IndexOfAnyExceptValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -581,7 +583,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), } else { - Debug.Assert(Unsafe.SizeOf() == sizeof(long)); + Debug.Assert(sizeof(T) == sizeof(long)); return SpanHelpers.IndexOfAnyExceptValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -605,11 +607,11 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), /// If all of the values are or , returns -1. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int IndexOfAnyExcept(this ReadOnlySpan span, T value0, T value1) where T : IEquatable? + public static unsafe int IndexOfAnyExcept(this ReadOnlySpan span, T value0, T value1) where T : IEquatable? { if (SpanHelpers.CanVectorizeAndBenefit(span.Length)) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.IndexOfAnyExceptValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -617,7 +619,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value1), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { return SpanHelpers.IndexOfAnyExceptValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -641,11 +643,11 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), /// If all of the values are , , and , returns -1. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int IndexOfAnyExcept(this ReadOnlySpan span, T value0, T value1, T value2) where T : IEquatable? + public static unsafe int IndexOfAnyExcept(this ReadOnlySpan span, T value0, T value1, T value2) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.IndexOfAnyExceptValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -654,7 +656,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value2), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { return SpanHelpers.IndexOfAnyExceptValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -669,11 +671,11 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int IndexOfAnyExcept(this ReadOnlySpan span, T value0, T value1, T value2, T value3) where T : IEquatable? + private static unsafe int IndexOfAnyExcept(this ReadOnlySpan span, T value0, T value1, T value2, T value3) where T : IEquatable? { if (SpanHelpers.CanVectorizeAndBenefit(span.Length)) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.IndexOfAnyExceptValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -683,7 +685,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value3), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { return SpanHelpers.IndexOfAnyExceptValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -706,7 +708,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), /// The index in the span of the first occurrence of any value other than those in . /// If all of the values are in , returns -1. /// - public static int IndexOfAnyExcept(this ReadOnlySpan span, ReadOnlySpan values) where T : IEquatable? + public static unsafe int IndexOfAnyExcept(this ReadOnlySpan span, ReadOnlySpan values) where T : IEquatable? { switch (values.Length) { @@ -731,7 +733,7 @@ public static int IndexOfAnyExcept(this ReadOnlySpan span, ReadOnlySpan default: if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte) && values.Length == 5) + if (sizeof(T) == sizeof(byte) && values.Length == 5) { ref byte valuesRef = ref Unsafe.As(ref MemoryMarshal.GetReference(values)); @@ -744,7 +746,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.Add(ref valuesRef, 4), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short) && values.Length == 5) + else if (sizeof(T) == sizeof(short) && values.Length == 5) { ref short valuesRef = ref Unsafe.As(ref MemoryMarshal.GetReference(values)); @@ -759,7 +761,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), } } - if (RuntimeHelpers.IsBitwiseEquatable() && Unsafe.SizeOf() == sizeof(char)) + if (RuntimeHelpers.IsBitwiseEquatable() && sizeof(T) == sizeof(char)) { return ProbabilisticMap.IndexOfAnyExcept( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -860,25 +862,25 @@ public static int LastIndexOfAnyExcept(this Span span, IndexOfAnyValues /// If all of the values are , returns -1. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int LastIndexOfAnyExcept(this ReadOnlySpan span, T value) where T : IEquatable? + public static unsafe int LastIndexOfAnyExcept(this ReadOnlySpan span, T value) where T : IEquatable? { if (SpanHelpers.CanVectorizeAndBenefit(span.Length)) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.LastIndexOfAnyExceptValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { return SpanHelpers.LastIndexOfAnyExceptValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } - else if (Unsafe.SizeOf() == sizeof(int)) + else if (sizeof(T) == sizeof(int)) { return SpanHelpers.LastIndexOfAnyExceptValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -887,7 +889,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), } else { - Debug.Assert(Unsafe.SizeOf() == sizeof(long)); + Debug.Assert(sizeof(T) == sizeof(long)); return SpanHelpers.LastIndexOfAnyExceptValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -911,11 +913,11 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), /// If all of the values are or , returns -1. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int LastIndexOfAnyExcept(this ReadOnlySpan span, T value0, T value1) where T : IEquatable? + public static unsafe int LastIndexOfAnyExcept(this ReadOnlySpan span, T value0, T value1) where T : IEquatable? { if (SpanHelpers.CanVectorizeAndBenefit(span.Length)) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.LastIndexOfAnyExceptValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -923,7 +925,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value1), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { return SpanHelpers.LastIndexOfAnyExceptValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -947,11 +949,11 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), /// If all of the values are , , and , returns -1. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int LastIndexOfAnyExcept(this ReadOnlySpan span, T value0, T value1, T value2) where T : IEquatable? + public static unsafe int LastIndexOfAnyExcept(this ReadOnlySpan span, T value0, T value1, T value2) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.LastIndexOfAnyExceptValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -960,7 +962,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value2), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { return SpanHelpers.LastIndexOfAnyExceptValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -975,11 +977,11 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int LastIndexOfAnyExcept(this ReadOnlySpan span, T value0, T value1, T value2, T value3) where T : IEquatable? + private static unsafe int LastIndexOfAnyExcept(this ReadOnlySpan span, T value0, T value1, T value2, T value3) where T : IEquatable? { if (SpanHelpers.CanVectorizeAndBenefit(span.Length)) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.LastIndexOfAnyExceptValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -989,7 +991,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value3), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { return SpanHelpers.LastIndexOfAnyExceptValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1012,7 +1014,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), /// The index in the span of the first occurrence of any value other than those in . /// If all of the values are in , returns -1. /// - public static int LastIndexOfAnyExcept(this ReadOnlySpan span, ReadOnlySpan values) where T : IEquatable? + public static unsafe int LastIndexOfAnyExcept(this ReadOnlySpan span, ReadOnlySpan values) where T : IEquatable? { switch (values.Length) { @@ -1038,7 +1040,7 @@ public static int LastIndexOfAnyExcept(this ReadOnlySpan span, ReadOnlySpa default: if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte) && values.Length == 5) + if (sizeof(T) == sizeof(byte) && values.Length == 5) { ref byte valuesRef = ref Unsafe.As(ref MemoryMarshal.GetReference(values)); @@ -1051,7 +1053,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.Add(ref valuesRef, 4), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short) && values.Length == 5) + else if (sizeof(T) == sizeof(short) && values.Length == 5) { ref short valuesRef = ref Unsafe.As(ref MemoryMarshal.GetReference(values)); @@ -1066,7 +1068,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), } } - if (RuntimeHelpers.IsBitwiseEquatable() && Unsafe.SizeOf() == sizeof(char)) + if (RuntimeHelpers.IsBitwiseEquatable() && sizeof(T) == sizeof(char)) { return ProbabilisticMap.LastIndexOfAnyExcept( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1376,13 +1378,13 @@ private static void ThrowNullLowHighInclusive(T? lowInclusive, T? highInclusi /// [Intrinsic] // Unrolled and vectorized for half-constant input [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool SequenceEqual(this Span span, ReadOnlySpan other) where T : IEquatable? + public static unsafe bool SequenceEqual(this Span span, ReadOnlySpan other) where T : IEquatable? { int length = span.Length; if (RuntimeHelpers.IsBitwiseEquatable()) { - nuint size = (nuint)Unsafe.SizeOf(); + nuint size = (nuint)sizeof(T); return length == other.Length && SpanHelpers.SequenceEqual( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1425,29 +1427,29 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(other)), /// The span to search. /// The value to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int IndexOf(this ReadOnlySpan span, T value) where T : IEquatable? + public static unsafe int IndexOf(this ReadOnlySpan span, T value) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) return SpanHelpers.IndexOfValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); - if (Unsafe.SizeOf() == sizeof(short)) + if (sizeof(T) == sizeof(short)) return SpanHelpers.IndexOfValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); - if (Unsafe.SizeOf() == sizeof(int)) + if (sizeof(T) == sizeof(int)) return SpanHelpers.IndexOfValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); - if (Unsafe.SizeOf() == sizeof(long)) + if (sizeof(T) == sizeof(long)) return SpanHelpers.IndexOfValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), @@ -1463,18 +1465,18 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), /// The span to search. /// The sequence to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int IndexOf(this ReadOnlySpan span, ReadOnlySpan value) where T : IEquatable? + public static unsafe int IndexOf(this ReadOnlySpan span, ReadOnlySpan value) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) return SpanHelpers.IndexOf( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As(ref MemoryMarshal.GetReference(value)), value.Length); - if (Unsafe.SizeOf() == sizeof(char)) + if (sizeof(T) == sizeof(char)) return SpanHelpers.IndexOf( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), span.Length, @@ -1491,32 +1493,32 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(value)), /// The span to search. /// The value to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int LastIndexOf(this ReadOnlySpan span, T value) where T : IEquatable? + public static unsafe int LastIndexOf(this ReadOnlySpan span, T value) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.LastIndexOfValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { return SpanHelpers.LastIndexOfValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } - else if (Unsafe.SizeOf() == sizeof(int)) + else if (sizeof(T) == sizeof(int)) { return SpanHelpers.LastIndexOfValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value), span.Length); } - else if (Unsafe.SizeOf() == sizeof(long)) + else if (sizeof(T) == sizeof(long)) { return SpanHelpers.LastIndexOfValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1534,11 +1536,11 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), /// The span to search. /// The sequence to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int LastIndexOf(this ReadOnlySpan span, ReadOnlySpan value) where T : IEquatable? + public static unsafe int LastIndexOf(this ReadOnlySpan span, ReadOnlySpan value) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.LastIndexOf( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1546,7 +1548,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), ref Unsafe.As(ref MemoryMarshal.GetReference(value)), value.Length); } - if (Unsafe.SizeOf() == sizeof(char)) + if (sizeof(T) == sizeof(char)) { return SpanHelpers.LastIndexOf( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1566,11 +1568,11 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(value)), /// One of the values to search for. /// One of the values to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int IndexOfAny(this Span span, T value0, T value1) where T : IEquatable? + public static unsafe int IndexOfAny(this Span span, T value0, T value1) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.IndexOfAnyValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1578,7 +1580,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value1), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { return SpanHelpers.IndexOfAnyValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1599,11 +1601,11 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), /// One of the values to search for. /// One of the values to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int IndexOfAny(this Span span, T value0, T value1, T value2) where T : IEquatable? + public static unsafe int IndexOfAny(this Span span, T value0, T value1, T value2) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.IndexOfAnyValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1612,7 +1614,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value2), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { return SpanHelpers.IndexOfAnyValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1651,11 +1653,11 @@ public static int IndexOfAny(this Span span, IndexOfAnyValues values) w /// One of the values to search for. /// One of the values to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int IndexOfAny(this ReadOnlySpan span, T value0, T value1) where T : IEquatable? + public static unsafe int IndexOfAny(this ReadOnlySpan span, T value0, T value1) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.IndexOfAnyValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1663,7 +1665,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value1), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { return SpanHelpers.IndexOfAnyValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1684,11 +1686,11 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), /// One of the values to search for. /// One of the values to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int IndexOfAny(this ReadOnlySpan span, T value0, T value1, T value2) where T : IEquatable? + public static unsafe int IndexOfAny(this ReadOnlySpan span, T value0, T value1, T value2) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.IndexOfAnyValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1697,7 +1699,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value2), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { return SpanHelpers.IndexOfAnyValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1717,11 +1719,11 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), /// The span to search. /// The set of values to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int IndexOfAny(this ReadOnlySpan span, ReadOnlySpan values) where T : IEquatable? + public static unsafe int IndexOfAny(this ReadOnlySpan span, ReadOnlySpan values) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { ref byte spanRef = ref Unsafe.As(ref MemoryMarshal.GetReference(span)); ref byte valueRef = ref Unsafe.As(ref MemoryMarshal.GetReference(values)); @@ -1770,7 +1772,7 @@ public static int IndexOfAny(this ReadOnlySpan span, ReadOnlySpan value } } - if (Unsafe.SizeOf() == sizeof(short)) + if (sizeof(T) == sizeof(short)) { ref short spanRef = ref Unsafe.As(ref MemoryMarshal.GetReference(span)); ref short valueRef = ref Unsafe.As(ref MemoryMarshal.GetReference(values)); @@ -1841,11 +1843,11 @@ public static int IndexOfAny(this ReadOnlySpan span, IndexOfAnyValues v /// One of the values to search for. /// One of the values to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int LastIndexOfAny(this Span span, T value0, T value1) where T : IEquatable? + public static unsafe int LastIndexOfAny(this Span span, T value0, T value1) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.LastIndexOfAnyValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1853,7 +1855,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value1), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { return SpanHelpers.LastIndexOfAnyValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1874,11 +1876,11 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), /// One of the values to search for. /// One of the values to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int LastIndexOfAny(this Span span, T value0, T value1, T value2) where T : IEquatable? + public static unsafe int LastIndexOfAny(this Span span, T value0, T value1, T value2) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.LastIndexOfAnyValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1887,7 +1889,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value2), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { return SpanHelpers.LastIndexOfAnyValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1926,11 +1928,11 @@ public static int LastIndexOfAny(this Span span, IndexOfAnyValues value /// One of the values to search for. /// One of the values to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int LastIndexOfAny(this ReadOnlySpan span, T value0, T value1) where T : IEquatable? + public static unsafe int LastIndexOfAny(this ReadOnlySpan span, T value0, T value1) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.LastIndexOfAnyValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1938,7 +1940,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value1), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { return SpanHelpers.LastIndexOfAnyValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1959,11 +1961,11 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), /// One of the values to search for. /// One of the values to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int LastIndexOfAny(this ReadOnlySpan span, T value0, T value1, T value2) where T : IEquatable? + public static unsafe int LastIndexOfAny(this ReadOnlySpan span, T value0, T value1, T value2) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return SpanHelpers.LastIndexOfAnyValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1972,7 +1974,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), Unsafe.As(ref value2), span.Length); } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { return SpanHelpers.LastIndexOfAnyValueType( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -1992,11 +1994,11 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(span)), /// The span to search. /// The set of values to search for. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int LastIndexOfAny(this ReadOnlySpan span, ReadOnlySpan values) where T : IEquatable? + public static unsafe int LastIndexOfAny(this ReadOnlySpan span, ReadOnlySpan values) where T : IEquatable? { if (RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { ref byte spanRef = ref Unsafe.As(ref MemoryMarshal.GetReference(span)); ref byte valueRef = ref Unsafe.As(ref MemoryMarshal.GetReference(values)); @@ -2046,7 +2048,7 @@ public static int LastIndexOfAny(this ReadOnlySpan span, ReadOnlySpan v } } - if (Unsafe.SizeOf() == sizeof(short)) + if (sizeof(T) == sizeof(short)) { ref short spanRef = ref Unsafe.As(ref MemoryMarshal.GetReference(span)); ref short valueRef = ref Unsafe.As(ref MemoryMarshal.GetReference(values)); @@ -2117,12 +2119,12 @@ public static int LastIndexOfAny(this ReadOnlySpan span, IndexOfAnyValues< /// [Intrinsic] // Unrolled and vectorized for half-constant input [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool SequenceEqual(this ReadOnlySpan span, ReadOnlySpan other) where T : IEquatable? + public static unsafe bool SequenceEqual(this ReadOnlySpan span, ReadOnlySpan other) where T : IEquatable? { int length = span.Length; if (RuntimeHelpers.IsBitwiseEquatable()) { - nuint size = (nuint)Unsafe.SizeOf(); + nuint size = (nuint)sizeof(T); return length == other.Length && SpanHelpers.SequenceEqual( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -2150,7 +2152,7 @@ public static bool SequenceEqual(this Span span, ReadOnlySpan other, IE /// The second sequence to compare. /// The implementation to use when comparing elements, or null to use the default for the type of an element. /// true if the two sequences are equal; otherwise, false. - public static bool SequenceEqual(this ReadOnlySpan span, ReadOnlySpan other, IEqualityComparer? comparer = null) + public static unsafe bool SequenceEqual(this ReadOnlySpan span, ReadOnlySpan other, IEqualityComparer? comparer = null) { // If the spans differ in length, they're not equal. if (span.Length != other.Length) @@ -2165,7 +2167,7 @@ public static bool SequenceEqual(this ReadOnlySpan span, ReadOnlySpan o // If no comparer was supplied and the type is bitwise equatable, take the fast path doing a bitwise comparison. if (RuntimeHelpers.IsBitwiseEquatable()) { - nuint size = (nuint)Unsafe.SizeOf(); + nuint size = (nuint)sizeof(T); return SpanHelpers.SequenceEqual( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), ref Unsafe.As(ref MemoryMarshal.GetReference(other)), @@ -2202,7 +2204,7 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(other)), /// Determines the relative order of the sequences being compared by comparing the elements using IComparable{T}.CompareTo(T). /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SequenceCompareTo(this ReadOnlySpan span, ReadOnlySpan other) + public static unsafe int SequenceCompareTo(this ReadOnlySpan span, ReadOnlySpan other) where T : IComparable? { // Can't use IsBitwiseEquatable() below because that only tells us about @@ -2230,12 +2232,12 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(other)), /// [Intrinsic] // Unrolled and vectorized for half-constant input [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool StartsWith(this Span span, ReadOnlySpan value) where T : IEquatable? + public static unsafe bool StartsWith(this Span span, ReadOnlySpan value) where T : IEquatable? { int valueLength = value.Length; if (RuntimeHelpers.IsBitwiseEquatable()) { - nuint size = (nuint)Unsafe.SizeOf(); + nuint size = (nuint)sizeof(T); return valueLength <= span.Length && SpanHelpers.SequenceEqual( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -2251,12 +2253,12 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(value)), /// [Intrinsic] // Unrolled and vectorized for half-constant input [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool StartsWith(this ReadOnlySpan span, ReadOnlySpan value) where T : IEquatable? + public static unsafe bool StartsWith(this ReadOnlySpan span, ReadOnlySpan value) where T : IEquatable? { int valueLength = value.Length; if (RuntimeHelpers.IsBitwiseEquatable()) { - nuint size = (nuint)Unsafe.SizeOf(); + nuint size = (nuint)sizeof(T); return valueLength <= span.Length && SpanHelpers.SequenceEqual( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), @@ -2271,13 +2273,13 @@ ref Unsafe.As(ref MemoryMarshal.GetReference(value)), /// Determines whether the specified sequence appears at the end of the span. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool EndsWith(this Span span, ReadOnlySpan value) where T : IEquatable? + public static unsafe bool EndsWith(this Span span, ReadOnlySpan value) where T : IEquatable? { int spanLength = span.Length; int valueLength = value.Length; if (RuntimeHelpers.IsBitwiseEquatable()) { - nuint size = (nuint)Unsafe.SizeOf(); + nuint size = (nuint)sizeof(T); return valueLength <= spanLength && SpanHelpers.SequenceEqual( ref Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), (nint)(uint)(spanLength - valueLength) /* force zero-extension */)), @@ -2296,13 +2298,13 @@ ref MemoryMarshal.GetReference(value), /// Determines whether the specified sequence appears at the end of the span. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool EndsWith(this ReadOnlySpan span, ReadOnlySpan value) where T : IEquatable? + public static unsafe bool EndsWith(this ReadOnlySpan span, ReadOnlySpan value) where T : IEquatable? { int spanLength = span.Length; int valueLength = value.Length; if (RuntimeHelpers.IsBitwiseEquatable()) { - nuint size = (nuint)Unsafe.SizeOf(); + nuint size = (nuint)sizeof(T); return valueLength <= spanLength && SpanHelpers.SequenceEqual( ref Unsafe.As(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), (nint)(uint)(spanLength - valueLength) /* force zero-extension */)), @@ -2632,9 +2634,9 @@ public static void CopyTo(this T[]? source, Memory destination) // Let's say there are two sequences, x and y. Let // // ref T xRef = MemoryMarshal.GetReference(x) - // uint xLength = x.Length * Unsafe.SizeOf() + // uint xLength = x.Length * sizeof(T) // ref T yRef = MemoryMarshal.GetReference(y) - // uint yLength = y.Length * Unsafe.SizeOf() + // uint yLength = y.Length * sizeof(T) // // Visually, the two sequences are located somewhere in the 32-bit // address space as follows: @@ -2729,33 +2731,25 @@ public static bool Overlaps(this Span span, ReadOnlySpan other, out int /// /// Determines whether two sequences overlap in memory. /// - public static bool Overlaps(this ReadOnlySpan span, ReadOnlySpan other) + public static unsafe bool Overlaps(this ReadOnlySpan span, ReadOnlySpan other) { if (span.IsEmpty || other.IsEmpty) { return false; } - IntPtr byteOffset = Unsafe.ByteOffset( + nint byteOffset = Unsafe.ByteOffset( ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other)); - if (Unsafe.SizeOf() == sizeof(int)) - { - return (uint)byteOffset < (uint)(span.Length * Unsafe.SizeOf()) || - (uint)byteOffset > (uint)-(other.Length * Unsafe.SizeOf()); - } - else - { - return (ulong)byteOffset < (ulong)((long)span.Length * Unsafe.SizeOf()) || - (ulong)byteOffset > (ulong)-((long)other.Length * Unsafe.SizeOf()); - } + return (nuint)byteOffset < (nuint)((nint)span.Length * sizeof(T)) || + (nuint)byteOffset > (nuint)(-((nint)other.Length * sizeof(T))); } /// /// Determines whether two sequences overlap in memory and outputs the element offset. /// - public static bool Overlaps(this ReadOnlySpan span, ReadOnlySpan other, out int elementOffset) + public static unsafe bool Overlaps(this ReadOnlySpan span, ReadOnlySpan other, out int elementOffset) { if (span.IsEmpty || other.IsEmpty) { @@ -2767,39 +2761,19 @@ public static bool Overlaps(this ReadOnlySpan span, ReadOnlySpan other, ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other)); - if (Unsafe.SizeOf() == sizeof(int)) + if ((nuint)byteOffset < (nuint)((nint)span.Length * sizeof(T)) || + (nuint)byteOffset > (nuint)(-((nint)other.Length * sizeof(T)))) { - if ((uint)byteOffset < (uint)(span.Length * Unsafe.SizeOf()) || - (uint)byteOffset > (uint)-(other.Length * Unsafe.SizeOf())) - { - if ((int)byteOffset % Unsafe.SizeOf() != 0) - ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch(); + if (byteOffset % sizeof(T) != 0) + ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch(); - elementOffset = (int)byteOffset / Unsafe.SizeOf(); - return true; - } - else - { - elementOffset = 0; - return false; - } + elementOffset = (int)(byteOffset / sizeof(T)); + return true; } else { - if ((ulong)byteOffset < (ulong)((long)span.Length * Unsafe.SizeOf()) || - (ulong)byteOffset > (ulong)-((long)other.Length * Unsafe.SizeOf())) - { - if ((long)byteOffset % Unsafe.SizeOf() != 0) - ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch(); - - elementOffset = (int)((long)byteOffset / Unsafe.SizeOf()); - return true; - } - else - { - elementOffset = 0; - return false; - } + elementOffset = 0; + return false; } } @@ -3096,13 +3070,13 @@ public static void Sort(this Span keys, Span items, /// The value to be replaced with . /// The value to replace all occurrences of . [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Replace(this Span span, T oldValue, T newValue) where T : IEquatable? + public static unsafe void Replace(this Span span, T oldValue, T newValue) where T : IEquatable? { if (SpanHelpers.CanVectorizeAndBenefit(span.Length)) { nuint length = (uint)span.Length; - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { ref byte src = ref Unsafe.As(ref MemoryMarshal.GetReference(span)); SpanHelpers.ReplaceValueType( @@ -3112,7 +3086,7 @@ public static void Replace(this Span span, T oldValue, T newValue) where T Unsafe.As(ref newValue), length); } - else if (Unsafe.SizeOf() == sizeof(ushort)) + else if (sizeof(T) == sizeof(ushort)) { // Use ushort rather than short, as this avoids a sign-extending move. ref ushort src = ref Unsafe.As(ref MemoryMarshal.GetReference(span)); @@ -3123,7 +3097,7 @@ public static void Replace(this Span span, T oldValue, T newValue) where T Unsafe.As(ref newValue), length); } - else if (Unsafe.SizeOf() == sizeof(int)) + else if (sizeof(T) == sizeof(int)) { ref int src = ref Unsafe.As(ref MemoryMarshal.GetReference(span)); SpanHelpers.ReplaceValueType( @@ -3135,7 +3109,7 @@ public static void Replace(this Span span, T oldValue, T newValue) where T } else { - Debug.Assert(Unsafe.SizeOf() == sizeof(long)); + Debug.Assert(sizeof(T) == sizeof(long)); ref long src = ref Unsafe.As(ref MemoryMarshal.GetReference(span)); SpanHelpers.ReplaceValueType( @@ -3172,12 +3146,12 @@ public static int CommonPrefixLength(this Span span, ReadOnlySpan other /// The first sequence to compare. /// The second sequence to compare. /// The length of the common prefix shared by the two spans. If there's no shared prefix, 0 is returned. - public static int CommonPrefixLength(this ReadOnlySpan span, ReadOnlySpan other) + public static unsafe int CommonPrefixLength(this ReadOnlySpan span, ReadOnlySpan other) { if (RuntimeHelpers.IsBitwiseEquatable()) { nuint length = Math.Min((nuint)(uint)span.Length, (nuint)(uint)other.Length); - nuint size = (uint)Unsafe.SizeOf(); + nuint size = (uint)sizeof(T); nuint index = SpanHelpers.CommonPrefixLength( ref Unsafe.As(ref MemoryMarshal.GetReference(span)), ref Unsafe.As(ref MemoryMarshal.GetReference(other)), diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector_1.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector_1.cs index 960bf2498338ba..55cd24908a0600 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector_1.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector_1.cs @@ -142,14 +142,16 @@ public static Vector AllBitsSet /// Gets the number of that are in a . /// The type of the current instance () is not supported. - public static int Count + public static unsafe int Count { [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] get { ThrowHelper.ThrowForUnsupportedNumericsVectorBaseType(); - return Unsafe.SizeOf>() / Unsafe.SizeOf(); +#pragma warning disable 8500 // sizeof of managed types + return sizeof(Vector) / sizeof(T); +#pragma warning restore 8500 } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/Unsafe.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/Unsafe.cs index 8a576105ba2604..9b2891bc2ebe7b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/Unsafe.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/Unsafe.cs @@ -12,6 +12,8 @@ // In AOT compilers, see Internal.IL.Stubs.UnsafeIntrinsics for details. // +#pragma warning disable 8500 // sizeof of managed types + namespace System.Runtime.CompilerServices { /// @@ -49,13 +51,7 @@ public static unsafe partial class Unsafe [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int SizeOf() { -#if CORECLR - typeof(T).ToString(); // Type token used by the actual method body -#endif - throw new PlatformNotSupportedException(); - - // sizeof !!T - // ret + return sizeof(T); } /// @@ -108,7 +104,7 @@ public static ref T Add(ref T source, int elementOffset) typeof(T).ToString(); // Type token used by the actual method body throw new PlatformNotSupportedException(); #else - return ref AddByteOffset(ref source, (IntPtr)(elementOffset * (nint)SizeOf())); + return ref AddByteOffset(ref source, (IntPtr)(elementOffset * (nint)sizeof(T))); #endif // ldarg .0 // ldarg .1 @@ -134,7 +130,7 @@ public static ref T Add(ref T source, IntPtr elementOffset) typeof(T).ToString(); // Type token used by the actual method body throw new PlatformNotSupportedException(); #else - return ref AddByteOffset(ref source, (IntPtr)((nint)elementOffset * (nint)SizeOf())); + return ref AddByteOffset(ref source, (IntPtr)((nint)elementOffset * (nint)sizeof(T))); #endif // ldarg .0 @@ -161,7 +157,7 @@ public static ref T Add(ref T source, IntPtr elementOffset) typeof(T).ToString(); // Type token used by the actual method body throw new PlatformNotSupportedException(); #else - return (byte*)source + (elementOffset * (nint)SizeOf()); + return (byte*)source + (elementOffset * (nint)sizeof(T)); #endif // ldarg .0 @@ -187,7 +183,7 @@ public static ref T Add(ref T source, nuint elementOffset) typeof(T).ToString(); throw new PlatformNotSupportedException(); #else - return ref AddByteOffset(ref source, (nuint)(elementOffset * (nuint)SizeOf())); + return ref AddByteOffset(ref source, (nuint)(elementOffset * (nuint)sizeof(T))); #endif // ldarg .0 @@ -767,7 +763,7 @@ public static ref T Subtract(ref T source, int elementOffset) typeof(T).ToString(); throw new PlatformNotSupportedException(); #else - return ref SubtractByteOffset(ref source, (IntPtr)(elementOffset * (nint)SizeOf())); + return ref SubtractByteOffset(ref source, (IntPtr)(elementOffset * (nint)sizeof(T))); #endif // ldarg .0 @@ -793,7 +789,7 @@ public static ref T Subtract(ref T source, int elementOffset) typeof(T).ToString(); throw new PlatformNotSupportedException(); #else - return (byte*)source - (elementOffset * (nint)Unsafe.SizeOf()); + return (byte*)source - (elementOffset * (nint)sizeof(T)); #endif // ldarg .0 @@ -818,7 +814,7 @@ public static ref T Subtract(ref T source, IntPtr elementOffset) typeof(T).ToString(); throw new PlatformNotSupportedException(); #else - return ref SubtractByteOffset(ref source, (IntPtr)((nint)elementOffset * (nint)SizeOf())); + return ref SubtractByteOffset(ref source, (IntPtr)((nint)elementOffset * (nint)sizeof(T))); #endif // ldarg .0 @@ -843,7 +839,7 @@ public static ref T Subtract(ref T source, nuint elementOffset) typeof(T).ToString(); throw new PlatformNotSupportedException(); #else - return ref SubtractByteOffset(ref source, (nuint)(elementOffset * (nuint)Unsafe.SizeOf())); + return ref SubtractByteOffset(ref source, (nuint)(elementOffset * (nuint)sizeof(T))); #endif // ldarg .0 diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs index 4c6dca1e3aa603..c1756ce8d4c60a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs @@ -183,7 +183,9 @@ public static unsafe IntPtr UnsafeAddrOfPinnedArrayElement(T[] arr, int index ArgumentNullException.ThrowIfNull(arr); void* pRawData = Unsafe.AsPointer(ref MemoryMarshal.GetArrayDataReference(arr)); - return (IntPtr)((byte*)pRawData + (uint)index * (nuint)Unsafe.SizeOf()); +#pragma warning disable 8500 // sizeof of managed types + return (IntPtr)((byte*)pRawData + (uint)index * (nuint)sizeof(T)); +#pragma warning restore 8500 } public static IntPtr OffsetOf(string fieldName) => OffsetOf(typeof(T), fieldName); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.cs index d1cdd3544ef58b..952b0cfcc730b8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.cs @@ -7,6 +7,8 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; +#pragma warning disable 8500 // sizeof of managed types + namespace System.Runtime.InteropServices { /// @@ -27,7 +29,7 @@ public static partial class MemoryMarshal /// Thrown if the Length property of the new Span would exceed int.MaxValue. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Span AsBytes(Span span) + public static unsafe Span AsBytes(Span span) where T : struct { if (RuntimeHelpers.IsReferenceOrContainsReferences()) @@ -35,7 +37,7 @@ public static Span AsBytes(Span span) return new Span( ref Unsafe.As(ref GetReference(span)), - checked(span.Length * Unsafe.SizeOf())); + checked(span.Length * sizeof(T))); } /// @@ -50,7 +52,7 @@ ref Unsafe.As(ref GetReference(span)), /// Thrown if the Length property of the new Span would exceed int.MaxValue. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ReadOnlySpan AsBytes(ReadOnlySpan span) + public static unsafe ReadOnlySpan AsBytes(ReadOnlySpan span) where T : struct { if (RuntimeHelpers.IsReferenceOrContainsReferences()) @@ -58,7 +60,7 @@ public static ReadOnlySpan AsBytes(ReadOnlySpan span) return new ReadOnlySpan( ref Unsafe.As(ref GetReference(span)), - checked(span.Length * Unsafe.SizeOf())); + checked(span.Length * sizeof(T))); } /// Creates a from a . @@ -414,14 +416,14 @@ public static bool TryGetString(ReadOnlyMemory memory, [NotNullWhen(true)] /// Reads a structure of type T out of a read-only span of bytes. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T Read(ReadOnlySpan source) + public static unsafe T Read(ReadOnlySpan source) where T : struct { if (RuntimeHelpers.IsReferenceOrContainsReferences()) { ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T)); } - if (Unsafe.SizeOf() > source.Length) + if (sizeof(T) > source.Length) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length); } @@ -433,14 +435,14 @@ public static T Read(ReadOnlySpan source) /// /// If the span is too small to contain the type T, return false. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryRead(ReadOnlySpan source, out T value) + public static unsafe bool TryRead(ReadOnlySpan source, out T value) where T : struct { if (RuntimeHelpers.IsReferenceOrContainsReferences()) { ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T)); } - if (Unsafe.SizeOf() > (uint)source.Length) + if (sizeof(T) > (uint)source.Length) { value = default; return false; @@ -453,14 +455,14 @@ public static bool TryRead(ReadOnlySpan source, out T value) /// Writes a structure of type T into a span of bytes. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Write(Span destination, ref T value) + public static unsafe void Write(Span destination, ref T value) where T : struct { if (RuntimeHelpers.IsReferenceOrContainsReferences()) { ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T)); } - if ((uint)Unsafe.SizeOf() > (uint)destination.Length) + if ((uint)sizeof(T) > (uint)destination.Length) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length); } @@ -472,14 +474,14 @@ public static void Write(Span destination, ref T value) /// /// If the span is too small to contain the type T, return false. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryWrite(Span destination, ref T value) + public static unsafe bool TryWrite(Span destination, ref T value) where T : struct { if (RuntimeHelpers.IsReferenceOrContainsReferences()) { ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T)); } - if (Unsafe.SizeOf() > (uint)destination.Length) + if (sizeof(T) > (uint)destination.Length) { return false; } @@ -495,14 +497,14 @@ public static bool TryWrite(Span destination, ref T value) /// Supported only for platforms that support misaligned memory access or when the memory block is aligned by other means. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ref T AsRef(Span span) + public static unsafe ref T AsRef(Span span) where T : struct { if (RuntimeHelpers.IsReferenceOrContainsReferences()) { ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T)); } - if (Unsafe.SizeOf() > (uint)span.Length) + if (sizeof(T) > (uint)span.Length) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length); } @@ -517,14 +519,14 @@ public static ref T AsRef(Span span) /// Supported only for platforms that support misaligned memory access or when the memory block is aligned by other means. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ref readonly T AsRef(ReadOnlySpan span) + public static unsafe ref readonly T AsRef(ReadOnlySpan span) where T : struct { if (RuntimeHelpers.IsReferenceOrContainsReferences()) { ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T)); } - if (Unsafe.SizeOf() > (uint)span.Length) + if (sizeof(T) > (uint)span.Length) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/SafeBuffer.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/SafeBuffer.cs index e01e569de38eab..ef19c8291e5d42 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/SafeBuffer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/SafeBuffer.cs @@ -409,7 +409,9 @@ internal static uint SizeOf() where T : struct if (RuntimeHelpers.IsReferenceOrContainsReferences()) throw new ArgumentException(SR.Argument_NeedStructWithNoRefs); - return (uint)Unsafe.SizeOf(); +#pragma warning disable 8500 // sizeof of managed types + return (uint)sizeof(T); +#pragma warning restore 8500 } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64_1.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64_1.cs index 4178ca1c5edc75..f2d369bcc9a471 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64_1.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64_1.cs @@ -53,14 +53,16 @@ public static Vector64 AllBitsSet /// Gets the number of that are in a . /// The type of the vector () is not supported. - public static int Count + public static unsafe int Count { [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] get { ThrowHelper.ThrowForUnsupportedIntrinsicsVector64BaseType(); - return Vector64.Size / Unsafe.SizeOf(); +#pragma warning disable 8500 // sizeof of managed types + return Vector64.Size / sizeof(T); +#pragma warning restore 8500 } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Span.cs b/src/libraries/System.Private.CoreLib/src/System/Span.cs index 5836ba4d5c8cbc..ce0f2a28012915 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Span.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Span.cs @@ -11,6 +11,8 @@ #pragma warning disable 0809 //warning CS0809: Obsolete member 'Span.Equals(object)' overrides non-obsolete member 'object.Equals(object)' +#pragma warning disable 8500 // sizeof of managed types + namespace System { /// @@ -283,11 +285,11 @@ public unsafe void Clear() { if (RuntimeHelpers.IsReferenceOrContainsReferences()) { - SpanHelpers.ClearWithReferences(ref Unsafe.As(ref _reference), (uint)_length * (nuint)(Unsafe.SizeOf() / sizeof(nuint))); + SpanHelpers.ClearWithReferences(ref Unsafe.As(ref _reference), (uint)_length * (nuint)(sizeof(T) / sizeof(nuint))); } else { - SpanHelpers.ClearWithoutReferences(ref Unsafe.As(ref _reference), (uint)_length * (nuint)Unsafe.SizeOf()); + SpanHelpers.ClearWithoutReferences(ref Unsafe.As(ref _reference), (uint)_length * (nuint)sizeof(T)); } } @@ -295,9 +297,9 @@ public unsafe void Clear() /// Fills the contents of this span with the given value. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Fill(T value) + public unsafe void Fill(T value) { - if (Unsafe.SizeOf() == 1) + if (sizeof(T) == 1) { // Special-case single-byte types like byte / sbyte / bool. // The runtime eventually calls memset, which can efficiently support large buffers. diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs index 898835744719e0..2d190a6ce9caa8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs @@ -712,7 +712,7 @@ private static unsafe nint UnalignedCountVector(ref char searchSpace) const int ElementsPerByte = sizeof(ushort) / sizeof(byte); // Figure out how many characters to read sequentially until we are vector aligned // This is equivalent to: - // unaligned = ((int)pCh % Unsafe.SizeOf>()) / ElementsPerByte + // unaligned = ((int)pCh % sizeof(Vector) / ElementsPerByte // length = (Vector.Count - unaligned) % Vector.Count // This alignment is only valid if the GC does not relocate; so we use ReadUnaligned to get the data. diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs index 0102f8c6751d76..83a72eef3fbe7b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs @@ -9,11 +9,13 @@ #pragma warning disable IDE0060 // https://github.com/dotnet/roslyn-analyzers/issues/6228 +#pragma warning disable 8500 // sizeof of managed types + namespace System { internal static partial class SpanHelpers // .T { - public static void Fill(ref T refData, nuint numElements, T value) + public static unsafe void Fill(ref T refData, nuint numElements, T value) { // Early checks to see if it's even possible to vectorize - JIT will turn these checks into consts. // - T cannot contain references (GC can't track references in vectors) @@ -23,39 +25,39 @@ public static void Fill(ref T refData, nuint numElements, T value) if (RuntimeHelpers.IsReferenceOrContainsReferences()) { goto CannotVectorize; } if (!Vector.IsHardwareAccelerated) { goto CannotVectorize; } - if (Unsafe.SizeOf() > Vector.Count) { goto CannotVectorize; } - if (!BitOperations.IsPow2(Unsafe.SizeOf())) { goto CannotVectorize; } + if (sizeof(T) > Vector.Count) { goto CannotVectorize; } + if (!BitOperations.IsPow2(sizeof(T))) { goto CannotVectorize; } - if (numElements >= (uint)(Vector.Count / Unsafe.SizeOf())) + if (numElements >= (uint)(Vector.Count / sizeof(T))) { // We have enough data for at least one vectorized write. T tmp = value; // Avoid taking address of the "value" argument. It would regress performance of the loops below. Vector vector; - if (Unsafe.SizeOf() == 1) + if (sizeof(T) == 1) { vector = new Vector(Unsafe.As(ref tmp)); } - else if (Unsafe.SizeOf() == 2) + else if (sizeof(T) == 2) { vector = (Vector)(new Vector(Unsafe.As(ref tmp))); } - else if (Unsafe.SizeOf() == 4) + else if (sizeof(T) == 4) { // special-case float since it's already passed in a SIMD reg vector = (typeof(T) == typeof(float)) ? (Vector)(new Vector((float)(object)tmp!)) : (Vector)(new Vector(Unsafe.As(ref tmp))); } - else if (Unsafe.SizeOf() == 8) + else if (sizeof(T) == 8) { // special-case double since it's already passed in a SIMD reg vector = (typeof(T) == typeof(double)) ? (Vector)(new Vector((double)(object)tmp!)) : (Vector)(new Vector(Unsafe.As(ref tmp))); } - else if (Unsafe.SizeOf() == 16) + else if (sizeof(T) == 16) { Vector128 vec128 = Unsafe.As>(ref tmp); if (Vector.Count == 16) @@ -72,7 +74,7 @@ public static void Fill(ref T refData, nuint numElements, T value) goto CannotVectorize; } } - else if (Unsafe.SizeOf() == 32) + else if (sizeof(T) == 32) { if (Vector.Count == 32) { @@ -91,7 +93,7 @@ public static void Fill(ref T refData, nuint numElements, T value) } ref byte refDataAsBytes = ref Unsafe.As(ref refData); - nuint totalByteLength = numElements * (nuint)Unsafe.SizeOf(); // get this calculation ready ahead of time + nuint totalByteLength = numElements * (nuint)sizeof(T); // get this calculation ready ahead of time nuint stopLoopAtOffset = totalByteLength & (nuint)(nint)(2 * (int)-Vector.Count); // intentional sign extension carries the negative bit nuint offset = 0; @@ -99,7 +101,7 @@ public static void Fill(ref T refData, nuint numElements, T value) // Compare 'numElements' rather than 'stopLoopAtOffset' because we don't want a dependency // on the very recently calculated 'stopLoopAtOffset' value. - if (numElements >= (uint)(2 * Vector.Count / Unsafe.SizeOf())) + if (numElements >= (uint)(2 * Vector.Count / sizeof(T))) { do { @@ -1302,23 +1304,23 @@ public static int SequenceCompareTo(ref T first, int firstLength, ref T secon } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static bool CanVectorizeAndBenefit(int length) where T : IEquatable? + internal static unsafe bool CanVectorizeAndBenefit(int length) where T : IEquatable? { if (Vector128.IsHardwareAccelerated && RuntimeHelpers.IsBitwiseEquatable()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { return length >= Vector128.Count; } - else if (Unsafe.SizeOf() == sizeof(short)) + else if (sizeof(T) == sizeof(short)) { return length >= Vector128.Count; } - else if (Unsafe.SizeOf() == sizeof(int)) + else if (sizeof(T) == sizeof(int)) { return length >= Vector128.Count; } - else if (Unsafe.SizeOf() == sizeof(long)) + else if (sizeof(T) == sizeof(long)) { return length >= Vector128.Count; } @@ -2844,19 +2846,19 @@ private static int LastIndexOfAnyValueType(ref TValue searchSp } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int ComputeFirstIndex(ref T searchSpace, ref T current, Vector128 equals) where T : struct + private static unsafe int ComputeFirstIndex(ref T searchSpace, ref T current, Vector128 equals) where T : struct { uint notEqualsElements = equals.ExtractMostSignificantBits(); int index = BitOperations.TrailingZeroCount(notEqualsElements); - return index + (int)(Unsafe.ByteOffset(ref searchSpace, ref current) / Unsafe.SizeOf()); + return index + (int)(Unsafe.ByteOffset(ref searchSpace, ref current) / sizeof(T)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int ComputeFirstIndex(ref T searchSpace, ref T current, Vector256 equals) where T : struct + private static unsafe int ComputeFirstIndex(ref T searchSpace, ref T current, Vector256 equals) where T : struct { uint notEqualsElements = equals.ExtractMostSignificantBits(); int index = BitOperations.TrailingZeroCount(notEqualsElements); - return index + (int)(Unsafe.ByteOffset(ref searchSpace, ref current) / Unsafe.SizeOf()); + return index + (int)(Unsafe.ByteOffset(ref searchSpace, ref current) / sizeof(T)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.cs index 6f3aa213061015..6f5ceb011ca6ca 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.cs @@ -6,6 +6,8 @@ using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; +#pragma warning disable 8500 // sizeof of managed types + namespace System { internal static partial class SpanHelpers @@ -557,28 +559,28 @@ public static void Reverse(ref long buf, nuint length) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Reverse(ref T elements, nuint length) + public static unsafe void Reverse(ref T elements, nuint length) { Debug.Assert(length > 1); if (!RuntimeHelpers.IsReferenceOrContainsReferences()) { - if (Unsafe.SizeOf() == sizeof(byte)) + if (sizeof(T) == sizeof(byte)) { Reverse(ref Unsafe.As(ref elements), length); return; } - else if (Unsafe.SizeOf() == sizeof(char)) + else if (sizeof(T) == sizeof(char)) { Reverse(ref Unsafe.As(ref elements), length); return; } - else if (Unsafe.SizeOf() == sizeof(int)) + else if (sizeof(T) == sizeof(int)) { Reverse(ref Unsafe.As(ref elements), length); return; } - else if (Unsafe.SizeOf() == sizeof(long)) + else if (sizeof(T) == sizeof(long)) { Reverse(ref Unsafe.As(ref elements), length); return; diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs b/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs index 118fdecc55786c..4165907b5192cc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs @@ -257,7 +257,7 @@ private static unsafe nuint GetIndexOfFirstNonAsciiByte_Intrinsified(byte* pBuff { // JIT turns the below into constants - uint SizeOfVector128 = (uint)Unsafe.SizeOf>(); + uint SizeOfVector128 = (uint)sizeof(Vector128); nuint MaskOfAllBitsInVector128 = (nuint)(SizeOfVector128 - 1); Debug.Assert(Sse2.IsSupported || AdvSimd.Arm64.IsSupported, "Sse2 or AdvSimd64 required."); @@ -776,7 +776,7 @@ private static unsafe nuint GetIndexOfFirstNonAsciiChar_Intrinsified(char* pBuff // JIT turns the below into constants - uint SizeOfVector128InBytes = (uint)Unsafe.SizeOf>(); + uint SizeOfVector128InBytes = (uint)sizeof(Vector128); uint SizeOfVector128InChars = SizeOfVector128InBytes / sizeof(char); Debug.Assert(Sse2.IsSupported || AdvSimd.Arm64.IsSupported, "Should've been checked by caller."); @@ -1187,7 +1187,7 @@ public static unsafe nuint NarrowUtf16ToAscii(char* pUtf16Buffer, byte* pAsciiBu } else if (Vector.IsHardwareAccelerated) { - uint SizeOfVector = (uint)Unsafe.SizeOf>(); // JIT will make this a const + uint SizeOfVector = (uint)sizeof(Vector); // JIT will make this a const // Only bother vectorizing if we have enough data to do so. if (elementCount >= 2 * SizeOfVector) @@ -1635,7 +1635,7 @@ public static unsafe nuint WidenAsciiToUtf16(byte* pAsciiBuffer, char* pUtf16Buf } else if (Vector.IsHardwareAccelerated) { - uint SizeOfVector = (uint)Unsafe.SizeOf>(); // JIT will make this a const + uint SizeOfVector = (uint)sizeof(Vector); // JIT will make this a const // Only bother vectorizing if we have enough data to do so. if (elementCount >= SizeOfVector) diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Utility.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Utility.cs index 8482d318f97114..e579f6fa9d56b1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Utility.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Utility.cs @@ -177,7 +177,7 @@ private static unsafe nuint GetIndexOfFirstNonLatin1Char_Sse2(char* pBuffer, nui // JIT turns the below into constants - uint SizeOfVector128InBytes = (uint)Unsafe.SizeOf>(); + uint SizeOfVector128InBytes = (uint)sizeof(Vector128); uint SizeOfVector128InChars = SizeOfVector128InBytes / sizeof(char); Debug.Assert(Sse2.IsSupported, "Should've been checked by caller."); @@ -538,7 +538,7 @@ public static unsafe nuint NarrowUtf16ToLatin1(char* pUtf16Buffer, byte* pLatin1 { Debug.Assert(BitConverter.IsLittleEndian, "Assume little endian if SSE2 is supported."); - if (elementCount >= 2 * (uint)Unsafe.SizeOf>()) + if (elementCount >= 2 * (uint)sizeof(Vector128)) { // Since there's overhead to setting up the vectorized code path, we only want to // call into it after a quick probe to ensure the next immediate characters really are Latin-1. @@ -567,7 +567,7 @@ public static unsafe nuint NarrowUtf16ToLatin1(char* pUtf16Buffer, byte* pLatin1 } else if (Vector.IsHardwareAccelerated) { - uint SizeOfVector = (uint)Unsafe.SizeOf>(); // JIT will make this a const + uint SizeOfVector = (uint)sizeof(Vector); // JIT will make this a const // Only bother vectorizing if we have enough data to do so. if (elementCount >= 2 * SizeOfVector) @@ -757,7 +757,7 @@ private static unsafe nuint NarrowUtf16ToLatin1_Sse2(char* pUtf16Buffer, byte* p // JIT turns the below into constants - uint SizeOfVector128 = (uint)Unsafe.SizeOf>(); + uint SizeOfVector128 = (uint)sizeof(Vector128); nuint MaskOfAllBitsInVector128 = SizeOfVector128 - 1; // This method is written such that control generally flows top-to-bottom, avoiding @@ -944,7 +944,7 @@ private static unsafe void WidenLatin1ToUtf16_Sse2(byte* pLatin1Buffer, char* pU { // JIT turns the below into constants - uint SizeOfVector128 = (uint)Unsafe.SizeOf>(); + uint SizeOfVector128 = (uint)sizeof(Vector128); nuint MaskOfAllBitsInVector128 = SizeOfVector128 - 1; Debug.Assert(Sse2.IsSupported); diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs index 6230fda260589c..d6d7a87e46d547 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs @@ -5252,14 +5252,19 @@ public static Task FromResult(TResult result) // For other value types, we special-case default(TResult) if we can easily compare bit patterns to default/0. else if (!RuntimeHelpers.IsReferenceOrContainsReferences()) { - // We don't need to go through the equality operator of the TResult because we cached a task for default(TResult), - // so we only need to confirm that this TResult has the same bits as default(TResult). - if ((Unsafe.SizeOf() == sizeof(byte) && Unsafe.As(ref result) == default(byte)) || - (Unsafe.SizeOf() == sizeof(ushort) && Unsafe.As(ref result) == default(ushort)) || - (Unsafe.SizeOf() == sizeof(uint) && Unsafe.As(ref result) == default) || - (Unsafe.SizeOf() == sizeof(ulong) && Unsafe.As(ref result) == default)) + unsafe { - return Task.s_defaultResultTask; +#pragma warning disable 8500 // sizeof of managed types + // We don't need to go through the equality operator of the TResult because we cached a task for default(TResult), + // so we only need to confirm that this TResult has the same bits as default(TResult). + if ((sizeof(TResult) == sizeof(byte) && Unsafe.As(ref result) == default(byte)) || + (sizeof(TResult) == sizeof(ushort) && Unsafe.As(ref result) == default(ushort)) || + (sizeof(TResult) == sizeof(uint) && Unsafe.As(ref result) == default) || + (sizeof(TResult) == sizeof(ulong) && Unsafe.As(ref result) == default)) + { + return Task.s_defaultResultTask; + } +#pragma warning restore 8500 } } } diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBufferReader.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBufferReader.cs index 57b71815a80684..5cfd9fb1d23728 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBufferReader.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBufferReader.cs @@ -938,18 +938,20 @@ public int GetInt8(int offset) return (sbyte)GetByte(offset); } - private T ReadRawBytes() where T : unmanaged +#pragma warning disable 8500 // sizeof of managed types + private unsafe T ReadRawBytes() where T : unmanaged { - ReadOnlySpan buffer = GetBuffer(Unsafe.SizeOf(), out int offset) - .AsSpan(offset, Unsafe.SizeOf()); + ReadOnlySpan buffer = GetBuffer(sizeof(T), out int offset) + .AsSpan(offset, sizeof(T)); T value = MemoryMarshal.Read(buffer); - Advance(Unsafe.SizeOf()); + Advance(sizeof(T)); return value; } - private T ReadRawBytes(int offset) where T : unmanaged - => MemoryMarshal.Read(_buffer.AsSpan(offset, Unsafe.SizeOf())); + private unsafe T ReadRawBytes(int offset) where T : unmanaged + => MemoryMarshal.Read(_buffer.AsSpan(offset, sizeof(T))); +#pragma warning restore 8500 public int GetInt16(int offset) => BitConverter.IsLittleEndian ? ReadRawBytes(offset) : BinaryPrimitives.ReverseEndianness(ReadRawBytes(offset)); diff --git a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/BaseCodePageEncoding.netcoreapp.cs b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/BaseCodePageEncoding.netcoreapp.cs index 63a538d659eabe..1158c7f66273f9 100644 --- a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/BaseCodePageEncoding.netcoreapp.cs +++ b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/BaseCodePageEncoding.netcoreapp.cs @@ -50,7 +50,7 @@ internal static unsafe EncodingInfo [] GetEncodings(CodePagesEncodingProvider pr EncodingInfo [] encodingInfoList = new EncodingInfo[codePagesCount]; CodePageIndex codePageIndex = default; - Span pCodePageIndex = new Span(&codePageIndex, Unsafe.SizeOf()); + Span pCodePageIndex = new Span(&codePageIndex, sizeof(CodePageIndex)); for (int i = 0; i < codePagesCount; i++) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs index e9b01aaf3d27f0..03f6f1711dd76b 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs @@ -96,7 +96,8 @@ public EnumConverter(EnumConverterOptions converterOptions, JsonNamingPolicy? na } } - public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) +#pragma warning disable 8500 // address of managed types + public override unsafe T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { JsonTokenType token = reader.TokenType; @@ -137,49 +138,49 @@ public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerial case TypeCode.Int32: if (reader.TryGetInt32(out int int32)) { - return Unsafe.As(ref int32); + return *(T*)&int32; } break; case TypeCode.UInt32: if (reader.TryGetUInt32(out uint uint32)) { - return Unsafe.As(ref uint32); + return *(T*)&uint32; } break; case TypeCode.UInt64: if (reader.TryGetUInt64(out ulong uint64)) { - return Unsafe.As(ref uint64); + return *(T*)&uint64; } break; case TypeCode.Int64: if (reader.TryGetInt64(out long int64)) { - return Unsafe.As(ref int64); + return *(T*)&int64; } break; case TypeCode.SByte: if (reader.TryGetSByte(out sbyte byte8)) { - return Unsafe.As(ref byte8); + return *(T*)&byte8; } break; case TypeCode.Byte: if (reader.TryGetByte(out byte ubyte8)) { - return Unsafe.As(ref ubyte8); + return *(T*)&ubyte8; } break; case TypeCode.Int16: if (reader.TryGetInt16(out short int16)) { - return Unsafe.As(ref int16); + return *(T*)&int16; } break; case TypeCode.UInt16: if (reader.TryGetUInt16(out ushort uint16)) { - return Unsafe.As(ref uint16); + return *(T*)&uint16; } break; } @@ -188,7 +189,7 @@ public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerial return default; } - public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) + public override unsafe void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) { // If strings are allowed, attempt to write it out as a string value if (_converterOptions.HasFlag(EnumConverterOptions.AllowStrings)) @@ -236,34 +237,35 @@ public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions switch (s_enumTypeCode) { case TypeCode.Int32: - writer.WriteNumberValue(Unsafe.As(ref value)); + writer.WriteNumberValue(*(int*)&value); break; case TypeCode.UInt32: - writer.WriteNumberValue(Unsafe.As(ref value)); + writer.WriteNumberValue(*(uint*)&value); break; case TypeCode.UInt64: - writer.WriteNumberValue(Unsafe.As(ref value)); + writer.WriteNumberValue(*(ulong*)&value); break; case TypeCode.Int64: - writer.WriteNumberValue(Unsafe.As(ref value)); + writer.WriteNumberValue(*(long*)&value); break; case TypeCode.Int16: - writer.WriteNumberValue(Unsafe.As(ref value)); + writer.WriteNumberValue(*(short*)&value); break; case TypeCode.UInt16: - writer.WriteNumberValue(Unsafe.As(ref value)); + writer.WriteNumberValue(*(ushort*)&value); break; case TypeCode.Byte: - writer.WriteNumberValue(Unsafe.As(ref value)); + writer.WriteNumberValue(*(byte*)&value); break; case TypeCode.SByte: - writer.WriteNumberValue(Unsafe.As(ref value)); + writer.WriteNumberValue(*(sbyte*)&value); break; default: ThrowHelper.ThrowJsonException(); break; } } +#pragma warning restore 8500 internal override T ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { diff --git a/src/mono/System.Private.CoreLib/src/System/Buffer.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Buffer.Mono.cs index ffd9f7d7165ac5..8f45f602e6fb11 100644 --- a/src/mono/System.Private.CoreLib/src/System/Buffer.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Buffer.Mono.cs @@ -17,15 +17,17 @@ public partial class Buffer private static extern void BulkMoveWithWriteBarrier(ref byte dmem, ref byte smem, nuint len, IntPtr type_handle); [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void Memmove(ref T destination, ref T source, nuint elementCount) + internal static unsafe void Memmove(ref T destination, ref T source, nuint elementCount) { if (!RuntimeHelpers.IsReferenceOrContainsReferences()) { +#pragma warning disable 8500 // sizeof of managed types // Blittable memmove Memmove( ref Unsafe.As(ref destination), ref Unsafe.As(ref source), - elementCount * (nuint)Unsafe.SizeOf()); + elementCount * (nuint)sizeof(T)); +#pragma warning restore 8500 } else if (elementCount > 0) {