Skip to content
23 changes: 21 additions & 2 deletions src/Compilers/Core/Portable/Text/SourceText.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel;
Expand Down Expand Up @@ -642,7 +642,26 @@ ImmutableArray<byte> computeContentHash()
sourceIndex: index, destination: charBuffer,
destinationIndex: 0, count: charsToCopy);

hash.Append(MemoryMarshal.AsBytes(charBuffer.AsSpan(0, charsToCopy)));
var charSpan = charBuffer.AsSpan(0, charsToCopy);

// Ensure everything is always little endian, so we get the same results across all platforms.
// This will be entirely elided by the jit on a little endian machine.
if (!BitConverter.IsLittleEndian)
{
var shortSpan = MemoryMarshal.Cast<char, short>(charSpan);

#if NET8_0_OR_GREATER
// Defer to the platform to do the reversal. It ships with a vectorized
// implementation for this on .NET 8 and above.
BinaryPrimitives.ReverseEndianness(source: shortSpan, destination: shortSpan);
#else
// Otherwise, fallback to the simple approach of reversing each pair of bytes.
for (var i = 0; i < shortSpan.Length; i++)
shortSpan[i] = BinaryPrimitives.ReverseEndianness(shortSpan[i]);
#endif
}

hash.Append(MemoryMarshal.AsBytes(charSpan));
}

// Switch this to ImmutableCollectionsMarshal.AsImmutableArray(hash.GetHashAndReset()) when we move to S.C.I v8.
Expand Down