From 816dabb009a9d4280b19062cd4d9d83e0ca9793a Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Wed, 7 Oct 2015 12:17:58 -0400 Subject: [PATCH 1/4] BitCount --- .../KnownHeaders.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tools/Microsoft.AspNet.Server.Kestrel.GeneratedCode/KnownHeaders.cs b/tools/Microsoft.AspNet.Server.Kestrel.GeneratedCode/KnownHeaders.cs index 11327a8d60..0fc30fa0de 100644 --- a/tools/Microsoft.AspNet.Server.Kestrel.GeneratedCode/KnownHeaders.cs +++ b/tools/Microsoft.AspNet.Server.Kestrel.GeneratedCode/KnownHeaders.cs @@ -195,14 +195,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http protected override int GetCountFast() {{ - var count = MaybeUnknown?.Count ?? 0; - {Each(loop.Headers, header => $@" - if ({header.TestBit()}) - {{ - ++count; - }} - ")} - return count; + return _bits.BitCount() + (MaybeUnknown?.Count ?? 0); }} protected override StringValues GetValueFast(string key) From 8bf2c814d64c8475415c1c9ba81ffaae84039275 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Wed, 7 Oct 2015 12:23:20 -0400 Subject: [PATCH 2/4] Add BitCount LongExtensions --- .../Http/FrameHeaders.Generated.cs | 364 +----------------- .../Infrastructure/LongExtensions.cs | 18 + .../KnownHeaders.cs | 1 + 3 files changed, 22 insertions(+), 361 deletions(-) create mode 100644 src/Microsoft.AspNet.Server.Kestrel/Infrastructure/LongExtensions.cs diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/FrameHeaders.Generated.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/FrameHeaders.Generated.cs index 9666fad29b..5ca0e5fc12 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/FrameHeaders.Generated.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/FrameHeaders.Generated.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; +using Microsoft.AspNet.Server.Kestrel.Extensions; using Microsoft.Extensions.Primitives; namespace Microsoft.AspNet.Server.Kestrel.Http @@ -589,214 +590,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http protected override int GetCountFast() { - var count = MaybeUnknown?.Count ?? 0; - - if (((_bits & 1L) != 0)) - { - ++count; - } - - if (((_bits & 2L) != 0)) - { - ++count; - } - - if (((_bits & 4L) != 0)) - { - ++count; - } - - if (((_bits & 8L) != 0)) - { - ++count; - } - - if (((_bits & 16L) != 0)) - { - ++count; - } - - if (((_bits & 32L) != 0)) - { - ++count; - } - - if (((_bits & 64L) != 0)) - { - ++count; - } - - if (((_bits & 128L) != 0)) - { - ++count; - } - - if (((_bits & 256L) != 0)) - { - ++count; - } - - if (((_bits & 512L) != 0)) - { - ++count; - } - - if (((_bits & 1024L) != 0)) - { - ++count; - } - - if (((_bits & 2048L) != 0)) - { - ++count; - } - - if (((_bits & 4096L) != 0)) - { - ++count; - } - - if (((_bits & 8192L) != 0)) - { - ++count; - } - - if (((_bits & 16384L) != 0)) - { - ++count; - } - - if (((_bits & 32768L) != 0)) - { - ++count; - } - - if (((_bits & 65536L) != 0)) - { - ++count; - } - - if (((_bits & 131072L) != 0)) - { - ++count; - } - - if (((_bits & 262144L) != 0)) - { - ++count; - } - - if (((_bits & 524288L) != 0)) - { - ++count; - } - - if (((_bits & 1048576L) != 0)) - { - ++count; - } - - if (((_bits & 2097152L) != 0)) - { - ++count; - } - - if (((_bits & 4194304L) != 0)) - { - ++count; - } - - if (((_bits & 8388608L) != 0)) - { - ++count; - } - - if (((_bits & 16777216L) != 0)) - { - ++count; - } - - if (((_bits & 33554432L) != 0)) - { - ++count; - } - - if (((_bits & 67108864L) != 0)) - { - ++count; - } - - if (((_bits & 134217728L) != 0)) - { - ++count; - } - - if (((_bits & 268435456L) != 0)) - { - ++count; - } - - if (((_bits & 536870912L) != 0)) - { - ++count; - } - - if (((_bits & 1073741824L) != 0)) - { - ++count; - } - - if (((_bits & 2147483648L) != 0)) - { - ++count; - } - - if (((_bits & 4294967296L) != 0)) - { - ++count; - } - - if (((_bits & 8589934592L) != 0)) - { - ++count; - } - - if (((_bits & 17179869184L) != 0)) - { - ++count; - } - - if (((_bits & 34359738368L) != 0)) - { - ++count; - } - - if (((_bits & 68719476736L) != 0)) - { - ++count; - } - - if (((_bits & 137438953472L) != 0)) - { - ++count; - } - - if (((_bits & 274877906944L) != 0)) - { - ++count; - } - - if (((_bits & 549755813888L) != 0)) - { - ++count; - } - - if (((_bits & 1099511627776L) != 0)) - { - ++count; - } - - return count; + return _bits.BitCount() + (MaybeUnknown?.Count ?? 0); } protected override StringValues GetValueFast(string key) @@ -5623,159 +5417,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http protected override int GetCountFast() { - var count = MaybeUnknown?.Count ?? 0; - - if (((_bits & 1L) != 0)) - { - ++count; - } - - if (((_bits & 2L) != 0)) - { - ++count; - } - - if (((_bits & 4L) != 0)) - { - ++count; - } - - if (((_bits & 8L) != 0)) - { - ++count; - } - - if (((_bits & 16L) != 0)) - { - ++count; - } - - if (((_bits & 32L) != 0)) - { - ++count; - } - - if (((_bits & 64L) != 0)) - { - ++count; - } - - if (((_bits & 128L) != 0)) - { - ++count; - } - - if (((_bits & 256L) != 0)) - { - ++count; - } - - if (((_bits & 512L) != 0)) - { - ++count; - } - - if (((_bits & 1024L) != 0)) - { - ++count; - } - - if (((_bits & 2048L) != 0)) - { - ++count; - } - - if (((_bits & 4096L) != 0)) - { - ++count; - } - - if (((_bits & 8192L) != 0)) - { - ++count; - } - - if (((_bits & 16384L) != 0)) - { - ++count; - } - - if (((_bits & 32768L) != 0)) - { - ++count; - } - - if (((_bits & 65536L) != 0)) - { - ++count; - } - - if (((_bits & 131072L) != 0)) - { - ++count; - } - - if (((_bits & 262144L) != 0)) - { - ++count; - } - - if (((_bits & 524288L) != 0)) - { - ++count; - } - - if (((_bits & 1048576L) != 0)) - { - ++count; - } - - if (((_bits & 2097152L) != 0)) - { - ++count; - } - - if (((_bits & 4194304L) != 0)) - { - ++count; - } - - if (((_bits & 8388608L) != 0)) - { - ++count; - } - - if (((_bits & 16777216L) != 0)) - { - ++count; - } - - if (((_bits & 33554432L) != 0)) - { - ++count; - } - - if (((_bits & 67108864L) != 0)) - { - ++count; - } - - if (((_bits & 134217728L) != 0)) - { - ++count; - } - - if (((_bits & 268435456L) != 0)) - { - ++count; - } - - if (((_bits & 536870912L) != 0)) - { - ++count; - } - - return count; + return _bits.BitCount() + (MaybeUnknown?.Count ?? 0); } protected override StringValues GetValueFast(string key) diff --git a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/LongExtensions.cs b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/LongExtensions.cs new file mode 100644 index 0000000000..0ac6a718d4 --- /dev/null +++ b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/LongExtensions.cs @@ -0,0 +1,18 @@ +// 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. + +namespace Microsoft.AspNet.Server.Kestrel.Extensions +{ + public static class LongExtensions + { + public static int BitCount(this long value) + { + // Parallel bit count for a 64-bit integer + var v = (ulong)value; + v = v - ((v >> 1) & 0x5555555555555555); + v = (v & 0x3333333333333333) + ((v >> 2) & 0x3333333333333333); + v = (v + (v >> 4) & 0x0f0f0f0f0f0f0f0f); + return (int)((v * 0x0101010101010101) >> 56); + } + } +} diff --git a/tools/Microsoft.AspNet.Server.Kestrel.GeneratedCode/KnownHeaders.cs b/tools/Microsoft.AspNet.Server.Kestrel.GeneratedCode/KnownHeaders.cs index 0fc30fa0de..6dbad61a7c 100644 --- a/tools/Microsoft.AspNet.Server.Kestrel.GeneratedCode/KnownHeaders.cs +++ b/tools/Microsoft.AspNet.Server.Kestrel.GeneratedCode/KnownHeaders.cs @@ -167,6 +167,7 @@ namespace Microsoft.AspNet.Server.Kestrel.GeneratedCode return $@" using System; using System.Collections.Generic; +using Microsoft.AspNet.Server.Kestrel.Extensions; using Microsoft.Extensions.Primitives; namespace Microsoft.AspNet.Server.Kestrel.Http From 05418dd18af08d67639d1ef97b4c2782210c69ff Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Wed, 7 Oct 2015 16:51:10 -0400 Subject: [PATCH 3/4] Use corefx implementation --- .../Infrastructure/LongExtensions.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/LongExtensions.cs b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/LongExtensions.cs index 0ac6a718d4..3b79425172 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/LongExtensions.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/LongExtensions.cs @@ -7,12 +7,18 @@ namespace Microsoft.AspNet.Server.Kestrel.Extensions { public static int BitCount(this long value) { - // Parallel bit count for a 64-bit integer + // see https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BitArithmetic.cs + + const ulong Mask01010101 = 0x5555555555555555UL; + const ulong Mask00110011 = 0x3333333333333333UL; + const ulong Mask00001111 = 0x0F0F0F0F0F0F0F0FUL; + const ulong Mask00000001 = 0x0101010101010101UL; + var v = (ulong)value; - v = v - ((v >> 1) & 0x5555555555555555); - v = (v & 0x3333333333333333) + ((v >> 2) & 0x3333333333333333); - v = (v + (v >> 4) & 0x0f0f0f0f0f0f0f0f); - return (int)((v * 0x0101010101010101) >> 56); + + v = v - ((v >> 1) & Mask01010101); + v = (v & Mask00110011) + ((v >> 2) & Mask00110011); + return (int)(unchecked(((v + (v >> 4)) & Mask00001111) * Mask00000001) >> 56); } } } From 4250d353472a8714bb4813631059b56fd53af922 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Thu, 8 Oct 2015 01:11:41 -0400 Subject: [PATCH 4/4] PR feeback --- .../Http/FrameHeaders.Generated.cs | 35 +++++++++++++++++-- .../Infrastructure/LongExtensions.cs | 24 ------------- .../KnownHeaders.cs | 18 ++++++++-- 3 files changed, 48 insertions(+), 29 deletions(-) delete mode 100644 src/Microsoft.AspNet.Server.Kestrel/Infrastructure/LongExtensions.cs diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/FrameHeaders.Generated.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/FrameHeaders.Generated.cs index 5ca0e5fc12..63eb6db9ad 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/FrameHeaders.Generated.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/FrameHeaders.Generated.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; -using Microsoft.AspNet.Server.Kestrel.Extensions; using Microsoft.Extensions.Primitives; namespace Microsoft.AspNet.Server.Kestrel.Http @@ -587,10 +586,25 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } + private static int BitCount(long value) + { + // see https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BitArithmetic.cs + + const ulong Mask01010101 = 0x5555555555555555UL; + const ulong Mask00110011 = 0x3333333333333333UL; + const ulong Mask00001111 = 0x0F0F0F0F0F0F0F0FUL; + const ulong Mask00000001 = 0x0101010101010101UL; + + var v = (ulong)value; + + v = v - ((v >> 1) & Mask01010101); + v = (v & Mask00110011) + ((v >> 2) & Mask00110011); + return (int)(unchecked(((v + (v >> 4)) & Mask00001111) * Mask00000001) >> 56); + } protected override int GetCountFast() { - return _bits.BitCount() + (MaybeUnknown?.Count ?? 0); + return BitCount(_bits) + (MaybeUnknown?.Count ?? 0); } protected override StringValues GetValueFast(string key) @@ -5414,10 +5428,25 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } + private static int BitCount(long value) + { + // see https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BitArithmetic.cs + + const ulong Mask01010101 = 0x5555555555555555UL; + const ulong Mask00110011 = 0x3333333333333333UL; + const ulong Mask00001111 = 0x0F0F0F0F0F0F0F0FUL; + const ulong Mask00000001 = 0x0101010101010101UL; + + var v = (ulong)value; + + v = v - ((v >> 1) & Mask01010101); + v = (v & Mask00110011) + ((v >> 2) & Mask00110011); + return (int)(unchecked(((v + (v >> 4)) & Mask00001111) * Mask00000001) >> 56); + } protected override int GetCountFast() { - return _bits.BitCount() + (MaybeUnknown?.Count ?? 0); + return BitCount(_bits) + (MaybeUnknown?.Count ?? 0); } protected override StringValues GetValueFast(string key) diff --git a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/LongExtensions.cs b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/LongExtensions.cs deleted file mode 100644 index 3b79425172..0000000000 --- a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/LongExtensions.cs +++ /dev/null @@ -1,24 +0,0 @@ -// 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. - -namespace Microsoft.AspNet.Server.Kestrel.Extensions -{ - public static class LongExtensions - { - public static int BitCount(this long value) - { - // see https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BitArithmetic.cs - - const ulong Mask01010101 = 0x5555555555555555UL; - const ulong Mask00110011 = 0x3333333333333333UL; - const ulong Mask00001111 = 0x0F0F0F0F0F0F0F0FUL; - const ulong Mask00000001 = 0x0101010101010101UL; - - var v = (ulong)value; - - v = v - ((v >> 1) & Mask01010101); - v = (v & Mask00110011) + ((v >> 2) & Mask00110011); - return (int)(unchecked(((v + (v >> 4)) & Mask00001111) * Mask00000001) >> 56); - } - } -} diff --git a/tools/Microsoft.AspNet.Server.Kestrel.GeneratedCode/KnownHeaders.cs b/tools/Microsoft.AspNet.Server.Kestrel.GeneratedCode/KnownHeaders.cs index 6dbad61a7c..ed50e3cc1f 100644 --- a/tools/Microsoft.AspNet.Server.Kestrel.GeneratedCode/KnownHeaders.cs +++ b/tools/Microsoft.AspNet.Server.Kestrel.GeneratedCode/KnownHeaders.cs @@ -167,7 +167,6 @@ namespace Microsoft.AspNet.Server.Kestrel.GeneratedCode return $@" using System; using System.Collections.Generic; -using Microsoft.AspNet.Server.Kestrel.Extensions; using Microsoft.Extensions.Primitives; namespace Microsoft.AspNet.Server.Kestrel.Http @@ -193,10 +192,25 @@ namespace Microsoft.AspNet.Server.Kestrel.Http }} }} ")} + private static int BitCount(long value) + {{ + // see https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BitArithmetic.cs + + const ulong Mask01010101 = 0x5555555555555555UL; + const ulong Mask00110011 = 0x3333333333333333UL; + const ulong Mask00001111 = 0x0F0F0F0F0F0F0F0FUL; + const ulong Mask00000001 = 0x0101010101010101UL; + + var v = (ulong)value; + + v = v - ((v >> 1) & Mask01010101); + v = (v & Mask00110011) + ((v >> 2) & Mask00110011); + return (int)(unchecked(((v + (v >> 4)) & Mask00001111) * Mask00000001) >> 56); + }} protected override int GetCountFast() {{ - return _bits.BitCount() + (MaybeUnknown?.Count ?? 0); + return BitCount(_bits) + (MaybeUnknown?.Count ?? 0); }} protected override StringValues GetValueFast(string key)