diff options
| author | Paul Eggert | 2011-09-30 10:07:40 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-09-30 10:07:40 -0700 |
| commit | f701dc2abbcfb64c0c4d02ac899dccb03ee2b246 (patch) | |
| tree | 6d2cfa91e42aeaa89763a4c938fe7347431d5cca | |
| parent | cbc5ee224e558a2ee11c7abab293b2f2084852cd (diff) | |
| download | emacs-f701dc2abbcfb64c0c4d02ac899dccb03ee2b246.tar.gz emacs-f701dc2abbcfb64c0c4d02ac899dccb03ee2b246.zip | |
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.
| -rw-r--r-- | src/ChangeLog | 16 | ||||
| -rw-r--r-- | src/alloc.c | 47 | ||||
| -rw-r--r-- | src/charset.c | 38 | ||||
| -rw-r--r-- | src/lisp.h | 48 |
4 files changed, 79 insertions, 70 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 37d2de93c11..89e705efd73 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,19 @@ | |||
| 1 | 2011-09-30 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Remove dependency on glibc malloc internals. | ||
| 4 | * alloc.c (XMALLOC_OVERRUN_CHECK_OVERHEAD, XMALLOC_OVERRUN_CHECK_SIZE): | ||
| 5 | Move back here from lisp.h, but with their new implementations. | ||
| 6 | (XMALLOC_BASE_ALIGNMENT, COMMON_MULTIPLE, XMALLOC_HEADER_ALIGNMENT) | ||
| 7 | (XMALLOC_OVERRUN_SIZE_SIZE): Move these new lisp.h macros here. | ||
| 8 | * charset.c (charset_table_init): New static var. | ||
| 9 | (syms_of_charset): Use it instead of xmalloc. This removes a | ||
| 10 | dependency on glibc malloc internals. See Eli Zaretskii's comment in | ||
| 11 | <http://lists.gnu.org/archive/html/emacs-devel/2011-09/msg00815.html>. | ||
| 12 | * lisp.h (XMALLOC_OVERRUN_CHECK_OVERHEAD, XMALLOC_OVERRUN_CHECK_SIZE): | ||
| 13 | Move back to alloc.c. | ||
| 14 | (XMALLOC_BASE_ALIGNMENT, COMMON_MULTIPLE, XMALLOC_HEADER_ALIGNMENT) | ||
| 15 | (XMALLOC_OVERRUN_SIZE_SIZE): Move to alloc.c. | ||
| 16 | |||
| 1 | 2011-09-30 Jan Djärv <jan.h.d@swipnet.se> | 17 | 2011-09-30 Jan Djärv <jan.h.d@swipnet.se> |
| 2 | 18 | ||
| 3 | * nsterm.m (windowDidResize): Call x_set_window_size only when | 19 | * nsterm.m (windowDidResize): Call x_set_window_size only when |
diff --git a/src/alloc.c b/src/alloc.c index 4c5094b8f48..ead5c8a8ca4 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -482,10 +482,53 @@ buffer_memory_full (EMACS_INT nbytes) | |||
| 482 | xsignal (Qnil, Vmemory_signal_data); | 482 | xsignal (Qnil, Vmemory_signal_data); |
| 483 | } | 483 | } |
| 484 | 484 | ||
| 485 | #ifdef XMALLOC_OVERRUN_CHECK | 485 | |
| 486 | #ifndef XMALLOC_OVERRUN_CHECK | ||
| 487 | #define XMALLOC_OVERRUN_CHECK_OVERHEAD 0 | ||
| 488 | #else | ||
| 486 | 489 | ||
| 487 | /* Check for overrun in malloc'ed buffers by wrapping a header and trailer | 490 | /* Check for overrun in malloc'ed buffers by wrapping a header and trailer |
| 488 | around each block. */ | 491 | around each block. |
| 492 | |||
| 493 | The header consists of XMALLOC_OVERRUN_CHECK_SIZE fixed bytes | ||
| 494 | followed by XMALLOC_OVERRUN_SIZE_SIZE bytes containing the original | ||
| 495 | block size in little-endian order. The trailer consists of | ||
| 496 | XMALLOC_OVERRUN_CHECK_SIZE fixed bytes. | ||
| 497 | |||
| 498 | The header is used to detect whether this block has been allocated | ||
| 499 | through these functions, as some low-level libc functions may | ||
| 500 | bypass the malloc hooks. */ | ||
| 501 | |||
| 502 | #define XMALLOC_OVERRUN_CHECK_SIZE 16 | ||
| 503 | #define XMALLOC_OVERRUN_CHECK_OVERHEAD \ | ||
| 504 | (2 * XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE) | ||
| 505 | |||
| 506 | /* Define XMALLOC_OVERRUN_SIZE_SIZE so that (1) it's large enough to | ||
| 507 | hold a size_t value and (2) the header size is a multiple of the | ||
| 508 | alignment that Emacs needs for C types and for USE_LSB_TAG. */ | ||
| 509 | #define XMALLOC_BASE_ALIGNMENT \ | ||
| 510 | offsetof ( \ | ||
| 511 | struct { \ | ||
| 512 | union { long double d; intmax_t i; void *p; } u; \ | ||
| 513 | char c; \ | ||
| 514 | }, \ | ||
| 515 | c) | ||
| 516 | #ifdef USE_LSB_TAG | ||
| 517 | /* A common multiple of the positive integers A and B. Ideally this | ||
| 518 | would be the least common multiple, but there's no way to do that | ||
| 519 | as a constant expression in C, so do the best that we can easily do. */ | ||
| 520 | # define COMMON_MULTIPLE(a, b) \ | ||
| 521 | ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b)) | ||
| 522 | # define XMALLOC_HEADER_ALIGNMENT \ | ||
| 523 | COMMON_MULTIPLE (1 << GCTYPEBITS, XMALLOC_BASE_ALIGNMENT) | ||
| 524 | #else | ||
| 525 | # define XMALLOC_HEADER_ALIGNMENT XMALLOC_BASE_ALIGNMENT | ||
| 526 | #endif | ||
| 527 | #define XMALLOC_OVERRUN_SIZE_SIZE \ | ||
| 528 | (((XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t) \ | ||
| 529 | + XMALLOC_HEADER_ALIGNMENT - 1) \ | ||
| 530 | / XMALLOC_HEADER_ALIGNMENT * XMALLOC_HEADER_ALIGNMENT) \ | ||
| 531 | - XMALLOC_OVERRUN_CHECK_SIZE) | ||
| 489 | 532 | ||
| 490 | static char const xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE] = | 533 | static char const xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE] = |
| 491 | { '\x9a', '\x9b', '\xae', '\xaf', | 534 | { '\x9a', '\x9b', '\xae', '\xaf', |
diff --git a/src/charset.c b/src/charset.c index f1b4897ffe6..8d6a3982d14 100644 --- a/src/charset.c +++ b/src/charset.c | |||
| @@ -1162,10 +1162,10 @@ usage: (define-charset-internal ...) */) | |||
| 1162 | sizeof *charset_table); | 1162 | sizeof *charset_table); |
| 1163 | memcpy (new_table, charset_table, old_size * sizeof *new_table); | 1163 | memcpy (new_table, charset_table, old_size * sizeof *new_table); |
| 1164 | charset_table = new_table; | 1164 | charset_table = new_table; |
| 1165 | /* FIXME: Doesn't this leak memory? The old charset_table becomes | 1165 | /* FIXME: This leaks memory, as the old charset_table becomes |
| 1166 | unreachable. It could be that this is intentional, because the | 1166 | unreachable. If the old charset table is charset_table_init |
| 1167 | old charset table may be in a dumped emacs, and reallocating such | 1167 | then this leak is intentional; otherwise, it's unclear. |
| 1168 | a table may not work. If the memory leak is intentional, a | 1168 | If the latter memory leak is intentional, a |
| 1169 | comment should be added to explain this. If not, the old | 1169 | comment should be added to explain this. If not, the old |
| 1170 | charset_table should be freed, by passing it as the 1st argument | 1170 | charset_table should be freed, by passing it as the 1st argument |
| 1171 | to xpalloc and removing the memcpy. */ | 1171 | to xpalloc and removing the memcpy. */ |
| @@ -2327,22 +2327,21 @@ init_charset_once (void) | |||
| 2327 | 2327 | ||
| 2328 | #ifdef emacs | 2328 | #ifdef emacs |
| 2329 | 2329 | ||
| 2330 | /* Allocate an initial charset table that is large enough to handle | ||
| 2331 | Emacs while it is bootstrapping. As of September 2011, the size | ||
| 2332 | needs to be at least 166; make it a bit bigger to allow for future | ||
| 2333 | expansion. | ||
| 2334 | |||
| 2335 | Don't make the value so small that the table is reallocated during | ||
| 2336 | bootstrapping, as glibc malloc calls larger than just under 64 KiB | ||
| 2337 | during an initial bootstrap wreak havoc after dumping; see the | ||
| 2338 | M_MMAP_THRESHOLD value in alloc.c, plus there is a extra overhead | ||
| 2339 | internal to glibc malloc and perhaps to Emacs malloc debugging. */ | ||
| 2340 | static struct charset charset_table_init[180]; | ||
| 2341 | |||
| 2330 | void | 2342 | void |
| 2331 | syms_of_charset (void) | 2343 | syms_of_charset (void) |
| 2332 | { | 2344 | { |
| 2333 | /* Allocate an initial charset table that is just under 64 KiB in size. | ||
| 2334 | This should be large enough so that the charset table need not be | ||
| 2335 | reallocated during an initial bootstrap. Allocating anything larger than | ||
| 2336 | 64 KiB in an initial run may not work, because glibc malloc might use | ||
| 2337 | mmap for larger allocations, and these don't work well across dumped | ||
| 2338 | systems. */ | ||
| 2339 | enum { | ||
| 2340 | glibc_malloc_overhead = 3 * sizeof (size_t) - 1, | ||
| 2341 | initial_malloc_max = | ||
| 2342 | (1 << 16) - 1 - glibc_malloc_overhead - XMALLOC_OVERRUN_CHECK_OVERHEAD, | ||
| 2343 | charset_table_size_init = initial_malloc_max / sizeof (struct charset) | ||
| 2344 | }; | ||
| 2345 | |||
| 2346 | DEFSYM (Qcharsetp, "charsetp"); | 2345 | DEFSYM (Qcharsetp, "charsetp"); |
| 2347 | 2346 | ||
| 2348 | DEFSYM (Qascii, "ascii"); | 2347 | DEFSYM (Qascii, "ascii"); |
| @@ -2375,9 +2374,8 @@ syms_of_charset (void) | |||
| 2375 | Vcharset_hash_table = Fmake_hash_table (2, args); | 2374 | Vcharset_hash_table = Fmake_hash_table (2, args); |
| 2376 | } | 2375 | } |
| 2377 | 2376 | ||
| 2378 | charset_table = (struct charset *) xmalloc (sizeof (struct charset) | 2377 | charset_table = charset_table_init; |
| 2379 | * charset_table_size_init); | 2378 | charset_table_size = sizeof charset_table_init / sizeof *charset_table_init; |
| 2380 | charset_table_size = charset_table_size_init; | ||
| 2381 | charset_table_used = 0; | 2379 | charset_table_used = 0; |
| 2382 | 2380 | ||
| 2383 | defsubr (&Scharsetp); | 2381 | defsubr (&Scharsetp); |
diff --git a/src/lisp.h b/src/lisp.h index 7aba299f162..e9a525a32b5 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -3568,54 +3568,6 @@ extern int initialized; | |||
| 3568 | 3568 | ||
| 3569 | extern int immediate_quit; /* Nonzero means ^G can quit instantly */ | 3569 | extern int immediate_quit; /* Nonzero means ^G can quit instantly */ |
| 3570 | 3570 | ||
| 3571 | /* Overhead for overrun check in malloc'ed buffers. The check | ||
| 3572 | operates by wrapping a header and trailer around each block. | ||
| 3573 | |||
| 3574 | The header consists of XMALLOC_OVERRUN_CHECK_SIZE fixed bytes | ||
| 3575 | followed by XMALLOC_OVERRUN_SIZE_SIZE bytes containing the original | ||
| 3576 | block size in little-endian order. The trailer consists of | ||
| 3577 | XMALLOC_OVERRUN_CHECK_SIZE fixed bytes. | ||
| 3578 | |||
| 3579 | The header is used to detect whether this block has been allocated | ||
| 3580 | through these functions, as some low-level libc functions may | ||
| 3581 | bypass the malloc hooks. */ | ||
| 3582 | |||
| 3583 | #ifndef XMALLOC_OVERRUN_CHECK | ||
| 3584 | # define XMALLOC_OVERRUN_CHECK_OVERHEAD 0 | ||
| 3585 | #else | ||
| 3586 | |||
| 3587 | # define XMALLOC_OVERRUN_CHECK_SIZE 16 | ||
| 3588 | # define XMALLOC_OVERRUN_CHECK_OVERHEAD \ | ||
| 3589 | (2 * XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE) | ||
| 3590 | |||
| 3591 | /* Define XMALLOC_OVERRUN_SIZE_SIZE so that (1) it's large enough to | ||
| 3592 | hold a size_t value and (2) the header size is a multiple of the | ||
| 3593 | alignment that Emacs needs for C types and for USE_LSB_TAG. */ | ||
| 3594 | # define XMALLOC_BASE_ALIGNMENT \ | ||
| 3595 | offsetof ( \ | ||
| 3596 | struct { \ | ||
| 3597 | union { long double d; intmax_t i; void *p; } u; \ | ||
| 3598 | char c; \ | ||
| 3599 | }, \ | ||
| 3600 | c) | ||
| 3601 | # ifdef USE_LSB_TAG | ||
| 3602 | /* A common multiple of the positive integers A and B. Ideally this | ||
| 3603 | would be the least common multiple, but there's no way to do that | ||
| 3604 | as a constant expression in C, so do the best that we can easily do. */ | ||
| 3605 | # define COMMON_MULTIPLE(a, b) \ | ||
| 3606 | ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b)) | ||
| 3607 | # define XMALLOC_HEADER_ALIGNMENT \ | ||
| 3608 | COMMON_MULTIPLE (1 << GCTYPEBITS, XMALLOC_BASE_ALIGNMENT) | ||
| 3609 | # else | ||
| 3610 | # define XMALLOC_HEADER_ALIGNMENT XMALLOC_BASE_ALIGNMENT | ||
| 3611 | # endif | ||
| 3612 | # define XMALLOC_OVERRUN_SIZE_SIZE \ | ||
| 3613 | (((XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t) \ | ||
| 3614 | + XMALLOC_HEADER_ALIGNMENT - 1) \ | ||
| 3615 | / XMALLOC_HEADER_ALIGNMENT * XMALLOC_HEADER_ALIGNMENT) \ | ||
| 3616 | - XMALLOC_OVERRUN_CHECK_SIZE) | ||
| 3617 | #endif | ||
| 3618 | |||
| 3619 | extern POINTER_TYPE *xmalloc (size_t); | 3571 | extern POINTER_TYPE *xmalloc (size_t); |
| 3620 | extern POINTER_TYPE *xrealloc (POINTER_TYPE *, size_t); | 3572 | extern POINTER_TYPE *xrealloc (POINTER_TYPE *, size_t); |
| 3621 | extern void xfree (POINTER_TYPE *); | 3573 | extern void xfree (POINTER_TYPE *); |