-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
(This issue was originally mentioned here)
Commit c6372c5 changed how overlap between the source and destination is detected in Buffer.Memmove
:
...became...
The original code may seem puzzling since the unsigned subtraction and compare "incorrectly" fails to identify source/destination overlap in the case where the destination (address) precedes the source (address) in memory. Indeed c6372c5 clarifies this and would also seem to fix a bug, but how did the original work anyway?
The answer, one eventually realizes, is that the original code was stealthily incorporating a strong assumption about--and dependency upon--the copy direction of the managed Buffer.Memmove
implementation which followed it.
The unfortunate upshot is that, while c6372c5 certainly makes the code clearer and more readable, it now excludes all overlap cases and thus no longer allows the performance benefit of fully-managed operation (i.e., non-P/Invoke) in the 50% of cases where the overlap happens to be compatible with the copy direction implemented in Buffer.cs. I blame the original code for not documenting its entirely non-obvious design and/or operation.
Anyway, can we revisit this line (re-relax the overlap test) to restore the optimization that was lost here? That is, once again allow the managed code path to prevail instead of P/Invoke for the half of the detected overlaps which happen to comport with the copy direction that's hard-coded into Buffer.Memmove
?