Commit f701dc2a authored by Paul Eggert's avatar Paul Eggert
Browse files

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.
parent cbc5ee22
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
......
......@@ -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',
......
......@@ -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);
......
......@@ -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 *);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment