Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

Commit fb5bd9c

Browse files
committed
CopyFrom to MemoryCopy
1 parent b958e1e commit fb5bd9c

File tree

1 file changed

+57
-1
lines changed

1 file changed

+57
-1
lines changed

src/Microsoft.AspNetCore.Server.Kestrel/Internal/Infrastructure/MemoryPoolIterator.cs

+57-1
Original file line numberDiff line numberDiff line change
@@ -955,7 +955,7 @@ public void CopyFrom(ArraySegment<byte> buffer)
955955

956956
public void CopyFrom(byte[] data, int offset, int count)
957957
{
958-
if (IsDefault)
958+
if (count == 0 || IsDefault)
959959
{
960960
return;
961961
}
@@ -964,6 +964,19 @@ public void CopyFrom(byte[] data, int offset, int count)
964964
Debug.Assert(_block.Next == null);
965965
Debug.Assert(_block.End == _index);
966966

967+
Debug.Assert(count + offset <= data.Length);
968+
969+
#if NET451
970+
BlockCopyFrom(data, offset, count);
971+
#else
972+
MemoryCopyFrom(data, offset, count);
973+
#endif
974+
}
975+
976+
#if NET451
977+
private void BlockCopyFrom(byte[] data, int offset, int count)
978+
{
979+
// Note: Ensure for any changes in this function MemoryCopyFrom is changed to match
967980
var pool = _block.Pool;
968981
var block = _block;
969982
var blockIndex = _index;
@@ -999,6 +1012,49 @@ public void CopyFrom(byte[] data, int offset, int count)
9991012
_block = block;
10001013
_index = blockIndex;
10011014
}
1015+
#else
1016+
private unsafe void MemoryCopyFrom(byte[] data, int offset, int count)
1017+
{
1018+
// Note: Ensure for any changes in this function BlockCopyFrom is changed to match
1019+
var pool = _block.Pool;
1020+
var block = _block;
1021+
var blockIndex = _index;
1022+
1023+
var bufferIndex = offset;
1024+
var remaining = count;
1025+
var bytesLeftInBlock = block.Data.Offset + block.Data.Count - blockIndex;
1026+
1027+
fixed (byte* pData = &data[0])
1028+
{
1029+
while (remaining > 0)
1030+
{
1031+
if (bytesLeftInBlock == 0)
1032+
{
1033+
var nextBlock = pool.Lease();
1034+
block.End = blockIndex;
1035+
Volatile.Write(ref block.Next, nextBlock);
1036+
block = nextBlock;
1037+
1038+
blockIndex = block.Data.Offset;
1039+
bytesLeftInBlock = block.Data.Count;
1040+
}
1041+
1042+
var bytesToCopy = remaining < bytesLeftInBlock ? remaining : bytesLeftInBlock;
1043+
1044+
Buffer.MemoryCopy(pData + bufferIndex, block.DataFixedPtr + blockIndex, bytesLeftInBlock, bytesToCopy);
1045+
1046+
blockIndex += bytesToCopy;
1047+
bufferIndex += bytesToCopy;
1048+
remaining -= bytesToCopy;
1049+
bytesLeftInBlock -= bytesToCopy;
1050+
}
1051+
}
1052+
1053+
block.End = blockIndex;
1054+
_block = block;
1055+
_index = blockIndex;
1056+
}
1057+
#endif
10021058

10031059
public unsafe void CopyFromAscii(string data)
10041060
{

0 commit comments

Comments
 (0)