From 6e4a388fbd8ce028b016c53f766678fdda1494bb Mon Sep 17 00:00:00 2001 From: Hamish Arblaster Date: Fri, 1 Mar 2024 16:57:29 +1100 Subject: [PATCH 01/14] Remove or document Unsafe.AsPointer uses in System.Memory - Also add internal helper method Unsafe.IsOpportunisticallyAligned - And cast a pointer to IntPtr instead of int for a unit test --- .../ArrayBufferWriterTests.T.cs | 9 +-------- .../tests/MemoryMarshal/CreateFromPinnedArray.cs | 5 +++-- .../tests/MemoryMarshal/GetArrayDataReference.cs | 2 +- .../System.Memory/tests/MemoryPool/MemoryPool.cs | 9 ++++----- .../System.Memory/tests/ReadOnlySpan/AsSpan.cs | 1 + src/libraries/System.Memory/tests/TestHelpers.cs | 4 ++-- .../System.Private.CoreLib/src/System/Memory.cs | 3 +++ .../src/System/ReadOnlyMemory.cs | 3 +++ .../System/Runtime/CompilerServices/Unsafe.cs | 16 ++++++++++++++++ .../src/System/SpanHelpers.cs | 2 +- 10 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/libraries/System.Memory/tests/ArrayBufferWriter/ArrayBufferWriterTests.T.cs b/src/libraries/System.Memory/tests/ArrayBufferWriter/ArrayBufferWriterTests.T.cs index 0cf99cbab5e4d..f609e38dae344 100644 --- a/src/libraries/System.Memory/tests/ArrayBufferWriter/ArrayBufferWriterTests.T.cs +++ b/src/libraries/System.Memory/tests/ArrayBufferWriter/ArrayBufferWriterTests.T.cs @@ -424,14 +424,7 @@ public void MultipleCallsToGetSpan() Assert.True(span.Length >= 256); Span newSpan = output.GetSpan(); Assert.Equal(span.Length, newSpan.Length); - - unsafe - { - void* pSpan = Unsafe.AsPointer(ref MemoryMarshal.GetReference(span)); - void* pNewSpan = Unsafe.AsPointer(ref MemoryMarshal.GetReference(newSpan)); - Assert.Equal((IntPtr)pSpan, (IntPtr)pNewSpan); - } - + Assert.Equal(0, Unsafe.ByteOffset(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(newSpan))); Assert.Equal(span.Length, output.GetSpan().Length); } finally diff --git a/src/libraries/System.Memory/tests/MemoryMarshal/CreateFromPinnedArray.cs b/src/libraries/System.Memory/tests/MemoryMarshal/CreateFromPinnedArray.cs index 3610ea0dbfbf6..762443f9845de 100644 --- a/src/libraries/System.Memory/tests/MemoryMarshal/CreateFromPinnedArray.cs +++ b/src/libraries/System.Memory/tests/MemoryMarshal/CreateFromPinnedArray.cs @@ -190,6 +190,7 @@ public static unsafe void CreateFromPinnedArrayVerifyPinning() int[] pinnedArray = { 90, 91, 92, 93, 94, 95, 96, 97, 98 }; GCHandle pinnedGCHandle = GCHandle.Alloc(pinnedArray, GCHandleType.Pinned); + // Unsafe.AsPointer is used to ensure we catch if the GC moves the memory Memory pinnedMemory = MemoryMarshal.CreateFromPinnedArray(pinnedArray, 0, 2); void* pinnedPtr = Unsafe.AsPointer(ref MemoryMarshal.GetReference(pinnedMemory.Span)); void* memoryHandlePinnedPtr = pinnedMemory.Pin().Pointer; @@ -197,8 +198,8 @@ public static unsafe void CreateFromPinnedArrayVerifyPinning() GC.Collect(); GC.Collect(2); - Assert.Equal((int)pinnedPtr, (int)Unsafe.AsPointer(ref MemoryMarshal.GetReference(pinnedMemory.Span))); - Assert.Equal((int)memoryHandlePinnedPtr, (int)pinnedGCHandle.AddrOfPinnedObject().ToPointer()); + Assert.Equal((IntPtr)pinnedPtr, (IntPtr)Unsafe.AsPointer(ref MemoryMarshal.GetReference(pinnedMemory.Span))); + Assert.Equal((IntPtr)memoryHandlePinnedPtr, (IntPtr)pinnedGCHandle.AddrOfPinnedObject().ToPointer()); pinnedGCHandle.Free(); } diff --git a/src/libraries/System.Memory/tests/MemoryMarshal/GetArrayDataReference.cs b/src/libraries/System.Memory/tests/MemoryMarshal/GetArrayDataReference.cs index 0fc55c64c4451..c3478421c358c 100644 --- a/src/libraries/System.Memory/tests/MemoryMarshal/GetArrayDataReference.cs +++ b/src/libraries/System.Memory/tests/MemoryMarshal/GetArrayDataReference.cs @@ -43,7 +43,7 @@ public static unsafe void GetArrayDataReference_EmptyInput_ReturnsRefToWhereFirs ref int theRef = ref MemoryMarshal.GetArrayDataReference(theArray); - Assert.True(Unsafe.AsPointer(ref theRef) != null); + Assert.False(Unsafe.IsNullRef(ref theRef)); Assert.True(Unsafe.AreSame(ref theRef, ref MemoryMarshal.GetReference(theArray.AsSpan()))); ref int theMdArrayRef = ref Unsafe.As(ref MemoryMarshal.GetArrayDataReference((Array)theArray)); // szarray passed to generalized Array helper diff --git a/src/libraries/System.Memory/tests/MemoryPool/MemoryPool.cs b/src/libraries/System.Memory/tests/MemoryPool/MemoryPool.cs index e040a363493bf..4ee663dc1dd88 100644 --- a/src/libraries/System.Memory/tests/MemoryPool/MemoryPool.cs +++ b/src/libraries/System.Memory/tests/MemoryPool/MemoryPool.cs @@ -52,6 +52,7 @@ public static void MemoryPoolSpan() { unsafe { + // Unsafe.AsPointer is safe here since it's pinned void* pSpan = Unsafe.AsPointer(ref MemoryMarshal.GetReference(sp)); Assert.Equal((IntPtr)newMemoryHandle.Pointer, (IntPtr)pSpan); } @@ -77,6 +78,7 @@ public static void MemoryPoolPin(int elementIndex) { unsafe { + // Unsafe.AsPointer is safe here since it's pinned void* pSpan = Unsafe.AsPointer(ref MemoryMarshal.GetReference(sp.Slice(elementIndex))); Assert.Equal((IntPtr)pSpan, ((IntPtr)newMemoryHandle.Pointer)); } @@ -112,6 +114,7 @@ public static void MemoryPoolPinOffsetAtEnd() { unsafe { + // Unsafe.AsPointer is safe here since it's pinned void* pSpan = Unsafe.AsPointer(ref MemoryMarshal.GetReference(sp.Slice(elementIndex))); Assert.Equal((IntPtr)pSpan, ((IntPtr)newMemoryHandle.Pointer)); } @@ -219,11 +222,7 @@ public static void MemoryPoolTryGetArray() unsafe { Assert.True(MemoryMarshal.TryGetArray(memory, out arraySegment)); - fixed (int* pArray = arraySegment.Array) - { - void* pSpan = Unsafe.AsPointer(ref MemoryMarshal.GetReference(memory.Span)); - Assert.Equal((IntPtr)pSpan, (IntPtr)pArray); - } + Assert.Equal(0, Unsafe.ByteOffset(ref MemoryMarshal.GetArrayDataReference(arraySegment.Array), ref MemoryMarshal.GetReference(memory.Span))); } } } diff --git a/src/libraries/System.Memory/tests/ReadOnlySpan/AsSpan.cs b/src/libraries/System.Memory/tests/ReadOnlySpan/AsSpan.cs index d6070d47c3ba9..83387f22a2d20 100644 --- a/src/libraries/System.Memory/tests/ReadOnlySpan/AsSpan.cs +++ b/src/libraries/System.Memory/tests/ReadOnlySpan/AsSpan.cs @@ -91,6 +91,7 @@ static unsafe void Validate(string text, int start, int length, ReadOnlySpan(this Span span) Assert.True(span.IsEmpty); // Validate that empty Span is not normalized to null - Assert.True(Unsafe.AsPointer(ref MemoryMarshal.GetReference(span)) != null); + Assert.False(Unsafe.IsNullRef(ref MemoryMarshal.GetReference(span))); } public delegate void AssertThrowsAction(Span span); @@ -98,7 +98,7 @@ public static unsafe void ValidateNonNullEmpty(this ReadOnlySpan span) Assert.True(span.IsEmpty); // Validate that empty Span is not normalized to null - Assert.True(Unsafe.AsPointer(ref MemoryMarshal.GetReference(span)) != null); + Assert.False(Unsafe.IsNullRef(ref MemoryMarshal.GetReference(span))); } public delegate void AssertThrowsActionReadOnly(ReadOnlySpan span); diff --git a/src/libraries/System.Private.CoreLib/src/System/Memory.cs b/src/libraries/System.Private.CoreLib/src/System/Memory.cs index 25e9778d66b53..989cac29c57c1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Memory.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Memory.cs @@ -398,6 +398,7 @@ public unsafe MemoryHandle Pin() { if (typeof(T) == typeof(char) && tmpObject is string s) { + // Unsafe.AsPointer is safe since the handle pins it GCHandle handle = GCHandle.Alloc(tmpObject, GCHandleType.Pinned); ref char stringData = ref Unsafe.Add(ref s.GetRawStringData(), _index); return new MemoryHandle(Unsafe.AsPointer(ref stringData), handle); @@ -410,11 +411,13 @@ public unsafe MemoryHandle Pin() // Array is already pre-pinned if (_index < 0) { + // Unsafe.AsPointer is safe since it's pinned void* pointer = Unsafe.Add(Unsafe.AsPointer(ref MemoryMarshal.GetArrayDataReference(Unsafe.As(tmpObject))), _index & ReadOnlyMemory.RemoveFlagsBitMask); return new MemoryHandle(pointer); } else { + // Unsafe.AsPointer is safe since the handle pins it GCHandle handle = GCHandle.Alloc(tmpObject, GCHandleType.Pinned); void* pointer = Unsafe.Add(Unsafe.AsPointer(ref MemoryMarshal.GetArrayDataReference(Unsafe.As(tmpObject))), _index); return new MemoryHandle(pointer, handle); diff --git a/src/libraries/System.Private.CoreLib/src/System/ReadOnlyMemory.cs b/src/libraries/System.Private.CoreLib/src/System/ReadOnlyMemory.cs index 9037e4110817e..6b59ac75e5766 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ReadOnlyMemory.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ReadOnlyMemory.cs @@ -313,6 +313,7 @@ public unsafe MemoryHandle Pin() { if (typeof(T) == typeof(char) && tmpObject is string s) { + // Unsafe.AsPointer is safe since the handle pins it GCHandle handle = GCHandle.Alloc(tmpObject, GCHandleType.Pinned); ref char stringData = ref Unsafe.Add(ref s.GetRawStringData(), _index); return new MemoryHandle(Unsafe.AsPointer(ref stringData), handle); @@ -325,11 +326,13 @@ public unsafe MemoryHandle Pin() // Array is already pre-pinned if (_index < 0) { + // Unsafe.AsPointer is safe since it's pinned void* pointer = Unsafe.Add(Unsafe.AsPointer(ref MemoryMarshal.GetArrayDataReference(Unsafe.As(tmpObject))), _index & RemoveFlagsBitMask); return new MemoryHandle(pointer); } else { + // Unsafe.AsPointer is safe since the handle pins it GCHandle handle = GCHandle.Alloc(tmpObject, GCHandleType.Pinned); void* pointer = Unsafe.Add(Unsafe.AsPointer(ref MemoryMarshal.GetArrayDataReference(Unsafe.As(tmpObject))), _index); return new MemoryHandle(pointer, handle); 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 b6dc25bb43643..706f9a4bb5034 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 @@ -3,6 +3,7 @@ #pragma warning disable IDE0060 // implementations provided as intrinsics using System; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.Versioning; @@ -907,5 +908,20 @@ public static ref T Unbox(object box) // unbox !!T // ret } + + + // Internal helper methods: + + // Determines if the address is aligned at least to `alignment` bytes. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool IsOpportunisticallyAligned(ref readonly T address, nuint aligment) + { + // `alignment` is expected to be a power of 2 in bytes. + // We use Unsafe.AsPointer to convert to a pointer, + // GC will keep alignment when moving objects (up to sizeof(void*)), + // otherwise alignment should be considered a hint if not pinned. + Debug.Assert(nuint.IsPow2(alignment)); + return ((nuint)AsPointer(ref AsRef(in address)) & (alignment - 1)) != 0; + } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.cs index aa7ed473d9fef..a5191a052baef 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.cs @@ -14,7 +14,7 @@ internal static partial class SpanHelpers { public static unsafe void ClearWithReferences(ref IntPtr ip, nuint pointerSizeLength) { - Debug.Assert((int)Unsafe.AsPointer(ref ip) % sizeof(IntPtr) == 0, "Should've been aligned on natural word boundary."); + Debug.Assert(Unsafe.IsOpportunisticallyAligned(ref ip, sizeof(IntPtr)), "Should've been aligned on natural word boundary."); // First write backward 8 natural words at a time. // Writing backward allows us to get away with only simple modifications to the From 9c016e01413db1d44869f0e9c11a8b4a45510395 Mon Sep 17 00:00:00 2001 From: Hamish Arblaster Date: Fri, 1 Mar 2024 17:11:24 +1100 Subject: [PATCH 02/14] Fix typo and cast size to unsigned --- .../src/System/Runtime/CompilerServices/Unsafe.cs | 2 +- src/libraries/System.Private.CoreLib/src/System/SpanHelpers.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 706f9a4bb5034..267a616310beb 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 @@ -914,7 +914,7 @@ public static ref T Unbox(object box) // Determines if the address is aligned at least to `alignment` bytes. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static bool IsOpportunisticallyAligned(ref readonly T address, nuint aligment) + internal static bool IsOpportunisticallyAligned(ref readonly T address, nuint alignment) { // `alignment` is expected to be a power of 2 in bytes. // We use Unsafe.AsPointer to convert to a pointer, diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.cs index a5191a052baef..a0e0b266589bd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.cs @@ -14,7 +14,7 @@ internal static partial class SpanHelpers { public static unsafe void ClearWithReferences(ref IntPtr ip, nuint pointerSizeLength) { - Debug.Assert(Unsafe.IsOpportunisticallyAligned(ref ip, sizeof(IntPtr)), "Should've been aligned on natural word boundary."); + Debug.Assert(Unsafe.IsOpportunisticallyAligned(ref ip, (uint)sizeof(IntPtr)), "Should've been aligned on natural word boundary."); // First write backward 8 natural words at a time. // Writing backward allows us to get away with only simple modifications to the From 9d52e37df1058f18e0891bd01efbc6d8822c957b Mon Sep 17 00:00:00 2001 From: Hamish Arblaster Date: Sat, 2 Mar 2024 07:05:29 +1100 Subject: [PATCH 03/14] Address feedback --- .../System.Memory/tests/MemoryMarshal/CreateFromPinnedArray.cs | 2 +- .../src/System/Runtime/CompilerServices/Unsafe.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Memory/tests/MemoryMarshal/CreateFromPinnedArray.cs b/src/libraries/System.Memory/tests/MemoryMarshal/CreateFromPinnedArray.cs index 762443f9845de..e56a24e5eea28 100644 --- a/src/libraries/System.Memory/tests/MemoryMarshal/CreateFromPinnedArray.cs +++ b/src/libraries/System.Memory/tests/MemoryMarshal/CreateFromPinnedArray.cs @@ -199,7 +199,7 @@ public static unsafe void CreateFromPinnedArrayVerifyPinning() GC.Collect(2); Assert.Equal((IntPtr)pinnedPtr, (IntPtr)Unsafe.AsPointer(ref MemoryMarshal.GetReference(pinnedMemory.Span))); - Assert.Equal((IntPtr)memoryHandlePinnedPtr, (IntPtr)pinnedGCHandle.AddrOfPinnedObject().ToPointer()); + Assert.Equal((IntPtr)memoryHandlePinnedPtr, pinnedGCHandle.AddrOfPinnedObject()); pinnedGCHandle.Free(); } 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 267a616310beb..505a3f324732e 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 @@ -921,7 +921,7 @@ internal static bool IsOpportunisticallyAligned(ref readonly T address, nuint // GC will keep alignment when moving objects (up to sizeof(void*)), // otherwise alignment should be considered a hint if not pinned. Debug.Assert(nuint.IsPow2(alignment)); - return ((nuint)AsPointer(ref AsRef(in address)) & (alignment - 1)) != 0; + return ((nuint)AsPointer(ref AsRef(in address)) & (alignment - 1)) == 0; } } } From a40d75292f6a49aaa91a8351bfe856cb6d2d2f49 Mon Sep 17 00:00:00 2001 From: Hamish Arblaster Date: Mon, 4 Mar 2024 20:29:20 +1100 Subject: [PATCH 04/14] Changes for the rest of the core libraries - Other than MethodHandle code for NativeAOT - Add Unsafe.OpportunisticMisalignment --- .../src/System/ArgIterator.cs | 2 +- .../src/System/GC.CoreCLR.cs | 4 +- .../CompilerHelpers/StartupCodeHelpers.cs | 6 ++- .../src/System/GC.NativeAot.cs | 12 ++++-- .../tools/Common/JitInterface/CorInfoImpl.cs | 4 +- .../HostApiInvokerApp/HostRuntimeContract.cs | 10 +++-- .../Common/src/System/Number.NumberBuffer.cs | 14 +++---- ...untimeEventSource.Threading.NativeSinks.cs | 4 +- .../NativeRuntimeEventSource.Threading.cs | 4 +- .../System/Globalization/CalendarData.Icu.cs | 16 ++++---- .../src/System/Number.Formatting.cs | 38 +++++++++---------- .../Number.NumberToFloatingPointBits.cs | 6 +-- .../src/System/Number.Parsing.cs | 4 +- .../System/Runtime/CompilerServices/Unsafe.cs | 12 ++++++ .../Runtime/InteropServices/GCHandle.cs | 1 + .../System/Runtime/InteropServices/Marshal.cs | 2 + .../Marshalling/AnsiStringMarshaller.cs | 1 + .../Marshalling/ArrayMarshaller.cs | 6 ++- .../Marshalling/BStrStringMarshaller.cs | 1 + .../Marshalling/PointerArrayMarshaller.cs | 6 ++- .../Marshalling/ReadOnlySpanMarshaller.cs | 6 ++- .../Marshalling/SpanMarshaller.cs | 6 ++- .../Marshalling/Utf8StringMarshaller.cs | 1 + .../src/System/SpanHelpers.ByteMemOps.cs | 4 +- .../src/System/Text/Ascii.cs | 4 +- .../src/System/Threading/Lock.cs | 4 +- .../System/Threading/Tasks/TplEventSource.cs | 8 +++- .../IStatefulPinnedMarshalling.cs | 1 + ...tatelessCallerAllocateBufferMarshalling.cs | 1 + .../TestAssets/SharedTypes/NonBlittable.cs | 4 ++ .../System.Runtime.Tests/System/GCTests.cs | 2 +- .../System/StringTests.cs | 1 + 32 files changed, 128 insertions(+), 67 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/ArgIterator.cs b/src/coreclr/System.Private.CoreLib/src/System/ArgIterator.cs index e7c2a99eeefa2..d49d1dcb270b5 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/ArgIterator.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/ArgIterator.cs @@ -24,7 +24,7 @@ private struct SigPointer private int _remainingArgs; // # of remaining args. #if TARGET_WINDOWS // Native Varargs are not supported on Unix - // ArgIterator is a ref struct. It does not require pinning. + // ArgIterator is a ref struct. It does not require pinning, therefore Unsafe.AsPointer is safe. // This method null checks the this pointer as a side-effect. private ArgIterator* ThisPtr => (ArgIterator*)Unsafe.AsPointer(ref _argCookie); 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 590fd5b18cee0..9cb38bf04f926 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs @@ -865,7 +865,9 @@ public static unsafe IReadOnlyDictionary GetConfigurationVariabl Configurations = new Dictionary() }; - _EnumerateConfigurationValues(Unsafe.AsPointer(ref context), &ConfigCallback); +#pragma warning disable CS8500 + _EnumerateConfigurationValues(&context, &ConfigCallback); +#pragma warning restore CS8500 return context.Configurations!; } diff --git a/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs b/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs index d47cae0a18ed0..03d9505186549 100644 --- a/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs +++ b/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs @@ -206,11 +206,12 @@ private static unsafe object[] InitializeStatics(IntPtr gcStaticRegionStart, int nint blockAddr = MethodTable.SupportsRelativePointers ? (nint)ReadRelPtr32(pBlock) : *pBlock; if ((blockAddr & GCStaticRegionConstants.Uninitialized) == GCStaticRegionConstants.Uninitialized) { +#pragma warning disable CS8500 object? obj = null; RuntimeImports.RhAllocateNewObject( new IntPtr(blockAddr & ~GCStaticRegionConstants.Mask), (uint)GC_ALLOC_FLAGS.GC_ALLOC_PINNED_OBJECT_HEAP, - Unsafe.AsPointer(ref obj)); + &obj); if (obj == null) { RuntimeExceptionHelpers.FailFast("Failed allocating GC static bases"); @@ -232,7 +233,8 @@ private static unsafe object[] InitializeStatics(IntPtr gcStaticRegionStart, int Unsafe.Add(ref rawSpineData, currentBase) = obj; // Update the base pointer to point to the pinned object - *pBlock = *(IntPtr*)Unsafe.AsPointer(ref obj); + *pBlock = *(IntPtr*)&obj; +#pragma warning restore CS8500 } currentBase++; 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 62ed9a722671a..56e8016a67377 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 @@ -695,7 +695,9 @@ public static unsafe IReadOnlyDictionary GetConfigurationVariabl Configurations = new Dictionary() }; - RuntimeImports.RhEnumerateConfigurationValues(Unsafe.AsPointer(ref context), &ConfigCallback); +#pragma warning disable CS8500 + RuntimeImports.RhEnumerateConfigurationValues(&context, &ConfigCallback); +#pragma warning restore CS8500 return context.Configurations!; } @@ -830,7 +832,9 @@ static T[] AllocateNewUninitializedArray(int length, bool pinned) throw new OverflowException(); T[]? array = null; - RuntimeImports.RhAllocateNewArray(MethodTable.Of(), (uint)length, (uint)flags, Unsafe.AsPointer(ref array)); +#pragma warning disable CS8500 + RuntimeImports.RhAllocateNewArray(MethodTable.Of(), (uint)length, (uint)flags, &array); +#pragma warning restore CS8500 if (array == null) throw new OutOfMemoryException(); @@ -857,7 +861,9 @@ public static unsafe T[] AllocateArray(int length, bool pinned = false) throw new OverflowException(); T[]? array = null; - RuntimeImports.RhAllocateNewArray(MethodTable.Of(), (uint)length, (uint)flags, Unsafe.AsPointer(ref array)); +#pragma warning disable CS8500 + RuntimeImports.RhAllocateNewArray(MethodTable.Of(), (uint)length, (uint)flags, &array); +#pragma warning restore CS8500 if (array == null) throw new OutOfMemoryException(); diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 5d10b4159feca..e56c515c11a80 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -350,9 +350,11 @@ private CompilationResult CompileMethodInternal(IMethodNode methodCodeNodeNeedin IntPtr exception; IntPtr nativeEntry; uint codeSize; +#pragma warning disable CS8500 var result = JitCompileMethod(out exception, - _jit, (IntPtr)Unsafe.AsPointer(ref _this), _unmanagedCallbacks, + _jit, (IntPtr)&_this, _unmanagedCallbacks, ref methodInfo, (uint)CorJitFlag.CORJIT_FLAG_CALL_GETJITFLAGS, out nativeEntry, out codeSize); +#pragma warning restore CS8500 if (exception != IntPtr.Zero) { if (_lastException != null) diff --git a/src/installer/tests/Assets/Projects/HostApiInvokerApp/HostRuntimeContract.cs b/src/installer/tests/Assets/Projects/HostApiInvokerApp/HostRuntimeContract.cs index a75f34be6942c..99ebe3adfe5d0 100644 --- a/src/installer/tests/Assets/Projects/HostApiInvokerApp/HostRuntimeContract.cs +++ b/src/installer/tests/Assets/Projects/HostApiInvokerApp/HostRuntimeContract.cs @@ -46,8 +46,9 @@ private static void Test_get_runtime_property(string[] args) static string GetProperty(string name, host_runtime_contract contract) { - Span nameSpan = stackalloc byte[Encoding.UTF8.GetMaxByteCount(name.Length)]; - byte* namePtr = (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(nameSpan)); + int nameSize = Encoding.UTF8.GetMaxByteCount(name.Length); + byte* namePtr = stackalloc byte[nameSize]; + Span nameSpan = new Span(namePtr, nameSize); int nameLen = Encoding.UTF8.GetBytes(name, nameSpan); nameSpan[nameLen] = 0; @@ -86,8 +87,9 @@ public static void Test_bundle_probe(string[] args) unsafe static void Probe(host_runtime_contract contract, string path) { - Span pathSpan = stackalloc byte[Encoding.UTF8.GetMaxByteCount(path.Length)]; - byte* pathPtr = (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(pathSpan)); + int pathSize = Encoding.UTF8.GetMaxByteCount(path.Length); + byte* pathPtr = stackalloc byte[pathSize]; + Span pathSpan = new Span(pathPtr, pathSize); int pathLen = Encoding.UTF8.GetBytes(path, pathSpan); pathSpan[pathLen] = 0; diff --git a/src/libraries/Common/src/System/Number.NumberBuffer.cs b/src/libraries/Common/src/System/Number.NumberBuffer.cs index 5b4fc7a7564e8..cba051294dbbf 100644 --- a/src/libraries/Common/src/System/Number.NumberBuffer.cs +++ b/src/libraries/Common/src/System/Number.NumberBuffer.cs @@ -29,7 +29,9 @@ internal unsafe ref struct NumberBuffer public bool IsNegative; public bool HasNonZeroTail; public NumberBufferKind Kind; - public Span Digits; + public byte* DigitsPtr; + public int DigitsLength; + public readonly Span Digits => new Span(DigitsPtr, DigitsLength); public NumberBuffer(NumberBufferKind kind, byte* digits, int digitsLength) : this(kind, new Span(digits, digitsLength)) { @@ -48,7 +50,8 @@ public NumberBuffer(NumberBufferKind kind, Span digits) IsNegative = false; HasNonZeroTail = false; Kind = kind; - Digits = digits; + DigitsPtr = Unsafe.AsPointer(ref MemoryMarshal.GetReference(digits)); // Safe since memory must be fixed + DigitsLength = digits.Length; #if DEBUG Digits.Fill(0xCC); #endif @@ -83,13 +86,6 @@ public void CheckConsistency() } #pragma warning restore CA1822 - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public byte* GetDigitsPointer() - { - // This is safe to do since we are a ref struct - return (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(Digits)); - } - // // Code coverage note: This only exists so that Number displays nicely in the VS watch window. So yes, I know it works. // diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.cs index 5ba348edd7fe2..bc9a6479989fe 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.cs @@ -355,12 +355,14 @@ private void WaitHandleWaitStart( LogWaitHandleWaitStart(WaitSource, AssociatedObjectID, ClrInstanceID); } +#pragma warning disable CS8500 [NonEvent] [MethodImpl(MethodImplOptions.NoInlining)] public unsafe void WaitHandleWaitStart( WaitHandleWaitSourceMap waitSource = WaitHandleWaitSourceMap.Unknown, object? associatedObject = null) => - WaitHandleWaitStart(waitSource, *(nint*)Unsafe.AsPointer(ref associatedObject)); + WaitHandleWaitStart(waitSource, *(nint*)&associatedObject); +#pragma warning restore CS8500 [Event(302, Level = EventLevel.Verbose, Message = Messages.WaitHandleWaitStop, Task = Tasks.WaitHandleWait, Opcode = EventOpcode.Stop, Version = 0, Keywords = Keywords.WaitHandleKeyword)] public void WaitHandleWaitStop(ushort ClrInstanceID = DefaultClrInstanceId) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.cs index 11c4dfcfe6c53..02307c27d61e0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.cs @@ -552,12 +552,14 @@ private unsafe void WaitHandleWaitStart( WriteEventCore(301, 3, data); } +#pragma warning disable CS8500 [NonEvent] [MethodImpl(MethodImplOptions.NoInlining)] public unsafe void WaitHandleWaitStart( WaitHandleWaitSourceMap waitSource = WaitHandleWaitSourceMap.Unknown, object? associatedObject = null) => - WaitHandleWaitStart(waitSource, *(nint*)Unsafe.AsPointer(ref associatedObject)); + WaitHandleWaitStart(waitSource, *(nint*)&associatedObject); +#pragma warning restore CS8500 [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:UnrecognizedReflectionPattern", Justification = "Parameters to this method are primitive and are trimmer safe")] [Event(302, Level = EventLevel.Verbose, Message = Messages.WaitHandleWaitStop, Task = Tasks.WaitHandleWait, Opcode = EventOpcode.Stop, Version = 0, Keywords = Keywords.WaitHandleKeyword)] diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs index 4d3314f22ec59..bf8ab2bfb108a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs @@ -135,14 +135,14 @@ private static unsafe bool GetCalendarInfo(string localeName, CalendarId calenda out calendarString); } - private static bool EnumDatePatterns(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[]? datePatterns) + private static unsafe bool EnumDatePatterns(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[]? datePatterns) { datePatterns = null; IcuEnumCalendarsData callbackContext = default; callbackContext.Results = new List(); callbackContext.DisallowDuplicates = true; - bool result = EnumCalendarInfo(localeName, calendarId, dataType, ref callbackContext); + bool result = EnumCalendarInfo(localeName, calendarId, dataType, &callbackContext); if (result) { List datePatternsList = callbackContext.Results; @@ -362,13 +362,13 @@ private static int CountOccurrences(string input, char value, ref int index) return index - startIndex; } - private static bool EnumMonthNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[]? monthNames, ref string? leapHebrewMonthName) + private static unsafe bool EnumMonthNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[]? monthNames, ref string? leapHebrewMonthName) { monthNames = null; IcuEnumCalendarsData callbackContext = default; callbackContext.Results = new List(); - bool result = EnumCalendarInfo(localeName, calendarId, dataType, ref callbackContext); + bool result = EnumCalendarInfo(localeName, calendarId, dataType, &callbackContext); if (result) { // the month-name arrays are expected to have 13 elements. If ICU only returns 12, add an @@ -410,13 +410,13 @@ private static bool EnumEraNames(string localeName, CalendarId calendarId, Calen return result; } - internal static bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[]? calendarData) + internal static unsafe bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[]? calendarData) { calendarData = null; IcuEnumCalendarsData callbackContext = default; callbackContext.Results = new List(); - bool result = EnumCalendarInfo(localeName, calendarId, dataType, ref callbackContext); + bool result = EnumCalendarInfo(localeName, calendarId, dataType, &callbackContext); if (result) { calendarData = callbackContext.Results.ToArray(); @@ -425,9 +425,9 @@ internal static bool EnumCalendarInfo(string localeName, CalendarId calendarId, return result; } - private static unsafe bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, ref IcuEnumCalendarsData callbackContext) + private static unsafe bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, IcuEnumCalendarsData* callbackContext) { - return Interop.Globalization.EnumCalendarInfo(&EnumCalendarInfoCallback, localeName, calendarId, dataType, (IntPtr)Unsafe.AsPointer(ref callbackContext)); + return Interop.Globalization.EnumCalendarInfo(&EnumCalendarInfoCallback, localeName, calendarId, dataType, (IntPtr)callbackContext); } [UnmanagedCallersOnly] diff --git a/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs b/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs index c888403677734..9dba42def297f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs @@ -407,7 +407,7 @@ public static unsafe bool TryFormatDecimal(decimal value, ReadOnlySpan= 0) { *dst++ = *p++; @@ -1627,7 +1627,7 @@ private static unsafe void Int32ToNumber(int value, ref NumberBuffer number) value = -value; } - byte* buffer = number.GetDigitsPointer(); + byte* buffer = number.DigitsPtr; byte* p = UInt32ToDecChars(buffer + Int32Precision, (uint)value, 0); int i = (int)(buffer + Int32Precision - p); @@ -1635,7 +1635,7 @@ private static unsafe void Int32ToNumber(int value, ref NumberBuffer number) number.DigitsCount = i; number.Scale = i; - byte* dst = number.GetDigitsPointer(); + byte* dst = number.DigitsPtr; while (--i >= 0) { *dst++ = *p++; @@ -1824,7 +1824,7 @@ private static unsafe void UInt32ToNumber(uint value, ref NumberBuffer number) number.DigitsCount = UInt32Precision; number.IsNegative = false; - byte* buffer = number.GetDigitsPointer(); + byte* buffer = number.DigitsPtr; byte* p = UInt32ToDecChars(buffer + UInt32Precision, value, 0); int i = (int)(buffer + UInt32Precision - p); @@ -1832,7 +1832,7 @@ private static unsafe void UInt32ToNumber(uint value, ref NumberBuffer number) number.DigitsCount = i; number.Scale = i; - byte* dst = number.GetDigitsPointer(); + byte* dst = number.DigitsPtr; while (--i >= 0) { *dst++ = *p++; @@ -2058,7 +2058,7 @@ private static unsafe void Int64ToNumber(long value, ref NumberBuffer number) value = -value; } - byte* buffer = number.GetDigitsPointer(); + byte* buffer = number.DigitsPtr; byte* p = UInt64ToDecChars(buffer + Int64Precision, (ulong)value, 0); int i = (int)(buffer + Int64Precision - p); @@ -2066,7 +2066,7 @@ private static unsafe void Int64ToNumber(long value, ref NumberBuffer number) number.DigitsCount = i; number.Scale = i; - byte* dst = number.GetDigitsPointer(); + byte* dst = number.DigitsPtr; while (--i >= 0) { *dst++ = *p++; @@ -2289,7 +2289,7 @@ private static unsafe void UInt64ToNumber(ulong value, ref NumberBuffer number) number.DigitsCount = UInt64Precision; number.IsNegative = false; - byte* buffer = number.GetDigitsPointer(); + byte* buffer = number.DigitsPtr; byte* p = UInt64ToDecChars(buffer + UInt64Precision, value, 0); int i = (int)(buffer + UInt64Precision - p); @@ -2297,7 +2297,7 @@ private static unsafe void UInt64ToNumber(ulong value, ref NumberBuffer number) number.DigitsCount = i; number.Scale = i; - byte* dst = number.GetDigitsPointer(); + byte* dst = number.DigitsPtr; while (--i >= 0) { *dst++ = *p++; @@ -2484,7 +2484,7 @@ private static unsafe void Int128ToNumber(Int128 value, ref NumberBuffer number) value = -value; } - byte* buffer = number.GetDigitsPointer(); + byte* buffer = number.DigitsPtr; byte* p = UInt128ToDecChars(buffer + Int128Precision, (UInt128)value, 0); int i = (int)(buffer + Int128Precision - p); @@ -2492,7 +2492,7 @@ private static unsafe void Int128ToNumber(Int128 value, ref NumberBuffer number) number.DigitsCount = i; number.Scale = i; - byte* dst = number.GetDigitsPointer(); + byte* dst = number.DigitsPtr; while (--i >= 0) { *dst++ = *p++; @@ -2701,7 +2701,7 @@ private static unsafe void UInt128ToNumber(UInt128 value, ref NumberBuffer numbe number.DigitsCount = UInt128Precision; number.IsNegative = false; - byte* buffer = number.GetDigitsPointer(); + byte* buffer = number.DigitsPtr; byte* p = UInt128ToDecChars(buffer + UInt128Precision, value, 0); int i = (int)(buffer + UInt128Precision - p); @@ -2709,7 +2709,7 @@ private static unsafe void UInt128ToNumber(UInt128 value, ref NumberBuffer numbe number.DigitsCount = i; number.Scale = i; - byte* dst = number.GetDigitsPointer(); + byte* dst = number.DigitsPtr; while (--i >= 0) { *dst++ = *p++; @@ -3050,7 +3050,7 @@ internal static unsafe void NumberToStringFormat(ref ValueListBuilder( Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); int digPos = number.Scale; - byte* dig = number.GetDigitsPointer(); + byte* dig = number.DigitsPtr; if (digPos > 0) { @@ -3657,7 +3657,7 @@ private static unsafe void FormatScientific(ref ValueListBuilder v { Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - byte* dig = number.GetDigitsPointer(); + byte* dig = number.DigitsPtr; vlb.Append(TChar.CastFrom((*dig != 0) ? (char)(*dig++) : '0')); @@ -3716,7 +3716,7 @@ private static unsafe void FormatGeneral(ref ValueListBuilder vlb, } } - byte* dig = number.GetDigitsPointer(); + byte* dig = number.DigitsPtr; if (digPos > 0) { @@ -3786,7 +3786,7 @@ private static void FormatPercent(ref ValueListBuilder vlb, ref Nu internal static unsafe void RoundNumber(ref NumberBuffer number, int pos, bool isCorrectlyRounded) { - byte* dig = number.GetDigitsPointer(); + byte* dig = number.DigitsPtr; int i = 0; while (i < pos && dig[i] != '\0') diff --git a/src/libraries/System.Private.CoreLib/src/System/Number.NumberToFloatingPointBits.cs b/src/libraries/System.Private.CoreLib/src/System/Number.NumberToFloatingPointBits.cs index 8043171f596df..303ae2f43c922 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Number.NumberToFloatingPointBits.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Number.NumberToFloatingPointBits.cs @@ -700,7 +700,7 @@ private static void AccumulateDecimalDigitsIntoBigInteger(scoped ref NumberBuffe { BigInteger.SetZero(out result); - byte* src = number.GetDigitsPointer() + firstIndex; + byte* src = number.DigitsPtr + firstIndex; uint remaining = lastIndex - firstIndex; while (remaining != 0) @@ -974,7 +974,7 @@ private static ulong NumberToFloatingPointBits(ref NumberBuffer number) { Debug.Assert(TFloat.DenormalMantissaBits <= FloatingPointMaxDenormalMantissaBits); - Debug.Assert(number.GetDigitsPointer()[0] != '0'); + Debug.Assert(number.DigitsPtr[0] != '0'); Debug.Assert(number.Scale <= FloatingPointMaxExponent); Debug.Assert(number.Scale >= FloatingPointMinExponent); @@ -998,7 +998,7 @@ private static ulong NumberToFloatingPointBits(ref NumberBuffer number) // Above 19 digits, we rely on slow path if (totalDigits <= 19) { - byte* src = number.GetDigitsPointer(); + byte* src = number.DigitsPtr; ulong mantissa = DigitsToUInt64(src, (int)(totalDigits)); diff --git a/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs b/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs index 952733c9268df..935328a21d20e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs @@ -113,7 +113,7 @@ private static unsafe bool TryNumberBufferToBinaryInteger(ref NumberBu return false; } - byte* p = number.GetDigitsPointer(); + byte* p = number.DigitsPtr; Debug.Assert(p != null); TInteger n = TInteger.Zero; @@ -725,7 +725,7 @@ internal static unsafe bool TryNumberToDecimal(ref NumberBuffer number, ref deci { number.CheckConsistency(); - byte* p = number.GetDigitsPointer(); + byte* p = number.DigitsPtr; int e = number.Scale; bool sign = number.IsNegative; uint c = *p; 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 505a3f324732e..901d354cfc7c8 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 @@ -923,5 +923,17 @@ internal static bool IsOpportunisticallyAligned(ref readonly T address, nuint Debug.Assert(nuint.IsPow2(alignment)); return ((nuint)AsPointer(ref AsRef(in address)) & (alignment - 1)) == 0; } + + // Determines the misalignment of the address with respect to the specified `alignment`. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static nuint OpportunisticMisalignment(ref readonly T address, nuint alignment) + { + // `alignment` is expected to be a power of 2 in bytes. + // We use Unsafe.AsPointer to convert to a pointer, + // GC will keep alignment when moving objects (up to sizeof(void*)), + // otherwise alignment should be considered a hint if not pinned. + Debug.Assert(nuint.IsPow2(alignment)); + return (nuint)AsPointer(ref AsRef(in address)) & (alignment - 1); + } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.cs index 7a45e868a3d02..14151c1c02705 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/GCHandle.cs @@ -127,6 +127,7 @@ public readonly IntPtr AddrOfPinnedObject() unsafe { + // Unsafe.AsPointer calls are safe since object is pinned. if (RuntimeHelpers.ObjectHasComponentSize(target)) { if (target.GetType() == typeof(string)) 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 109efc9da4471..74ef8257749aa 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 @@ -165,6 +165,7 @@ public static unsafe IntPtr UnsafeAddrOfPinnedArrayElement(Array arr, int index) { ArgumentNullException.ThrowIfNull(arr); + // Unsafe.AsPointer is safe since array must be pinned void* pRawData = Unsafe.AsPointer(ref MemoryMarshal.GetArrayDataReference(arr)); return (IntPtr)((byte*)pRawData + (uint)index * (nuint)arr.GetElementSize()); } @@ -173,6 +174,7 @@ public static unsafe IntPtr UnsafeAddrOfPinnedArrayElement(T[] arr, int index { ArgumentNullException.ThrowIfNull(arr); + // Unsafe.AsPointer is safe since array must be pinned void* pRawData = Unsafe.AsPointer(ref MemoryMarshal.GetArrayDataReference(arr)); #pragma warning disable 8500 // sizeof of managed types return (IntPtr)((byte*)pRawData + (uint)index * (nuint)sizeof(T)); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/AnsiStringMarshaller.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/AnsiStringMarshaller.cs index 4588f6912efd8..34cfccd08755d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/AnsiStringMarshaller.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/AnsiStringMarshaller.cs @@ -87,6 +87,7 @@ public void FromManaged(string? managed, Span buffer) } } + // Unsafe.AsPointer is safe since buffer must be pinned _unmanagedValue = (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(buffer)); Marshal.GetAnsiStringBytes(managed, buffer); // Includes null terminator diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/ArrayMarshaller.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/ArrayMarshaller.cs index 0800b623d449e..823c31917e764 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/ArrayMarshaller.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/ArrayMarshaller.cs @@ -173,7 +173,11 @@ public void FromManaged(T[]? array, Span buffer) /// Returns the unmanaged value representing the array. /// /// A pointer to the beginning of the unmanaged value. - public TUnmanagedElement* ToUnmanaged() => (TUnmanagedElement*)Unsafe.AsPointer(ref GetPinnableReference()); + public TUnmanagedElement* ToUnmanaged() + { + // Unsafe.AsPointer is safe since buffer must be pinned + return (TUnmanagedElement*)Unsafe.AsPointer(ref GetPinnableReference()); + } /// /// Frees resources. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/BStrStringMarshaller.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/BStrStringMarshaller.cs index 38b033d0a9bd7..561f8ce8de312 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/BStrStringMarshaller.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/BStrStringMarshaller.cs @@ -86,6 +86,7 @@ public void FromManaged(string? managed, Span buffer) else { // Set length and update buffer target + // Unsafe.AsPointer is safe since buffer must be pinned byte* pBuffer = (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(buffer)); *((uint*)pBuffer) = (uint)lengthInBytes; ptrToFirstChar = (ushort*)(pBuffer + sizeof(uint)); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/PointerArrayMarshaller.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/PointerArrayMarshaller.cs index ee7a3a134229c..846879583d5ac 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/PointerArrayMarshaller.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/PointerArrayMarshaller.cs @@ -174,7 +174,11 @@ public void FromManaged(T*[]? array, Span buffer) /// Returns the unmanaged value representing the array. /// /// A pointer to the beginning of the unmanaged value. - public TUnmanagedElement* ToUnmanaged() => (TUnmanagedElement*)Unsafe.AsPointer(ref GetPinnableReference()); + public TUnmanagedElement* ToUnmanaged() + { + // Unsafe.AsPointer is safe since buffer must be pinned + return (TUnmanagedElement*)Unsafe.AsPointer(ref GetPinnableReference()); + } /// /// Frees resources. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/ReadOnlySpanMarshaller.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/ReadOnlySpanMarshaller.cs index 8fe502608dce6..bab60b629e319 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/ReadOnlySpanMarshaller.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/ReadOnlySpanMarshaller.cs @@ -142,7 +142,11 @@ public void FromManaged(ReadOnlySpan managed, Span buffer) /// /// Returns the unmanaged value representing the array. /// - public TUnmanagedElement* ToUnmanaged() => (TUnmanagedElement*)Unsafe.AsPointer(ref GetPinnableReference()); + public TUnmanagedElement* ToUnmanaged() + { + // Unsafe.AsPointer is safe since buffer must be pinned + return (TUnmanagedElement*)Unsafe.AsPointer(ref GetPinnableReference()); + } /// /// Frees resources. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/SpanMarshaller.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/SpanMarshaller.cs index a9d42299848df..fb8aa49b12b61 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/SpanMarshaller.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/SpanMarshaller.cs @@ -170,7 +170,11 @@ public void FromManaged(Span managed, Span buffer) /// /// Returns the unmanaged value representing the array. /// - public TUnmanagedElement* ToUnmanaged() => (TUnmanagedElement*)Unsafe.AsPointer(ref GetPinnableReference()); + public TUnmanagedElement* ToUnmanaged() + { + // Unsafe.AsPointer is safe since buffer must be pinned + return (TUnmanagedElement*)Unsafe.AsPointer(ref GetPinnableReference()); + } /// /// Frees resources. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/Utf8StringMarshaller.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/Utf8StringMarshaller.cs index e6d529392bc9e..ee231616eaad2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/Utf8StringMarshaller.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshalling/Utf8StringMarshaller.cs @@ -91,6 +91,7 @@ public void FromManaged(string? managed, Span buffer) } } + // Unsafe.AsPointer is safe since buffer must be pinned _unmanagedValue = (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(buffer)); int byteCount = Encoding.UTF8.GetBytes(managed, buffer); diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.ByteMemOps.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.ByteMemOps.cs index 5429459209925..b4aa563b27747 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.ByteMemOps.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.ByteMemOps.cs @@ -162,7 +162,7 @@ internal static unsafe void Memmove(ref byte dest, ref byte src, nuint len) // // dest is more important to align than src because an unaligned store is more expensive // than an unaligned load. - nuint misalignedElements = 64 - (nuint)Unsafe.AsPointer(ref dest) & 63; + nuint misalignedElements = 64 - Unsafe.OpportunisticMisalignment(ref dest, 64); Unsafe.As(ref dest) = Unsafe.As(ref src); src = ref Unsafe.Add(ref src, misalignedElements); dest = ref Unsafe.Add(ref dest, misalignedElements); @@ -366,7 +366,7 @@ public static unsafe void ClearWithoutReferences(ref byte dest, nuint len) { // Try to opportunistically align the destination below. The input isn't pinned, so the GC // is free to move the references. We're therefore assuming that reads may still be unaligned. - nuint misalignedElements = 64 - (nuint)Unsafe.AsPointer(ref dest) & 63; + nuint misalignedElements = 64 - Unsafe.OpportunisticMisalignment(ref dest, 64); Unsafe.WriteUnaligned(ref dest, default); dest = ref Unsafe.Add(ref dest, misalignedElements); len -= misalignedElements; diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Ascii.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Ascii.cs index 85801e101a173..996ea2c96fbf1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Ascii.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Ascii.cs @@ -141,7 +141,7 @@ private static unsafe bool IsValidCore(ref T searchSpace, int length) where T // Try to opportunistically align the reads below. The input isn't pinned, so the GC // is free to move the references. We're therefore assuming that reads may still be unaligned. // They may also be unaligned if the input chars aren't 2-byte aligned. - nuint misalignedElements = ((nuint)Unsafe.AsPointer(ref searchSpace) & (nuint)(Vector256.Count - 1)) / (nuint)sizeof(T); + nuint misalignedElements = Unsafe.OpportunisticMisalignment(ref searchSpace, Vector256.Count) / (nuint)sizeof(T); i -= misalignedElements; Debug.Assert((int)i > 3 * Vector256.Count); @@ -193,7 +193,7 @@ private static unsafe bool IsValidCore(ref T searchSpace, int length) where T // Try to opportunistically align the reads below. The input isn't pinned, so the GC // is free to move the references. We're therefore assuming that reads may still be unaligned. // They may also be unaligned if the input chars aren't 2-byte aligned. - nuint misalignedElements = ((nuint)Unsafe.AsPointer(ref searchSpace) & (nuint)(Vector128.Count - 1)) / (nuint)sizeof(T); + nuint misalignedElements = Unsafe.OpportunisticMisalignment(ref searchSpace, Vector128.Count) / (nuint)sizeof(T); i -= misalignedElements; Debug.Assert((int)i > 3 * Vector128.Count); diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.cs index 056ff96d41b1e..f269e96544793 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.cs @@ -641,7 +641,9 @@ internal unsafe nint ObjectIdForEvents get { Lock lockObj = this; - return *(nint*)Unsafe.AsPointer(ref lockObj); +#pragma warning disable CS8500 + return *(nint*)&lockObj; +#pragma warning restore CS8500 } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs index c80e3f300e5d8..3ce0ae9e6f8a7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs @@ -501,8 +501,10 @@ public void TraceSynchronousWorkEnd(CausalitySynchronousWork Work) } } +#pragma warning disable CS8500 [NonEvent] - public unsafe void RunningContinuation(int TaskID, object Object) { RunningContinuation(TaskID, (long)*((void**)Unsafe.AsPointer(ref Object))); } + public unsafe void RunningContinuation(int TaskID, object Object) { RunningContinuation(TaskID, (long)*((void**)&Object)); } +#pragma warning restore CS8500 [Event(20, Keywords = Keywords.Debug)] private void RunningContinuation(int TaskID, long Object) { @@ -510,8 +512,10 @@ private void RunningContinuation(int TaskID, long Object) WriteEvent(20, TaskID, Object); } +#pragma warning disable CS8500 [NonEvent] - public unsafe void RunningContinuationList(int TaskID, int Index, object Object) { RunningContinuationList(TaskID, Index, (long)*((void**)Unsafe.AsPointer(ref Object))); } + public unsafe void RunningContinuationList(int TaskID, int Index, object Object) { RunningContinuationList(TaskID, Index, (long)*((void**)&Object)); } +#pragma warning restore CS8500 [Event(21, Keywords = Keywords.Debug)] public void RunningContinuationList(int TaskID, int Index, long Object) diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulPinnedMarshalling.cs b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulPinnedMarshalling.cs index eaac2608d8184..1347a2858e372 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulPinnedMarshalling.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatefulPinnedMarshalling.cs @@ -86,6 +86,7 @@ public ref StatefulPinnedNative GetPinnableReference() _canFree = true; if (_isPinned) { + // Unsafe.AsPointer is safe, because the result from GetPinnableReference is pinned _refNativeStruct = new StatefulPinnedNative() { I = _managed.I }; return (StatefulPinnedNative*)Unsafe.AsPointer(ref _refNativeStruct); } diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessCallerAllocateBufferMarshalling.cs b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessCallerAllocateBufferMarshalling.cs index f8b1174799b13..6388ab2990113 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessCallerAllocateBufferMarshalling.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IStatelessCallerAllocateBufferMarshalling.cs @@ -94,6 +94,7 @@ public static class ManagedToUnmanagedIn { var unmanaged = new StatelessCallerAllocatedBufferNative() { I = managed.I }; MemoryMarshal.Write(buffer, in unmanaged); + // Unsafe.AsPointer is safe since buffer is pinned return (StatelessCallerAllocatedBufferNative*)Unsafe.AsPointer(ref MemoryMarshal.AsRef(buffer)); } diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/NonBlittable.cs b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/NonBlittable.cs index 88e594d9f6a2d..aa4df06e002f4 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/NonBlittable.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/NonBlittable.cs @@ -84,6 +84,7 @@ public static unsafe class DoubleToBytesBigEndianMarshaller public static byte* ConvertToUnmanaged(double managed, Span buffer) { + // Unsafe.AsPointer is safe since buffer must be pinned BinaryPrimitives.WriteDoubleBigEndian(buffer, managed); return (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(buffer)); } @@ -305,6 +306,7 @@ public struct StatefulGetPinnableReference private IntWrapperWithoutGetPinnableReference _managed; public void FromManaged(IntWrapperWithoutGetPinnableReference managed) => _managed = managed; + // Unsafe.AsPointer is safe since buffer must be pinned public int* ToUnmanaged() => (int*)Unsafe.AsPointer(ref _managed.i); public ref int GetPinnableReference() => ref _managed.i; @@ -463,6 +465,7 @@ public unsafe static class ListMarshallerWithBuffer where if (spaceRequired > buffer.Length) throw new InvalidOperationException(); + // Unsafe.AsPointer is safe since buffer must be pinned return (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(buffer)); } @@ -520,6 +523,7 @@ public void FromManaged(List managed, Span buffer) public ref TUnmanagedElement GetPinnableReference() => ref MemoryMarshal.GetReference(_span); + // Unsafe.AsPointer is safe since buffer must be pinned public byte* ToUnmanaged() => (byte*)Unsafe.AsPointer(ref GetPinnableReference()); public Span GetManagedValuesDestination(int length) diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/GCTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/GCTests.cs index 59cedd9a5cea6..e4aad71c5ac35 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/GCTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/GCTests.cs @@ -1096,7 +1096,7 @@ private unsafe static void AllocateArrayPinned_ManagedValueType_CanRoundtripThro var rng = new Random(0xAF); EmbeddedValueType[] array = uninitialized ? GC.AllocateUninitializedArray>(length, pinned: true) : GC.AllocateArray>(length, pinned: true); - byte* pointer = (byte*)Unsafe.AsPointer(ref array[0]); + byte* pointer = (byte*)Unsafe.AsPointer(ref array[0]); // Unsafe.AsPointer is safe since array is pinned var size = Unsafe.SizeOf>(); for(int i = 0; i < length; ++i) diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/StringTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/StringTests.cs index dbd6bf7cbee5b..9f59853b136da 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/StringTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/StringTests.cs @@ -999,6 +999,7 @@ public static unsafe void GetPinnableReference_ReturnsSameAsGCHandleAndLegacyFix GCHandle gcHandle = GCHandle.Alloc(input, GCHandleType.Pinned); try { + // Unsafe.AsPointer is safe since it's pinned by the gc handle Assert.Equal((IntPtr)Unsafe.AsPointer(ref Unsafe.AsRef(in rChar)), gcHandle.AddrOfPinnedObject()); } finally From 69779a455546e171f07dde9b7a4eb7df086169c4 Mon Sep 17 00:00:00 2001 From: Hamish Arblaster Date: Mon, 4 Mar 2024 20:53:55 +1100 Subject: [PATCH 05/14] Fix compile errors --- src/libraries/Common/src/System/Number.NumberBuffer.cs | 2 +- .../src/System/Globalization/CalendarData.Icu.cs | 8 ++++++++ .../System.Private.CoreLib/src/System/Text/Ascii.cs | 4 ++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/libraries/Common/src/System/Number.NumberBuffer.cs b/src/libraries/Common/src/System/Number.NumberBuffer.cs index cba051294dbbf..1fb6949182ac9 100644 --- a/src/libraries/Common/src/System/Number.NumberBuffer.cs +++ b/src/libraries/Common/src/System/Number.NumberBuffer.cs @@ -50,7 +50,7 @@ public NumberBuffer(NumberBufferKind kind, Span digits) IsNegative = false; HasNonZeroTail = false; Kind = kind; - DigitsPtr = Unsafe.AsPointer(ref MemoryMarshal.GetReference(digits)); // Safe since memory must be fixed + DigitsPtr = (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(digits)); // Safe since memory must be fixed DigitsLength = digits.Length; #if DEBUG Digits.Fill(0xCC); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs index bf8ab2bfb108a..563b453d3abd0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs @@ -142,7 +142,9 @@ private static unsafe bool EnumDatePatterns(string localeName, CalendarId calend IcuEnumCalendarsData callbackContext = default; callbackContext.Results = new List(); callbackContext.DisallowDuplicates = true; +#pragma warning disable CS8500 bool result = EnumCalendarInfo(localeName, calendarId, dataType, &callbackContext); +#pragma warning restore CS8500 if (result) { List datePatternsList = callbackContext.Results; @@ -368,7 +370,9 @@ private static unsafe bool EnumMonthNames(string localeName, CalendarId calendar IcuEnumCalendarsData callbackContext = default; callbackContext.Results = new List(); +#pragma warning disable CS8500 bool result = EnumCalendarInfo(localeName, calendarId, dataType, &callbackContext); +#pragma warning restore CS8500 if (result) { // the month-name arrays are expected to have 13 elements. If ICU only returns 12, add an @@ -416,7 +420,9 @@ internal static unsafe bool EnumCalendarInfo(string localeName, CalendarId calen IcuEnumCalendarsData callbackContext = default; callbackContext.Results = new List(); +#pragma warning disable CS8500 bool result = EnumCalendarInfo(localeName, calendarId, dataType, &callbackContext); +#pragma warning restore CS8500 if (result) { calendarData = callbackContext.Results.ToArray(); @@ -425,10 +431,12 @@ internal static unsafe bool EnumCalendarInfo(string localeName, CalendarId calen return result; } +#pragma warning disable CS8500 private static unsafe bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, IcuEnumCalendarsData* callbackContext) { return Interop.Globalization.EnumCalendarInfo(&EnumCalendarInfoCallback, localeName, calendarId, dataType, (IntPtr)callbackContext); } +#pragma warning restore CS8500 [UnmanagedCallersOnly] private static unsafe void EnumCalendarInfoCallback(char* calendarStringPtr, IntPtr context) diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Ascii.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Ascii.cs index 996ea2c96fbf1..5507aed9c7700 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Ascii.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Ascii.cs @@ -141,7 +141,7 @@ private static unsafe bool IsValidCore(ref T searchSpace, int length) where T // Try to opportunistically align the reads below. The input isn't pinned, so the GC // is free to move the references. We're therefore assuming that reads may still be unaligned. // They may also be unaligned if the input chars aren't 2-byte aligned. - nuint misalignedElements = Unsafe.OpportunisticMisalignment(ref searchSpace, Vector256.Count) / (nuint)sizeof(T); + nuint misalignedElements = Unsafe.OpportunisticMisalignment(ref searchSpace, (uint)Vector256.Count) / (nuint)sizeof(T); i -= misalignedElements; Debug.Assert((int)i > 3 * Vector256.Count); @@ -193,7 +193,7 @@ private static unsafe bool IsValidCore(ref T searchSpace, int length) where T // Try to opportunistically align the reads below. The input isn't pinned, so the GC // is free to move the references. We're therefore assuming that reads may still be unaligned. // They may also be unaligned if the input chars aren't 2-byte aligned. - nuint misalignedElements = Unsafe.OpportunisticMisalignment(ref searchSpace, Vector128.Count) / (nuint)sizeof(T); + nuint misalignedElements = Unsafe.OpportunisticMisalignment(ref searchSpace, (uint)Vector128.Count) / (nuint)sizeof(T); i -= misalignedElements; Debug.Assert((int)i > 3 * Vector128.Count); From cde3b14be697d51534e6bcfe82a30a1162d3104c Mon Sep 17 00:00:00 2001 From: Hamish Arblaster Date: Mon, 4 Mar 2024 21:17:58 +1100 Subject: [PATCH 06/14] Update CorInfoImpl.cs --- src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index e56c515c11a80..457f8decf7eb3 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -352,7 +352,7 @@ private CompilationResult CompileMethodInternal(IMethodNode methodCodeNodeNeedin uint codeSize; #pragma warning disable CS8500 var result = JitCompileMethod(out exception, - _jit, (IntPtr)&_this, _unmanagedCallbacks, + _jit, (IntPtr)(&_this), _unmanagedCallbacks, ref methodInfo, (uint)CorJitFlag.CORJIT_FLAG_CALL_GETJITFLAGS, out nativeEntry, out codeSize); #pragma warning restore CS8500 if (exception != IntPtr.Zero) From 85c813f06899ca04b455b3439c1bdf6b5de00c47 Mon Sep 17 00:00:00 2001 From: Hamish Arblaster Date: Tue, 5 Mar 2024 07:40:00 +1100 Subject: [PATCH 07/14] Apply feedback --- .../Runtime/CompilerHelpers/StartupCodeHelpers.cs | 6 +++--- .../NativeRuntimeEventSource.Threading.NativeSinks.cs | 8 +++----- .../Tracing/NativeRuntimeEventSource.Threading.cs | 8 +++----- .../src/System/Runtime/CompilerServices/Unsafe.cs | 5 +++++ .../src/System/Threading/Lock.cs | 11 ----------- 5 files changed, 14 insertions(+), 24 deletions(-) diff --git a/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs b/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs index 03d9505186549..ef46af45a7f79 100644 --- a/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs +++ b/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs @@ -206,12 +206,13 @@ private static unsafe object[] InitializeStatics(IntPtr gcStaticRegionStart, int nint blockAddr = MethodTable.SupportsRelativePointers ? (nint)ReadRelPtr32(pBlock) : *pBlock; if ((blockAddr & GCStaticRegionConstants.Uninitialized) == GCStaticRegionConstants.Uninitialized) { -#pragma warning disable CS8500 object? obj = null; +#pragma warning disable CS8500 RuntimeImports.RhAllocateNewObject( new IntPtr(blockAddr & ~GCStaticRegionConstants.Mask), (uint)GC_ALLOC_FLAGS.GC_ALLOC_PINNED_OBJECT_HEAP, &obj); +#pragma warning restore CS8500 if (obj == null) { RuntimeExceptionHelpers.FailFast("Failed allocating GC static bases"); @@ -233,8 +234,7 @@ private static unsafe object[] InitializeStatics(IntPtr gcStaticRegionStart, int Unsafe.Add(ref rawSpineData, currentBase) = obj; // Update the base pointer to point to the pinned object - *pBlock = *(IntPtr*)&obj; -#pragma warning restore CS8500 + *pBlock = Unsafe.GetPinnedObjectPointer(obj); } currentBase++; diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.cs index bc9a6479989fe..08f0193388ba7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.cs @@ -94,7 +94,7 @@ private void ContentionLockCreated(nint LockID, nint AssociatedObjectID, ushort [NonEvent] [MethodImpl(MethodImplOptions.NoInlining)] - public void ContentionLockCreated(Lock lockObj) => ContentionLockCreated(lockObj.LockIdForEvents, lockObj.ObjectIdForEvents); + public void ContentionLockCreated(Lock lockObj) => ContentionLockCreated(lockObj.LockIdForEvents, Unsafe.ObjectIDForEvents(lockObj)); [Event(81, Level = EventLevel.Informational, Message = Messages.ContentionStart, Task = Tasks.Contention, Opcode = EventOpcode.Start, Version = 2, Keywords = Keywords.ContentionKeyword)] private void ContentionStart( @@ -115,7 +115,7 @@ public void ContentionStart(Lock lockObj) => ContentionFlagsMap.Managed, DefaultClrInstanceId, lockObj.LockIdForEvents, - lockObj.ObjectIdForEvents, + Unsafe.ObjectIDForEvents(lockObj), lockObj.OwningThreadId); [Event(91, Level = EventLevel.Informational, Message = Messages.ContentionStop, Task = Tasks.Contention, Opcode = EventOpcode.Stop, Version = 1, Keywords = Keywords.ContentionKeyword)] @@ -355,14 +355,12 @@ private void WaitHandleWaitStart( LogWaitHandleWaitStart(WaitSource, AssociatedObjectID, ClrInstanceID); } -#pragma warning disable CS8500 [NonEvent] [MethodImpl(MethodImplOptions.NoInlining)] public unsafe void WaitHandleWaitStart( WaitHandleWaitSourceMap waitSource = WaitHandleWaitSourceMap.Unknown, object? associatedObject = null) => - WaitHandleWaitStart(waitSource, *(nint*)&associatedObject); -#pragma warning restore CS8500 + WaitHandleWaitStart(waitSource, Unsafe.ObjectIDForEvents(associatedObject)); [Event(302, Level = EventLevel.Verbose, Message = Messages.WaitHandleWaitStop, Task = Tasks.WaitHandleWait, Opcode = EventOpcode.Stop, Version = 0, Keywords = Keywords.WaitHandleKeyword)] public void WaitHandleWaitStop(ushort ClrInstanceID = DefaultClrInstanceId) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.cs index 02307c27d61e0..62c90a67f44b1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.cs @@ -107,7 +107,7 @@ private unsafe void ContentionLockCreated(nint LockID, nint AssociatedObjectID, [NonEvent] [MethodImpl(MethodImplOptions.NoInlining)] - public void ContentionLockCreated(Lock lockObj) => ContentionLockCreated(lockObj.LockIdForEvents, lockObj.ObjectIdForEvents); + public void ContentionLockCreated(Lock lockObj) => ContentionLockCreated(lockObj.LockIdForEvents, Unsafe.ObjectIDForEvents(lockObj)); [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:UnrecognizedReflectionPattern", Justification = "Parameters to this method are primitive and are trimmer safe")] [Event(81, Level = EventLevel.Informational, Message = Messages.ContentionStart, Task = Tasks.Contention, Opcode = EventOpcode.Start, Version = 2, Keywords = Keywords.ContentionKeyword)] @@ -146,7 +146,7 @@ public void ContentionStart(Lock lockObj) => ContentionFlagsMap.Managed, DefaultClrInstanceId, lockObj.LockIdForEvents, - lockObj.ObjectIdForEvents, + Unsafe.ObjectIDForEvents(lockObj), lockObj.OwningThreadId); [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:UnrecognizedReflectionPattern", Justification = "Parameters to this method are primitive and are trimmer safe")] @@ -552,14 +552,12 @@ private unsafe void WaitHandleWaitStart( WriteEventCore(301, 3, data); } -#pragma warning disable CS8500 [NonEvent] [MethodImpl(MethodImplOptions.NoInlining)] public unsafe void WaitHandleWaitStart( WaitHandleWaitSourceMap waitSource = WaitHandleWaitSourceMap.Unknown, object? associatedObject = null) => - WaitHandleWaitStart(waitSource, *(nint*)&associatedObject); -#pragma warning restore CS8500 + WaitHandleWaitStart(waitSource, Unsafe.ObjectIDForEvents(associatedObject)); [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:UnrecognizedReflectionPattern", Justification = "Parameters to this method are primitive and are trimmer safe")] [Event(302, Level = EventLevel.Verbose, Message = Messages.WaitHandleWaitStop, Task = Tasks.WaitHandleWait, Opcode = EventOpcode.Stop, Version = 0, Keywords = Keywords.WaitHandleKeyword)] 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 901d354cfc7c8..4825b87319fc5 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 @@ -935,5 +935,10 @@ internal static nuint OpportunisticMisalignment(ref readonly T address, nuint Debug.Assert(nuint.IsPow2(alignment)); return (nuint)AsPointer(ref AsRef(in address)) & (alignment - 1); } + + // Returns the object as a IntPtr - safe when object is pinned, or when only used for logging; + // The second method is also defined so that safe usage is always obvious by name. + internal static nint GetPinnedObjectPointer(object o) => *(nint*)&o; + internal static nint ObjectIDForEvents(object o) => GetPinnedObjectPointer(o); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.cs index f269e96544793..c3d7f633af43c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.cs @@ -636,17 +636,6 @@ internal nint LockIdForEvents } } - internal unsafe nint ObjectIdForEvents - { - get - { - Lock lockObj = this; -#pragma warning disable CS8500 - return *(nint*)&lockObj; -#pragma warning restore CS8500 - } - } - internal ulong OwningThreadId => _owningThreadId; private static short DetermineMaxSpinCount() => From cbdc59b38d5677a2316310ff41a1d032de2d606b Mon Sep 17 00:00:00 2001 From: Hamish Arblaster Date: Tue, 5 Mar 2024 07:49:46 +1100 Subject: [PATCH 08/14] Apply feedback --- .../src/System/Diagnostics/Tracing/EventSource.cs | 6 ++++++ .../NativeRuntimeEventSource.Threading.NativeSinks.cs | 6 +++--- .../Tracing/NativeRuntimeEventSource.Threading.cs | 6 +++--- .../src/System/Runtime/CompilerServices/Unsafe.cs | 7 ++++--- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs index 7a292e019fdda..e1cd3931e7da5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs @@ -1118,6 +1118,12 @@ protected unsafe void WriteEvent(int eventId, long arg1, byte[]? arg2) } } } + + // Returns the object as a IntPtr - safe when only used for logging + internal static nint ObjectIDForEvents(object o) + { + return Unsafe.GetPinnedObjectPointer(o); + } } #pragma warning restore 1591 diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.cs index 08f0193388ba7..432540c79ff15 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.NativeSinks.cs @@ -94,7 +94,7 @@ private void ContentionLockCreated(nint LockID, nint AssociatedObjectID, ushort [NonEvent] [MethodImpl(MethodImplOptions.NoInlining)] - public void ContentionLockCreated(Lock lockObj) => ContentionLockCreated(lockObj.LockIdForEvents, Unsafe.ObjectIDForEvents(lockObj)); + public void ContentionLockCreated(Lock lockObj) => ContentionLockCreated(lockObj.LockIdForEvents, ObjectIDForEvents(lockObj)); [Event(81, Level = EventLevel.Informational, Message = Messages.ContentionStart, Task = Tasks.Contention, Opcode = EventOpcode.Start, Version = 2, Keywords = Keywords.ContentionKeyword)] private void ContentionStart( @@ -115,7 +115,7 @@ public void ContentionStart(Lock lockObj) => ContentionFlagsMap.Managed, DefaultClrInstanceId, lockObj.LockIdForEvents, - Unsafe.ObjectIDForEvents(lockObj), + ObjectIDForEvents(lockObj), lockObj.OwningThreadId); [Event(91, Level = EventLevel.Informational, Message = Messages.ContentionStop, Task = Tasks.Contention, Opcode = EventOpcode.Stop, Version = 1, Keywords = Keywords.ContentionKeyword)] @@ -360,7 +360,7 @@ private void WaitHandleWaitStart( public unsafe void WaitHandleWaitStart( WaitHandleWaitSourceMap waitSource = WaitHandleWaitSourceMap.Unknown, object? associatedObject = null) => - WaitHandleWaitStart(waitSource, Unsafe.ObjectIDForEvents(associatedObject)); + WaitHandleWaitStart(waitSource, ObjectIDForEvents(associatedObject)); [Event(302, Level = EventLevel.Verbose, Message = Messages.WaitHandleWaitStop, Task = Tasks.WaitHandleWait, Opcode = EventOpcode.Stop, Version = 0, Keywords = Keywords.WaitHandleKeyword)] public void WaitHandleWaitStop(ushort ClrInstanceID = DefaultClrInstanceId) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.cs index 62c90a67f44b1..8c85770e1f0aa 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.Threading.cs @@ -107,7 +107,7 @@ private unsafe void ContentionLockCreated(nint LockID, nint AssociatedObjectID, [NonEvent] [MethodImpl(MethodImplOptions.NoInlining)] - public void ContentionLockCreated(Lock lockObj) => ContentionLockCreated(lockObj.LockIdForEvents, Unsafe.ObjectIDForEvents(lockObj)); + public void ContentionLockCreated(Lock lockObj) => ContentionLockCreated(lockObj.LockIdForEvents, ObjectIDForEvents(lockObj)); [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:UnrecognizedReflectionPattern", Justification = "Parameters to this method are primitive and are trimmer safe")] [Event(81, Level = EventLevel.Informational, Message = Messages.ContentionStart, Task = Tasks.Contention, Opcode = EventOpcode.Start, Version = 2, Keywords = Keywords.ContentionKeyword)] @@ -146,7 +146,7 @@ public void ContentionStart(Lock lockObj) => ContentionFlagsMap.Managed, DefaultClrInstanceId, lockObj.LockIdForEvents, - Unsafe.ObjectIDForEvents(lockObj), + ObjectIDForEvents(lockObj), lockObj.OwningThreadId); [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:UnrecognizedReflectionPattern", Justification = "Parameters to this method are primitive and are trimmer safe")] @@ -557,7 +557,7 @@ private unsafe void WaitHandleWaitStart( public unsafe void WaitHandleWaitStart( WaitHandleWaitSourceMap waitSource = WaitHandleWaitSourceMap.Unknown, object? associatedObject = null) => - WaitHandleWaitStart(waitSource, Unsafe.ObjectIDForEvents(associatedObject)); + WaitHandleWaitStart(waitSource, ObjectIDForEvents(associatedObject)); [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:UnrecognizedReflectionPattern", Justification = "Parameters to this method are primitive and are trimmer safe")] [Event(302, Level = EventLevel.Verbose, Message = Messages.WaitHandleWaitStop, Task = Tasks.WaitHandleWait, Opcode = EventOpcode.Stop, Version = 0, Keywords = Keywords.WaitHandleKeyword)] 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 4825b87319fc5..91e28f10f35bb 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 @@ -937,8 +937,9 @@ internal static nuint OpportunisticMisalignment(ref readonly T address, nuint } // Returns the object as a IntPtr - safe when object is pinned, or when only used for logging; - // The second method is also defined so that safe usage is always obvious by name. - internal static nint GetPinnedObjectPointer(object o) => *(nint*)&o; - internal static nint ObjectIDForEvents(object o) => GetPinnedObjectPointer(o); + internal static nint GetPinnedObjectPointer(object o) + { + return *(nint*)&o; + } } } From 8cfeb0ab51f49e659d55a5dfc77ce670a017245a Mon Sep 17 00:00:00 2001 From: Hamish Arblaster Date: Tue, 5 Mar 2024 07:51:47 +1100 Subject: [PATCH 09/14] Apply feedback --- .../Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs | 6 +++--- .../src/System/Diagnostics/Tracing/EventSource.cs | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs b/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs index ef46af45a7f79..03d9505186549 100644 --- a/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs +++ b/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs @@ -206,13 +206,12 @@ private static unsafe object[] InitializeStatics(IntPtr gcStaticRegionStart, int nint blockAddr = MethodTable.SupportsRelativePointers ? (nint)ReadRelPtr32(pBlock) : *pBlock; if ((blockAddr & GCStaticRegionConstants.Uninitialized) == GCStaticRegionConstants.Uninitialized) { - object? obj = null; #pragma warning disable CS8500 + object? obj = null; RuntimeImports.RhAllocateNewObject( new IntPtr(blockAddr & ~GCStaticRegionConstants.Mask), (uint)GC_ALLOC_FLAGS.GC_ALLOC_PINNED_OBJECT_HEAP, &obj); -#pragma warning restore CS8500 if (obj == null) { RuntimeExceptionHelpers.FailFast("Failed allocating GC static bases"); @@ -234,7 +233,8 @@ private static unsafe object[] InitializeStatics(IntPtr gcStaticRegionStart, int Unsafe.Add(ref rawSpineData, currentBase) = obj; // Update the base pointer to point to the pinned object - *pBlock = Unsafe.GetPinnedObjectPointer(obj); + *pBlock = *(IntPtr*)&obj; +#pragma warning restore CS8500 } currentBase++; diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs index e1cd3931e7da5..4f77dbee8f667 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs @@ -1122,7 +1122,9 @@ protected unsafe void WriteEvent(int eventId, long arg1, byte[]? arg2) // Returns the object as a IntPtr - safe when only used for logging internal static nint ObjectIDForEvents(object o) { - return Unsafe.GetPinnedObjectPointer(o); +#pragma warning disable CS8500 + return *(nint*)&o; +#pragma warning restore CS8500 } } From 92f1f689856c7122c6b380b4baa118294302a455 Mon Sep 17 00:00:00 2001 From: Hamish Arblaster Date: Tue, 5 Mar 2024 07:52:38 +1100 Subject: [PATCH 10/14] Update Unsafe.cs --- .../src/System/Runtime/CompilerServices/Unsafe.cs | 6 ------ 1 file changed, 6 deletions(-) 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 91e28f10f35bb..901d354cfc7c8 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 @@ -935,11 +935,5 @@ internal static nuint OpportunisticMisalignment(ref readonly T address, nuint Debug.Assert(nuint.IsPow2(alignment)); return (nuint)AsPointer(ref AsRef(in address)) & (alignment - 1); } - - // Returns the object as a IntPtr - safe when object is pinned, or when only used for logging; - internal static nint GetPinnedObjectPointer(object o) - { - return *(nint*)&o; - } } } From c4433e8a764ac0372daa44beb368f87b73e2bf58 Mon Sep 17 00:00:00 2001 From: Hamish Arblaster Date: Tue, 5 Mar 2024 08:06:43 +1100 Subject: [PATCH 11/14] Fix compile errors :) --- .../src/System/Diagnostics/Tracing/EventSource.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs index 4f77dbee8f667..6e0931e864e8d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs @@ -1118,14 +1118,14 @@ protected unsafe void WriteEvent(int eventId, long arg1, byte[]? arg2) } } } + } - // Returns the object as a IntPtr - safe when only used for logging - internal static nint ObjectIDForEvents(object o) - { + // Returns the object as a IntPtr - safe when only used for logging + internal static nint ObjectIDForEvents(object o) + { #pragma warning disable CS8500 - return *(nint*)&o; + return *(nint*)&o; #pragma warning restore CS8500 - } } #pragma warning restore 1591 From 5fbc273e3c94ea9ec384e68505a8e82c6a4b9a34 Mon Sep 17 00:00:00 2001 From: Hamish Arblaster Date: Tue, 5 Mar 2024 08:29:03 +1100 Subject: [PATCH 12/14] Add full CS8500 comment & fix compile error --- .../src/System/GC.CoreCLR.cs | 4 ++-- .../CompilerHelpers/StartupCodeHelpers.cs | 4 ++-- .../src/System/GC.NativeAot.cs | 12 ++++++------ .../tools/Common/JitInterface/CorInfoImpl.cs | 4 ++-- .../System/Diagnostics/Tracing/EventSource.cs | 6 +++--- .../src/System/Globalization/CalendarData.Icu.cs | 16 ++++++++-------- .../src/System/Threading/Tasks/TplEventSource.cs | 8 ++++---- 7 files changed, 27 insertions(+), 27 deletions(-) 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 9cb38bf04f926..0ee9c4a41e0fb 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs @@ -865,9 +865,9 @@ public static unsafe IReadOnlyDictionary GetConfigurationVariabl Configurations = new Dictionary() }; -#pragma warning disable CS8500 +#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type _EnumerateConfigurationValues(&context, &ConfigCallback); -#pragma warning restore CS8500 +#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type return context.Configurations!; } diff --git a/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs b/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs index 03d9505186549..98c23ef127454 100644 --- a/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs +++ b/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs @@ -206,7 +206,7 @@ private static unsafe object[] InitializeStatics(IntPtr gcStaticRegionStart, int nint blockAddr = MethodTable.SupportsRelativePointers ? (nint)ReadRelPtr32(pBlock) : *pBlock; if ((blockAddr & GCStaticRegionConstants.Uninitialized) == GCStaticRegionConstants.Uninitialized) { -#pragma warning disable CS8500 +#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type object? obj = null; RuntimeImports.RhAllocateNewObject( new IntPtr(blockAddr & ~GCStaticRegionConstants.Mask), @@ -234,7 +234,7 @@ private static unsafe object[] InitializeStatics(IntPtr gcStaticRegionStart, int // Update the base pointer to point to the pinned object *pBlock = *(IntPtr*)&obj; -#pragma warning restore CS8500 +#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type } currentBase++; 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 56e8016a67377..2278257087551 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 @@ -695,9 +695,9 @@ public static unsafe IReadOnlyDictionary GetConfigurationVariabl Configurations = new Dictionary() }; -#pragma warning disable CS8500 +#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type RuntimeImports.RhEnumerateConfigurationValues(&context, &ConfigCallback); -#pragma warning restore CS8500 +#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type return context.Configurations!; } @@ -832,9 +832,9 @@ static T[] AllocateNewUninitializedArray(int length, bool pinned) throw new OverflowException(); T[]? array = null; -#pragma warning disable CS8500 +#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type RuntimeImports.RhAllocateNewArray(MethodTable.Of(), (uint)length, (uint)flags, &array); -#pragma warning restore CS8500 +#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type if (array == null) throw new OutOfMemoryException(); @@ -861,9 +861,9 @@ public static unsafe T[] AllocateArray(int length, bool pinned = false) throw new OverflowException(); T[]? array = null; -#pragma warning disable CS8500 +#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type RuntimeImports.RhAllocateNewArray(MethodTable.Of(), (uint)length, (uint)flags, &array); -#pragma warning restore CS8500 +#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type if (array == null) throw new OutOfMemoryException(); diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 457f8decf7eb3..bfd53a47c4c89 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -350,11 +350,11 @@ private CompilationResult CompileMethodInternal(IMethodNode methodCodeNodeNeedin IntPtr exception; IntPtr nativeEntry; uint codeSize; -#pragma warning disable CS8500 +#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type var result = JitCompileMethod(out exception, _jit, (IntPtr)(&_this), _unmanagedCallbacks, ref methodInfo, (uint)CorJitFlag.CORJIT_FLAG_CALL_GETJITFLAGS, out nativeEntry, out codeSize); -#pragma warning restore CS8500 +#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type if (exception != IntPtr.Zero) { if (_lastException != null) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs index 6e0931e864e8d..2450474fb5e89 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs @@ -1121,11 +1121,11 @@ protected unsafe void WriteEvent(int eventId, long arg1, byte[]? arg2) } // Returns the object as a IntPtr - safe when only used for logging - internal static nint ObjectIDForEvents(object o) + internal static unsafe nint ObjectIDForEvents(object? o) { -#pragma warning disable CS8500 +#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type return *(nint*)&o; -#pragma warning restore CS8500 +#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type } #pragma warning restore 1591 diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs index 563b453d3abd0..caf470992ff3f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs @@ -142,9 +142,9 @@ private static unsafe bool EnumDatePatterns(string localeName, CalendarId calend IcuEnumCalendarsData callbackContext = default; callbackContext.Results = new List(); callbackContext.DisallowDuplicates = true; -#pragma warning disable CS8500 +#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type bool result = EnumCalendarInfo(localeName, calendarId, dataType, &callbackContext); -#pragma warning restore CS8500 +#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type if (result) { List datePatternsList = callbackContext.Results; @@ -370,9 +370,9 @@ private static unsafe bool EnumMonthNames(string localeName, CalendarId calendar IcuEnumCalendarsData callbackContext = default; callbackContext.Results = new List(); -#pragma warning disable CS8500 +#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type bool result = EnumCalendarInfo(localeName, calendarId, dataType, &callbackContext); -#pragma warning restore CS8500 +#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type if (result) { // the month-name arrays are expected to have 13 elements. If ICU only returns 12, add an @@ -420,9 +420,9 @@ internal static unsafe bool EnumCalendarInfo(string localeName, CalendarId calen IcuEnumCalendarsData callbackContext = default; callbackContext.Results = new List(); -#pragma warning disable CS8500 +#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type bool result = EnumCalendarInfo(localeName, calendarId, dataType, &callbackContext); -#pragma warning restore CS8500 +#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type if (result) { calendarData = callbackContext.Results.ToArray(); @@ -431,12 +431,12 @@ internal static unsafe bool EnumCalendarInfo(string localeName, CalendarId calen return result; } -#pragma warning disable CS8500 +#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type private static unsafe bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, IcuEnumCalendarsData* callbackContext) { return Interop.Globalization.EnumCalendarInfo(&EnumCalendarInfoCallback, localeName, calendarId, dataType, (IntPtr)callbackContext); } -#pragma warning restore CS8500 +#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type [UnmanagedCallersOnly] private static unsafe void EnumCalendarInfoCallback(char* calendarStringPtr, IntPtr context) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs index 3ce0ae9e6f8a7..2b34b76f70cfa 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs @@ -501,10 +501,10 @@ public void TraceSynchronousWorkEnd(CausalitySynchronousWork Work) } } -#pragma warning disable CS8500 +#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type [NonEvent] public unsafe void RunningContinuation(int TaskID, object Object) { RunningContinuation(TaskID, (long)*((void**)&Object)); } -#pragma warning restore CS8500 +#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type [Event(20, Keywords = Keywords.Debug)] private void RunningContinuation(int TaskID, long Object) { @@ -512,10 +512,10 @@ private void RunningContinuation(int TaskID, long Object) WriteEvent(20, TaskID, Object); } -#pragma warning disable CS8500 +#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type [NonEvent] public unsafe void RunningContinuationList(int TaskID, int Index, object Object) { RunningContinuationList(TaskID, Index, (long)*((void**)&Object)); } -#pragma warning restore CS8500 +#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type [Event(21, Keywords = Keywords.Debug)] public void RunningContinuationList(int TaskID, int Index, long Object) From b1a561845a62ce9a052ab9c01a4e3b976d898224 Mon Sep 17 00:00:00 2001 From: Hamish Arblaster Date: Tue, 5 Mar 2024 09:12:42 +1100 Subject: [PATCH 13/14] Address feedback --- .../src/System/GC.CoreCLR.cs | 4 ++-- .../CompilerHelpers/StartupCodeHelpers.cs | 4 ++-- .../src/System/GC.NativeAot.cs | 12 ++++++------ .../tools/Common/JitInterface/CorInfoImpl.cs | 4 ++-- .../System/Diagnostics/Tracing/EventSource.cs | 4 ++-- .../src/System/Globalization/CalendarData.Icu.cs | 16 ++++++++-------- .../src/System/Threading/Tasks/TplEventSource.cs | 8 ++++---- 7 files changed, 26 insertions(+), 26 deletions(-) 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 0ee9c4a41e0fb..697788316ba03 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs @@ -865,9 +865,9 @@ public static unsafe IReadOnlyDictionary GetConfigurationVariabl Configurations = new Dictionary() }; -#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning disable CS8500 // takes address of managed type _EnumerateConfigurationValues(&context, &ConfigCallback); -#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning restore CS8500 return context.Configurations!; } diff --git a/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs b/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs index 98c23ef127454..16b1659caeab7 100644 --- a/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs +++ b/src/coreclr/nativeaot/Common/src/Internal/Runtime/CompilerHelpers/StartupCodeHelpers.cs @@ -206,7 +206,7 @@ private static unsafe object[] InitializeStatics(IntPtr gcStaticRegionStart, int nint blockAddr = MethodTable.SupportsRelativePointers ? (nint)ReadRelPtr32(pBlock) : *pBlock; if ((blockAddr & GCStaticRegionConstants.Uninitialized) == GCStaticRegionConstants.Uninitialized) { -#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning disable CS8500 // takes address of managed type object? obj = null; RuntimeImports.RhAllocateNewObject( new IntPtr(blockAddr & ~GCStaticRegionConstants.Mask), @@ -234,7 +234,7 @@ private static unsafe object[] InitializeStatics(IntPtr gcStaticRegionStart, int // Update the base pointer to point to the pinned object *pBlock = *(IntPtr*)&obj; -#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning restore CS8500 } currentBase++; 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 2278257087551..0ee16609157ab 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 @@ -695,9 +695,9 @@ public static unsafe IReadOnlyDictionary GetConfigurationVariabl Configurations = new Dictionary() }; -#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning disable CS8500 // takes address of managed type RuntimeImports.RhEnumerateConfigurationValues(&context, &ConfigCallback); -#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning restore CS8500 return context.Configurations!; } @@ -832,9 +832,9 @@ static T[] AllocateNewUninitializedArray(int length, bool pinned) throw new OverflowException(); T[]? array = null; -#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning disable CS8500 // takes address of managed type RuntimeImports.RhAllocateNewArray(MethodTable.Of(), (uint)length, (uint)flags, &array); -#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning restore CS8500 if (array == null) throw new OutOfMemoryException(); @@ -861,9 +861,9 @@ public static unsafe T[] AllocateArray(int length, bool pinned = false) throw new OverflowException(); T[]? array = null; -#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning disable CS8500 // takes address of managed type RuntimeImports.RhAllocateNewArray(MethodTable.Of(), (uint)length, (uint)flags, &array); -#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning restore CS8500 if (array == null) throw new OutOfMemoryException(); diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index bfd53a47c4c89..fdaae7fdb715b 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -350,11 +350,11 @@ private CompilationResult CompileMethodInternal(IMethodNode methodCodeNodeNeedin IntPtr exception; IntPtr nativeEntry; uint codeSize; -#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning disable CS8500 // takes address of managed type var result = JitCompileMethod(out exception, _jit, (IntPtr)(&_this), _unmanagedCallbacks, ref methodInfo, (uint)CorJitFlag.CORJIT_FLAG_CALL_GETJITFLAGS, out nativeEntry, out codeSize); -#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning restore CS8500 if (exception != IntPtr.Zero) { if (_lastException != null) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs index 2450474fb5e89..78b745e232fa1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs @@ -1123,9 +1123,9 @@ protected unsafe void WriteEvent(int eventId, long arg1, byte[]? arg2) // Returns the object as a IntPtr - safe when only used for logging internal static unsafe nint ObjectIDForEvents(object? o) { -#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning disable CS8500 // takes address of managed type return *(nint*)&o; -#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning restore CS8500 } #pragma warning restore 1591 diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs index caf470992ff3f..26919ba0d50a8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs @@ -142,9 +142,9 @@ private static unsafe bool EnumDatePatterns(string localeName, CalendarId calend IcuEnumCalendarsData callbackContext = default; callbackContext.Results = new List(); callbackContext.DisallowDuplicates = true; -#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning disable CS8500 // takes address of managed type bool result = EnumCalendarInfo(localeName, calendarId, dataType, &callbackContext); -#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning restore CS8500 if (result) { List datePatternsList = callbackContext.Results; @@ -370,9 +370,9 @@ private static unsafe bool EnumMonthNames(string localeName, CalendarId calendar IcuEnumCalendarsData callbackContext = default; callbackContext.Results = new List(); -#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning disable CS8500 // takes address of managed type bool result = EnumCalendarInfo(localeName, calendarId, dataType, &callbackContext); -#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning restore CS8500 if (result) { // the month-name arrays are expected to have 13 elements. If ICU only returns 12, add an @@ -420,9 +420,9 @@ internal static unsafe bool EnumCalendarInfo(string localeName, CalendarId calen IcuEnumCalendarsData callbackContext = default; callbackContext.Results = new List(); -#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning disable CS8500 // takes address of managed type bool result = EnumCalendarInfo(localeName, calendarId, dataType, &callbackContext); -#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning restore CS8500 if (result) { calendarData = callbackContext.Results.ToArray(); @@ -431,12 +431,12 @@ internal static unsafe bool EnumCalendarInfo(string localeName, CalendarId calen return result; } -#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning disable CS8500 // takes address of managed type private static unsafe bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, IcuEnumCalendarsData* callbackContext) { return Interop.Globalization.EnumCalendarInfo(&EnumCalendarInfoCallback, localeName, calendarId, dataType, (IntPtr)callbackContext); } -#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning restore CS8500 [UnmanagedCallersOnly] private static unsafe void EnumCalendarInfoCallback(char* calendarStringPtr, IntPtr context) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs index 2b34b76f70cfa..cbcf8ad68971d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs @@ -501,10 +501,10 @@ public void TraceSynchronousWorkEnd(CausalitySynchronousWork Work) } } -#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning disable CS8500 // takes address of managed type [NonEvent] public unsafe void RunningContinuation(int TaskID, object Object) { RunningContinuation(TaskID, (long)*((void**)&Object)); } -#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning restore CS8500 [Event(20, Keywords = Keywords.Debug)] private void RunningContinuation(int TaskID, long Object) { @@ -512,10 +512,10 @@ private void RunningContinuation(int TaskID, long Object) WriteEvent(20, TaskID, Object); } -#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning disable CS8500 // takes address of managed type [NonEvent] public unsafe void RunningContinuationList(int TaskID, int Index, object Object) { RunningContinuationList(TaskID, Index, (long)*((void**)&Object)); } -#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type +#pragma warning restore CS8500 [Event(21, Keywords = Keywords.Debug)] public void RunningContinuationList(int TaskID, int Index, long Object) From f032d6804369907eefb4a2c3a5878a74ef7107f5 Mon Sep 17 00:00:00 2001 From: Hamish Arblaster Date: Tue, 5 Mar 2024 09:51:55 +1100 Subject: [PATCH 14/14] Update TplEventSource.cs --- .../src/System/Threading/Tasks/TplEventSource.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs index cbcf8ad68971d..048306cdf5076 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TplEventSource.cs @@ -501,10 +501,8 @@ public void TraceSynchronousWorkEnd(CausalitySynchronousWork Work) } } -#pragma warning disable CS8500 // takes address of managed type [NonEvent] - public unsafe void RunningContinuation(int TaskID, object Object) { RunningContinuation(TaskID, (long)*((void**)&Object)); } -#pragma warning restore CS8500 + public unsafe void RunningContinuation(int TaskID, object Object) => RunningContinuation(TaskID, ObjectIDForEvents(Object)); [Event(20, Keywords = Keywords.Debug)] private void RunningContinuation(int TaskID, long Object) { @@ -512,10 +510,8 @@ private void RunningContinuation(int TaskID, long Object) WriteEvent(20, TaskID, Object); } -#pragma warning disable CS8500 // takes address of managed type [NonEvent] - public unsafe void RunningContinuationList(int TaskID, int Index, object Object) { RunningContinuationList(TaskID, Index, (long)*((void**)&Object)); } -#pragma warning restore CS8500 + public unsafe void RunningContinuationList(int TaskID, int Index, object Object) => RunningContinuationList(TaskID, Index, ObjectIDForEvents(Object)); [Event(21, Keywords = Keywords.Debug)] public void RunningContinuationList(int TaskID, int Index, long Object)