aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKen Brown2014-08-28 10:48:02 -0400
committerKen Brown2014-08-28 10:48:02 -0400
commitea652500776aacbb8cb64f9ecca16a2d2c7add80 (patch)
treec759fc62dfa422e8fb636aef6dbb04df2c68cc7e /src
parenta7ef7a0e53ae1f391f4bda207bb5e9b9d833d354 (diff)
downloademacs-ea652500776aacbb8cb64f9ecca16a2d2c7add80.tar.gz
emacs-ea652500776aacbb8cb64f9ecca16a2d2c7add80.zip
Add support for HYBRID_MALLOC, allowing the use of gmalloc before
dumping and the system malloc after dumping. (Bug#18222) * configure.ac (HYBRID_MALLOC): New macro; define to use gmalloc before dumping and the system malloc after dumping. Define on Cygwin. * src/conf_post.h (malloc, realloc, calloc, free) [HYBRID_MALLOC]: Define as macros, expanding to hybrid_malloc, etc. (HYBRID_GET_CURRENT_DIR_NAME): New macro. (get_current_dir_name) [HYBRID_GET_CURRENT_DIR_NAME]: Define as macro. * src/gmalloc.c: Set up the infrastructure for HYBRID_MALLOC, with a full implementation on Cygwin. Remove Cygwin-specific code that is no longer needed. (malloc, realloc, calloc, free, aligned_alloc) [HYBRID_MALLOC]: Redefine as macros expanding to gmalloc, grealloc, etc. (DUMPED, ALLOCATED_BEFORE_DUMPING) [CYGWIN]: New macros. (get_current_dir_name) [HYBRID_GET_CURRENT_DIR_NAME]: Undefine. (USE_PTHREAD, posix_memalign) [HYBRID_MALLOC]: Don't define. (hybrid_malloc, hybrid_calloc, hybrid_free, hybrid_realloc) [HYBRID_MALLOC]: (hybrid_get_current_dir_name) [HYBRID_GET_CURRENT_DIR_NAME]: (hybrid_aligned_alloc) [HYBRID_MALLOC && (HAVE_ALIGNED_ALLOC || HAVE_POSIX_MEMALIGN)]: New functions. * src/alloc.c (aligned_alloc) [HYBRID_MALLOC && (ALIGNED_ALLOC || HAVE_POSIX_MEMALIGN)]: Define as macro expanding to hybrid_aligned_alloc; declare. (USE_ALIGNED_ALLOC) [HYBRID_MALLOC && (ALIGNED_ALLOC || HAVE_POSIX_MEMALIGN)]: Define. (refill_memory_reserve) [HYBRID_MALLOC]: Do nothing. * src/sysdep.c (get_current_dir_name) [HYBRID_GET_CURRENT_DIR_NAME]: Define as macro, expanding to gget_current_dir_name, and define the latter. * src/emacs.c (main) [HYBRID_MALLOC]: Don't call memory_warnings() or malloc_enable_thread(). Don't initialize malloc. * src/lisp.h (NONPOINTER_BITS) [CYGWIN]: Define (because GNU_MALLOC is no longer defined on Cygwin). (refill_memory_reserve) [HYBRID_MALLOC]: Don't declare. * src/sheap.c (bss_sbrk_buffer_end): New variable. * src/unexcw.c (__malloc_initialized): Remove variable. * src/ralloc.c: Throughout, treat HYBRID_MALLOC the same as SYSTEM_MALLOC. * src/xdisp.c (decode_mode_spec) [HYBRID_MALLOC]: Don't check Vmemory_full.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog44
-rw-r--r--src/alloc.c15
-rw-r--r--src/conf_post.h17
-rw-r--r--src/emacs.c19
-rw-r--r--src/gmalloc.c231
-rw-r--r--src/lisp.h5
-rw-r--r--src/ralloc.c12
-rw-r--r--src/sheap.c1
-rw-r--r--src/sysdep.c13
-rw-r--r--src/unexcw.c5
-rw-r--r--src/xdisp.c2
11 files changed, 252 insertions, 112 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index d0eec16a60a..05c3c5cf65b 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,47 @@
12014-08-28 Ken Brown <kbrown@cornell.edu>
2
3 Add support for HYBRID_MALLOC, allowing the use of gmalloc before
4 dumping and the system malloc after dumping. (Bug#18222)
5
6 * conf_post.h (malloc, realloc, calloc, free) [HYBRID_MALLOC]:
7 Define as macros, expanding to hybrid_malloc, etc.
8 (HYBRID_GET_CURRENT_DIR_NAME): New macro.
9 (get_current_dir_name) [HYBRID_GET_CURRENT_DIR_NAME]: Define as
10 macro.
11 * gmalloc.c: Set up the infrastructure for HYBRID_MALLOC, with a
12 full implementation on Cygwin. Remove Cygwin-specific code that
13 is no longer needed.
14 (malloc, realloc, calloc, free, aligned_alloc) [HYBRID_MALLOC]:
15 Redefine as macros expanding to gmalloc, grealloc, etc.
16 (DUMPED, ALLOCATED_BEFORE_DUMPING) [CYGWIN]: New macros.
17 (get_current_dir_name) [HYBRID_GET_CURRENT_DIR_NAME]: Undefine.
18 (USE_PTHREAD, posix_memalign) [HYBRID_MALLOC]: Don't define.
19 (hybrid_malloc, hybrid_calloc, hybrid_free, hybrid_realloc)
20 [HYBRID_MALLOC]:
21 (hybrid_get_current_dir_name) [HYBRID_GET_CURRENT_DIR_NAME]:
22 (hybrid_aligned_alloc) [HYBRID_MALLOC && (HAVE_ALIGNED_ALLOC ||
23 HAVE_POSIX_MEMALIGN)]: New functions.
24 * alloc.c (aligned_alloc) [HYBRID_MALLOC && (ALIGNED_ALLOC ||
25 HAVE_POSIX_MEMALIGN)]: Define as macro expanding to
26 hybrid_aligned_alloc; declare.
27 (USE_ALIGNED_ALLOC) [HYBRID_MALLOC && (ALIGNED_ALLOC ||
28 HAVE_POSIX_MEMALIGN)]: Define.
29 (refill_memory_reserve) [HYBRID_MALLOC]: Do nothing.
30 * sysdep.c (get_current_dir_name) [HYBRID_GET_CURRENT_DIR_NAME]:
31 Define as macro, expanding to gget_current_dir_name, and define
32 the latter.
33 * emacs.c (main) [HYBRID_MALLOC]: Don't call memory_warnings() or
34 malloc_enable_thread(). Don't initialize malloc.
35 * lisp.h (NONPOINTER_BITS) [CYGWIN]: Define (because GNU_MALLOC is
36 no longer defined on Cygwin).
37 (refill_memory_reserve) [HYBRID_MALLOC]: Don't declare.
38 * sheap.c (bss_sbrk_buffer_end): New variable.
39 * unexcw.c (__malloc_initialized): Remove variable.
40 * ralloc.c: Throughout, treat HYBRID_MALLOC the same as
41 SYSTEM_MALLOC.
42 * xdisp.c (decode_mode_spec) [HYBRID_MALLOC]: Don't check
43 Vmemory_full.
44
12014-08-28 Martin Rudalics <rudalics@gmx.at> 452014-08-28 Martin Rudalics <rudalics@gmx.at>
2 46
3 * w32term.c (w32_horizontal_scroll_bar_handle_click): In 47 * w32term.c (w32_horizontal_scroll_bar_handle_click): In
diff --git a/src/alloc.c b/src/alloc.c
index ac154b587e6..9c81ae2eedf 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -80,7 +80,7 @@ static bool valgrind_p;
80 marked objects. */ 80 marked objects. */
81 81
82#if (defined SYSTEM_MALLOC || defined DOUG_LEA_MALLOC \ 82#if (defined SYSTEM_MALLOC || defined DOUG_LEA_MALLOC \
83 || defined GC_CHECK_MARKED_OBJECTS) 83 || defined HYBRID_MALLOC || defined GC_CHECK_MARKED_OBJECTS)
84#undef GC_MALLOC_CHECK 84#undef GC_MALLOC_CHECK
85#endif 85#endif
86 86
@@ -285,7 +285,7 @@ static void gc_sweep (void);
285static Lisp_Object make_pure_vector (ptrdiff_t); 285static Lisp_Object make_pure_vector (ptrdiff_t);
286static void mark_buffer (struct buffer *); 286static void mark_buffer (struct buffer *);
287 287
288#if !defined REL_ALLOC || defined SYSTEM_MALLOC 288#if !defined REL_ALLOC || defined SYSTEM_MALLOC || defined HYBRID_MALLOC
289static void refill_memory_reserve (void); 289static void refill_memory_reserve (void);
290#endif 290#endif
291static void compact_small_strings (void); 291static void compact_small_strings (void);
@@ -1014,10 +1014,17 @@ lisp_free (void *block)
1014 clang 3.3 anyway. */ 1014 clang 3.3 anyway. */
1015 1015
1016#if ! ADDRESS_SANITIZER 1016#if ! ADDRESS_SANITIZER
1017# if !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC 1017# if !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC && !defined HYBRID_MALLOC
1018# define USE_ALIGNED_ALLOC 1 1018# define USE_ALIGNED_ALLOC 1
1019/* Defined in gmalloc.c. */ 1019/* Defined in gmalloc.c. */
1020void *aligned_alloc (size_t, size_t); 1020void *aligned_alloc (size_t, size_t);
1021# elif defined HYBRID_MALLOC
1022# if defined ALIGNED_ALLOC || defined HAVE_POSIX_MEMALIGN
1023# define USE_ALIGNED_ALLOC 1
1024# define aligned_alloc hybrid_aligned_alloc
1025/* Defined in gmalloc.c. */
1026void *aligned_alloc (size_t, size_t);
1027# endif
1021# elif defined HAVE_ALIGNED_ALLOC 1028# elif defined HAVE_ALIGNED_ALLOC
1022# define USE_ALIGNED_ALLOC 1 1029# define USE_ALIGNED_ALLOC 1
1023# elif defined HAVE_POSIX_MEMALIGN 1030# elif defined HAVE_POSIX_MEMALIGN
@@ -3829,7 +3836,7 @@ memory_full (size_t nbytes)
3829void 3836void
3830refill_memory_reserve (void) 3837refill_memory_reserve (void)
3831{ 3838{
3832#ifndef SYSTEM_MALLOC 3839#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
3833 if (spare_memory[0] == 0) 3840 if (spare_memory[0] == 0)
3834 spare_memory[0] = malloc (SPARE_MEMORY); 3841 spare_memory[0] = malloc (SPARE_MEMORY);
3835 if (spare_memory[1] == 0) 3842 if (spare_memory[1] == 0)
diff --git a/src/conf_post.h b/src/conf_post.h
index c8e3672b228..35d9e6d1385 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -80,6 +80,23 @@ typedef bool bool_bf;
80#define vfork fork 80#define vfork fork
81#endif /* DARWIN_OS */ 81#endif /* DARWIN_OS */
82 82
83/* If HYBRID_MALLOC is defined (e.g., on Cygwin), emacs will use
84 gmalloc before dumping and the system malloc after dumping.
85 hybrid_malloc and friends, defined in gmalloc.c, are wrappers that
86 accomplish this. */
87#ifdef HYBRID_MALLOC
88#ifdef emacs
89#define malloc hybrid_malloc
90#define realloc hybrid_realloc
91#define calloc hybrid_calloc
92#define free hybrid_free
93#if defined HAVE_GET_CURRENT_DIR_NAME && !defined BROKEN_GET_CURRENT_DIR_NAME
94#define HYBRID_GET_CURRENT_DIR_NAME 1
95#define get_current_dir_name hybrid_get_current_dir_name
96#endif
97#endif
98#endif /* HYBRID_MALLOC */
99
83/* We have to go this route, rather than the old hpux9 approach of 100/* We have to go this route, rather than the old hpux9 approach of
84 renaming the functions via macros. The system's stdlib.h has fully 101 renaming the functions via macros. The system's stdlib.h has fully
85 prototyped declarations, which yields a conflicting definition of 102 prototyped declarations, which yields a conflicting definition of
diff --git a/src/emacs.c b/src/emacs.c
index c381a771a68..0b52659172c 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -145,7 +145,7 @@ extern int malloc_set_state (void *);
145/* True if the MALLOC_CHECK_ environment variable was set while 145/* True if the MALLOC_CHECK_ environment variable was set while
146 dumping. Used to work around a bug in glibc's malloc. */ 146 dumping. Used to work around a bug in glibc's malloc. */
147static bool malloc_using_checking; 147static bool malloc_using_checking;
148#elif defined HAVE_PTHREAD && !defined SYSTEM_MALLOC 148#elif defined HAVE_PTHREAD && !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
149extern void malloc_enable_thread (void); 149extern void malloc_enable_thread (void);
150#endif 150#endif
151 151
@@ -906,7 +906,7 @@ main (int argc, char **argv)
906 906
907 clearerr (stdin); 907 clearerr (stdin);
908 908
909#ifndef SYSTEM_MALLOC 909#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
910 /* Arrange to get warning messages as memory fills up. */ 910 /* Arrange to get warning messages as memory fills up. */
911 memory_warnings (0, malloc_warning); 911 memory_warnings (0, malloc_warning);
912 912
@@ -914,7 +914,7 @@ main (int argc, char **argv)
914 Also call realloc and free for consistency. */ 914 Also call realloc and free for consistency. */
915 free (realloc (malloc (4), 4)); 915 free (realloc (malloc (4), 4));
916 916
917#endif /* not SYSTEM_MALLOC */ 917#endif /* not SYSTEM_MALLOC and not HYBRID_MALLOC */
918 918
919#ifdef MSDOS 919#ifdef MSDOS
920 SET_BINARY (fileno (stdin)); 920 SET_BINARY (fileno (stdin));
@@ -1139,12 +1139,13 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1139#endif /* DOS_NT */ 1139#endif /* DOS_NT */
1140 } 1140 }
1141 1141
1142#if defined HAVE_PTHREAD && !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC 1142#if defined HAVE_PTHREAD && !defined SYSTEM_MALLOC \
1143 && !defined DOUG_LEA_MALLOC && !defined HYBRID_MALLOC
1143# ifndef CANNOT_DUMP 1144# ifndef CANNOT_DUMP
1144 /* Do not make gmalloc thread-safe when creating bootstrap-emacs, as 1145 /* Do not make gmalloc thread-safe when creating bootstrap-emacs, as
1145 that causes an infinite recursive loop with FreeBSD. But do make 1146 that causes an infinite recursive loop with FreeBSD. See
1146 it thread-safe when creating emacs, otherwise bootstrap-emacs 1147 Bug#14569. The part of this bug involving Cygwin is no longer
1147 fails on Cygwin. See Bug#14569. */ 1148 relevant, now that Cygwin defines HYBRID_MALLOC. */
1148 if (!noninteractive || initialized) 1149 if (!noninteractive || initialized)
1149# endif 1150# endif
1150 malloc_enable_thread (); 1151 malloc_enable_thread ();
@@ -2131,7 +2132,7 @@ You must run Emacs in batch mode in order to dump it. */)
2131 fflush (stdout); 2132 fflush (stdout);
2132 /* Tell malloc where start of impure now is. */ 2133 /* Tell malloc where start of impure now is. */
2133 /* Also arrange for warnings when nearly out of space. */ 2134 /* Also arrange for warnings when nearly out of space. */
2134#ifndef SYSTEM_MALLOC 2135#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
2135#ifndef WINDOWSNT 2136#ifndef WINDOWSNT
2136 /* On Windows, this was done before dumping, and that once suffices. 2137 /* On Windows, this was done before dumping, and that once suffices.
2137 Meanwhile, my_edata is not valid on Windows. */ 2138 Meanwhile, my_edata is not valid on Windows. */
@@ -2140,7 +2141,7 @@ You must run Emacs in batch mode in order to dump it. */)
2140 memory_warnings (my_edata, malloc_warning); 2141 memory_warnings (my_edata, malloc_warning);
2141 } 2142 }
2142#endif /* not WINDOWSNT */ 2143#endif /* not WINDOWSNT */
2143#endif /* not SYSTEM_MALLOC */ 2144#endif /* not SYSTEM_MALLOC and not HYBRID_MALLOC */
2144#ifdef DOUG_LEA_MALLOC 2145#ifdef DOUG_LEA_MALLOC
2145 malloc_state_ptr = malloc_get_state (); 2146 malloc_state_ptr = malloc_get_state ();
2146#endif 2147#endif
diff --git a/src/gmalloc.c b/src/gmalloc.c
index 27965e37539..f4a32c79ca1 100644
--- a/src/gmalloc.c
+++ b/src/gmalloc.c
@@ -19,15 +19,27 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
19 The author may be reached (Email) at the address mike@ai.mit.edu, 19 The author may be reached (Email) at the address mike@ai.mit.edu,
20 or (US mail) as Mike Haertel c/o Free Software Foundation. */ 20 or (US mail) as Mike Haertel c/o Free Software Foundation. */
21 21
22/* If HYBRID_MALLOC is defined in config.h, then conf_post.h #defines
23 malloc and friends as macros before including stdlib.h. In this
24 file we will need the prototypes for the system malloc, so we must
25 include stdlib.h before config.h. And we have to do this
26 unconditionally, since HYBRID_MALLOC hasn't been defined yet. */
27#include <stdlib.h>
28
22#include <config.h> 29#include <config.h>
23 30
24#ifdef HAVE_PTHREAD 31#if defined HAVE_PTHREAD && !defined HYBRID_MALLOC
25#define USE_PTHREAD 32#define USE_PTHREAD
26#endif 33#endif
27 34
28#include <string.h> 35#include <string.h>
29#include <limits.h> 36#include <limits.h>
30#include <stdint.h> 37#include <stdint.h>
38
39#ifdef HYBRID_GET_CURRENT_DIR_NAME
40#undef get_current_dir_name
41#endif
42
31#include <unistd.h> 43#include <unistd.h>
32 44
33#ifdef USE_PTHREAD 45#ifdef USE_PTHREAD
@@ -42,6 +54,41 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
42extern void emacs_abort (void); 54extern void emacs_abort (void);
43#endif 55#endif
44 56
57/* If HYBRID_MALLOC is defined, then temacs will use malloc,
58 realloc... as defined in this file (and renamed gmalloc,
59 grealloc... via the macros that follow). The dumped emacs,
60 however, will use the system malloc, realloc.... In other source
61 files, malloc, realloc... are renamed hybrid_malloc,
62 hybrid_realloc... via macros in conf_post.h. hybrid_malloc and
63 friends are wrapper functions defined later in this file.
64 aligned_alloc is defined as a macro only in alloc.c.
65
66 As of this writing (August 2014), Cygwin is the only platform on
67 which HYBRID_MACRO is defined. Any other platform that wants to
68 define it will have to define the macros DUMPED and
69 ALLOCATED_BEFORE_DUMPING, defined below for Cygwin. */
70#ifdef HYBRID_MALLOC
71#undef malloc
72#undef realloc
73#undef calloc
74#undef free
75#define malloc gmalloc
76#define realloc grealloc
77#define calloc gcalloc
78#define aligned_alloc galigned_alloc
79#define free gfree
80#endif /* HYBRID_MALLOC */
81
82#ifdef CYGWIN
83extern void *bss_sbrk (ptrdiff_t size);
84extern int bss_sbrk_did_unexec;
85extern char *bss_sbrk_buffer;
86extern char *bss_sbrk_buffer_end;
87#define DUMPED bss_sbrk_did_unexec
88#define ALLOCATED_BEFORE_DUMPING(P) \
89 ((char *) (P) < bss_sbrk_buffer_end && (char *) (P) >= bss_sbrk_buffer)
90#endif
91
45#ifdef __cplusplus 92#ifdef __cplusplus
46extern "C" 93extern "C"
47{ 94{
@@ -306,22 +353,6 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
306 353
307#include <errno.h> 354#include <errno.h>
308 355
309/* On Cygwin there are two heaps. temacs uses the static heap
310 (defined in sheap.c and managed with bss_sbrk), and the dumped
311 emacs uses the Cygwin heap (managed with sbrk). When emacs starts
312 on Cygwin, it reinitializes malloc, and we save the old info for
313 use by free and realloc if they're called with a pointer into the
314 static heap.
315
316 Currently (2011-08-16) the Cygwin build doesn't use ralloc.c; if
317 this is changed in the future, we'll have to similarly deal with
318 reinitializing ralloc. */
319#ifdef CYGWIN
320extern void *bss_sbrk (ptrdiff_t size);
321extern int bss_sbrk_did_unexec;
322char *bss_sbrk_heapbase; /* _heapbase for static heap */
323malloc_info *bss_sbrk_heapinfo; /* _heapinfo for static heap */
324#endif
325void *(*__morecore) (ptrdiff_t size) = __default_morecore; 356void *(*__morecore) (ptrdiff_t size) = __default_morecore;
326 357
327/* Debugging hook for `malloc'. */ 358/* Debugging hook for `malloc'. */
@@ -490,18 +521,8 @@ register_heapinfo (void)
490} 521}
491 522
492#ifdef USE_PTHREAD 523#ifdef USE_PTHREAD
493/* On Cygwin prior to 1.7.31, pthread_mutexes were ERRORCHECK mutexes
494 by default. When the default changed to NORMAL in Cygwin-1.7.31,
495 deadlocks occurred (bug#18222). As a temporary workaround, we
496 explicitly set the mutexes to be of ERRORCHECK type, restoring the
497 previous behavior. */
498#ifdef CYGWIN
499pthread_mutex_t _malloc_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
500pthread_mutex_t _aligned_blocks_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
501#else /* not CYGWIN */
502pthread_mutex_t _malloc_mutex = PTHREAD_MUTEX_INITIALIZER; 524pthread_mutex_t _malloc_mutex = PTHREAD_MUTEX_INITIALIZER;
503pthread_mutex_t _aligned_blocks_mutex = PTHREAD_MUTEX_INITIALIZER; 525pthread_mutex_t _aligned_blocks_mutex = PTHREAD_MUTEX_INITIALIZER;
504#endif /* not CYGWIN */
505int _malloc_thread_enabled_p; 526int _malloc_thread_enabled_p;
506 527
507static void 528static void
@@ -536,17 +557,8 @@ malloc_enable_thread (void)
536 initialized mutexes when they are used first. To avoid such a 557 initialized mutexes when they are used first. To avoid such a
537 situation, we initialize mutexes here while their use is 558 situation, we initialize mutexes here while their use is
538 disabled in malloc etc. */ 559 disabled in malloc etc. */
539#ifdef CYGWIN
540 /* Use ERRORCHECK mutexes; see comment above. */
541 pthread_mutexattr_t attr;
542 pthread_mutexattr_init (&attr);
543 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK);
544 pthread_mutex_init (&_malloc_mutex, &attr);
545 pthread_mutex_init (&_aligned_blocks_mutex, &attr);
546#else /* not CYGWIN */
547 pthread_mutex_init (&_malloc_mutex, NULL); 560 pthread_mutex_init (&_malloc_mutex, NULL);
548 pthread_mutex_init (&_aligned_blocks_mutex, NULL); 561 pthread_mutex_init (&_aligned_blocks_mutex, NULL);
549#endif /* not CYGWIN */
550 pthread_atfork (malloc_atfork_handler_prepare, 562 pthread_atfork (malloc_atfork_handler_prepare,
551 malloc_atfork_handler_parent, 563 malloc_atfork_handler_parent,
552 malloc_atfork_handler_child); 564 malloc_atfork_handler_child);
@@ -561,16 +573,6 @@ malloc_initialize_1 (void)
561 mcheck (NULL); 573 mcheck (NULL);
562#endif 574#endif
563 575
564#ifdef CYGWIN
565 if (bss_sbrk_did_unexec)
566 /* we're reinitializing the dumped emacs */
567 {
568 bss_sbrk_heapbase = _heapbase;
569 bss_sbrk_heapinfo = _heapinfo;
570 memset (_fraghead, 0, BLOCKLOG * sizeof (struct list));
571 }
572#endif
573
574 if (__malloc_initialize_hook) 576 if (__malloc_initialize_hook)
575 (*__malloc_initialize_hook) (); 577 (*__malloc_initialize_hook) ();
576 578
@@ -1027,12 +1029,6 @@ _free_internal_nolock (void *ptr)
1027 if (ptr == NULL) 1029 if (ptr == NULL)
1028 return; 1030 return;
1029 1031
1030#ifdef CYGWIN
1031 if ((char *) ptr < _heapbase)
1032 /* We're being asked to free something in the static heap. */
1033 return;
1034#endif
1035
1036 PROTECT_MALLOC_STATE (0); 1032 PROTECT_MALLOC_STATE (0);
1037 1033
1038 LOCK_ALIGNED_BLOCKS (); 1034 LOCK_ALIGNED_BLOCKS ();
@@ -1317,29 +1313,6 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
1317#define min(A, B) ((A) < (B) ? (A) : (B)) 1313#define min(A, B) ((A) < (B) ? (A) : (B))
1318#endif 1314#endif
1319 1315
1320/* On Cygwin the dumped emacs may try to realloc storage allocated in
1321 the static heap. We just malloc space in the new heap and copy the
1322 data. */
1323#ifdef CYGWIN
1324void *
1325special_realloc (void *ptr, size_t size)
1326{
1327 void *result;
1328 int type;
1329 size_t block, oldsize;
1330
1331 block = ((char *) ptr - bss_sbrk_heapbase) / BLOCKSIZE + 1;
1332 type = bss_sbrk_heapinfo[block].busy.type;
1333 oldsize =
1334 type == 0 ? bss_sbrk_heapinfo[block].busy.info.size * BLOCKSIZE
1335 : (size_t) 1 << type;
1336 result = _malloc_internal_nolock (size);
1337 if (result)
1338 return memcpy (result, ptr, min (oldsize, size));
1339 return result;
1340}
1341#endif
1342
1343/* Debugging hook for realloc. */ 1316/* Debugging hook for realloc. */
1344void *(*__realloc_hook) (void *ptr, size_t size); 1317void *(*__realloc_hook) (void *ptr, size_t size);
1345 1318
@@ -1364,12 +1337,6 @@ _realloc_internal_nolock (void *ptr, size_t size)
1364 else if (ptr == NULL) 1337 else if (ptr == NULL)
1365 return _malloc_internal_nolock (size); 1338 return _malloc_internal_nolock (size);
1366 1339
1367#ifdef CYGWIN
1368 if ((char *) ptr < _heapbase)
1369 /* ptr points into the static heap */
1370 return special_realloc (ptr, size);
1371#endif
1372
1373 block = BLOCK (ptr); 1340 block = BLOCK (ptr);
1374 1341
1375 PROTECT_MALLOC_STATE (0); 1342 PROTECT_MALLOC_STATE (0);
@@ -1566,7 +1533,7 @@ __default_morecore (ptrdiff_t increment)
1566{ 1533{
1567 void *result; 1534 void *result;
1568#if defined (CYGWIN) 1535#if defined (CYGWIN)
1569 if (!bss_sbrk_did_unexec) 1536 if (!DUMPED)
1570 { 1537 {
1571 return bss_sbrk (increment); 1538 return bss_sbrk (increment);
1572 } 1539 }
@@ -1689,6 +1656,9 @@ memalign (size_t alignment, size_t size)
1689 return aligned_alloc (alignment, size); 1656 return aligned_alloc (alignment, size);
1690} 1657}
1691 1658
1659/* If HYBRID_MALLOC is defined, we may want to use the system
1660 posix_memalign below. */
1661#ifndef HYBRID_MALLOC
1692int 1662int
1693posix_memalign (void **memptr, size_t alignment, size_t size) 1663posix_memalign (void **memptr, size_t alignment, size_t size)
1694{ 1664{
@@ -1707,6 +1677,7 @@ posix_memalign (void **memptr, size_t alignment, size_t size)
1707 1677
1708 return 0; 1678 return 0;
1709} 1679}
1680#endif
1710 1681
1711/* Allocate memory on a page boundary. 1682/* Allocate memory on a page boundary.
1712 Copyright (C) 1991, 92, 93, 94, 96 Free Software Foundation, Inc. 1683 Copyright (C) 1991, 92, 93, 94, 96 Free Software Foundation, Inc.
@@ -1747,6 +1718,102 @@ valloc (size_t size)
1747 return aligned_alloc (pagesize, size); 1718 return aligned_alloc (pagesize, size);
1748} 1719}
1749 1720
1721#ifdef HYBRID_MALLOC
1722#undef malloc
1723#undef realloc
1724#undef calloc
1725#undef aligned_alloc
1726#undef free
1727
1728/* See the comments near the beginning of this file for explanations
1729 of the following functions. */
1730
1731void *
1732hybrid_malloc (size_t size)
1733{
1734 if (DUMPED)
1735 return malloc (size);
1736 return gmalloc (size);
1737}
1738
1739void *
1740hybrid_calloc (size_t nmemb, size_t size)
1741{
1742 if (DUMPED)
1743 return calloc (nmemb, size);
1744 return gcalloc (nmemb, size);
1745}
1746
1747void
1748hybrid_free (void *ptr)
1749{
1750 if (!DUMPED)
1751 gfree (ptr);
1752 else if (!ALLOCATED_BEFORE_DUMPING (ptr))
1753 free (ptr);
1754 /* Otherwise the dumped emacs is trying to free something allocated
1755 before dumping; do nothing. */
1756 return;
1757}
1758
1759#if defined HAVE_ALIGNED_ALLOC || defined HAVE_POSIX_MEMALIGN
1760void *
1761hybrid_aligned_alloc (size_t alignment, size_t size)
1762{
1763 if (!DUMPED)
1764 return galigned_alloc (alignment, size);
1765 /* The following is copied from alloc.c */
1766#ifdef HAVE_ALIGNED_ALLOC
1767 return aligned_alloc (alignment, size);
1768#else /* HAVE_POSIX_MEMALIGN */
1769 void *p;
1770 return posix_memalign (&p, alignment, size) == 0 ? p : 0;
1771#endif
1772}
1773#endif
1774
1775void *
1776hybrid_realloc (void *ptr, size_t size)
1777{
1778 void *result;
1779 int type;
1780 size_t block, oldsize;
1781
1782 if (!DUMPED)
1783 return grealloc (ptr, size);
1784 if (!ALLOCATED_BEFORE_DUMPING (ptr))
1785 return realloc (ptr, size);
1786
1787 /* The dumped emacs is trying to realloc storage allocated before
1788 dumping. We just malloc new space and copy the data. */
1789 if (size == 0 || ptr == NULL)
1790 return malloc (size);
1791 block = ((char *) ptr - _heapbase) / BLOCKSIZE + 1;
1792 type = _heapinfo[block].busy.type;
1793 oldsize =
1794 type == 0 ? _heapinfo[block].busy.info.size * BLOCKSIZE
1795 : (size_t) 1 << type;
1796 result = malloc (size);
1797 if (result)
1798 return memcpy (result, ptr, min (oldsize, size));
1799 return result;
1800}
1801
1802#ifdef HYBRID_GET_CURRENT_DIR_NAME
1803/* Defined in sysdep.c. */
1804char *gget_current_dir_name (void);
1805
1806char *
1807hybrid_get_current_dir_name (void)
1808{
1809 if (DUMPED)
1810 return get_current_dir_name ();
1811 return gget_current_dir_name ();
1812}
1813#endif
1814
1815#endif /* HYBRID_MALLOC */
1816
1750#ifdef GC_MCHECK 1817#ifdef GC_MCHECK
1751 1818
1752/* Standard debugging hooks for `malloc'. 1819/* Standard debugging hooks for `malloc'.
diff --git a/src/lisp.h b/src/lisp.h
index b9f456b3745..98734a55812 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -88,7 +88,8 @@ DEFINE_GDB_SYMBOL_END (GCTYPEBITS)
88 2. We know malloc returns a multiple of 8. */ 88 2. We know malloc returns a multiple of 8. */
89#if (defined alignas \ 89#if (defined alignas \
90 && (defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ \ 90 && (defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ \
91 || defined DARWIN_OS || defined __sun || defined __MINGW32__)) 91 || defined DARWIN_OS || defined __sun || defined __MINGW32__ \
92 || defined CYGWIN))
92# define NONPOINTER_BITS 0 93# define NONPOINTER_BITS 0
93#else 94#else
94# define NONPOINTER_BITS GCTYPEBITS 95# define NONPOINTER_BITS GCTYPEBITS
@@ -3629,7 +3630,7 @@ extern _Noreturn void memory_full (size_t);
3629extern _Noreturn void buffer_memory_full (ptrdiff_t); 3630extern _Noreturn void buffer_memory_full (ptrdiff_t);
3630extern bool survives_gc_p (Lisp_Object); 3631extern bool survives_gc_p (Lisp_Object);
3631extern void mark_object (Lisp_Object); 3632extern void mark_object (Lisp_Object);
3632#if defined REL_ALLOC && !defined SYSTEM_MALLOC 3633#if defined REL_ALLOC && !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
3633extern void refill_memory_reserve (void); 3634extern void refill_memory_reserve (void);
3634#endif 3635#endif
3635extern const char *pending_malloc_warning; 3636extern const char *pending_malloc_warning;
diff --git a/src/ralloc.c b/src/ralloc.c
index c82cd4548d2..e63ed34c89b 100644
--- a/src/ralloc.c
+++ b/src/ralloc.c
@@ -35,9 +35,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
35#define M_TOP_PAD -2 35#define M_TOP_PAD -2
36extern int mallopt (int, int); 36extern int mallopt (int, int);
37#else /* not DOUG_LEA_MALLOC */ 37#else /* not DOUG_LEA_MALLOC */
38#ifndef SYSTEM_MALLOC 38#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
39extern size_t __malloc_extra_blocks; 39extern size_t __malloc_extra_blocks;
40#endif /* SYSTEM_MALLOC */ 40#endif /* not SYSTEM_MALLOC and not HYBRID_MALLOC */
41#endif /* not DOUG_LEA_MALLOC */ 41#endif /* not DOUG_LEA_MALLOC */
42 42
43#else /* not emacs */ 43#else /* not emacs */
@@ -95,7 +95,7 @@ static int extra_bytes;
95/* The hook `malloc' uses for the function which gets more space 95/* The hook `malloc' uses for the function which gets more space
96 from the system. */ 96 from the system. */
97 97
98#ifndef SYSTEM_MALLOC 98#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
99extern void *(*__morecore) (ptrdiff_t); 99extern void *(*__morecore) (ptrdiff_t);
100#endif 100#endif
101 101
@@ -1179,7 +1179,7 @@ r_alloc_init (void)
1179 r_alloc_initialized = 1; 1179 r_alloc_initialized = 1;
1180 1180
1181 page_size = PAGE; 1181 page_size = PAGE;
1182#ifndef SYSTEM_MALLOC 1182#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
1183 real_morecore = __morecore; 1183 real_morecore = __morecore;
1184 __morecore = r_alloc_sbrk; 1184 __morecore = r_alloc_sbrk;
1185 1185
@@ -1198,7 +1198,7 @@ r_alloc_init (void)
1198 mallopt (M_TOP_PAD, 64 * 4096); 1198 mallopt (M_TOP_PAD, 64 * 4096);
1199 unblock_input (); 1199 unblock_input ();
1200#else 1200#else
1201#ifndef SYSTEM_MALLOC 1201#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
1202 /* Give GNU malloc's morecore some hysteresis so that we move all 1202 /* Give GNU malloc's morecore some hysteresis so that we move all
1203 the relocatable blocks much less often. The number used to be 1203 the relocatable blocks much less often. The number used to be
1204 64, but alloc.c would override that with 32 in code that was 1204 64, but alloc.c would override that with 32 in code that was
@@ -1211,7 +1211,7 @@ r_alloc_init (void)
1211#endif 1211#endif
1212#endif 1212#endif
1213 1213
1214#ifndef SYSTEM_MALLOC 1214#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
1215 first_heap->end = (void *) PAGE_ROUNDUP (first_heap->start); 1215 first_heap->end = (void *) PAGE_ROUNDUP (first_heap->start);
1216 1216
1217 /* The extra call to real_morecore guarantees that the end of the 1217 /* The extra call to real_morecore guarantees that the end of the
diff --git a/src/sheap.c b/src/sheap.c
index 5069744435b..dc34df59556 100644
--- a/src/sheap.c
+++ b/src/sheap.c
@@ -44,6 +44,7 @@ int debug_sheap = 0;
44#define BLOCKSIZE 4096 44#define BLOCKSIZE 4096
45 45
46char bss_sbrk_buffer[STATIC_HEAP_SIZE]; 46char bss_sbrk_buffer[STATIC_HEAP_SIZE];
47char *bss_sbrk_buffer_end = bss_sbrk_buffer + STATIC_HEAP_SIZE;
47char *bss_sbrk_ptr; 48char *bss_sbrk_ptr;
48char *max_bss_sbrk_ptr; 49char *max_bss_sbrk_ptr;
49int bss_sbrk_did_unexec; 50int bss_sbrk_did_unexec;
diff --git a/src/sysdep.c b/src/sysdep.c
index a336a1e9058..c753f84831b 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -19,6 +19,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19 19
20#include <config.h> 20#include <config.h>
21 21
22/* If HYBRID_GET_CURRENT_DIR_NAME is defined in conf_post.h, then we
23 need the following before including unistd.h, in order to pick up
24 the right prototype for gget_current_dir_name. */
25#ifdef HYBRID_GET_CURRENT_DIR_NAME
26#undef get_current_dir_name
27#define get_current_dir_name gget_current_dir_name
28#endif
29
22#include <execinfo.h> 30#include <execinfo.h>
23#include "sysstdio.h" 31#include "sysstdio.h"
24#ifdef HAVE_PWD_H 32#ifdef HAVE_PWD_H
@@ -121,9 +129,8 @@ static const int baud_convert[] =
121 1800, 2400, 4800, 9600, 19200, 38400 129 1800, 2400, 4800, 9600, 19200, 38400
122 }; 130 };
123 131
124 132#if !defined HAVE_GET_CURRENT_DIR_NAME || defined BROKEN_GET_CURRENT_DIR_NAME \
125#if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME) 133 || (defined HYBRID_GET_CURRENT_DIR_NAME)
126
127/* Return the current working directory. Returns NULL on errors. 134/* Return the current working directory. Returns NULL on errors.
128 Any other returned value must be freed with free. This is used 135 Any other returned value must be freed with free. This is used
129 only when get_current_dir_name is not defined on the system. */ 136 only when get_current_dir_name is not defined on the system. */
diff --git a/src/unexcw.c b/src/unexcw.c
index 7636b05a12e..72456b33ec4 100644
--- a/src/unexcw.c
+++ b/src/unexcw.c
@@ -34,8 +34,6 @@ extern void report_sheap_usage (int);
34 34
35extern int bss_sbrk_did_unexec; 35extern int bss_sbrk_did_unexec;
36 36
37extern int __malloc_initialized;
38
39/* emacs symbols that indicate where bss and data end for emacs internals */ 37/* emacs symbols that indicate where bss and data end for emacs internals */
40extern char my_endbss[]; 38extern char my_endbss[];
41extern char my_edata[]; 39extern char my_edata[];
@@ -233,12 +231,9 @@ fixup_executable (int fd)
233 lseek (fd, (long) (exe_header->section_header[i].s_scnptr), 231 lseek (fd, (long) (exe_header->section_header[i].s_scnptr),
234 SEEK_SET); 232 SEEK_SET);
235 assert (ret != -1); 233 assert (ret != -1);
236 /* force the dumped emacs to reinitialize malloc */
237 __malloc_initialized = 0;
238 ret = 234 ret =
239 write (fd, (char *) start_address, 235 write (fd, (char *) start_address,
240 my_endbss - (char *) start_address); 236 my_endbss - (char *) start_address);
241 __malloc_initialized = 1;
242 assert (ret == (my_endbss - (char *) start_address)); 237 assert (ret == (my_endbss - (char *) start_address));
243 if (debug_unexcw) 238 if (debug_unexcw)
244 printf (" .bss, mem start %#lx mem length %d\n", 239 printf (" .bss, mem start %#lx mem length %d\n",
diff --git a/src/xdisp.c b/src/xdisp.c
index 1f2c5a02d6c..2b12dd8f557 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -22826,7 +22826,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
22826 } 22826 }
22827 22827
22828 case 'e': 22828 case 'e':
22829#ifndef SYSTEM_MALLOC 22829#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
22830 { 22830 {
22831 if (NILP (Vmemory_full)) 22831 if (NILP (Vmemory_full))
22832 return ""; 22832 return "";