Skip to content
This repository has been archived by the owner on Nov 1, 2020. It is now read-only.

Commit

Permalink
Fix string.strlen (dotnet/coreclr#22397)
Browse files Browse the repository at this point in the history
* Add explanation comment

Fixes #22393

Signed-off-by: dotnet-bot <[email protected]>
  • Loading branch information
benaadams authored and jkotas committed Feb 5, 2019
1 parent 041e400 commit ecc96e7
Showing 1 changed file with 26 additions and 0 deletions.
26 changes: 26 additions & 0 deletions src/System.Private.CoreLib/shared/System/SpanHelpers.Byte.cs
Original file line number Diff line number Diff line change
Expand Up @@ -266,10 +266,36 @@ public static unsafe int IndexOf(ref byte searchSpace, byte value, int length)
offset += 1;
}

// We get past SequentialScan only if IsHardwareAccelerated or intrinsic .IsSupported is true; and remain length is greater than Vector length.
// However, we still have the redundant check to allow the JIT to see that the code is unreachable and eliminate it when the platform does not
// have hardware accelerated. After processing Vector lengths we return to SequentialScan to finish any remaining.
if (Avx2.IsSupported)
{
if ((int)(byte*)offset < length)
{
if ((((nuint)Unsafe.AsPointer(ref searchSpace) + (nuint)offset) & (nuint)(Vector256<byte>.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.
// Start with a check on Vector128 to align to Vector256, before moving to processing Vector256.
// This ensures we do not fault across memory pages while searching for an end of string.
Vector128<byte> values = Vector128.Create(value);
Vector128<byte> search = LoadVector128(ref searchSpace, offset);

// Same method as below
int matches = Sse2.MoveMask(Sse2.CompareEqual(values, search));
if (matches == 0)
{
// Zero flags set so no matches
offset += Vector128<byte>.Count;
}
else
{
// Find bitflag offset of first match and add to current offset
return ((int)(byte*)offset) + BitOps.TrailingZeroCount(matches);
}
}

nLength = GetByteVector256SpanLength(offset, length);
if ((byte*)nLength > (byte*)offset)
{
Expand Down

0 comments on commit ecc96e7

Please sign in to comment.