@@ -9,8 +9,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Infrastructure
9
9
{
10
10
public static class MemoryPoolIterator2Extensions
11
11
{
12
- private const int _maxStackAllocBytes = 16384 ;
13
-
14
12
private static Encoding _utf8 = Encoding . UTF8 ;
15
13
16
14
public const string HttpConnectMethod = "CONNECT" ;
@@ -69,77 +67,58 @@ private unsafe static long GetAsciiStringAsLong(string str)
69
67
}
70
68
}
71
69
72
- private static unsafe string GetAsciiStringStack ( byte [ ] input , int inputOffset , int length )
70
+ private unsafe static string GetAsciiString ( MemoryPoolBlock2 start , MemoryPoolIterator2 end , int inputOffset , int length )
73
71
{
74
- // avoid declaring other local vars, or doing work with stackalloc
75
- // to prevent the .locals init cil flag , see: https://github.com/dotnet/coreclr/issues/1279
76
- char * output = stackalloc char [ length ] ;
77
-
78
- return GetAsciiStringImplementation ( output , input , inputOffset , length ) ;
79
- }
72
+ var asciiString = new string ( '\0 ' , length ) ;
80
73
81
- private static unsafe string GetAsciiStringImplementation ( char * output , byte [ ] input , int inputOffset , int length )
82
- {
83
- for ( var i = 0 ; i < length ; i ++ )
74
+ fixed ( char * outputStart = asciiString )
84
75
{
85
- output [ i ] = ( char ) input [ inputOffset + i ] ;
86
- }
87
-
88
- return new string ( output , 0 , length ) ;
89
- }
90
-
91
- private static unsafe string GetAsciiStringStack ( MemoryPoolBlock2 start , MemoryPoolIterator2 end , int inputOffset , int length )
92
- {
93
- // avoid declaring other local vars, or doing work with stackalloc
94
- // to prevent the .locals init cil flag , see: https://github.com/dotnet/coreclr/issues/1279
95
- char * output = stackalloc char [ length ] ;
96
-
97
- return GetAsciiStringImplementation ( output , start , end , inputOffset , length ) ;
98
- }
99
-
100
- private unsafe static string GetAsciiStringHeap ( MemoryPoolBlock2 start , MemoryPoolIterator2 end , int inputOffset , int length )
101
- {
102
- var buffer = new char [ length ] ;
103
-
104
- fixed ( char * output = buffer )
105
- {
106
- return GetAsciiStringImplementation ( output , start , end , inputOffset , length ) ;
107
- }
108
- }
109
-
110
- private static unsafe string GetAsciiStringImplementation ( char * output , MemoryPoolBlock2 start , MemoryPoolIterator2 end , int inputOffset , int length )
111
- {
112
- var outputOffset = 0 ;
113
- var block = start ;
114
- var remaining = length ;
115
-
116
- var endBlock = end . Block ;
117
- var endIndex = end . Index ;
76
+ var output = outputStart ;
77
+ var block = start ;
78
+ var remaining = length ;
118
79
119
- while ( true )
120
- {
121
- int following = ( block != endBlock ? block . End : endIndex ) - inputOffset ;
80
+ var endBlock = end . Block ;
81
+ var endIndex = end . Index ;
122
82
123
- if ( following > 0 )
83
+ while ( true )
124
84
{
125
- var input = block . Array ;
126
- for ( var i = 0 ; i < following ; i ++ )
85
+ int following = ( block != endBlock ? block . End : endIndex ) - inputOffset ;
86
+
87
+ if ( following > 0 )
127
88
{
128
- output [ i + outputOffset ] = ( char ) input [ i + inputOffset ] ;
89
+ fixed ( byte * blockStart = block . Array )
90
+ {
91
+ var input = blockStart + inputOffset ;
92
+ var i = 0 ;
93
+ var followingMinusSpan = following - 3 ;
94
+ for ( ; i < followingMinusSpan ; i += 4 )
95
+ {
96
+ * ( output ) = ( char ) * ( input ) ;
97
+ * ( output + 1 ) = ( char ) * ( input + 1 ) ;
98
+ * ( output + 2 ) = ( char ) * ( input + 2 ) ;
99
+ * ( output + 3 ) = ( char ) * ( input + 3 ) ;
100
+ output += 4 ;
101
+ input += 4 ;
102
+ }
103
+ for ( ; i < following ; i ++ )
104
+ {
105
+ * ( output ++ ) = ( char ) * ( input ++ ) ;
106
+ }
107
+ }
108
+ remaining -= following ;
129
109
}
130
110
131
- remaining -= following ;
132
- outputOffset += following ;
133
- }
111
+ if ( remaining == 0 )
112
+ {
113
+ break ;
114
+ }
134
115
135
- if ( remaining == 0 )
136
- {
137
- return new string ( output , 0 , length ) ;
116
+ block = block . Next ;
117
+ inputOffset = block . Start ;
138
118
}
139
-
140
- block = block . Next ;
141
- inputOffset = block . Start ;
142
119
}
120
+
121
+ return asciiString ;
143
122
}
144
123
145
124
public static string GetAsciiString ( this MemoryPoolIterator2 start , MemoryPoolIterator2 end )
@@ -151,20 +130,16 @@ public static string GetAsciiString(this MemoryPoolIterator2 start, MemoryPoolIt
151
130
152
131
var length = start . GetLength ( end ) ;
153
132
154
- // Bytes out of the range of ascii are treated as "opaque data"
155
- // and kept in string as a char value that casts to same input byte value
156
- // https://tools.ietf.org/html/rfc7230#section-3.2.4
157
- if ( end . Block == start . Block )
133
+ if ( length == 0 )
158
134
{
159
- return GetAsciiStringStack ( start . Block . Array , start . Index , length ) ;
135
+ return default ( string ) ;
160
136
}
161
137
162
- if ( length > _maxStackAllocBytes )
163
- {
164
- return GetAsciiStringHeap ( start . Block , end , start . Index , length ) ;
165
- }
138
+ // Bytes out of the range of ascii are treated as "opaque data"
139
+ // and kept in string as a char value that casts to same input byte value
140
+ // https://tools.ietf.org/html/rfc7230#section-3.2.4
166
141
167
- return GetAsciiStringStack ( start . Block , end , start . Index , length ) ;
142
+ return GetAsciiString ( start . Block , end , start . Index , length ) ;
168
143
}
169
144
170
145
public static string GetUtf8String ( this MemoryPoolIterator2 start , MemoryPoolIterator2 end )
0 commit comments