[PATCH] malloc: replace instances of __builtin_expect with __glibc_unlikely in malloc.c
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Tue Jun 24 19:45:18 GMT 2025
On 24/06/25 14:10, William Hunt wrote:
> Replaced all instances of __builtin_expect within malloc.c
> to __glibc_unlikely. This improves the portability of glibc
> by avoiding calls to GNU C built-in functions. Since all
> the expected results from calls to __builtin_expect were 0,
> __glibc_likely was never used as a replacement. Multiple
> calls to __builtin_expect within a single if statement have
> been replaced with one call to __glibc_unlikely, which wraps
> every condition.
>
> Passes regress, OK for commit?
LGTM, thanks. There are still some __builtin_expect usage on malloc/malloc-debug.c.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> ---
> malloc/malloc.c | 41 ++++++++++++++++++++---------------------
> 1 file changed, 20 insertions(+), 21 deletions(-)
>
> diff --git a/malloc/malloc.c b/malloc/malloc.c
> index d28cd66faa..e73085af42 100644
> --- a/malloc/malloc.c
> +++ b/malloc/malloc.c
> @@ -1623,7 +1623,7 @@ unlink_chunk (mstate av, mchunkptr p)
> mchunkptr fd = p->fd;
> mchunkptr bk = p->bk;
>
> - if (__builtin_expect (fd->bk != p || bk->fd != p, 0))
> + if (__glibc_unlikely (fd->bk != p || bk->fd != p))
> malloc_printerr ("corrupted double-linked list");
>
> fd->bk = bk;
> @@ -3630,8 +3630,8 @@ __libc_realloc (void *oldmem, size_t bytes)
> never wraps around at the end of the address space. Therefore
> we can exclude some size values which might appear here by
> accident or by "design" from some intruder. */
> - if ((__builtin_expect ((uintptr_t) oldp > (uintptr_t) -oldsize, 0)
> - || __builtin_expect (misaligned_chunk (oldp), 0)))
> + if (__glibc_unlikely ((uintptr_t) oldp > (uintptr_t) -oldsize
> + || misaligned_chunk (oldp)))
> malloc_printerr ("realloc(): invalid pointer");
>
> nb = checked_request2size (bytes);
> @@ -3901,7 +3901,7 @@ __libc_calloc2 (size_t sz)
> /* Two optional cases in which clearing not necessary */
> if (chunk_is_mmapped (p))
> {
> - if (__builtin_expect (perturb_byte, 0))
> + if (__glibc_unlikely (perturb_byte))
> return memset (mem, 0, sz);
>
> return mem;
> @@ -4066,7 +4066,7 @@ _int_malloc (mstate av, size_t bytes)
> if (__glibc_likely (victim != NULL))
> {
> size_t victim_idx = fastbin_index (chunksize (victim));
> - if (__builtin_expect (victim_idx != idx, 0))
> + if (__glibc_unlikely (victim_idx != idx))
> malloc_printerr ("malloc(): memory corruption (fast)");
> check_remalloced_chunk (av, victim, nb);
> #if USE_TCACHE
> @@ -4655,10 +4655,9 @@ _int_free_chunk (mstate av, mchunkptr p, INTERNAL_SIZE_T size, int have_lock)
> #endif
> ) {
>
> - if (__builtin_expect (chunksize_nomask (chunk_at_offset (p, size))
> - <= CHUNK_HDR_SZ, 0)
> - || __builtin_expect (chunksize (chunk_at_offset (p, size))
> - >= av->system_mem, 0))
> + if (__glibc_unlikely (
> + chunksize_nomask (chunk_at_offset(p, size)) <= CHUNK_HDR_SZ
> + || chunksize (chunk_at_offset(p, size)) >= av->system_mem))
> {
> bool fail = true;
> /* We might not have a lock at this point and concurrent modifications
> @@ -4689,7 +4688,7 @@ _int_free_chunk (mstate av, mchunkptr p, INTERNAL_SIZE_T size, int have_lock)
> {
> /* Check that the top of the bin is not the record we are going to
> add (i.e., double free). */
> - if (__builtin_expect (old == p, 0))
> + if (__glibc_unlikely (old == p))
> malloc_printerr ("double free or corruption (fasttop)");
> p->fd = PROTECT_PTR (&p->fd, old);
> *fb = p;
> @@ -4699,7 +4698,7 @@ _int_free_chunk (mstate av, mchunkptr p, INTERNAL_SIZE_T size, int have_lock)
> {
> /* Check that the top of the bin is not the record we are going to
> add (i.e., double free). */
> - if (__builtin_expect (old == p, 0))
> + if (__glibc_unlikely (old == p))
> malloc_printerr ("double free or corruption (fasttop)");
> old2 = old;
> p->fd = PROTECT_PTR (&p->fd, old);
> @@ -4712,7 +4711,7 @@ _int_free_chunk (mstate av, mchunkptr p, INTERNAL_SIZE_T size, int have_lock)
> only if we have the lock, otherwise it might have already been
> allocated again. */
> if (have_lock && old != NULL
> - && __builtin_expect (fastbin_index (chunksize (old)) != idx, 0))
> + && __glibc_unlikely (fastbin_index (chunksize (old)) != idx))
> malloc_printerr ("invalid fastbin entry (free)");
> }
>
> @@ -4779,17 +4778,17 @@ _int_free_merge_chunk (mstate av, mchunkptr p, INTERNAL_SIZE_T size)
> if (__glibc_unlikely (p == av->top))
> malloc_printerr ("double free or corruption (top)");
> /* Or whether the next chunk is beyond the boundaries of the arena. */
> - if (__builtin_expect (contiguous (av)
> + if (__glibc_unlikely (contiguous (av)
> && (char *) nextchunk
> - >= ((char *) av->top + chunksize(av->top)), 0))
> + >= ((char *) av->top + chunksize(av->top))))
> malloc_printerr ("double free or corruption (out)");
> /* Or whether the block is actually not marked used. */
> if (__glibc_unlikely (!prev_inuse(nextchunk)))
> malloc_printerr ("double free or corruption (!prev)");
>
> INTERNAL_SIZE_T nextsize = chunksize(nextchunk);
> - if (__builtin_expect (chunksize_nomask (nextchunk) <= CHUNK_HDR_SZ, 0)
> - || __builtin_expect (nextsize >= av->system_mem, 0))
> + if (__glibc_unlikely (chunksize_nomask (nextchunk) <= CHUNK_HDR_SZ
> + || nextsize >= av->system_mem))
> malloc_printerr ("free(): invalid next size (normal)");
>
> free_perturb (chunk2mem(p), size - CHUNK_HDR_SZ);
> @@ -5046,9 +5045,9 @@ _int_realloc (mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
> unsigned long remainder_size; /* its size */
>
> /* oldmem size */
> - if (__builtin_expect (chunksize_nomask (oldp) <= CHUNK_HDR_SZ, 0)
> - || __builtin_expect (oldsize >= av->system_mem, 0)
> - || __builtin_expect (oldsize != chunksize (oldp), 0))
> + if (__glibc_unlikely (chunksize_nomask (oldp) <= CHUNK_HDR_SZ
> + || oldsize >= av->system_mem
> + || oldsize != chunksize (oldp)))
> malloc_printerr ("realloc(): invalid old size");
>
> check_inuse_chunk (av, oldp);
> @@ -5058,8 +5057,8 @@ _int_realloc (mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
>
> next = chunk_at_offset (oldp, oldsize);
> INTERNAL_SIZE_T nextsize = chunksize (next);
> - if (__builtin_expect (chunksize_nomask (next) <= CHUNK_HDR_SZ, 0)
> - || __builtin_expect (nextsize >= av->system_mem, 0))
> + if (__glibc_unlikely (chunksize_nomask (next) <= CHUNK_HDR_SZ
> + || nextsize >= av->system_mem))
> malloc_printerr ("realloc(): invalid next size");
>
> if ((unsigned long) (oldsize) >= (unsigned long) (nb))
More information about the Libc-alpha
mailing list