From a7f48838296b7eb3351e77eab5646bcfd20df96b Mon Sep 17 00:00:00 2001
From: zesstra <zesstra@zesstra.de>
Date: Thu, 21 May 2009 20:18:52 +0200
Subject: [PATCH 3/3] Removed amalloc/afree(), MALLOC_ALIGN and MEM_ALIGN.

If we replace the system malloc, we defined amalloc() to get aligned memory.
These function used MEM_ALIGN and MALLOC_ALIGN. Unfortunately it contained
an overflow (it reserved MALLOC_ALIGN-MEM_ALIGN, but wrote up to
MALLOC_ALIGN chars).
Additionally, it never worked. If using slaballoc/smalloc/sysmalloc,
MEM_ALIGN and MALLOC_ALIGN were always equal and in case of xptmalloc
MALLOC_ALIGN was always <= MEM_ALIGN. Therefore, amalloc never added
anything for alignment.
Furthermore, if malloc/amalloc() should use the same alignment as the system
allocator, our amalloc() was not sufficient.
We may re-introduce allocator functions for aligned memory if needed (the
driver does not), but then we should do it properly (and ensure to have the
same alignment as the system allocator).

Signed-off-by: zesstra <zesstra@zesstra.de>
---
 src/autoconf/configure.in |   10 ----
 src/slaballoc.c           |   42 +++++++++------
 src/smalloc.c             |   46 ++++++++++-------
 src/sysmalloc.c           |    1 -
 src/xalloc.c              |  124 ++++----------------------------------------
 src/xptmalloc.c           |    4 --
 6 files changed, 65 insertions(+), 162 deletions(-)

diff --git a/src/autoconf/configure.in b/src/autoconf/configure.in
index 0077d9a..cdd5540 100644
--- a/src/autoconf/configure.in
+++ b/src/autoconf/configure.in
@@ -817,16 +817,6 @@ AC_CHECK_FUNCS(fchmod getrusage bzero memset memcpy memmem strdup strcspn)
 AC_CHECK_FUNCS(strchr strrchr getcwd memmove sysconf gettimeofday wait3 waitpid)
 AC_CHECK_FUNCS(fcntl getdomainname poll strtoul trunc)
 
-
-AC_CACHE_CHECK(for needed malloc() alignment,lp_cv_sys_malloc_align,
-AC_TRY_COMPILE([struct ts {double d; char *p; double e;};
-int i = 96/(sizeof(struct ts)-20);
-],,
-lp_cv_sys_malloc_align=8,
-lp_cv_sys_malloc_align=4))
-AC_DEFINE_UNQUOTED(MALLOC_ALIGN,$lp_cv_sys_malloc_align,[word alignment])
-
-
 if test "x$ac_cv_type_signal" = "xvoid"; then
   AC_DEFINE(RETSIGTYPE_VOID, 1,                                                                                                                                                                                    
     [Set in response to the signal handler return type, since not all                                                                                                                                              
diff --git a/src/slaballoc.c b/src/slaballoc.c
index 07ad8f7..2725aef 100644
--- a/src/slaballoc.c
+++ b/src/slaballoc.c
@@ -110,12 +110,25 @@
  * A new AVL node is created for every free large block.
 #endif
  *
-#ifdef SBRK_OK && MALLOC_SBRK
+#ifdef MALLOC_SBRK && SBRK_OK
  * Memory is allocated from the system with sbrk() and brk(), which puts
  * the whole heap under our control.
  *
- * In this mode, several functions like amalloc() are compiled as malloc(),
- * implementing all libc memory functions.
+ * In this mode, we replace the system malloc() and free() by our own 
+ * functions, implementing all libc memory functions (malloc, free, calloc,
+ * realloc()).
+#else if MALLOC_SBRK && HAVE_MMAP
+ * If brk/sbrk() are non-functional (e.g. on Darwin; remember: they are legacy
+ * and not POSIX anymore), we check if mmap() is available. If it is, we use 
+ * it to map anonymous memory pages to get memory from the VM system.
+ *
+ * The allocated block (modulo joints) is tagged at both ends with fake
+ * "allocated" blocks of which cover the unallocated areas - large_malloc()
+ * will perceive this as a fragmented heap.
+ *
+ * In this mode, we replace the system malloc() and free() by our own 
+ * functions, implementing all libc memory functions (malloc, free, calloc,
+ * realloc()). 
 #else
  * malloc() is used to allocate a new block of memory. If this block borders
  * previous ones, the blocks are joined.
@@ -232,25 +245,19 @@
  */
 #define GRANULARITY sizeof(word_t)
 
-/* Defines required by the xalloc.c wrapper */
-#define MEM_ALIGN GRANULARITY
-
 /* If possible, request memory using sbrk(). But if using pthreads, do
  * not replace malloc() with our routines, even if the system allows it,
  * as slaballoc is not threadsafe.
+ * If sbrk/brk() are not working, but mmap() is, then use mmap() for getting
+ * memory. If that is also not available, use malloc().
  */
-
 #if defined(SBRK_OK)
 #  ifdef MALLOC_SBRK
-#      if MALLOC_ALIGN == 4
-#          define REPLACE_MALLOC
-#      else
-#          undef SBRK_OK
-#      endif
+#      define REPLACE_MALLOC
 #  else
 #      undef SBRK_OK
 #  endif
-#else if defined (HAVE_MMAP)
+#else if defined(HAVE_MMAP)
 #  ifdef MALLOC_SBRK
 #      define REPLACE_MALLOC
 #  endif
@@ -605,12 +612,15 @@ static unsigned long num_avl_nodes = 0;
 /*-------------------------------------------------------------------------*/
 /* Forward declarations */
 
-static char *esbrk(word_t, size_t * pExtra);
+static char *esbrk(word_t size, size_t * pExtra) __attribute__((malloc,warn_unused_result));
 
-static char *large_malloc(word_t, Bool);
+static char *large_malloc(word_t size, Bool force_m) __attribute__((malloc,warn_unused_result));
 #define large_malloc_int(size, force_m) large_malloc(size, force_m)
 static void large_free(char *);
 
+static INLINE size_t mem_overhead (void) __attribute__((const));
+
+
 #ifdef MALLOC_EXT_STATISTICS
 /*=========================================================================*/
 
@@ -726,7 +736,7 @@ mem_block_size (POINTER p)
 
     if (q[M_SIZE] & M_SMALL)
     {
-        return mem_block_total_size(p) - M_OVERHEAD*GRANULARITY;
+        return mem_block_total_size(p) - mem_overhead();
     }
     return mem_block_total_size(p) - ML_OVERHEAD*GRANULARITY;
 } /* mem_block_size() */
diff --git a/src/smalloc.c b/src/smalloc.c
index d9dfaed..e657e7c 100644
--- a/src/smalloc.c
+++ b/src/smalloc.c
@@ -112,20 +112,33 @@
  * A new AVL node is created for every free large block.
 #endif
  *
-#ifdef SBRK_OK && MALLOC_SBRK
+ #ifdef MALLOC_SBRK && SBRK_OK
  * Memory is allocated from the system with sbrk() and brk(), which puts
  * the whole heap under our control.
  *
- * In this mode, several functions like amalloc() are compiled as malloc(),
- * implementing all libc memory functions.
-#else
+ * In this mode, we replace the system malloc() and free() by our own 
+ * functions, implementing all libc memory functions (malloc, free, calloc,
+ * realloc()).
+ #else if MALLOC_SBRK && HAVE_MMAP
+ * If brk/sbrk() are non-functional (e.g. on Darwin; remember: they are legacy
+ * and not POSIX anymore), we check if mmap() is available. If it is, we use 
+ * it to map anonymous memory pages to get memory from the VM system.
+ *
+ * The allocated block (modulo joints) is tagged at both ends with fake
+ * "allocated" blocks of which cover the unallocated areas - large_malloc()
+ * will perceive this as a fragmented heap.
+ *
+ * In this mode, we replace the system malloc() and free() by our own 
+ * functions, implementing all libc memory functions (malloc, free, calloc,
+ * realloc()). 
+ #else
  * malloc() is used to allocate a new block of memory. If this block borders
  * previous ones, the blocks are joined.
  *
  * The allocated block (modulo joints) is tagged at both ends with fake
  * "allocated" blocks of which cover the unallocated areas - large_malloc()
  * will perceive this as a fragmented heap.
-#endif
+ #endif
  *
  *  -- Privilege Level --
  *
@@ -245,20 +258,13 @@
  */
 #define GRANULARITY sizeof(word_t)
 
-/* Defines required by the xalloc.c wrapper */
-
-#define MEM_ALIGN GRANULARITY
-
 /* If possible, request memory using sbrk().
+ * If sbrk/brk() are not working, but mmap() is, then use mmap() for getting
+ * memory. If that is also not available, use malloc().
  */
-
 #if defined(SBRK_OK)
 #  ifdef MALLOC_SBRK
-#      if MALLOC_ALIGN == 4
-#          define REPLACE_MALLOC
-#      else
-#          undef SBRK_OK
-#      endif
+#      define REPLACE_MALLOC
 #  else
 #      undef SBRK_OK
 #  endif
@@ -603,11 +609,13 @@ static long num_avl_nodes = 0;
 /*-------------------------------------------------------------------------*/
 /* Forward declarations */
 
-static char *esbrk(word_t, size_t * pExtra);
+static char *esbrk(word_t size, size_t * pExtra) __attribute__((malloc,warn_unused_result));
 
-static char *large_malloc(word_t, Bool);
+static char *large_malloc(word_t size, Bool force_m) __attribute__((malloc,warn_unused_result));
 #define large_malloc_int(size, force_m) large_malloc(size, force_m)
-static void large_free(char *);
+static void large_free(char *ptr);
+static INLINE size_t mem_overhead(void) __attribute__((const));
+
 
 #ifdef MALLOC_EXT_STATISTICS
 /*=========================================================================*/
@@ -695,7 +703,7 @@ mem_block_size (POINTER p)
     word_t size = (q[M_SIZE] & M_MASK);
     if (size > SMALL_BLOCK_MAX)
         return mem_block_total_size(p) - ML_OVERHEAD*GRANULARITY;
-    return mem_block_total_size(p) - M_OVERHEAD*GRANULARITY;
+    return mem_block_total_size(p) - mem_overhead();
 } /* mem_block_size() */
 
 /*-------------------------------------------------------------------------*/
diff --git a/src/sysmalloc.c b/src/sysmalloc.c
index 5e0b81a..49c59e1 100644
--- a/src/sysmalloc.c
+++ b/src/sysmalloc.c
@@ -17,7 +17,6 @@
 #include "../mudlib/sys/debug_info.h"
 
 /* Defines required by the xalloc.c wrapper */
-#define MEM_ALIGN (MALLOC_ALIGN)
 /* #undef REPLACE_MALLOC */
 #define NO_MEM_BLOCK_SIZE
 #define MEM_THREADSAFE
diff --git a/src/xalloc.c b/src/xalloc.c
index 0ae0784..a5c6b2c 100644
--- a/src/xalloc.c
+++ b/src/xalloc.c
@@ -113,8 +113,6 @@ enum xalloc_header_fields {
     XM_OVERHEAD_SIZE = XM_OVERHEAD * sizeof(word_t),
 };
 
-#define XM_OVERHEAD_SIZE (XM_OVERHEAD * sizeof(word_t))
-
 /*-------------------------------------------------------------------------*/
 
 /* -- Global Variables/Arguments dealing with memory -- */
@@ -323,8 +321,6 @@ mdb_log_sbrk (p_int size)
 #endif
 #endif
  *
- *   #define MEM_ALIGN
- *     the alignment guaranteed by the allocator
  *   #define REPLACE_MALLOC
  *     if the allocator's mem_alloc()/mem_free() can be used to replace the
  *     libc allocation routines (ie. the allocator doesn't use malloc()
@@ -1181,122 +1177,26 @@ dump_malloc_trace (int d
 #if defined(REPLACE_MALLOC) && (defined(SBRK_OK) || defined(HAVE_MMAP))
 
 /*-------------------------------------------------------------------------*/
-static POINTER
-amalloc (size_t size)
+POINTER
+malloc (size_t size)
 
-/* Allocate an aligned block of <size> bytes, if necessary, with
- * SYSTEM privilege. The block is not subject to GC.
- * Result is the pointer to the allocated block, or NULL.
+/* Allocate an empty memory block of size <sizel>.
+ * The memory is aligned and not subject to GC.
  */
 
 {
-    char *temp;
-    size_t orig_size UNUSED; // unused if no HAVE_MADVISE.
-    
-    if (MALLOC_ALIGN > MEM_ALIGN)
-    {
-        
-#if defined(HAVE_MADVISE)
-        orig_size = size;
-#endif
-        
-        size += (MALLOC_ALIGN-MEM_ALIGN);
-    }
-
-    temp = (char *)pxalloc(size);
-    if (!temp)
+    POINTER result = pxalloc(size);
+    if (!result)
     {
         int save_privilege = malloc_privilege;
         malloc_privilege = MALLOC_SYSTEM;
-        temp = (char *)pxalloc(size);
+        result = pxalloc(size);
         malloc_privilege = save_privilege;
     }
-
-    if (MALLOC_ALIGN > MEM_ALIGN) 
-    {
-        if (temp)
-        {
-            /* Set the first byte of the alignment area to 0xAF - afree(0
-             * is going to look for it - and the rest to 0.
-             */
-            *temp++ = 0xAF;
-            while ((p_int)temp & (MALLOC_ALIGN-1))
-                *temp++ = 0;
-            MADVISE(temp, orig_size);
-        }
-    }
-
-    return (POINTER)temp;
-} /* amalloc() */
-
-/*-------------------------------------------------------------------------*/
-static void
-afree (POINTER p)
-
-/* Free the aligned memory block <p>.
- */
-
-{
-    char *q = (char *)p;
-
-    if (!q)
-        return;
-
-    if (MALLOC_ALIGN > MEM_ALIGN)
-    {
-        
-        /* amalloc() filled the alignment area with 0s except for the first byte.
-         * Search backwards to find that marker and with it the real block begin.
-         */
-        while (!*--q) NOOP;
-    }
-
-    pfree(q);
-} /* afree() */
-
-/*-------------------------------------------------------------------------*/
-static INLINE long
-get_block_size (POINTER ptr)
-
-/* Get the allocated block size for the block with user area starting
- * at <ptr>. This function is meant only for block allocated with (a)malloc().
- * Result is the size in bytes inclusive overhead.
- */
-{
-    long size = 0;
-
-    if (ptr)
-    {
-        /* Get the allocated size of the block for the statistics */
-
-        char *q;
-
-        q = (char *)ptr;
-        
-        if (MALLOC_ALIGN > MEM_ALIGN)
-            while ( !(size = *--q) ) NOOP;
-
-        size = xalloced_size(q) + mem_overhead();
-    }
-
-    return size;
-} /* get_block_size() */
-
-/*-------------------------------------------------------------------------*/
-POINTER
-malloc (size_t size)
-
-/* Allocate an empty memory block of size <sizel>.
- * The memory is aligned and not subject to GC.
- */
-
-{
-    POINTER result;
-
-    result = amalloc(size);
+    
     if (result)
     {
-        count_up(&clib_alloc_stat, get_block_size(result));
+        count_up(&clib_alloc_stat, xalloced_size(result) + mem_overhead());
     }
 
     return result;
@@ -1312,10 +1212,10 @@ free (POINTER ptr)
 {
     if (ptr)
     {
-        count_back(&clib_alloc_stat, get_block_size(ptr));
+        count_back(&clib_alloc_stat, xalloced_size(ptr) + mem_overhead());
     }
 
-    afree(ptr);
+    pfree(ptr);
     FREE_RETURN
 } /* free() */
 
@@ -1354,7 +1254,7 @@ realloc (POINTER p, size_t size)
    if (!p)
         return malloc(size);
 
-   old_size = get_block_size(p) - xalloc_overhead();
+   old_size = xalloced_size(p) - xalloc_overhead();
 
    if (old_size >= size)
       return p;
diff --git a/src/xptmalloc.c b/src/xptmalloc.c
index d8fa66f..d467b11 100644
--- a/src/xptmalloc.c
+++ b/src/xptmalloc.c
@@ -232,10 +232,6 @@ static Bool mem_is_freed (POINTER p, size_t minsize) {
 
 #endif /* GC_SUPPORT */
 
-/*     the alignment guaranteed by the allocator */
-//#define MEM_ALIGN (2*(sizeof(size_t)))
-#define MEM_ALIGN (2*SIZEOF_INT)
-
 /* If the allocator can replace the libc allocation routines.
  * See above for the *BSD situation.
  */
-- 
1.6.1

