only use memcpy realloc to shrink if an exact-sized free chunk exists master
authorRich Felker <dalias@aerifal.cx>
Tue, 16 Jun 2020 04:53:57 +0000 (00:53 -0400)
committerRich Felker <dalias@aerifal.cx>
Tue, 16 Jun 2020 04:58:22 +0000 (00:58 -0400)
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.

src/malloc/oldmalloc/malloc.c

index 52af19759171d28514470a4e3afe96ab28ed4d49..c0997ad858fdf8d554eece3b29e02affedf0aa90 100644 (file)
@@ -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);