[PATCH v4] malloc: send freed small chunks to smallbin

DJ Delorie dj@redhat.com
Tue Nov 5 20:19:36 GMT 2024


LGTM assuming the legal issues are resolved.
Reviewed-by: DJ Delorie <dj@redhat.com>

k4lizen <k4lizen@proton.me> writes:
> -          /* place chunk in bin */
> -
> -          if (in_smallbin_range (size))
> +          /* Place chunk in bin.  Only malloc_consolidate() and splitting can put
> +             small chunks into the unsorted bin. */
> +          if (__glibc_unlikely (in_smallbin_range (size)))
>              {

No logic change; ok.

>                victim_index = smallbin_index (size);
>                bck = bin_at (av, victim_index);
> @@ -4723,23 +4723,39 @@ _int_free_create_chunk (mstate av, mchunkptr p, INTERNAL_SIZE_T size,
>        } else
>  	clear_inuse_bit_at_offset(nextchunk, 0);
>  
> -      /*
> -	Place the chunk in unsorted chunk list. Chunks are
> -	not placed into regular bins until after they have
> -	been given one chance to be used in malloc.
> -      */

Ok.

> +      mchunkptr bck, fwd;
> +
> +      if (!in_smallbin_range (size))
> +        {
> +          /* Place large chunks in unsorted chunk list.  Large chunks are
> +             not placed into regular bins until after they have
> +             been given one chance to be used in malloc.
> +
> +             This branch is first in the if-statement to help branch
> +             prediction on consecutive adjacent frees. */
> +          bck = unsorted_chunks (av);
> +          fwd = bck->fd;
> +          if (__glibc_unlikely (fwd->bk != bck))
> +            malloc_printerr ("free(): corrupted unsorted chunks");
> +          p->fd_nextsize = NULL;
> +          p->bk_nextsize = NULL;
> +        }

Ok.  bck/fwd point to the unsorted list and the first (maybe) unsorted
chunk.  NOTE: fwd may point to the bin if the list is empty!  It should
never be NULL.

> +      else
> +        {
> +          /* Place small chunks directly in their smallbin, so they
> +             don't pollute the unsorted bin. */
> +          int chunk_index = smallbin_index (size);
> +          bck = bin_at (av, chunk_index);
> +          fwd = bck->fd;
> +
> +          if (__glibc_unlikely (fwd->bk != bck))
> +            malloc_printerr ("free(): chunks in smallbin corrupted");
> +
> +          mark_bin (av, chunk_index);
> +        }

Ok.  Likewise, but for a small bin.


> -      mchunkptr bck = unsorted_chunks (av);
> -      mchunkptr fwd = bck->fd;
> -      if (__glibc_unlikely (fwd->bk != bck))
> -	malloc_printerr ("free(): corrupted unsorted chunks");

Ok.

> -      if (!in_smallbin_range(size))
> -	{
> -	  p->fd_nextsize = NULL;
> -	  p->bk_nextsize = NULL;
> -	}

This is done above, ok.

> -      p->fd = fwd;
>        p->bk = bck;
> +      p->fd = fwd;
>        bck->fd = p;
>        fwd->bk = p;

Unneeded swapping, but no problem there.  Stitch the chunk into its bin,
then stitch the bin to the chunk.

> @@ -4748,7 +4764,6 @@ _int_free_create_chunk (mstate av, mchunkptr p, INTERNAL_SIZE_T size,
>  
>        check_free_chunk(av, p);
>      }
> -
>    else
>      {
>        /* If the chunk borders the current high end of memory,

Unneeded removal but OK.



More information about the Libc-alpha mailing list