diff --git a/src/libraries/System.Private.CoreLib/src/System/HashCode.cs b/src/libraries/System.Private.CoreLib/src/System/HashCode.cs index e11a37af24124a..6a80fa07da246f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/HashCode.cs +++ b/src/libraries/System.Private.CoreLib/src/System/HashCode.cs @@ -45,7 +45,6 @@ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT using System.Diagnostics; using System.Numerics; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; #pragma warning disable CA1066 // Implement IEquatable when overriding Object.Equals @@ -317,9 +316,6 @@ public void Add(T value, IEqualityComparer? comparer) /// public void AddBytes(ReadOnlySpan value) { - ref byte pos = ref MemoryMarshal.GetReference(value); - ref byte end = ref Unsafe.Add(ref pos, value.Length); - if (value.Length < (sizeof(int) * 4)) { goto Small; @@ -337,55 +333,47 @@ public void AddBytes(ReadOnlySpan value) switch (_length % 4) { case 1: - Debug.Assert(Unsafe.ByteOffset(ref pos, ref end) >= sizeof(int)); - Add(Unsafe.ReadUnaligned(ref pos)); - pos = ref Unsafe.Add(ref pos, sizeof(int)); + Debug.Assert(value.Length >= sizeof(int)); + Add(BitConverter.ToInt32(value)); + value = value.Slice(sizeof(int)); goto case 2; case 2: - Debug.Assert(Unsafe.ByteOffset(ref pos, ref end) >= sizeof(int)); - Add(Unsafe.ReadUnaligned(ref pos)); - pos = ref Unsafe.Add(ref pos, sizeof(int)); + Debug.Assert(value.Length >= sizeof(int)); + Add(BitConverter.ToInt32(value)); + value = value.Slice(sizeof(int)); goto case 3; case 3: - Debug.Assert(Unsafe.ByteOffset(ref pos, ref end) >= sizeof(int)); - Add(Unsafe.ReadUnaligned(ref pos)); - pos = ref Unsafe.Add(ref pos, sizeof(int)); + Debug.Assert(value.Length >= sizeof(int)); + Add(BitConverter.ToInt32(value)); + value = value.Slice(sizeof(int)); break; } } // With the queue clear, we add sixteen bytes at a time until the input has fewer than sixteen bytes remaining. - // We first have to round the end pointer to the nearest 16-byte block from the offset. This makes the loop's condition simpler. - ref byte blockEnd = ref Unsafe.Subtract(ref end, Unsafe.ByteOffset(ref pos, ref end) % (sizeof(int) * 4)); - while (Unsafe.IsAddressLessThan(ref pos, ref blockEnd)) + while (value.Length >= sizeof(int) * 4) { - Debug.Assert(Unsafe.ByteOffset(ref pos, ref blockEnd) >= (sizeof(int) * 4)); - uint v1 = Unsafe.ReadUnaligned(ref pos); - _v1 = Round(_v1, v1); - uint v2 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref pos, sizeof(int) * 1)); - _v2 = Round(_v2, v2); - uint v3 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref pos, sizeof(int) * 2)); - _v3 = Round(_v3, v3); - uint v4 = Unsafe.ReadUnaligned(ref Unsafe.Add(ref pos, sizeof(int) * 3)); - _v4 = Round(_v4, v4); + _v1 = Round(_v1, BitConverter.ToUInt32(value)); + _v2 = Round(_v2, BitConverter.ToUInt32(value.Slice(sizeof(int) * 1))); + _v3 = Round(_v3, BitConverter.ToUInt32(value.Slice(sizeof(int) * 2))); + _v4 = Round(_v4, BitConverter.ToUInt32(value.Slice(sizeof(int) * 3))); _length += 4; - pos = ref Unsafe.Add(ref pos, sizeof(int) * 4); + value = value.Slice(sizeof(int) * 4); } Small: // Add four bytes at a time until the input has fewer than four bytes remaining. - while (Unsafe.ByteOffset(ref pos, ref end) >= sizeof(int)) + while (value.Length >= sizeof(int)) { - Add(Unsafe.ReadUnaligned(ref pos)); - pos = ref Unsafe.Add(ref pos, sizeof(int)); + Add(BitConverter.ToInt32(value)); + value = value.Slice(sizeof(int)); } // Add the remaining bytes a single byte at a time. - while (Unsafe.IsAddressLessThan(ref pos, ref end)) + foreach (byte b in value) { - Add((int)pos); - pos = ref Unsafe.Add(ref pos, 1); + Add((int)b); } }