Remove Unsafe from ChunkWriter (#18450)

This commit is contained in:
Ben Adams 2020-01-22 22:50:34 +00:00 committed by Justin Kotalik
parent bc60e9576f
commit 2127e5d08e
1 changed files with 8 additions and 11 deletions

View File

@ -4,17 +4,11 @@
using System; using System;
using System.Buffers; using System.Buffers;
using System.IO.Pipelines; using System.IO.Pipelines;
using System.Text;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
internal static class ChunkWriter internal static class ChunkWriter
{ {
// This uses C# compiler's ability to refer to static data directly. For more information see https://vcsjones.dev/2019/02/01/csharp-readonly-span-bytes-static
private static ReadOnlySpan<byte> Hex => new byte[16] { (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f' };
public static int BeginChunkBytes(int dataCount, Span<byte> span) public static int BeginChunkBytes(int dataCount, Span<byte> span)
{ {
// Determine the most-significant non-zero nibble // Determine the most-significant non-zero nibble
@ -29,14 +23,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
count = (total >> 2) + 3; count = (total >> 2) + 3;
var offset = 0; // This must be explicity typed as ReadOnlySpan<byte>
ref var startHex = ref MemoryMarshal.GetReference(Hex); // It then becomes a non-allocating mapping to the data section of the assembly.
// For more information see https://vcsjones.dev/2019/02/01/csharp-readonly-span-bytes-static
ReadOnlySpan<byte> hex = new byte[16] { (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f' };
var offset = 0;
for (shift = total; shift >= 0; shift -= 4) for (shift = total; shift >= 0; shift -= 4)
{ {
// Using Unsafe.Add to elide the bounds check on _hex as the & 0x0f definitely // Uses dotnet/runtime#1644 to elide the bounds check on hex as the & 0x0f definitely
// constrains it to the range 0x0 - 0xf, matching the bounds of the array // constrains it to the range 0x0 - 0xf, matching the bounds of the array.
span[offset] = Unsafe.Add(ref startHex, ((dataCount >> shift) & 0x0f)); span[offset] = hex[(dataCount >> shift) & 0x0f];
offset++; offset++;
} }