@@ -1402,6 +1402,7 @@ void QCALLTYPE ExceptionNative::GetMessageFromNativeResources(ExceptionMessageKi
1402
1402
END_QCALL;
1403
1403
}
1404
1404
1405
+ static MethodTable * g_pByteArrayMT;
1405
1406
1406
1407
// BlockCopy
1407
1408
// This method from one primitive array to another based
@@ -1416,20 +1417,45 @@ FCIMPL5(VOID, Buffer::BlockCopy, ArrayBase *src, int srcOffset, ArrayBase *dst,
1416
1417
if (src==NULL || dst==NULL )
1417
1418
FCThrowArgumentNullVoid ((src==NULL ) ? W (" src" ) : W (" dst" ));
1418
1419
1419
- // Size of the Arrays in bytes
1420
- SIZE_T srcLen = src->GetNumComponents () * src->GetComponentSize ();
1421
- SIZE_T dstLen = srcLen;
1420
+ SIZE_T srcLen, dstLen;
1422
1421
1423
- // We only want to allow arrays of primitives, no Objects.
1424
- const CorElementType srcET = src-> GetArrayElementType ();
1425
- if (! CorTypeInfo::IsPrimitiveType_NoThrow (srcET))
1426
- FCThrowArgumentVoid ( W ( " src " ), W ( " Arg_MustBePrimArray " ));
1422
+ //
1423
+ // Use specialized fast path for byte arrays because of it is what Buffer::BlockCopy is
1424
+ // typically used for.
1425
+ //
1427
1426
1428
- if (src != dst) {
1429
- const CorElementType dstET = dst->GetArrayElementType ();
1430
- if (!CorTypeInfo::IsPrimitiveType_NoThrow (dstET))
1431
- FCThrowArgumentVoid (W (" dest" ), W (" Arg_MustBePrimArray" ));
1432
- dstLen = dst->GetNumComponents () * dst->GetComponentSize ();
1427
+ MethodTable * pByteArrayMT = g_pByteArrayMT;
1428
+ if (pByteArrayMT == NULL )
1429
+ {
1430
+ if (g_pPredefinedArrayTypes[ELEMENT_TYPE_U1] != NULL )
1431
+ {
1432
+ pByteArrayMT = g_pPredefinedArrayTypes[ELEMENT_TYPE_U1]->GetMethodTable ();
1433
+ g_pByteArrayMT = pByteArrayMT;
1434
+ }
1435
+ }
1436
+
1437
+ if (src->GetMethodTable () == pByteArrayMT && dst->GetMethodTable () == pByteArrayMT)
1438
+ {
1439
+ srcLen = src->GetNumComponents ();
1440
+ dstLen = dst->GetNumComponents ();
1441
+ }
1442
+ else
1443
+ {
1444
+ // Size of the Arrays in bytes
1445
+ srcLen = src->GetNumComponents () * src->GetComponentSize ();
1446
+ dstLen = srcLen;
1447
+
1448
+ // We only want to allow arrays of primitives, no Objects.
1449
+ const CorElementType srcET = src->GetArrayElementType ();
1450
+ if (!CorTypeInfo::IsPrimitiveType_NoThrow (srcET))
1451
+ FCThrowArgumentVoid (W (" src" ), W (" Arg_MustBePrimArray" ));
1452
+
1453
+ if (src != dst) {
1454
+ const CorElementType dstET = dst->GetArrayElementType ();
1455
+ if (!CorTypeInfo::IsPrimitiveType_NoThrow (dstET))
1456
+ FCThrowArgumentVoid (W (" dest" ), W (" Arg_MustBePrimArray" ));
1457
+ dstLen = dst->GetNumComponents () * dst->GetComponentSize ();
1458
+ }
1433
1459
}
1434
1460
1435
1461
if (srcOffset < 0 || dstOffset < 0 || count < 0 ) {
0 commit comments