summaryrefslogtreecommitdiff
path: root/src/vm/comutilnative.cpp
diff options
context:
space:
mode:
authorBen Adams <thundercat@illyriad.co.uk>2015-02-03 21:41:36 +0000
committerben_a_adams <ben.adams@ageofascent.com>2015-02-04 19:47:15 +0000
commita5dd659fdc1719f943fead7e1b6e2db167a271a4 (patch)
tree21682a83d1b5b74faa97ce37d4a65c6c4a250bae /src/vm/comutilnative.cpp
parentb846bb46cfa695d7fc39993a70a4d0add762d6c3 (diff)
downloadcoreclr-a5dd659fdc1719f943fead7e1b6e2db167a271a4.tar.gz
coreclr-a5dd659fdc1719f943fead7e1b6e2db167a271a4.tar.bz2
coreclr-a5dd659fdc1719f943fead7e1b6e2db167a271a4.zip
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.
Diffstat (limited to 'src/vm/comutilnative.cpp')
-rw-r--r--src/vm/comutilnative.cpp7
1 files changed, 5 insertions, 2 deletions
diff --git a/src/vm/comutilnative.cpp b/src/vm/comutilnative.cpp
index 8c27b2f478..ae9a9c18ed 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();