@@ -1402,7 +1402,6 @@ void QCALLTYPE ExceptionNative::GetMessageFromNativeResources(ExceptionMessageKi
14021402 END_QCALL ;
14031403}
14041404
1405-
14061405// BlockCopy
14071406// This method from one primitive array to another based
14081407// upon an offset into each an a byte count.
@@ -1416,20 +1415,37 @@ FCIMPL5(VOID, Buffer::BlockCopy, ArrayBase *src, int srcOffset, ArrayBase *dst,
14161415 if (src==NULL || dst==NULL )
14171416 FCThrowArgumentNullVoid ((src==NULL ) ? W (" src" ) : W (" dst" ));
14181417
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;
14221419
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+ //
14271424
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+ }
14331449 }
14341450
14351451 if (srcOffset < 0 || dstOffset < 0 || count < 0 ) {
0 commit comments