diff options
author | Andreas Rheinhardt <andreas.rheinhardt@outlook.com> | 2021-08-10 19:40:02 +0200 |
---|---|---|
committer | Andreas Rheinhardt <andreas.rheinhardt@outlook.com> | 2021-08-12 15:25:58 +0200 |
commit | f9126b62b6f62f5373a5e5cfff64fb2ff2b19cd1 (patch) | |
tree | daca5b6c02ceda6c0be23ad34d70b2d1b767e141 | |
parent | 26aa844a214388b775839cc1ae06c97e695b464a (diff) | |
download | ffmpeg-f9126b62b6f62f5373a5e5cfff64fb2ff2b19cd1.tar.gz |
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 <andreas.rheinhardt@outlook.com>
-rw-r--r-- | libavutil/mem.c | 43 |
1 files 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); } |