@@ -1402,7 +1402,6 @@ void QCALLTYPE ExceptionNative::GetMessageFromNativeResources(ExceptionMessageKi
1402
1402
END_QCALL;
1403
1403
}
1404
1404
1405
-
1406
1405
// BlockCopy
1407
1406
// This method from one primitive array to another based
1408
1407
// upon an offset into each an a byte count.
@@ -1416,20 +1415,37 @@ FCIMPL5(VOID, Buffer::BlockCopy, ArrayBase *src, int srcOffset, ArrayBase *dst,
1416
1415
if (src==NULL || dst==NULL )
1417
1416
FCThrowArgumentNullVoid ((src==NULL ) ? W (" src" ) : W (" dst" ));
1418
1417
1419
- // Size of the Arrays in bytes
1420
- SIZE_T srcLen = src->GetNumComponents () * src->GetComponentSize ();
1421
- SIZE_T dstLen = srcLen;
1418
+ SIZE_T srcLen, dstLen;
1422
1419
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 " ));
1420
+ //
1421
+ // Use specialized fast path for byte arrays because of it is what Buffer::BlockCopy is
1422
+ // typically used for.
1423
+ //
1427
1424
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 ();
1425
+ MethodTable * pByteArrayMT = g_pByteArrayMT;
1426
+ _ASSERTE (pByteArrayMT != NULL );
1427
+ if (src->GetMethodTable () == pByteArrayMT && dst->GetMethodTable () == pByteArrayMT)
1428
+ {
1429
+ srcLen = src->GetNumComponents ();
1430
+ dstLen = dst->GetNumComponents ();
1431
+ }
1432
+ else
1433
+ {
1434
+ // Size of the Arrays in bytes
1435
+ srcLen = src->GetNumComponents () * src->GetComponentSize ();
1436
+ dstLen = srcLen;
1437
+
1438
+ // We only want to allow arrays of primitives, no Objects.
1439
+ const CorElementType srcET = src->GetArrayElementType ();
1440
+ if (!CorTypeInfo::IsPrimitiveType_NoThrow (srcET))
1441
+ 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
+ }
1433
1449
}
1434
1450
1435
1451
if (srcOffset < 0 || dstOffset < 0 || count < 0 ) {
0 commit comments