[FFmpeg-devel] [PATCH 1/3] avutil/mem: Fix *realloc() alignment with memalign hack

Michael Niedermayer michael at niedermayer.cc
Mon Nov 21 17:18:56 EET 2016


Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>
---
 libavutil/mem.c | 44 ++++++++++++++++++++++++++++++++------------
 1 file changed, 32 insertions(+), 12 deletions(-)

diff --git a/libavutil/mem.c b/libavutil/mem.c
index 1a8fc21..6273d89 100644
--- a/libavutil/mem.c
+++ b/libavutil/mem.c
@@ -86,12 +86,15 @@ void *av_malloc(size_t size)
         return NULL;
 
 #if CONFIG_MEMALIGN_HACK
-    ptr = malloc(size + ALIGN);
+    ptr = malloc(size + ALIGN + 8);
     if (!ptr)
         return ptr;
-    diff              = ((~(long)ptr)&(ALIGN - 1)) + 1;
+
+    diff = ((((uintptr_t)ptr) + 9 + ALIGN - 1) & ~(ALIGN - 1)) - (uintptr_t)ptr;
+    av_assert0(diff>0 && diff<=ALIGN + 8);
     ptr               = (char *)ptr + diff;
-    ((char *)ptr)[-1] = diff;
+    ((char *)ptr)[-9] = diff;
+    ((int64_t *)ptr)[-1] = size;
 #elif HAVE_POSIX_MEMALIGN
     if (size) //OS X on SDK 10.6 has a broken posix_memalign implementation
     if (posix_memalign(&ptr, ALIGN, size))
@@ -146,6 +149,7 @@ void *av_realloc(void *ptr, size_t size)
 {
 #if CONFIG_MEMALIGN_HACK
     int diff;
+    void *ptr2;
 #endif
 
     /* let's disallow possibly ambiguous cases */
@@ -153,15 +157,31 @@ void *av_realloc(void *ptr, size_t size)
         return NULL;
 
 #if CONFIG_MEMALIGN_HACK
-    //FIXME this isn't aligned correctly, though it probably isn't needed
     if (!ptr)
         return av_malloc(size);
-    diff = ((char *)ptr)[-1];
-    av_assert0(diff>0 && diff<=ALIGN);
-    ptr = realloc((char *)ptr - diff, size + diff);
-    if (ptr)
-        ptr = (char *)ptr + diff;
-    return ptr;
+    diff = ((char *)ptr)[-9];
+    av_assert0(diff>0 && diff<=ALIGN + 8);
+
+    // Quick path for apparently and likly aligned realloc()
+    if (diff == ALIGN) {
+        ptr = realloc((char *)ptr - diff, size + diff);
+        if (ptr)
+            ptr = (char *)ptr + diff;
+        if (!(((uintptr_t)ptr) & (ALIGN - 1))) {
+            if (ptr)
+                ((int64_t *)ptr)[-1] = size;
+            return ptr;
+        }
+    }
+
+    ptr2 = av_malloc(size);
+    if (!ptr2)
+        return NULL;
+
+    memcpy(ptr2, ptr, FFMIN(((int64_t *)ptr)[-1], size));
+    ((int64_t *)ptr2)[-1] = size;
+    av_free(ptr);
+    return ptr2;
 #elif HAVE_ALIGNED_MALLOC
     return _aligned_realloc(ptr, size + !size, ALIGN);
 #else
@@ -229,8 +249,8 @@ void av_free(void *ptr)
 {
 #if CONFIG_MEMALIGN_HACK
     if (ptr) {
-        int v= ((char *)ptr)[-1];
-        av_assert0(v>0 && v<=ALIGN);
+        int v= ((char *)ptr)[-9];
+        av_assert0(v>0 && v<=ALIGN + 8);
         free((char *)ptr - v);
     }
 #elif HAVE_ALIGNED_MALLOC
-- 
2.10.2



More information about the ffmpeg-devel mailing list