arespr/knownmethods-optimizations cleanup

This commit is contained in:
Stephen Halter 2017-04-27 12:39:36 -07:00
parent f464760bf8
commit 557cf29e4a
9 changed files with 54 additions and 74 deletions

View File

@ -1,44 +1,44 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Http;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
{
public static partial class HttpUtilities
{
// readonly primitive statics can be Jit'd to consts https://github.com/dotnet/coreclr/issues/1079
private readonly static ulong _httpConnectMethodLong = GetAsciiStringAsLong("CONNECT ");
private readonly static ulong _httpDeleteMethodLong = GetAsciiStringAsLong("DELETE \0");
private readonly static ulong _httpHeadMethodLong = GetAsciiStringAsLong("HEAD \0\0\0");
private readonly static ulong _httpPatchMethodLong = GetAsciiStringAsLong("PATCH \0\0");
private readonly static ulong _httpPostMethodLong = GetAsciiStringAsLong("POST \0\0\0");
private readonly static ulong _httpPutMethodLong = GetAsciiStringAsLong("PUT \0\0\0\0");
private readonly static ulong _httpOptionsMethodLong = GetAsciiStringAsLong("OPTIONS ");
private readonly static ulong _httpTraceMethodLong = GetAsciiStringAsLong("TRACE \0\0");
private static readonly ulong _httpConnectMethodLong = GetAsciiStringAsLong("CONNECT ");
private static readonly ulong _httpDeleteMethodLong = GetAsciiStringAsLong("DELETE \0");
private static readonly ulong _httpHeadMethodLong = GetAsciiStringAsLong("HEAD \0\0\0");
private static readonly ulong _httpPatchMethodLong = GetAsciiStringAsLong("PATCH \0\0");
private static readonly ulong _httpPostMethodLong = GetAsciiStringAsLong("POST \0\0\0");
private static readonly ulong _httpPutMethodLong = GetAsciiStringAsLong("PUT \0\0\0\0");
private static readonly ulong _httpOptionsMethodLong = GetAsciiStringAsLong("OPTIONS ");
private static readonly ulong _httpTraceMethodLong = GetAsciiStringAsLong("TRACE \0\0");
private readonly static ulong _mask8Chars = GetMaskAsLong(new byte[]
private static readonly ulong _mask8Chars = GetMaskAsLong(new byte[]
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff});
private readonly static ulong _mask7Chars = GetMaskAsLong(new byte[]
private static readonly ulong _mask7Chars = GetMaskAsLong(new byte[]
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00});
private readonly static ulong _mask6Chars = GetMaskAsLong(new byte[]
private static readonly ulong _mask6Chars = GetMaskAsLong(new byte[]
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00});
private readonly static ulong _mask5Chars = GetMaskAsLong(new byte[]
private static readonly ulong _mask5Chars = GetMaskAsLong(new byte[]
{0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00});
private readonly static ulong _mask4Chars = GetMaskAsLong(new byte[]
private static readonly ulong _mask4Chars = GetMaskAsLong(new byte[]
{0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00});
private readonly static Tuple<ulong, ulong, HttpMethod, int>[] _knownMethods =
private static readonly Tuple<ulong, ulong, HttpMethod, int>[] _knownMethods =
new Tuple<ulong, ulong, HttpMethod, int>[17];
private readonly static string[] _methodNames = new string[9];
private static readonly string[] _methodNames = new string[9];
static HttpUtilities()
{

View File

@ -5,7 +5,6 @@ using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Text;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
using Microsoft.AspNetCore.Server.Kestrel.Internal.System;
@ -20,10 +19,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
public const string HttpsUriScheme = "https://";
// readonly primitive statics can be Jit'd to consts https://github.com/dotnet/coreclr/issues/1079
private readonly static ulong _httpSchemeLong = GetAsciiStringAsLong(HttpUriScheme + "\0");
private readonly static ulong _httpsSchemeLong = GetAsciiStringAsLong(HttpsUriScheme);
private static readonly ulong _httpSchemeLong = GetAsciiStringAsLong(HttpUriScheme + "\0");
private static readonly ulong _httpsSchemeLong = GetAsciiStringAsLong(HttpsUriScheme);
private const uint _httpGetMethodInt = 542393671; // retun of GetAsciiStringAsInt("GET "); const results in better codegen
private const uint _httpGetMethodInt = 542393671; // GetAsciiStringAsInt("GET "); const results in better codegen
private const ulong _http10VersionLong = 3471766442030158920; // GetAsciiStringAsLong("HTTP/1.0"); const results in better codegen
private const ulong _http11VersionLong = 3543824036068086856; // GetAsciiStringAsLong("HTTP/1.1"); const results in better codegen
@ -34,18 +33,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
_knownMethods[GetKnownMethodIndex(knownMethodUlong)] = new Tuple<ulong, ulong, HttpMethod, int>(mask, knownMethodUlong, knownMethod, length);
}
private readonly static Tuple<ulong, ulong, HttpMethod, int>[] _knownMethods =
{
Tuple.Create(_mask4Chars, _httpPutMethodLong, HttpMethod.Put, 3),
Tuple.Create(_mask5Chars, _httpPostMethodLong, HttpMethod.Post, 4),
Tuple.Create(_mask5Chars, _httpHeadMethodLong, HttpMethod.Head, 4),
Tuple.Create(_mask6Chars, _httpTraceMethodLong, HttpMethod.Trace, 5),
Tuple.Create(_mask6Chars, _httpPatchMethodLong, HttpMethod.Patch, 5),
Tuple.Create(_mask7Chars, _httpDeleteMethodLong, HttpMethod.Delete, 6),
Tuple.Create(_mask8Chars, _httpConnectMethodLong, HttpMethod.Connect, 7),
Tuple.Create(_mask8Chars, _httpOptionsMethodLong, HttpMethod.Options, 7),
};
private static void FillKnownMethodsGaps()
{
var knownMethods = _knownMethods;
@ -60,7 +47,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
}
}
private unsafe static ulong GetAsciiStringAsLong(string str)
private static unsafe ulong GetAsciiStringAsLong(string str)
{
Debug.Assert(str.Length == 8, "String must be exactly 8 (ASCII) characters long.");
@ -72,7 +59,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
}
}
private unsafe static uint GetAsciiStringAsInt(string str)
private static unsafe uint GetAsciiStringAsInt(string str)
{
Debug.Assert(str.Length == 4, "String must be exactly 4 (ASCII) characters long.");
@ -84,7 +71,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
}
}
private unsafe static ulong GetMaskAsLong(byte[] bytes)
private static unsafe ulong GetMaskAsLong(byte[] bytes)
{
Debug.Assert(bytes.Length == 8, "Mask must be exactly 8 bytes long.");
@ -94,7 +81,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
}
}
public unsafe static string GetAsciiStringNonNullCharacters(this Span<byte> span)
public static unsafe string GetAsciiStringNonNullCharacters(this Span<byte> span)
{
if (span.IsEmpty)
{
@ -157,7 +144,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal unsafe static HttpMethod GetKnownMethod(byte* data, int length, out int methodLength)
internal static unsafe HttpMethod GetKnownMethod(byte* data, int length, out int methodLength)
{
methodLength = 0;
if (length < sizeof(uint))
@ -229,7 +216,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
/// </remarks>
/// <returns><c>true</c> if the input matches a known string, <c>false</c> otherwise.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal unsafe static HttpVersion GetKnownVersion(byte* location, int length)
internal static unsafe HttpVersion GetKnownVersion(byte* location, int length)
{
HttpVersion knownVersion;
var version = *(ulong*)location;

View File

@ -15,9 +15,6 @@
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(AspNetCoreVersion)" />
</ItemGroup>
<ItemGroup>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.AspNetCore.Server.Kestrel.Core\Microsoft.AspNetCore.Server.Kestrel.Core.csproj" />
<ProjectReference Include="..\Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv\Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.csproj" />

View File

@ -1,12 +1,13 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Http;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
using Microsoft.AspNetCore.Server.Kestrel.Internal.System;
using Xunit;
namespace Microsoft.AspNetCore.Server.KestrelTests

View File

@ -15,10 +15,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
{
const string frameHeadersGeneratedPath = "../../../../../src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameHeaders.Generated.cs";
const string frameGeneratedPath = "../../../../../src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/Frame.Generated.cs";
const string httpUtilitiesGeneratedPath = "../../../../../src/Microsoft.AspNetCore.Server.Kestrel/Internal/Infrastructure/HttpUtilities.Generated.cs";
const string httpUtilitiesGeneratedPath = "../../../../../src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Infrastructure/HttpUtilities.Generated.cs";
var testFrameHeadersGeneratedPath = Path.GetTempFileName();
var testFrameGeneratedPath = Path.GetTempFileName();
var testHttpUtilitiesGeneratedPath = Path.GetTempFileName();
try
{
var currentFrameHeadersGenerated = File.ReadAllText(frameHeadersGeneratedPath);

View File

@ -6,28 +6,21 @@
<TargetFramework>netcoreapp1.1</TargetFramework>
<OutputType>Exe</OutputType>
<IsPackable>false</IsPackable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.Kestrel.Core\Microsoft.AspNetCore.Server.Kestrel.Core.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Http.Features" Version="$(AspNetCoreVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Server.Kestrel\Microsoft.AspNetCore.Server.Kestrel.csproj" />
</ItemGroup>
<PropertyGroup>
<StartWorkingDirectory>$(MSBuildThisFileDirectory)..\..\src\Microsoft.AspNetCore.Server.Kestrel.Core\Internal\Http</StartWorkingDirectory>
<StartArguments>FrameHeaders.Generated.cs Frame.Generated.cs</StartArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<StartWorkingDirectory>$(MSBuildThisFileDirectory)..\..\src\Microsoft.AspNetCore.Server.Kestrel.Core</StartWorkingDirectory>
<StartArguments>Internal\Http\FrameHeaders.Generated.cs Internal\Http\Frame.Generated.cs Internal\Infrastructure\HttpUtilities.Generated.cs</StartArguments>
</PropertyGroup>
</Project>

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
@ -10,11 +10,10 @@ namespace CodeGenerator.HttpUtilities
// C code for Algorithm L (Lexicographic combinations) in Section 7.2.1.3 of The Art of Computer Programming, Volume 4A: Combinatorial Algorithms, Part 1 :
internal class CombinationsWithoutRepetition<T> : IEnumerator<T[]>
{
private bool _firstElement;
private int[] _pointers;
private T[] _nElements;
private readonly int _p;
public T[] Current { get; private set; }
object IEnumerator.Current => Current;
public CombinationsWithoutRepetition(T[] nElements, int p)
{
@ -26,7 +25,8 @@ namespace CodeGenerator.HttpUtilities
ResetCurrent();
}
private bool _firstElement;
public T[] Current { get; private set; }
object IEnumerator.Current => Current;
public bool MoveNext()
{

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
@ -7,7 +7,7 @@ using System.Diagnostics;
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Http;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
namespace CodeGenerator.HttpUtilities
{
@ -66,9 +66,9 @@ namespace CodeGenerator.HttpUtilities
using System;
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Http;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
{{
public static partial class HttpUtilities
{{
@ -76,10 +76,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure
{0}
{1}
private readonly static Tuple<ulong, ulong, HttpMethod, int>[] _knownMethods =
private static readonly Tuple<ulong, ulong, HttpMethod, int>[] _knownMethods =
new Tuple<ulong, ulong, HttpMethod, int>[{2}];
private readonly static string[] _methodNames = new string[{3}];
private static readonly string[] _methodNames = new string[{3}];
static HttpUtilities()
{{
@ -106,7 +106,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure
var methodInfo = methodsInfo[index];
var httpMethodFieldName = GetHttpMethodFieldName(methodInfo);
result.AppendFormat(" private readonly static ulong {0} = GetAsciiStringAsLong(\"{1}\");", httpMethodFieldName, methodInfo.MethodAsciiString.Replace("\0", "\\0"));
result.AppendFormat(" private static readonly ulong {0} = GetAsciiStringAsLong(\"{1}\");", httpMethodFieldName, methodInfo.MethodAsciiString.Replace("\0", "\\0"));
if (index < methodsInfo.Count - 1)
{
@ -133,7 +133,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure
var hexMaskString = HttpUtilitiesGeneratorHelpers.GeHexString(maskArray, "0x", ", ");
var maskFieldName = GetMaskFieldName(maskBytesLength);
result.AppendFormat(" private readonly static ulong {0} = GetMaskAsLong(new byte[]\r\n {{{1}}});", maskFieldName, hexMaskString);
result.AppendFormat(" private static readonly ulong {0} = GetMaskAsLong(new byte[]\r\n {{{1}}});", maskFieldName, hexMaskString);
result.AppendLine();
if (index < distinctLengths.Count - 1)
{

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;