From a5dd659fdc1719f943fead7e1b6e2db167a271a4 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Tue, 3 Feb 2015 21:41:36 +0000 Subject: [PATCH] Avoid unnecessary work for identical locations in Buffer.BlockCopy Perform validity checks to ensure parameters are correct but short-circuit out memmove when exactly the same data would be copied to the same location. There are a number of occasions; which can be intentional or unintentional, where the buffer being copied is the same place - e.g an internal buffer is the same as the return buffer, and there is no need to call memmove's overwrite safe copy. Generally the call to BlockCopy will be in a library so it is more practical to enable the check here rather than alter all the calling functions, including 3rd party libraries to preform additional checks. --- src/vm/comutilnative.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/vm/comutilnative.cpp b/src/vm/comutilnative.cpp index 8c27b2f478b6..ae9a9c18ed60 100644 --- a/src/vm/comutilnative.cpp +++ b/src/vm/comutilnative.cpp @@ -1443,9 +1443,12 @@ FCIMPL5(VOID, Buffer::BlockCopy, ArrayBase *src, int srcOffset, ArrayBase *dst, if (srcLen < (SIZE_T)srcOffset + (SIZE_T)count || dstLen < (SIZE_T)dstOffset + (SIZE_T)count) { FCThrowArgumentVoid(NULL, W("Argument_InvalidOffLen")); } + + PTR_BYTE srcPtr = src->GetDataPtr() + srcOffset; + PTR_BYTE dstPtr = dst->GetDataPtr() + dstOffset; - if (count > 0) { - memmove(dst->GetDataPtr() + dstOffset, src->GetDataPtr() + srcOffset, count); + if ((srcPtr != dstPtr) && (count > 0)) { + memmove(dstPtr, srcPtr, count); } FC_GC_POLL();