From f9126b62b6f62f5373a5e5cfff64fb2ff2b19cd1 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt Date: Tue, 10 Aug 2021 19:40:02 +0200 Subject: [PATCH] avutil/mem: Reinline av_size_mult() internally Since 580e168a945b65100ec2c25433f33bfacfe9f7be, av_size_mult() is no longer inlined; on systems where interposing is a thing, this also inhibits the compiler from inlining said function into the internal callers of said function, although inlining such a small function is typically beneficial: With GCC 10.3 on Ubuntu x64 and -O3 this decreases the size of av_realloc_array from 91B to 23B, from 129B to 81B for av_realloc_f and from 77B to 23B for each of av_malloc_array, av_mallocz_array and av_calloc. Signed-off-by: Andreas Rheinhardt --- libavutil/mem.c | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/libavutil/mem.c b/libavutil/mem.c index 0969749077..dcc75945d4 100644 --- a/libavutil/mem.c +++ b/libavutil/mem.c @@ -74,6 +74,24 @@ void av_max_alloc(size_t max){ atomic_store_explicit(&max_alloc_size, max, memory_order_relaxed); } +static int size_mult(size_t a, size_t b, size_t *r) +{ + size_t t; + +#if (!defined(__INTEL_COMPILER) && AV_GCC_VERSION_AT_LEAST(5,1)) || AV_HAS_BUILTIN(__builtin_mul_overflow) + if (__builtin_mul_overflow(a, b, &t)) + return AVERROR(EINVAL); +#else + t = a * b; + /* Hack inspired from glibc: don't try the division if nelem and elsize + * are both less than sqrt(SIZE_MAX). */ + if ((a | b) >= ((size_t)1 << (sizeof(size_t) * 4)) && a && t / a != b) + return AVERROR(EINVAL); +#endif + *r = t; + return 0; +} + void *av_malloc(size_t size) { void *ptr = NULL; @@ -154,7 +172,7 @@ void *av_realloc_f(void *ptr, size_t nelem, size_t elsize) size_t size; void *r; - if (av_size_mult(elsize, nelem, &size)) { + if (size_mult(elsize, nelem, &size)) { av_free(ptr); return NULL; } @@ -188,7 +206,7 @@ int av_reallocp(void *ptr, size_t size) void *av_malloc_array(size_t nmemb, size_t size) { size_t result; - if (av_size_mult(nmemb, size, &result) < 0) + if (size_mult(nmemb, size, &result) < 0) return NULL; return av_malloc(result); } @@ -196,7 +214,7 @@ void *av_malloc_array(size_t nmemb, size_t size) void *av_mallocz_array(size_t nmemb, size_t size) { size_t result; - if (av_size_mult(nmemb, size, &result) < 0) + if (size_mult(nmemb, size, &result) < 0) return NULL; return av_mallocz(result); } @@ -204,7 +222,7 @@ void *av_mallocz_array(size_t nmemb, size_t size) void *av_realloc_array(void *ptr, size_t nmemb, size_t size) { size_t result; - if (av_size_mult(nmemb, size, &result) < 0) + if (size_mult(nmemb, size, &result) < 0) return NULL; return av_realloc(ptr, result); } @@ -251,7 +269,7 @@ void *av_mallocz(size_t size) void *av_calloc(size_t nmemb, size_t size) { size_t result; - if (av_size_mult(nmemb, size, &result) < 0) + if (size_mult(nmemb, size, &result) < 0) return NULL; return av_mallocz(result); } @@ -549,18 +567,5 @@ void av_fast_mallocz(void *ptr, unsigned int *size, size_t min_size) int av_size_mult(size_t a, size_t b, size_t *r) { - size_t t; - -#if (!defined(__INTEL_COMPILER) && AV_GCC_VERSION_AT_LEAST(5,1)) || AV_HAS_BUILTIN(__builtin_mul_overflow) - if (__builtin_mul_overflow(a, b, &t)) - return AVERROR(EINVAL); -#else - t = a * b; - /* Hack inspired from glibc: don't try the division if nelem and elsize - * are both less than sqrt(SIZE_MAX). */ - if ((a | b) >= ((size_t)1 << (sizeof(size_t) * 4)) && a && t / a != b) - return AVERROR(EINVAL); -#endif - *r = t; - return 0; + return size_mult(a, b, r); }