Remove dependency on glibc malloc internals.
authorPaul Eggert <eggert@cs.ucla.edu>
Fri, 30 Sep 2011 17:07:40 +0000 (10:07 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Fri, 30 Sep 2011 17:07:40 +0000 (10:07 -0700)
* alloc.c (XMALLOC_OVERRUN_CHECK_OVERHEAD, XMALLOC_OVERRUN_CHECK_SIZE):
Move back here from lisp.h, but with their new implementations.
(XMALLOC_BASE_ALIGNMENT, COMMON_MULTIPLE, XMALLOC_HEADER_ALIGNMENT)
(XMALLOC_OVERRUN_SIZE_SIZE): Move these new lisp.h macros here.
* charset.c (charset_table_init): New static var.
(syms_of_charset): Use it instead of xmalloc.  This removes a
dependency on glibc malloc internals.  See Eli Zaretskii's comment in
<http://lists.gnu.org/archive/html/emacs-devel/2011-09/msg00815.html>.
* lisp.h (XMALLOC_OVERRUN_CHECK_OVERHEAD, XMALLOC_OVERRUN_CHECK_SIZE):
Move back to alloc.c.
(XMALLOC_BASE_ALIGNMENT, COMMON_MULTIPLE, XMALLOC_HEADER_ALIGNMENT)
(XMALLOC_OVERRUN_SIZE_SIZE): Move to alloc.c.

src/ChangeLog
src/alloc.c
src/charset.c
src/lisp.h

index 37d2de9..89e705e 100644 (file)
@@ -1,3 +1,19 @@
+2011-09-30  Paul Eggert  <eggert@cs.ucla.edu>
+
+       Remove dependency on glibc malloc internals.
+       * alloc.c (XMALLOC_OVERRUN_CHECK_OVERHEAD, XMALLOC_OVERRUN_CHECK_SIZE):
+       Move back here from lisp.h, but with their new implementations.
+       (XMALLOC_BASE_ALIGNMENT, COMMON_MULTIPLE, XMALLOC_HEADER_ALIGNMENT)
+       (XMALLOC_OVERRUN_SIZE_SIZE): Move these new lisp.h macros here.
+       * charset.c (charset_table_init): New static var.
+       (syms_of_charset): Use it instead of xmalloc.  This removes a
+       dependency on glibc malloc internals.  See Eli Zaretskii's comment in
+       <http://lists.gnu.org/archive/html/emacs-devel/2011-09/msg00815.html>.
+       * lisp.h (XMALLOC_OVERRUN_CHECK_OVERHEAD, XMALLOC_OVERRUN_CHECK_SIZE):
+       Move back to alloc.c.
+       (XMALLOC_BASE_ALIGNMENT, COMMON_MULTIPLE, XMALLOC_HEADER_ALIGNMENT)
+       (XMALLOC_OVERRUN_SIZE_SIZE): Move to alloc.c.
+
 2011-09-30  Jan Djärv  <jan.h.d@swipnet.se>
 
        * nsterm.m (windowDidResize): Call x_set_window_size only when
index 4c5094b..ead5c8a 100644 (file)
@@ -482,10 +482,53 @@ buffer_memory_full (EMACS_INT nbytes)
   xsignal (Qnil, Vmemory_signal_data);
 }
 
-#ifdef XMALLOC_OVERRUN_CHECK
+
+#ifndef XMALLOC_OVERRUN_CHECK
+#define XMALLOC_OVERRUN_CHECK_OVERHEAD 0
+#else
 
 /* Check for overrun in malloc'ed buffers by wrapping a header and trailer
-   around each block.  */
+   around each block.
+
+   The header consists of XMALLOC_OVERRUN_CHECK_SIZE fixed bytes
+   followed by XMALLOC_OVERRUN_SIZE_SIZE bytes containing the original
+   block size in little-endian order.  The trailer consists of
+   XMALLOC_OVERRUN_CHECK_SIZE fixed bytes.
+
+   The header is used to detect whether this block has been allocated
+   through these functions, as some low-level libc functions may
+   bypass the malloc hooks.  */
+
+#define XMALLOC_OVERRUN_CHECK_SIZE 16
+#define XMALLOC_OVERRUN_CHECK_OVERHEAD \
+  (2 * XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE)
+
+/* Define XMALLOC_OVERRUN_SIZE_SIZE so that (1) it's large enough to
+   hold a size_t value and (2) the header size is a multiple of the
+   alignment that Emacs needs for C types and for USE_LSB_TAG.  */
+#define XMALLOC_BASE_ALIGNMENT                         \
+  offsetof (                                           \
+    struct {                                           \
+      union { long double d; intmax_t i; void *p; } u; \
+      char c;                                          \
+    },                                                 \
+    c)
+#ifdef USE_LSB_TAG
+/* A common multiple of the positive integers A and B.  Ideally this
+   would be the least common multiple, but there's no way to do that
+   as a constant expression in C, so do the best that we can easily do.  */
+# define COMMON_MULTIPLE(a, b) \
+    ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b))
+# define XMALLOC_HEADER_ALIGNMENT \
+    COMMON_MULTIPLE (1 << GCTYPEBITS, XMALLOC_BASE_ALIGNMENT)
+#else
+# define XMALLOC_HEADER_ALIGNMENT XMALLOC_BASE_ALIGNMENT
+#endif
+#define XMALLOC_OVERRUN_SIZE_SIZE                              \
+   (((XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t)             \
+      + XMALLOC_HEADER_ALIGNMENT - 1)                          \
+     / XMALLOC_HEADER_ALIGNMENT * XMALLOC_HEADER_ALIGNMENT)    \
+    - XMALLOC_OVERRUN_CHECK_SIZE)
 
 static char const xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE] =
   { '\x9a', '\x9b', '\xae', '\xaf',
index f1b4897..8d6a398 100644 (file)
@@ -1162,10 +1162,10 @@ usage: (define-charset-internal ...)  */)
                     sizeof *charset_table);
          memcpy (new_table, charset_table, old_size * sizeof *new_table);
          charset_table = new_table;
-         /* FIXME: Doesn't this leak memory?  The old charset_table becomes
-            unreachable.  It could be that this is intentional, because the
-            old charset table may be in a dumped emacs, and reallocating such
-            a table may not work.  If the memory leak is intentional, a
+         /* FIXME: This leaks memory, as the old charset_table becomes
+            unreachable.  If the old charset table is charset_table_init
+            then this leak is intentional; otherwise, it's unclear.
+            If the latter memory leak is intentional, a
             comment should be added to explain this.  If not, the old
             charset_table should be freed, by passing it as the 1st argument
             to xpalloc and removing the memcpy.  */
@@ -2327,22 +2327,21 @@ init_charset_once (void)
 
 #ifdef emacs
 
+/* Allocate an initial charset table that is large enough to handle
+   Emacs while it is bootstrapping.  As of September 2011, the size
+   needs to be at least 166; make it a bit bigger to allow for future
+   expansion.
+
+   Don't make the value so small that the table is reallocated during
+   bootstrapping, as glibc malloc calls larger than just under 64 KiB
+   during an initial bootstrap wreak havoc after dumping; see the
+   M_MMAP_THRESHOLD value in alloc.c, plus there is a extra overhead
+   internal to glibc malloc and perhaps to Emacs malloc debugging.  */
+static struct charset charset_table_init[180];
+
 void
 syms_of_charset (void)
 {
-  /* Allocate an initial charset table that is just under 64 KiB in size.
-     This should be large enough so that the charset table need not be
-     reallocated during an initial bootstrap.  Allocating anything larger than
-     64 KiB in an initial run may not work, because glibc malloc might use
-     mmap for larger allocations, and these don't work well across dumped
-     systems.  */
-  enum {
-    glibc_malloc_overhead = 3 * sizeof (size_t) - 1,
-    initial_malloc_max =
-      (1 << 16) - 1 - glibc_malloc_overhead - XMALLOC_OVERRUN_CHECK_OVERHEAD,
-    charset_table_size_init = initial_malloc_max / sizeof (struct charset)
-  };
-
   DEFSYM (Qcharsetp, "charsetp");
 
   DEFSYM (Qascii, "ascii");
@@ -2375,9 +2374,8 @@ syms_of_charset (void)
     Vcharset_hash_table = Fmake_hash_table (2, args);
   }
 
-  charset_table = (struct charset *) xmalloc (sizeof (struct charset)
-                                             * charset_table_size_init);
-  charset_table_size = charset_table_size_init;
+  charset_table = charset_table_init;
+  charset_table_size = sizeof charset_table_init / sizeof *charset_table_init;
   charset_table_used = 0;
 
   defsubr (&Scharsetp);
index 7aba299..e9a525a 100644 (file)
@@ -3568,54 +3568,6 @@ extern int initialized;
 
 extern int immediate_quit;         /* Nonzero means ^G can quit instantly */
 
-/* Overhead for overrun check in malloc'ed buffers.  The check
-   operates by wrapping a header and trailer around each block.
-
-   The header consists of XMALLOC_OVERRUN_CHECK_SIZE fixed bytes
-   followed by XMALLOC_OVERRUN_SIZE_SIZE bytes containing the original
-   block size in little-endian order.  The trailer consists of
-   XMALLOC_OVERRUN_CHECK_SIZE fixed bytes.
-
-   The header is used to detect whether this block has been allocated
-   through these functions, as some low-level libc functions may
-   bypass the malloc hooks.  */
-
-#ifndef XMALLOC_OVERRUN_CHECK
-# define XMALLOC_OVERRUN_CHECK_OVERHEAD 0
-#else
-
-# define XMALLOC_OVERRUN_CHECK_SIZE 16
-# define XMALLOC_OVERRUN_CHECK_OVERHEAD \
-   (2 * XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE)
-
-/* Define XMALLOC_OVERRUN_SIZE_SIZE so that (1) it's large enough to
-   hold a size_t value and (2) the header size is a multiple of the
-   alignment that Emacs needs for C types and for USE_LSB_TAG.  */
-# define XMALLOC_BASE_ALIGNMENT                                \
-   offsetof (                                          \
-     struct {                                          \
-       union { long double d; intmax_t i; void *p; } u;        \
-       char c;                                         \
-     },                                                        \
-     c)
-# ifdef USE_LSB_TAG
-/* A common multiple of the positive integers A and B.  Ideally this
-   would be the least common multiple, but there's no way to do that
-   as a constant expression in C, so do the best that we can easily do.  */
-#  define COMMON_MULTIPLE(a, b) \
-     ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b))
-#  define XMALLOC_HEADER_ALIGNMENT \
-     COMMON_MULTIPLE (1 << GCTYPEBITS, XMALLOC_BASE_ALIGNMENT)
-# else
-#  define XMALLOC_HEADER_ALIGNMENT XMALLOC_BASE_ALIGNMENT
-# endif
-# define XMALLOC_OVERRUN_SIZE_SIZE                             \
-   (((XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t)             \
-      + XMALLOC_HEADER_ALIGNMENT - 1)                          \
-     / XMALLOC_HEADER_ALIGNMENT * XMALLOC_HEADER_ALIGNMENT)    \
-    - XMALLOC_OVERRUN_CHECK_SIZE)
-#endif
-
 extern POINTER_TYPE *xmalloc (size_t);
 extern POINTER_TYPE *xrealloc (POINTER_TYPE *, size_t);
 extern void xfree (POINTER_TYPE *);