malloc: Add sysdep hook for user allocation size alignment

Add a sysdep hook for additional user allocation size alignment
requirements used by request-size and usable-size calculations.

Use the same hook for tcache usable-size calculations and allow the
small calloc clear helper to fall back to memset for allocations whose
usable size is smaller than the unrolled clear path supports.

Reviewed-by: DJ Delorie <dj@redhat.com>
This commit is contained in:
Muhammad Kamran authored and Yury Khrustalev committed 2026-10-21 12:50:10 +01:00
1 parent 392350ecbb
commit 663cacc22b
2 files changed
+32 -8

No files matched your search

+23 -6
View File
@@ -283,6 +283,17 @@ verify (PTRDIFF_MAX <= SIZE_MAX / 2);
#define MALLOC_DEBUG 0
#endif
/* If defined, additional alignment requirements for the size and thus
the end address of the user-visible memory. Must not exceed
malloc's default pointer alignment. */
#ifndef MALLOC_USER_SIZE_ALIGNMENT
# define CHUNK2USER_OVERHEAD SIZE_SZ
#else
verify (powerof2 (MALLOC_USER_SIZE_ALIGNMENT));
verify (MALLOC_USER_SIZE_ALIGNMENT <= MALLOC_ALIGNMENT);
# define CHUNK2USER_OVERHEAD roundup (SIZE_SZ, MALLOC_USER_SIZE_ALIGNMENT)
#endif
#if USE_TCACHE
/* We want 64 entries. This is an arbitrary limit, which tunables can reduce. */
# define TCACHE_SMALL_BINS 64
@@ -291,7 +302,10 @@ verify (PTRDIFF_MAX <= SIZE_MAX / 2);
# define MAX_TCACHE_SMALL_SIZE tidx2csize (TCACHE_SMALL_BINS-1)
# define tidx2csize(idx) (((size_t) idx) * MALLOC_ALIGNMENT + MINSIZE)
# define tidx2usize(idx) (((size_t) idx) * MALLOC_ALIGNMENT + MINSIZE - SIZE_SZ)
# define tidx2usize(idx) \
(((size_t) idx) * MALLOC_ALIGNMENT \
+ MINSIZE \
- CHUNK2USER_OVERHEAD)
/* When "x" is from chunksize(). */
# define csize2tidx(x) (((x) - MINSIZE) / MALLOC_ALIGNMENT)
@@ -1011,9 +1025,12 @@ checked_request2size (size_t req)
if (__glibc_unlikely (req > PTRDIFF_MAX))
return SIZE_MAX;
return (req + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE
? MINSIZE
: (req + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK);
size_t rs = req + CHUNK2USER_OVERHEAD
+ MALLOC_ALIGN_MASK;
return (rs < MINSIZE
? MINSIZE
: (rs) & ~MALLOC_ALIGN_MASK);
}
/*
@@ -1115,7 +1132,7 @@ checked_request2size (size_t req)
/* This is the size of the real usable data in the chunk. Not valid for
dumped heap chunks. */
#define chunksize2usable(n) (n - CHUNK_HDR_SZ + SIZE_SZ)
#define chunksize2usable(n) (n - CHUNK2USER_OVERHEAD)
#define memsize(p) (chunksize2usable (chunksize (p)))
/* Huge page used for an mmap chunk. */
@@ -3453,7 +3470,7 @@ _int_malloc (mstate av, size_t bytes)
mchunkptr bck; /* misc temp for linking */
/*
Convert request size to internal form by adding SIZE_SZ bytes
Convert request size to internal form by adding chunk-to-user
overhead plus possibly more to obtain necessary alignment and/or
to obtain a size of at least MINSIZE, the smallest allocatable
size. Also, checked_request2size returns false for request sizes
+9 -2
View File
@@ -30,9 +30,16 @@ clear_memory (void *p, unsigned long clearsize)
if (nclears > 9)
return memset (d, 0, clearsize);
/* NB: The VRP pass in GCC 14.2 will optimize it out. */
/* NB: The VRP pass in GCC 14.2 will optimize it out for the default size
calculations. */
if (nclears < 3)
__builtin_unreachable ();
{
#ifdef MALLOC_USER_SIZE_ALIGNMENT
return memset (d, 0, clearsize);
#else
__builtin_unreachable ();
#endif
}
/* Use repeated stores with 1 branch, instead of up to 3. */
*(d + 0) = 0;