Message ID | 20160528131223.GB18662@bubble.grove.modra.org |
---|---|
State | New |
Headers | show |
On Sat, May 28, 2016 at 10:12:19PM -0400, DJ Delorie wrote: > > Alan Modra <amodra@gmail.com> writes: > > * xmemdup.c (xmemdup): Use xmalloc rather than xcalloc. > > In glibc at least, calloc can be faster than memset if the kernel is > pre-zero-ing pages. Thus, in those cases, your change makes the code > slower by adding an unneeded memset. Have you considered these cases? Actually, I didn't consider that.. I was looking at usage of xmemdup in binutils, gdb and gcc, and noticed that a lot of the calls don't need to clear any memory, and those that do only need to clear at most two bytes. ie. All uses have alloc_size <= copy_size + 2. So in real-world usage of xmemdup, I think the possible gain of fresh sbrk memory resulting in no internal calloc memset is minimal at best and of course if calloc is reusing freed memory then it will internally memset to zero.
diff --git a/libiberty/xmemdup.c b/libiberty/xmemdup.c index aa56f0b..4602afd 100644 --- a/libiberty/xmemdup.c +++ b/libiberty/xmemdup.c @@ -1,4 +1,4 @@ -/* xmemdup.c -- Duplicate a memory buffer, using xcalloc. +/* xmemdup.c -- Duplicate a memory buffer, using xmalloc. This trivial function is in the public domain. Jeff Garzik, September 1999. */ @@ -34,6 +34,8 @@ allocated, the remaining memory is zeroed. PTR xmemdup (const PTR input, size_t copy_size, size_t alloc_size) { - PTR output = xcalloc (1, alloc_size); + PTR output = xmalloc (alloc_size); + if (alloc_size > copy_size) + memset ((char *) output + copy_size, 0, alloc_size - copy_size); return (PTR) memcpy (output, input, copy_size); }