reintroduce calloc elison of memset for direct-mmapped allocations
authorRich Felker <dalias@aerifal.cx>
Thu, 11 Jun 2020 00:44:51 +0000 (20:44 -0400)
committerRich Felker <dalias@aerifal.cx>
Thu, 11 Jun 2020 00:51:17 +0000 (20:51 -0400)
a new weak predicate function replacable by the malloc implementation,
__malloc_allzerop, is introduced. by default it's always false; the
default version will be used when static linking if the bump allocator
was used (in which case performance doesn't matter) or if malloc was
replaced by the application. only if the real internal malloc is
linked (always the case with dynamic linking) does the real version
get used.

if malloc was replaced dynamically, as indicated by __malloc_replaced,
the predicate function is ignored and conditional-memset is always
performed.

src/internal/dynlink.h
src/malloc/calloc.c
src/malloc/oldmalloc/malloc.c

index b739add2f3fee0cee149fc0f61b61dffc0e22f90..78baa0804d4ebe2bf5520e796089722bd4627c3f 100644 (file)
@@ -107,5 +107,6 @@ hidden ptrdiff_t __tlsdesc_static(), __tlsdesc_dynamic();
 
 hidden extern int __malloc_replaced;
 hidden void __malloc_donate(char *, char *);
 
 hidden extern int __malloc_replaced;
 hidden void __malloc_donate(char *, char *);
+hidden int __malloc_allzerop(void *);
 
 #endif
 
 #endif
index 322193ca868b8e8ed76f7b3d17c431e762a3ac3b..bf6bddca3fd81aca3b246391e34ea9afbc95ed3e 100644 (file)
@@ -2,6 +2,7 @@
 #include <stdint.h>
 #include <string.h>
 #include <errno.h>
 #include <stdint.h>
 #include <string.h>
 #include <errno.h>
+#include "dynlink.h"
 
 static size_t mal0_clear(char *p, size_t n)
 {
 
 static size_t mal0_clear(char *p, size_t n)
 {
@@ -23,6 +24,12 @@ static size_t mal0_clear(char *p, size_t n)
        }
 }
 
        }
 }
 
+static int allzerop(void *p)
+{
+       return 0;
+}
+weak_alias(allzerop, __malloc_allzerop);
+
 void *calloc(size_t m, size_t n)
 {
        if (n && m > (size_t)-1/n) {
 void *calloc(size_t m, size_t n)
 {
        if (n && m > (size_t)-1/n) {
@@ -31,7 +38,8 @@ void *calloc(size_t m, size_t n)
        }
        n *= m;
        void *p = malloc(n);
        }
        n *= m;
        void *p = malloc(n);
-       if (!p) return p;
+       if (!p || (!__malloc_replaced && __malloc_allzerop(p)))
+               return p;
        n = mal0_clear(p, n);
        return memset(p, 0, n);
 }
        n = mal0_clear(p, n);
        return memset(p, 0, n);
 }
index 1c6b07eca2d4a31bb17b0f67dd12045075c42b3d..0a38690c628a584a2820f268bb49fa33afc8a61f 100644 (file)
@@ -339,6 +339,11 @@ void *malloc(size_t n)
        return CHUNK_TO_MEM(c);
 }
 
        return CHUNK_TO_MEM(c);
 }
 
+int __malloc_allzerop(void *p)
+{
+       return IS_MMAPPED(MEM_TO_CHUNK(p));
+}
+
 void *realloc(void *p, size_t n)
 {
        struct chunk *self, *next;
 void *realloc(void *p, size_t n)
 {
        struct chunk *self, *next;