diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs index a657cebe4c78b..f965f98ac7f5e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs @@ -105,13 +105,13 @@ public static int LastIndexOfAny(ref byte searchSpace, int searchSpaceLength, re // Adapted from IndexOf(...) [MethodImpl(MethodImplOptions.AggressiveOptimization)] - public static unsafe bool Contains(ref byte searchSpace, byte value, int length) + public static bool Contains(ref byte searchSpace, byte value, int length) { Debug.Assert(length >= 0); uint uValue = value; // Use uint for comparisons to avoid unnecessary 8->32 extensions - IntPtr offset = (IntPtr)0; // Use IntPtr for arithmetic to avoid unnecessary 64->32->64 truncations - IntPtr lengthToExamine = (IntPtr)length; + nuint offset = 0; // Use nuint for arithmetic to avoid unnecessary 64->32->64 truncations + nuint lengthToExamine = (nuint)(uint)length; if (Vector.IsHardwareAccelerated && length >= Vector.Count * 2) { @@ -119,7 +119,7 @@ public static unsafe bool Contains(ref byte searchSpace, byte value, int length) } SequentialScan: - while ((byte*)lengthToExamine >= (byte*)8) + while (lengthToExamine >= 8) { lengthToExamine -= 8; @@ -138,7 +138,7 @@ public static unsafe bool Contains(ref byte searchSpace, byte value, int length) offset += 8; } - if ((byte*)lengthToExamine >= (byte*)4) + if (lengthToExamine >= 4) { lengthToExamine -= 4; @@ -153,7 +153,7 @@ public static unsafe bool Contains(ref byte searchSpace, byte value, int length) offset += 4; } - while ((byte*)lengthToExamine > (byte*)0) + while (lengthToExamine > 0) { lengthToExamine -= 1; @@ -163,27 +163,27 @@ public static unsafe bool Contains(ref byte searchSpace, byte value, int length) offset += 1; } - if (Vector.IsHardwareAccelerated && ((int)(byte*)offset < length)) + if (Vector.IsHardwareAccelerated && (offset < (nuint)(uint)length)) { - lengthToExamine = (IntPtr)((length - (int)(byte*)offset) & ~(Vector.Count - 1)); + lengthToExamine = (((nuint)(uint)length - offset) & (nuint)~(Vector.Count - 1)); Vector values = new Vector(value); - while ((byte*)lengthToExamine > (byte*)offset) + while (lengthToExamine > offset) { var matches = Vector.Equals(values, LoadVector(ref searchSpace, offset)); if (Vector.Zero.Equals(matches)) { - offset += Vector.Count; + offset += (nuint)Vector.Count; continue; } goto Found; } - if ((int)(byte*)offset < length) + if (offset < (nuint)(uint)length) { - lengthToExamine = (IntPtr)(length - (int)(byte*)offset); + lengthToExamine = ((nuint)(uint)length - offset); goto SequentialScan; } } @@ -200,8 +200,8 @@ public static unsafe int IndexOf(ref byte searchSpace, byte value, int length) Debug.Assert(length >= 0); uint uValue = value; // Use uint for comparisons to avoid unnecessary 8->32 extensions - IntPtr offset = (IntPtr)0; // Use IntPtr for arithmetic to avoid unnecessary 64->32->64 truncations - IntPtr lengthToExamine = (IntPtr)length; + nuint offset = 0; // Use nuint for arithmetic to avoid unnecessary 64->32->64 truncations + nuint lengthToExamine = (nuint)(uint)length; if (Avx2.IsSupported || Sse2.IsSupported) { @@ -219,7 +219,7 @@ public static unsafe int IndexOf(ref byte searchSpace, byte value, int length) } } SequentialScan: - while ((byte*)lengthToExamine >= (byte*)8) + while (lengthToExamine >= 8) { lengthToExamine -= 8; @@ -243,7 +243,7 @@ public static unsafe int IndexOf(ref byte searchSpace, byte value, int length) offset += 8; } - if ((byte*)lengthToExamine >= (byte*)4) + if (lengthToExamine >= 4) { lengthToExamine -= 4; @@ -259,7 +259,7 @@ public static unsafe int IndexOf(ref byte searchSpace, byte value, int length) offset += 4; } - while ((byte*)lengthToExamine > (byte*)0) + while (lengthToExamine > 0) { lengthToExamine -= 1; @@ -274,9 +274,9 @@ public static unsafe int IndexOf(ref byte searchSpace, byte value, int length) // have hardware accelerated. After processing Vector lengths we return to SequentialScan to finish any remaining. if (Avx2.IsSupported) { - if ((int)(byte*)offset < length) + if (offset < (nuint)(uint)length) { - if ((((nuint)Unsafe.AsPointer(ref searchSpace) + (nuint)offset) & (nuint)(Vector256.Count - 1)) != 0) + if ((((nuint)(uint)Unsafe.AsPointer(ref searchSpace) + offset) & (nuint)(Vector256.Count - 1)) != 0) { // Not currently aligned to Vector256 (is aligned to Vector128); this can cause a problem for searches // with no upper bound e.g. String.strlen. @@ -290,17 +290,17 @@ public static unsafe int IndexOf(ref byte searchSpace, byte value, int length) if (matches == 0) { // Zero flags set so no matches - offset += Vector128.Count; + offset += (nuint)Vector128.Count; } else { // Find bitflag offset of first match and add to current offset - return ((int)(byte*)offset) + BitOperations.TrailingZeroCount(matches); + return (int)(offset + (uint)BitOperations.TrailingZeroCount(matches)); } } lengthToExamine = GetByteVector256SpanLength(offset, length); - if ((byte*)lengthToExamine > (byte*)offset) + if (lengthToExamine > offset) { Vector256 values = Vector256.Create(value); do @@ -312,17 +312,17 @@ public static unsafe int IndexOf(ref byte searchSpace, byte value, int length) if (matches == 0) { // Zero flags set so no matches - offset += Vector256.Count; + offset += (nuint)Vector256.Count; continue; } // Find bitflag offset of first match and add to current offset - return ((int)(byte*)offset) + BitOperations.TrailingZeroCount(matches); - } while ((byte*)lengthToExamine > (byte*)offset); + return (int)(offset + (uint)BitOperations.TrailingZeroCount(matches)); + } while (lengthToExamine > offset); } lengthToExamine = GetByteVector128SpanLength(offset, length); - if ((byte*)lengthToExamine > (byte*)offset) + if (lengthToExamine > offset) { Vector128 values = Vector128.Create(value); Vector128 search = LoadVector128(ref searchSpace, offset); @@ -332,30 +332,30 @@ public static unsafe int IndexOf(ref byte searchSpace, byte value, int length) if (matches == 0) { // Zero flags set so no matches - offset += Vector128.Count; + offset += (nuint)Vector128.Count; } else { // Find bitflag offset of first match and add to current offset - return ((int)(byte*)offset) + BitOperations.TrailingZeroCount(matches); + return (int)(offset + (uint)BitOperations.TrailingZeroCount(matches)); } } - if ((int)(byte*)offset < length) + if (offset < (nuint)(uint)length) { - lengthToExamine = (IntPtr)(length - (int)(byte*)offset); + lengthToExamine = ((nuint)(uint)length - offset); goto SequentialScan; } } } else if (Sse2.IsSupported) { - if ((int)(byte*)offset < length) + if (offset < (nuint)(uint)length) { lengthToExamine = GetByteVector128SpanLength(offset, length); Vector128 values = Vector128.Create(value); - while ((byte*)lengthToExamine > (byte*)offset) + while (lengthToExamine > offset) { Vector128 search = LoadVector128(ref searchSpace, offset); @@ -364,66 +364,66 @@ public static unsafe int IndexOf(ref byte searchSpace, byte value, int length) if (matches == 0) { // Zero flags set so no matches - offset += Vector128.Count; + offset += (nuint)Vector128.Count; continue; } // Find bitflag offset of first match and add to current offset - return ((int)(byte*)offset) + BitOperations.TrailingZeroCount(matches); + return (int)(offset + (uint)BitOperations.TrailingZeroCount(matches)); } - if ((int)(byte*)offset < length) + if (offset < (nuint)(uint)length) { - lengthToExamine = (IntPtr)(length - (int)(byte*)offset); + lengthToExamine = ((nuint)(uint)length - offset); goto SequentialScan; } } } else if (Vector.IsHardwareAccelerated) { - if ((int)(byte*)offset < length) + if (offset < (nuint)(uint)length) { lengthToExamine = GetByteVectorSpanLength(offset, length); Vector values = new Vector(value); - while ((byte*)lengthToExamine > (byte*)offset) + while (lengthToExamine > offset) { var matches = Vector.Equals(values, LoadVector(ref searchSpace, offset)); if (Vector.Zero.Equals(matches)) { - offset += Vector.Count; + offset += (nuint)Vector.Count; continue; } // Find offset of first match and add to current offset - return (int)(byte*)offset + LocateFirstFoundByte(matches); + return (int)offset + LocateFirstFoundByte(matches); } - if ((int)(byte*)offset < length) + if (offset < (nuint)(uint)length) { - lengthToExamine = (IntPtr)(length - (int)(byte*)offset); + lengthToExamine = ((nuint)(uint)length - offset); goto SequentialScan; } } } return -1; Found: // Workaround for https://github.com/dotnet/runtime/issues/8795 - return (int)(byte*)offset; + return (int)offset; Found1: - return (int)(byte*)(offset + 1); + return (int)(offset + 1); Found2: - return (int)(byte*)(offset + 2); + return (int)(offset + 2); Found3: - return (int)(byte*)(offset + 3); + return (int)(offset + 3); Found4: - return (int)(byte*)(offset + 4); + return (int)(offset + 4); Found5: - return (int)(byte*)(offset + 5); + return (int)(offset + 5); Found6: - return (int)(byte*)(offset + 6); + return (int)(offset + 6); Found7: - return (int)(byte*)(offset + 7); + return (int)(offset + 7); } public static int LastIndexOf(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength) @@ -452,7 +452,7 @@ public static int LastIndexOf(ref byte searchSpace, int searchSpaceLength, ref b break; // Found the first element of "value". See if the tail matches. - if (SequenceEqual(ref Unsafe.Add(ref searchSpace, relativeIndex + 1), ref valueTail, (nuint)valueTailLength)) // The (nunit)-cast is necessary to pick the correct overload + if (SequenceEqual(ref Unsafe.Add(ref searchSpace, relativeIndex + 1), ref valueTail, (nuint)(uint)valueTailLength)) // The (nunit)-cast is necessary to pick the correct overload return relativeIndex; // The tail matched. Return a successful find. offset += remainingSearchSpaceLength - relativeIndex; @@ -461,20 +461,20 @@ public static int LastIndexOf(ref byte searchSpace, int searchSpaceLength, ref b } [MethodImpl(MethodImplOptions.AggressiveOptimization)] - public static unsafe int LastIndexOf(ref byte searchSpace, byte value, int length) + public static int LastIndexOf(ref byte searchSpace, byte value, int length) { Debug.Assert(length >= 0); uint uValue = value; // Use uint for comparisons to avoid unnecessary 8->32 extensions - IntPtr offset = (IntPtr)length; // Use IntPtr for arithmetic to avoid unnecessary 64->32->64 truncations - IntPtr lengthToExamine = (IntPtr)length; + nuint offset = (nuint)(uint)length; // Use nuint for arithmetic to avoid unnecessary 64->32->64 truncations + nuint lengthToExamine = (nuint)(uint)length; if (Vector.IsHardwareAccelerated && length >= Vector.Count * 2) { lengthToExamine = UnalignedCountVectorFromEnd(ref searchSpace, length); } SequentialScan: - while ((byte*)lengthToExamine >= (byte*)8) + while (lengthToExamine >= 8) { lengthToExamine -= 8; offset -= 8; @@ -497,7 +497,7 @@ public static unsafe int LastIndexOf(ref byte searchSpace, byte value, int lengt goto Found; } - if ((byte*)lengthToExamine >= (byte*)4) + if (lengthToExamine >= 4) { lengthToExamine -= 4; offset -= 4; @@ -512,7 +512,7 @@ public static unsafe int LastIndexOf(ref byte searchSpace, byte value, int lengt goto Found; } - while ((byte*)lengthToExamine > (byte*)0) + while (lengthToExamine > 0) { lengthToExamine -= 1; offset -= 1; @@ -521,26 +521,26 @@ public static unsafe int LastIndexOf(ref byte searchSpace, byte value, int lengt goto Found; } - if (Vector.IsHardwareAccelerated && ((byte*)offset > (byte*)0)) + if (Vector.IsHardwareAccelerated && (offset > 0)) { - lengthToExamine = (IntPtr)((int)(byte*)offset & ~(Vector.Count - 1)); + lengthToExamine = (offset & (nuint)~(Vector.Count - 1)); Vector values = new Vector(value); - while ((byte*)lengthToExamine > (byte*)(Vector.Count - 1)) + while (lengthToExamine > (nuint)(Vector.Count - 1)) { - var matches = Vector.Equals(values, LoadVector(ref searchSpace, offset - Vector.Count)); + var matches = Vector.Equals(values, LoadVector(ref searchSpace, offset - (nuint)Vector.Count)); if (Vector.Zero.Equals(matches)) { - offset -= Vector.Count; - lengthToExamine -= Vector.Count; + offset -= (nuint)Vector.Count; + lengthToExamine -= (nuint)Vector.Count; continue; } // Find offset of first match and add to current offset return (int)(offset) - Vector.Count + LocateLastFoundByte(matches); } - if ((byte*)offset > (byte*)0) + if (offset > 0) { lengthToExamine = offset; goto SequentialScan; @@ -548,32 +548,32 @@ public static unsafe int LastIndexOf(ref byte searchSpace, byte value, int lengt } return -1; Found: // Workaround for https://github.com/dotnet/runtime/issues/8795 - return (int)(byte*)offset; + return (int)offset; Found1: - return (int)(byte*)(offset + 1); + return (int)(offset + 1); Found2: - return (int)(byte*)(offset + 2); + return (int)(offset + 2); Found3: - return (int)(byte*)(offset + 3); + return (int)(offset + 3); Found4: - return (int)(byte*)(offset + 4); + return (int)(offset + 4); Found5: - return (int)(byte*)(offset + 5); + return (int)(offset + 5); Found6: - return (int)(byte*)(offset + 6); + return (int)(offset + 6); Found7: - return (int)(byte*)(offset + 7); + return (int)(offset + 7); } [MethodImpl(MethodImplOptions.AggressiveOptimization)] - public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte value1, int length) + public static int IndexOfAny(ref byte searchSpace, byte value0, byte value1, int length) { Debug.Assert(length >= 0); uint uValue0 = value0; // Use uint for comparisons to avoid unnecessary 8->32 extensions uint uValue1 = value1; // Use uint for comparisons to avoid unnecessary 8->32 extensions - IntPtr offset = (IntPtr)0; // Use IntPtr for arithmetic to avoid unnecessary 64->32->64 truncations - IntPtr lengthToExamine = (IntPtr)length; + nuint offset = 0; // Use nuint for arithmetic to avoid unnecessary 64->32->64 truncations + nuint lengthToExamine = (nuint)(uint)length; if (Avx2.IsSupported || Sse2.IsSupported) { @@ -592,7 +592,7 @@ public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte valu } SequentialScan: uint lookUp; - while ((byte*)lengthToExamine >= (byte*)8) + while (lengthToExamine >= 8) { lengthToExamine -= 8; @@ -624,7 +624,7 @@ public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte valu offset += 8; } - if ((byte*)lengthToExamine >= (byte*)4) + if (lengthToExamine >= 4) { lengthToExamine -= 4; @@ -644,7 +644,7 @@ public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte valu offset += 4; } - while ((byte*)lengthToExamine > (byte*)0) + while (lengthToExamine > 0) { lengthToExamine -= 1; @@ -659,10 +659,10 @@ public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte valu // the JIT to see that the code is unreachable and eliminate it when the platform does not have hardware accelerated. if (Avx2.IsSupported) { - if ((int)(byte*)offset < length) + if (offset < (nuint)(uint)length) { lengthToExamine = GetByteVector256SpanLength(offset, length); - if ((byte*)lengthToExamine > (byte*)offset) + if (lengthToExamine > offset) { Vector256 values0 = Vector256.Create(value0); Vector256 values1 = Vector256.Create(value1); @@ -679,17 +679,17 @@ public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte valu if (matches == 0) { // Zero flags set so no matches - offset += Vector256.Count; + offset += (nuint)Vector256.Count; continue; } // Find bitflag offset of first match and add to current offset - return ((int)(byte*)offset) + BitOperations.TrailingZeroCount(matches); - } while ((byte*)lengthToExamine > (byte*)offset); + return (int)(offset + (uint)BitOperations.TrailingZeroCount(matches)); + } while (lengthToExamine > offset); } lengthToExamine = GetByteVector128SpanLength(offset, length); - if ((byte*)lengthToExamine > (byte*)offset) + if (lengthToExamine > offset) { Vector128 values0 = Vector128.Create(value0); Vector128 values1 = Vector128.Create(value1); @@ -703,32 +703,32 @@ public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte valu if (matches == 0) { // Zero flags set so no matches - offset += Vector128.Count; + offset += (nuint)Vector128.Count; } else { // Find bitflag offset of first match and add to current offset - return ((int)(byte*)offset) + BitOperations.TrailingZeroCount(matches); + return (int)(offset + (uint)BitOperations.TrailingZeroCount(matches)); } } - if ((int)(byte*)offset < length) + if (offset < (nuint)(uint)length) { - lengthToExamine = (IntPtr)(length - (int)(byte*)offset); + lengthToExamine = ((nuint)(uint)length - offset); goto SequentialScan; } } } else if (Sse2.IsSupported) { - if ((int)(byte*)offset < length) + if (offset < (nuint)(uint)length) { lengthToExamine = GetByteVector128SpanLength(offset, length); Vector128 values0 = Vector128.Create(value0); Vector128 values1 = Vector128.Create(value1); - while ((byte*)lengthToExamine > (byte*)offset) + while (lengthToExamine > offset) { Vector128 search = LoadVector128(ref searchSpace, offset); // Same method as above @@ -739,31 +739,31 @@ public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte valu if (matches == 0) { // Zero flags set so no matches - offset += Vector128.Count; + offset += (nuint)Vector128.Count; continue; } // Find bitflag offset of first match and add to current offset - return ((int)(byte*)offset) + BitOperations.TrailingZeroCount(matches); + return (int)(offset + (uint)BitOperations.TrailingZeroCount(matches)); } - if ((int)(byte*)offset < length) + if (offset < (nuint)(uint)length) { - lengthToExamine = (IntPtr)(length - (int)(byte*)offset); + lengthToExamine = ((nuint)(uint)length - offset); goto SequentialScan; } } } else if (Vector.IsHardwareAccelerated) { - if ((int)(byte*)offset < length) + if (offset < (nuint)(uint)length) { lengthToExamine = GetByteVectorSpanLength(offset, length); Vector values0 = new Vector(value0); Vector values1 = new Vector(value1); - while ((byte*)lengthToExamine > (byte*)offset) + while (lengthToExamine > offset) { Vector search = LoadVector(ref searchSpace, offset); var matches = Vector.BitwiseOr( @@ -771,50 +771,50 @@ public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte valu Vector.Equals(search, values1)); if (Vector.Zero.Equals(matches)) { - offset += Vector.Count; + offset += (nuint)Vector.Count; continue; } // Find offset of first match and add to current offset - return (int)(byte*)offset + LocateFirstFoundByte(matches); + return (int)offset + LocateFirstFoundByte(matches); } - if ((int)(byte*)offset < length) + if (offset < (nuint)(uint)length) { - lengthToExamine = (IntPtr)(length - (int)(byte*)offset); + lengthToExamine = ((nuint)(uint)length - offset); goto SequentialScan; } } } return -1; Found: // Workaround for https://github.com/dotnet/runtime/issues/8795 - return (int)(byte*)offset; + return (int)offset; Found1: - return (int)(byte*)(offset + 1); + return (int)(offset + 1); Found2: - return (int)(byte*)(offset + 2); + return (int)(offset + 2); Found3: - return (int)(byte*)(offset + 3); + return (int)(offset + 3); Found4: - return (int)(byte*)(offset + 4); + return (int)(offset + 4); Found5: - return (int)(byte*)(offset + 5); + return (int)(offset + 5); Found6: - return (int)(byte*)(offset + 6); + return (int)(offset + 6); Found7: - return (int)(byte*)(offset + 7); + return (int)(offset + 7); } [MethodImpl(MethodImplOptions.AggressiveOptimization)] - public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte value1, byte value2, int length) + public static int IndexOfAny(ref byte searchSpace, byte value0, byte value1, byte value2, int length) { Debug.Assert(length >= 0); uint uValue0 = value0; // Use uint for comparisons to avoid unnecessary 8->32 extensions uint uValue1 = value1; uint uValue2 = value2; - IntPtr offset = (IntPtr)0; // Use IntPtr for arithmetic to avoid unnecessary 64->32->64 truncations - IntPtr lengthToExamine = (IntPtr)length; + nuint offset = 0; // Use nuint for arithmetic to avoid unnecessary 64->32->64 truncations + nuint lengthToExamine = (nuint)(uint)length; if (Avx2.IsSupported || Sse2.IsSupported) { @@ -833,7 +833,7 @@ public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte valu } SequentialScan: uint lookUp; - while ((byte*)lengthToExamine >= (byte*)8) + while (lengthToExamine >= 8) { lengthToExamine -= 8; @@ -865,7 +865,7 @@ public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte valu offset += 8; } - if ((byte*)lengthToExamine >= (byte*)4) + if (lengthToExamine >= 4) { lengthToExamine -= 4; @@ -885,7 +885,7 @@ public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte valu offset += 4; } - while ((byte*)lengthToExamine > (byte*)0) + while (lengthToExamine > 0) { lengthToExamine -= 1; @@ -898,10 +898,10 @@ public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte valu if (Avx2.IsSupported) { - if ((int)(byte*)offset < length) + if (offset < (nuint)(uint)length) { lengthToExamine = GetByteVector256SpanLength(offset, length); - if ((byte*)lengthToExamine > (byte*)offset) + if (lengthToExamine > offset) { Vector256 values0 = Vector256.Create(value0); Vector256 values1 = Vector256.Create(value1); @@ -920,17 +920,17 @@ public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte valu if (matches == 0) { // Zero flags set so no matches - offset += Vector256.Count; + offset += (nuint)Vector256.Count; continue; } // Find bitflag offset of first match and add to current offset - return ((int)(byte*)offset) + BitOperations.TrailingZeroCount(matches); - } while ((byte*)lengthToExamine > (byte*)offset); + return (int)(offset + (uint)BitOperations.TrailingZeroCount(matches)); + } while (lengthToExamine > offset); } lengthToExamine = GetByteVector128SpanLength(offset, length); - if ((byte*)lengthToExamine > (byte*)offset) + if (lengthToExamine > offset) { Vector128 values0 = Vector128.Create(value0); Vector128 values1 = Vector128.Create(value1); @@ -946,25 +946,25 @@ public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte valu if (matches == 0) { // Zero flags set so no matches - offset += Vector128.Count; + offset += (nuint)Vector128.Count; } else { // Find bitflag offset of first match and add to current offset - return ((int)(byte*)offset) + BitOperations.TrailingZeroCount(matches); + return (int)(offset + (uint)BitOperations.TrailingZeroCount(matches)); } } - if ((int)(byte*)offset < length) + if (offset < (nuint)(uint)length) { - lengthToExamine = (IntPtr)(length - (int)(byte*)offset); + lengthToExamine = ((nuint)(uint)length - offset); goto SequentialScan; } } } else if (Sse2.IsSupported) { - if ((int)(byte*)offset < length) + if (offset < (nuint)(uint)length) { lengthToExamine = GetByteVector128SpanLength(offset, length); @@ -972,7 +972,7 @@ public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte valu Vector128 values1 = Vector128.Create(value1); Vector128 values2 = Vector128.Create(value2); - while ((byte*)lengthToExamine > (byte*)offset) + while (lengthToExamine > offset) { Vector128 search = LoadVector128(ref searchSpace, offset); @@ -984,24 +984,24 @@ public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte valu if (matches == 0) { // Zero flags set so no matches - offset += Vector128.Count; + offset += (nuint)Vector128.Count; continue; } // Find bitflag offset of first match and add to current offset - return ((int)(byte*)offset) + BitOperations.TrailingZeroCount(matches); + return (int)(offset + (uint)BitOperations.TrailingZeroCount(matches)); } - if ((int)(byte*)offset < length) + if (offset < (nuint)(uint)length) { - lengthToExamine = (IntPtr)(length - (int)(byte*)offset); + lengthToExamine = ((nuint)(uint)length - offset); goto SequentialScan; } } } else if (Vector.IsHardwareAccelerated) { - if ((int)(byte*)offset < length) + if (offset < (nuint)(uint)length) { lengthToExamine = GetByteVectorSpanLength(offset, length); @@ -1009,7 +1009,7 @@ public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte valu Vector values1 = new Vector(value1); Vector values2 = new Vector(value2); - while ((byte*)lengthToExamine > (byte*)offset) + while (lengthToExamine > offset) { Vector search = LoadVector(ref searchSpace, offset); @@ -1021,48 +1021,48 @@ public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte valu if (Vector.Zero.Equals(matches)) { - offset += Vector.Count; + offset += (nuint)Vector.Count; continue; } // Find offset of first match and add to current offset - return (int)(byte*)offset + LocateFirstFoundByte(matches); + return (int)offset + LocateFirstFoundByte(matches); } - if ((int)(byte*)offset < length) + if (offset < (nuint)(uint)length) { - lengthToExamine = (IntPtr)(length - (int)(byte*)offset); + lengthToExamine = ((nuint)(uint)length - offset); goto SequentialScan; } } } return -1; Found: // Workaround for https://github.com/dotnet/runtime/issues/8795 - return (int)(byte*)offset; + return (int)offset; Found1: - return (int)(byte*)(offset + 1); + return (int)(offset + 1); Found2: - return (int)(byte*)(offset + 2); + return (int)(offset + 2); Found3: - return (int)(byte*)(offset + 3); + return (int)(offset + 3); Found4: - return (int)(byte*)(offset + 4); + return (int)(offset + 4); Found5: - return (int)(byte*)(offset + 5); + return (int)(offset + 5); Found6: - return (int)(byte*)(offset + 6); + return (int)(offset + 6); Found7: - return (int)(byte*)(offset + 7); + return (int)(offset + 7); } - public static unsafe int LastIndexOfAny(ref byte searchSpace, byte value0, byte value1, int length) + public static int LastIndexOfAny(ref byte searchSpace, byte value0, byte value1, int length) { Debug.Assert(length >= 0); uint uValue0 = value0; // Use uint for comparisons to avoid unnecessary 8->32 extensions uint uValue1 = value1; - IntPtr offset = (IntPtr)length; // Use IntPtr for arithmetic to avoid unnecessary 64->32->64 truncations - IntPtr lengthToExamine = (IntPtr)length; + nuint offset = (nuint)(uint)length; // Use nuint for arithmetic to avoid unnecessary 64->32->64 truncations + nuint lengthToExamine = (nuint)(uint)length; if (Vector.IsHardwareAccelerated && length >= Vector.Count * 2) { @@ -1070,7 +1070,7 @@ public static unsafe int LastIndexOfAny(ref byte searchSpace, byte value0, byte } SequentialScan: uint lookUp; - while ((byte*)lengthToExamine >= (byte*)8) + while (lengthToExamine >= 8) { lengthToExamine -= 8; offset -= 8; @@ -1101,7 +1101,7 @@ public static unsafe int LastIndexOfAny(ref byte searchSpace, byte value0, byte goto Found; } - if ((byte*)lengthToExamine >= (byte*)4) + if (lengthToExamine >= 4) { lengthToExamine -= 4; offset -= 4; @@ -1120,7 +1120,7 @@ public static unsafe int LastIndexOfAny(ref byte searchSpace, byte value0, byte goto Found; } - while ((byte*)lengthToExamine > (byte*)0) + while (lengthToExamine > 0) { lengthToExamine -= 1; offset -= 1; @@ -1130,23 +1130,23 @@ public static unsafe int LastIndexOfAny(ref byte searchSpace, byte value0, byte goto Found; } - if (Vector.IsHardwareAccelerated && ((byte*)offset > (byte*)0)) + if (Vector.IsHardwareAccelerated && (offset > 0)) { - lengthToExamine = (IntPtr)((int)(byte*)offset & ~(Vector.Count - 1)); + lengthToExamine = (offset & (nuint)~(Vector.Count - 1)); Vector values0 = new Vector(value0); Vector values1 = new Vector(value1); - while ((byte*)lengthToExamine > (byte*)(Vector.Count - 1)) + while (lengthToExamine > (nuint)(Vector.Count - 1)) { - Vector search = LoadVector(ref searchSpace, offset - Vector.Count); + Vector search = LoadVector(ref searchSpace, offset - (nuint)Vector.Count); var matches = Vector.BitwiseOr( Vector.Equals(search, values0), Vector.Equals(search, values1)); if (Vector.Zero.Equals(matches)) { - offset -= Vector.Count; - lengthToExamine -= Vector.Count; + offset -= (nuint)Vector.Count; + lengthToExamine -= (nuint)Vector.Count; continue; } @@ -1154,7 +1154,7 @@ public static unsafe int LastIndexOfAny(ref byte searchSpace, byte value0, byte return (int)(offset) - Vector.Count + LocateLastFoundByte(matches); } - if ((byte*)offset > (byte*)0) + if (offset > 0) { lengthToExamine = offset; goto SequentialScan; @@ -1162,32 +1162,32 @@ public static unsafe int LastIndexOfAny(ref byte searchSpace, byte value0, byte } return -1; Found: // Workaround for https://github.com/dotnet/runtime/issues/8795 - return (int)(byte*)offset; + return (int)offset; Found1: - return (int)(byte*)(offset + 1); + return (int)(offset + 1); Found2: - return (int)(byte*)(offset + 2); + return (int)(offset + 2); Found3: - return (int)(byte*)(offset + 3); + return (int)(offset + 3); Found4: - return (int)(byte*)(offset + 4); + return (int)(offset + 4); Found5: - return (int)(byte*)(offset + 5); + return (int)(offset + 5); Found6: - return (int)(byte*)(offset + 6); + return (int)(offset + 6); Found7: - return (int)(byte*)(offset + 7); + return (int)(offset + 7); } - public static unsafe int LastIndexOfAny(ref byte searchSpace, byte value0, byte value1, byte value2, int length) + public static int LastIndexOfAny(ref byte searchSpace, byte value0, byte value1, byte value2, int length) { Debug.Assert(length >= 0); uint uValue0 = value0; // Use uint for comparisons to avoid unnecessary 8->32 extensions uint uValue1 = value1; uint uValue2 = value2; - IntPtr offset = (IntPtr)length; // Use IntPtr for arithmetic to avoid unnecessary 64->32->64 truncations - IntPtr lengthToExamine = (IntPtr)length; + nuint offset = (nuint)(uint)length; // Use nuint for arithmetic to avoid unnecessary 64->32->64 truncations + nuint lengthToExamine = (nuint)(uint)length; if (Vector.IsHardwareAccelerated && length >= Vector.Count * 2) { @@ -1195,7 +1195,7 @@ public static unsafe int LastIndexOfAny(ref byte searchSpace, byte value0, byte } SequentialScan: uint lookUp; - while ((byte*)lengthToExamine >= (byte*)8) + while (lengthToExamine >= 8) { lengthToExamine -= 8; offset -= 8; @@ -1226,7 +1226,7 @@ public static unsafe int LastIndexOfAny(ref byte searchSpace, byte value0, byte goto Found; } - if ((byte*)lengthToExamine >= (byte*)4) + if (lengthToExamine >= 4) { lengthToExamine -= 4; offset -= 4; @@ -1245,7 +1245,7 @@ public static unsafe int LastIndexOfAny(ref byte searchSpace, byte value0, byte goto Found; } - while ((byte*)lengthToExamine > (byte*)0) + while (lengthToExamine > 0) { lengthToExamine -= 1; offset -= 1; @@ -1255,17 +1255,17 @@ public static unsafe int LastIndexOfAny(ref byte searchSpace, byte value0, byte goto Found; } - if (Vector.IsHardwareAccelerated && ((byte*)offset > (byte*)0)) + if (Vector.IsHardwareAccelerated && (offset > 0)) { - lengthToExamine = (IntPtr)((int)(byte*)offset & ~(Vector.Count - 1)); + lengthToExamine = (offset & (nuint)~(Vector.Count - 1)); Vector values0 = new Vector(value0); Vector values1 = new Vector(value1); Vector values2 = new Vector(value2); - while ((byte*)lengthToExamine > (byte*)(Vector.Count - 1)) + while (lengthToExamine > (nuint)(Vector.Count - 1)) { - Vector search = LoadVector(ref searchSpace, offset - Vector.Count); + Vector search = LoadVector(ref searchSpace, offset - (nuint)Vector.Count); var matches = Vector.BitwiseOr( Vector.BitwiseOr( @@ -1275,8 +1275,8 @@ public static unsafe int LastIndexOfAny(ref byte searchSpace, byte value0, byte if (Vector.Zero.Equals(matches)) { - offset -= Vector.Count; - lengthToExamine -= Vector.Count; + offset -= (nuint)Vector.Count; + lengthToExamine -= (nuint)Vector.Count; continue; } @@ -1284,7 +1284,7 @@ public static unsafe int LastIndexOfAny(ref byte searchSpace, byte value0, byte return (int)(offset) - Vector.Count + LocateLastFoundByte(matches); } - if ((byte*)offset > (byte*)0) + if (offset > 0) { lengthToExamine = offset; goto SequentialScan; @@ -1292,21 +1292,21 @@ public static unsafe int LastIndexOfAny(ref byte searchSpace, byte value0, byte } return -1; Found: // Workaround for https://github.com/dotnet/runtime/issues/8795 - return (int)(byte*)offset; + return (int)offset; Found1: - return (int)(byte*)(offset + 1); + return (int)(offset + 1); Found2: - return (int)(byte*)(offset + 2); + return (int)(offset + 2); Found3: - return (int)(byte*)(offset + 3); + return (int)(offset + 3); Found4: - return (int)(byte*)(offset + 4); + return (int)(offset + 4); Found5: - return (int)(byte*)(offset + 5); + return (int)(offset + 5); Found6: - return (int)(byte*)(offset + 6); + return (int)(offset + 6); Found7: - return (int)(byte*)(offset + 7); + return (int)(offset + 7); } // Optimized byte-based SequenceEquals. The "length" parameter for this one is declared a nuint rather than int as we also use it for types other than byte @@ -1540,7 +1540,7 @@ private static int LocateFirstFoundByte(Vector match) } [MethodImpl(MethodImplOptions.AggressiveOptimization)] - public static unsafe int SequenceCompareTo(ref byte first, int firstLength, ref byte second, int secondLength) + public static int SequenceCompareTo(ref byte first, int firstLength, ref byte second, int secondLength) { Debug.Assert(firstLength >= 0); Debug.Assert(secondLength >= 0); @@ -1548,18 +1548,18 @@ public static unsafe int SequenceCompareTo(ref byte first, int firstLength, ref if (Unsafe.AreSame(ref first, ref second)) goto Equal; - IntPtr minLength = (IntPtr)((firstLength < secondLength) ? firstLength : secondLength); + nuint minLength = (nuint)(((uint)firstLength < (uint)secondLength) ? (uint)firstLength : (uint)secondLength); - IntPtr offset = (IntPtr)0; // Use IntPtr for arithmetic to avoid unnecessary 64->32->64 truncations - IntPtr lengthToExamine = (IntPtr)(void*)minLength; + nuint offset = 0; // Use nuint for arithmetic to avoid unnecessary 64->32->64 truncations + nuint lengthToExamine = minLength; if (Avx2.IsSupported) { - if ((byte*)lengthToExamine >= (byte*)Vector256.Count) + if (lengthToExamine >= (nuint)Vector256.Count) { - lengthToExamine -= Vector256.Count; + lengthToExamine -= (nuint)Vector256.Count; uint matches; - while ((byte*)lengthToExamine > (byte*)offset) + while (lengthToExamine > offset) { matches = (uint)Avx2.MoveMask(Avx2.CompareEqual(LoadVector256(ref first, offset), LoadVector256(ref second, offset))); // Note that MoveMask has converted the equal vector elements into a set of bit flags, @@ -1569,7 +1569,7 @@ public static unsafe int SequenceCompareTo(ref byte first, int firstLength, ref if (matches == uint.MaxValue) { // All matched - offset += Vector256.Count; + offset += (nuint)Vector256.Count; continue; } @@ -1588,7 +1588,7 @@ public static unsafe int SequenceCompareTo(ref byte first, int firstLength, ref // Invert matches to find differences uint differences = ~matches; // Find bitflag offset of first difference and add to current offset - offset = (IntPtr)((int)(byte*)offset + BitOperations.TrailingZeroCount((int)differences)); + offset += (uint)BitOperations.TrailingZeroCount(differences); int result = Unsafe.AddByteOffset(ref first, offset).CompareTo(Unsafe.AddByteOffset(ref second, offset)); Debug.Assert(result != 0); @@ -1596,11 +1596,11 @@ public static unsafe int SequenceCompareTo(ref byte first, int firstLength, ref return result; } - if ((byte*)lengthToExamine >= (byte*)Vector128.Count) + if (lengthToExamine >= (nuint)Vector128.Count) { - lengthToExamine -= Vector128.Count; + lengthToExamine -= (nuint)Vector128.Count; uint matches; - if ((byte*)lengthToExamine > (byte*)offset) + if (lengthToExamine > offset) { matches = (uint)Sse2.MoveMask(Sse2.CompareEqual(LoadVector128(ref first, offset), LoadVector128(ref second, offset))); // Note that MoveMask has converted the equal vector elements into a set of bit flags, @@ -1625,7 +1625,7 @@ public static unsafe int SequenceCompareTo(ref byte first, int firstLength, ref // Invert matches to find differences uint differences = ~matches; // Find bitflag offset of first difference and add to current offset - offset = (IntPtr)((int)(byte*)offset + BitOperations.TrailingZeroCount((int)differences)); + offset += (uint)BitOperations.TrailingZeroCount(differences); int result = Unsafe.AddByteOffset(ref first, offset).CompareTo(Unsafe.AddByteOffset(ref second, offset)); Debug.Assert(result != 0); @@ -1635,11 +1635,11 @@ public static unsafe int SequenceCompareTo(ref byte first, int firstLength, ref } else if (Sse2.IsSupported) { - if ((byte*)lengthToExamine >= (byte*)Vector128.Count) + if (lengthToExamine >= (nuint)Vector128.Count) { - lengthToExamine -= Vector128.Count; + lengthToExamine -= (nuint)Vector128.Count; uint matches; - while ((byte*)lengthToExamine > (byte*)offset) + while (lengthToExamine > offset) { matches = (uint)Sse2.MoveMask(Sse2.CompareEqual(LoadVector128(ref first, offset), LoadVector128(ref second, offset))); // Note that MoveMask has converted the equal vector elements into a set of bit flags, @@ -1649,7 +1649,7 @@ public static unsafe int SequenceCompareTo(ref byte first, int firstLength, ref if (matches == ushort.MaxValue) { // All matched - offset += Vector128.Count; + offset += (nuint)Vector128.Count; continue; } @@ -1668,7 +1668,7 @@ public static unsafe int SequenceCompareTo(ref byte first, int firstLength, ref // Invert matches to find differences uint differences = ~matches; // Find bitflag offset of first difference and add to current offset - offset = (IntPtr)((int)(byte*)offset + BitOperations.TrailingZeroCount((int)differences)); + offset += (uint)BitOperations.TrailingZeroCount(differences); int result = Unsafe.AddByteOffset(ref first, offset).CompareTo(Unsafe.AddByteOffset(ref second, offset)); Debug.Assert(result != 0); @@ -1678,36 +1678,36 @@ public static unsafe int SequenceCompareTo(ref byte first, int firstLength, ref } else if (Vector.IsHardwareAccelerated) { - if ((byte*)lengthToExamine > (byte*)Vector.Count) + if (lengthToExamine > (nuint)Vector.Count) { - lengthToExamine -= Vector.Count; - while ((byte*)lengthToExamine > (byte*)offset) + lengthToExamine -= (nuint)Vector.Count; + while (lengthToExamine > offset) { if (LoadVector(ref first, offset) != LoadVector(ref second, offset)) { goto BytewiseCheck; } - offset += Vector.Count; + offset += (nuint)Vector.Count; } goto BytewiseCheck; } } - if ((byte*)lengthToExamine > (byte*)sizeof(UIntPtr)) + if (lengthToExamine > sizeof(nuint)) { - lengthToExamine -= sizeof(UIntPtr); - while ((byte*)lengthToExamine > (byte*)offset) + lengthToExamine -= sizeof(nuint); + while (lengthToExamine > offset) { - if (LoadUIntPtr(ref first, offset) != LoadUIntPtr(ref second, offset)) + if (LoadNUInt(ref first, offset) != LoadNUInt(ref second, offset)) { goto BytewiseCheck; } - offset += sizeof(UIntPtr); + offset += sizeof(nuint); } } BytewiseCheck: // Workaround for https://github.com/dotnet/runtime/issues/8795 - while ((byte*)minLength > (byte*)offset) + while (minLength > offset) { int result = Unsafe.AddByteOffset(ref first, offset).CompareTo(Unsafe.AddByteOffset(ref second, offset)); if (result != 0) @@ -1774,10 +1774,6 @@ private static int LocateLastFoundByte(ulong match) private static ushort LoadUShort(ref byte start) => Unsafe.ReadUnaligned(ref start); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ushort LoadUShort(ref byte start, nuint offset) - => Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref start, offset)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] private static uint LoadUInt(ref byte start) => Unsafe.ReadUnaligned(ref start); @@ -1794,65 +1790,49 @@ private static nuint LoadNUInt(ref byte start) private static nuint LoadNUInt(ref byte start, nuint offset) => Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref start, offset)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static UIntPtr LoadUIntPtr(ref byte start, IntPtr offset) - => Unsafe.ReadUnaligned(ref Unsafe.AddByteOffset(ref start, offset)); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Vector LoadVector(ref byte start, IntPtr offset) - => Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref start, offset)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector LoadVector(ref byte start, nuint offset) => Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref start, offset)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Vector128 LoadVector128(ref byte start, IntPtr offset) - => Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref start, offset)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector128 LoadVector128(ref byte start, nuint offset) => Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref start, offset)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Vector256 LoadVector256(ref byte start, IntPtr offset) - => Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref start, offset)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector256 LoadVector256(ref byte start, nuint offset) => Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref start, offset)); [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe IntPtr GetByteVectorSpanLength(IntPtr offset, int length) - => (IntPtr)((length - (int)(byte*)offset) & ~(Vector.Count - 1)); + private static nuint GetByteVectorSpanLength(nuint offset, int length) + => (nuint)(uint)((length - (int)offset) & ~(Vector.Count - 1)); [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe IntPtr GetByteVector128SpanLength(IntPtr offset, int length) - => (IntPtr)((length - (int)(byte*)offset) & ~(Vector128.Count - 1)); + private static nuint GetByteVector128SpanLength(nuint offset, int length) + => (nuint)(uint)((length - (int)offset) & ~(Vector128.Count - 1)); [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe IntPtr GetByteVector256SpanLength(IntPtr offset, int length) - => (IntPtr)((length - (int)(byte*)offset) & ~(Vector256.Count - 1)); + private static nuint GetByteVector256SpanLength(nuint offset, int length) + => (nuint)(uint)((length - (int)offset) & ~(Vector256.Count - 1)); [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe IntPtr UnalignedCountVector(ref byte searchSpace) + private static unsafe nuint UnalignedCountVector(ref byte searchSpace) { - int unaligned = (int)Unsafe.AsPointer(ref searchSpace) & (Vector.Count - 1); - return (IntPtr)((Vector.Count - unaligned) & (Vector.Count - 1)); + nint unaligned = (nint)Unsafe.AsPointer(ref searchSpace) & (Vector.Count - 1); + return (nuint)((Vector.Count - unaligned) & (Vector.Count - 1)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe IntPtr UnalignedCountVector128(ref byte searchSpace) + private static unsafe nuint UnalignedCountVector128(ref byte searchSpace) { - int unaligned = (int)Unsafe.AsPointer(ref searchSpace) & (Vector128.Count - 1); - return (IntPtr)((Vector128.Count - unaligned) & (Vector128.Count - 1)); + nint unaligned = (nint)Unsafe.AsPointer(ref searchSpace) & (Vector128.Count - 1); + return (nuint)(uint)((Vector128.Count - unaligned) & (Vector128.Count - 1)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe IntPtr UnalignedCountVectorFromEnd(ref byte searchSpace, int length) + private static unsafe nuint UnalignedCountVectorFromEnd(ref byte searchSpace, int length) { - int unaligned = (int)Unsafe.AsPointer(ref searchSpace) & (Vector.Count - 1); - return (IntPtr)(((length & (Vector.Count - 1)) + unaligned) & (Vector.Count - 1)); + nint unaligned = (nint)Unsafe.AsPointer(ref searchSpace) & (Vector.Count - 1); + return (nuint)(uint)(((length & (Vector.Count - 1)) + unaligned) & (Vector.Count - 1)); } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs index d0426d0889a2a..0f21d07c107c0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs @@ -54,7 +54,7 @@ public static int IndexOf(ref char searchSpace, int searchSpaceLength, ref char if (SequenceEqual( ref Unsafe.As(ref Unsafe.Add(ref searchSpace, index + 1)), ref Unsafe.As(ref valueTail), - (nuint)valueTailLength * 2)) + (nuint)(uint)valueTailLength * 2)) { return index; // The tail matched. Return a successful find. } @@ -66,7 +66,7 @@ ref Unsafe.As(ref valueTail), } [MethodImpl(MethodImplOptions.AggressiveOptimization)] - public static unsafe int SequenceCompareTo(ref char first, int firstLength, ref char second, int secondLength) + public static int SequenceCompareTo(ref char first, int firstLength, ref char second, int secondLength) { Debug.Assert(firstLength >= 0); Debug.Assert(secondLength >= 0); @@ -76,51 +76,51 @@ public static unsafe int SequenceCompareTo(ref char first, int firstLength, ref if (Unsafe.AreSame(ref first, ref second)) goto Equal; - IntPtr minLength = (IntPtr)((firstLength < secondLength) ? firstLength : secondLength); - IntPtr i = (IntPtr)0; // Use IntPtr for arithmetic to avoid unnecessary 64->32->64 truncations + nuint minLength = (nuint)(((uint)firstLength < (uint)secondLength) ? (uint)firstLength : (uint)secondLength); + nuint i = 0; // Use nuint for arithmetic to avoid unnecessary 64->32->64 truncations - if ((byte*)minLength >= (byte*)(sizeof(UIntPtr) / sizeof(char))) + if (minLength >= (sizeof(nuint) / sizeof(char))) { - if (Vector.IsHardwareAccelerated && (byte*)minLength >= (byte*)Vector.Count) + if (Vector.IsHardwareAccelerated && minLength >= (nuint)Vector.Count) { - IntPtr nLength = minLength - Vector.Count; + nuint nLength = minLength - (nuint)Vector.Count; do { - if (Unsafe.ReadUnaligned>(ref Unsafe.As(ref Unsafe.Add(ref first, i))) != - Unsafe.ReadUnaligned>(ref Unsafe.As(ref Unsafe.Add(ref second, i)))) + if (Unsafe.ReadUnaligned>(ref Unsafe.As(ref Unsafe.Add(ref first, (nint)i))) != + Unsafe.ReadUnaligned>(ref Unsafe.As(ref Unsafe.Add(ref second, (nint)i)))) { break; } - i += Vector.Count; + i += (nuint)Vector.Count; } - while ((byte*)nLength >= (byte*)i); + while (nLength >= i); } - while ((byte*)minLength >= (byte*)(i + sizeof(UIntPtr) / sizeof(char))) + while (minLength >= (i + sizeof(nuint) / sizeof(char))) { - if (Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.Add(ref first, i))) != - Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.Add(ref second, i)))) + if (Unsafe.ReadUnaligned (ref Unsafe.As(ref Unsafe.Add(ref first, (nint)i))) != + Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.Add(ref second, (nint)i)))) { break; } - i += sizeof(UIntPtr) / sizeof(char); + i += sizeof(nuint) / sizeof(char); } } #if TARGET_64BIT - if ((byte*)minLength >= (byte*)(i + sizeof(int) / sizeof(char))) + if (minLength >= (i + sizeof(int) / sizeof(char))) { - if (Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.Add(ref first, i))) == - Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.Add(ref second, i)))) + if (Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.Add(ref first, (nint)i))) == + Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.Add(ref second, (nint)i)))) { i += sizeof(int) / sizeof(char); } } #endif - while ((byte*)i < (byte*)minLength) + while (i < minLength) { - int result = Unsafe.Add(ref first, i).CompareTo(Unsafe.Add(ref second, i)); + int result = Unsafe.Add(ref first, (nint)i).CompareTo(Unsafe.Add(ref second, (nint)i)); if (result != 0) return result; i += 1; @@ -287,7 +287,7 @@ public static unsafe int IndexOf(ref char searchSpace, char value, int length) if (offset < length) { Debug.Assert(length - offset >= Vector128.Count); - if (((nint)Unsafe.AsPointer(ref Unsafe.Add(ref searchSpace, (IntPtr)offset)) & (nint)(Vector256.Count - 1)) != 0) + if (((nint)Unsafe.AsPointer(ref Unsafe.Add(ref searchSpace, (nint)offset)) & (nint)(Vector256.Count - 1)) != 0) { // Not currently aligned to Vector256 (is aligned to Vector128); this can cause a problem for searches // with no upper bound e.g. String.wcslen. Start with a check on Vector128 to align to Vector256, @@ -1034,23 +1034,23 @@ private static int LocateLastFoundChar(ulong match) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe Vector LoadVector(ref char start, nint offset) - => Unsafe.ReadUnaligned>(ref Unsafe.As(ref Unsafe.Add(ref start, (IntPtr)offset))); + private static Vector LoadVector(ref char start, nint offset) + => Unsafe.ReadUnaligned>(ref Unsafe.As(ref Unsafe.Add(ref start, offset))); [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe Vector128 LoadVector128(ref char start, nint offset) - => Unsafe.ReadUnaligned>(ref Unsafe.As(ref Unsafe.Add(ref start, (IntPtr)offset))); + private static Vector128 LoadVector128(ref char start, nint offset) + => Unsafe.ReadUnaligned>(ref Unsafe.As(ref Unsafe.Add(ref start, offset))); [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe Vector256 LoadVector256(ref char start, nint offset) - => Unsafe.ReadUnaligned>(ref Unsafe.As(ref Unsafe.Add(ref start, (IntPtr)offset))); + private static Vector256 LoadVector256(ref char start, nint offset) + => Unsafe.ReadUnaligned>(ref Unsafe.As(ref Unsafe.Add(ref start, offset))); [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe nint GetCharVectorSpanLength(nint offset, nint length) + private static nint GetCharVectorSpanLength(nint offset, nint length) => (length - offset) & ~(Vector.Count - 1); [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe nint GetCharVector128SpanLength(nint offset, nint length) + private static nint GetCharVector128SpanLength(nint offset, nint length) => (length - offset) & ~(Vector128.Count - 1); [MethodImpl(MethodImplOptions.AggressiveInlining)]