diff options
author | Rich Felker <dalias@aerifal.cx> | 2020-06-16 00:53:57 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2020-06-16 00:58:22 -0400 |
commit | fca7428c096066482d8c3f52450810288e27515c (patch) | |
tree | 985334c5d64519bbaa87a7502654718cd5bb577e /src/malloc | |
parent | cb5babdc8d624a3e3e7bea0b4e28a677a2f2fc46 (diff) | |
download | musl-fca7428c096066482d8c3f52450810288e27515c.tar.gz musl-fca7428c096066482d8c3f52450810288e27515c.tar.bz2 musl-fca7428c096066482d8c3f52450810288e27515c.tar.xz musl-fca7428c096066482d8c3f52450810288e27515c.zip |
only use memcpy realloc to shrink if an exact-sized free chunk exists
otherwise, shrink in-place. as explained in the description of commit
3e16313f8fe2ed143ae0267fd79d63014c24779f, the split here is valid
without holding split_merge_lock because all chunks involved are in
the in-use state.
Diffstat (limited to 'src/malloc')
-rw-r--r-- | src/malloc/oldmalloc/malloc.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/src/malloc/oldmalloc/malloc.c b/src/malloc/oldmalloc/malloc.c index 52af1975..c0997ad8 100644 --- a/src/malloc/oldmalloc/malloc.c +++ b/src/malloc/oldmalloc/malloc.c @@ -385,6 +385,18 @@ void *realloc(void *p, size_t n) /* Crash on corrupted footer (likely from buffer overflow) */ if (next->psize != self->csize) a_crash(); + if (n < n0) { + int i = bin_index_up(n); + int j = bin_index(n0); + if (i<j && (mal.binmap & (1ULL << i))) + goto copy_realloc; + struct chunk *split = (void *)((char *)self + n); + self->csize = split->psize = n | C_INUSE; + split->csize = next->psize = n0-n | C_INUSE; + __bin_chunk(split); + return CHUNK_TO_MEM(self); + } + lock(mal.split_merge_lock); size_t nsize = next->csize & C_INUSE ? 0 : CHUNK_SIZE(next); |