From: <jik...@li...> - 2013-08-19 19:09:38
|
details: http://hg.code.sourceforge.net/p/jikesrvm/code/rev/f8c062ff106b changeset: 10661:f8c062ff106b user: Erik Brangs <eri...@gm...> date: Mon Aug 19 20:38:11 2013 +0200 description: RVM-1050 : Use memmove() instead of memcpy() when memory regions overlap in org.jikesrvm.runtime.Memory.memcopy(Address, Address, Extent). diffstat: rvm/src/org/jikesrvm/runtime/BootRecord.java | 1 + rvm/src/org/jikesrvm/runtime/Memory.java | 23 ++++++++++++++++++----- rvm/src/org/jikesrvm/runtime/SysCall.java | 20 ++++++++++++++++++++ tools/bootImageRunner/sys.C | 12 +++++++++++- 4 files changed, 50 insertions(+), 6 deletions(-) diffs (117 lines): diff --git a/rvm/src/org/jikesrvm/runtime/BootRecord.java b/rvm/src/org/jikesrvm/runtime/BootRecord.java --- a/rvm/src/org/jikesrvm/runtime/BootRecord.java +++ b/rvm/src/org/jikesrvm/runtime/BootRecord.java @@ -226,6 +226,7 @@ // memory public Address sysCopyIP; + public Address sysMemmoveIP; public Address sysMallocIP; public Address sysCallocIP; public Address sysFreeIP; diff --git a/rvm/src/org/jikesrvm/runtime/Memory.java b/rvm/src/org/jikesrvm/runtime/Memory.java --- a/rvm/src/org/jikesrvm/runtime/Memory.java +++ b/rvm/src/org/jikesrvm/runtime/Memory.java @@ -424,22 +424,35 @@ } /** - * Copy a region of memory. - * <p> - * Assumption: source and destination regions do not overlap + * Copies a region of memory. * * @param dst Destination address * @param src Source address * @param cnt Number of bytes to copy */ public static void memcopy(Address dst, Address src, Extent cnt) { - SysCall.sysCall.sysCopy(dst, src, cnt); + Address srcEnd = src.plus(cnt); + Address dstEnd = dst.plus(cnt); + boolean overlap = !srcEnd.LE(dst) && !dstEnd.LE(src); + if (overlap) { + SysCall.sysCall.sysMemmove(dst, src, cnt); + } else { + SysCall.sysCall.sysCopy(dst, src, cnt); + } } + /** + * Wrapper method for {@link #memcopy(Address, Address, Extent)}. + * + * @param dst Destination address + * @param src Source address + * @param cnt Number of bytes to copy + */ public static void memcopy(Address dst, Address src, int cnt) { - SysCall.sysCall.sysCopy(dst, src, Extent.fromIntSignExtend(cnt)); + memcopy(dst, src, Extent.fromIntSignExtend(cnt)); } + /** * Zero a region of memory. * diff --git a/rvm/src/org/jikesrvm/runtime/SysCall.java b/rvm/src/org/jikesrvm/runtime/SysCall.java --- a/rvm/src/org/jikesrvm/runtime/SysCall.java +++ b/rvm/src/org/jikesrvm/runtime/SysCall.java @@ -80,9 +80,29 @@ public abstract int sysGetenv(byte[] varName, byte[] buf, int limit); // memory + + /** + * Copies memory.<p> + * + * Assumption: the memory regions do not overlap. Use + * {@link #sysMemmove(Address, Address, Extent)} if the regions might overlap. + * @param dst destination address + * @param src source address + * @param cnt number of bytes to copy + */ @SysCallTemplate public abstract void sysCopy(Address dst, Address src, Extent cnt); + /** + * Copies memory without making any assumptions about the memory areas. + * + * @param dst destination address + * @param src source address + * @param cnt number of bytes to copy + */ + @SysCallTemplate + public abstract void sysMemmove(Address dst, Address src, Extent cnt); + @SysCallTemplate public abstract Address sysMalloc(int length); diff --git a/tools/bootImageRunner/sys.C b/tools/bootImageRunner/sys.C --- a/tools/bootImageRunner/sys.C +++ b/tools/bootImageRunner/sys.C @@ -1664,7 +1664,7 @@ // Memory operations // //-------------------// -// Memory to memory copy. +// Memory to memory copy. Memory regions must not overlap. // extern "C" void sysCopy(void *dst, const void *src, Extent cnt) @@ -1672,6 +1672,16 @@ memcpy(dst, src, cnt); } +// Memory to memory copy. Memory regions may overlap. +// +extern "C" void +sysMemmove(void *dst, const void *src, Extent cnt) +{ + memmove(dst, src, cnt); +} + + + int inRVMAddressSpace(Address a); // Allocate memory. |