Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 32e44ef

Browse files
jamesqojkotas
authored andcommitted
Generalize Buffer.BlockCopy optimization for either src or dst (#4736)
* Generalize Buffer.BlockCopy optimization for either src or dst
1 parent 92e2d4e commit 32e44ef

File tree

1 file changed

+23
-11
lines changed

1 file changed

+23
-11
lines changed

src/vm/comutilnative.cpp

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1424,28 +1424,40 @@ FCIMPL5(VOID, Buffer::BlockCopy, ArrayBase *src, int srcOffset, ArrayBase *dst,
14241424

14251425
MethodTable * pByteArrayMT = g_pByteArrayMT;
14261426
_ASSERTE(pByteArrayMT != NULL);
1427-
if (src->GetMethodTable() == pByteArrayMT && dst->GetMethodTable() == pByteArrayMT)
1427+
1428+
// Optimization: If src is a byte array, we can
1429+
// simply set srcLen to GetNumComponents, without having
1430+
// to call GetComponentSize or verifying GetArrayElementType
1431+
if (src->GetMethodTable() == pByteArrayMT)
14281432
{
14291433
srcLen = src->GetNumComponents();
1430-
dstLen = dst->GetNumComponents();
14311434
}
14321435
else
14331436
{
1434-
// Size of the Arrays in bytes
14351437
srcLen = src->GetNumComponents() * src->GetComponentSize();
1436-
dstLen = srcLen;
14371438

14381439
// We only want to allow arrays of primitives, no Objects.
14391440
const CorElementType srcET = src->GetArrayElementType();
14401441
if (!CorTypeInfo::IsPrimitiveType_NoThrow(srcET))
14411442
FCThrowArgumentVoid(W("src"), W("Arg_MustBePrimArray"));
1442-
1443-
if (src != dst) {
1444-
const CorElementType dstET = dst->GetArrayElementType();
1445-
if (!CorTypeInfo::IsPrimitiveType_NoThrow(dstET))
1446-
FCThrowArgumentVoid(W("dest"), W("Arg_MustBePrimArray"));
1447-
dstLen = dst->GetNumComponents() * dst->GetComponentSize();
1448-
}
1443+
}
1444+
1445+
// Optimization: If copying to/from the same array, then
1446+
// we know that dstLen and srcLen must be the same.
1447+
if (src == dst)
1448+
{
1449+
dstLen = srcLen;
1450+
}
1451+
else if (dst->GetMethodTable() == pByteArrayMT)
1452+
{
1453+
dstLen = dst->GetNumComponents();
1454+
}
1455+
else
1456+
{
1457+
const CorElementType dstET = dst->GetArrayElementType();
1458+
if (!CorTypeInfo::IsPrimitiveType_NoThrow(dstET))
1459+
FCThrowArgumentVoid(W("dest"), W("Arg_MustBePrimArray"));
1460+
dstLen = dst->GetNumComponents() * dst->GetComponentSize();
14491461
}
14501462

14511463
if (srcOffset < 0 || dstOffset < 0 || count < 0) {

0 commit comments

Comments
 (0)