summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Brown <kbrown@cornell.edu>2014-08-28 10:48:02 -0400
committerKen Brown <kbrown@cornell.edu>2014-08-28 10:48:02 -0400
commitea652500776aacbb8cb64f9ecca16a2d2c7add80 (patch)
treec759fc62dfa422e8fb636aef6dbb04df2c68cc7e
parenta7ef7a0e53ae1f391f4bda207bb5e9b9d833d354 (diff)
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.
-rw-r--r--ChangeLog6
-rw-r--r--configure.ac19
-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
13 files changed, 274 insertions, 115 deletions
diff --git a/ChangeLog b/ChangeLog
index fd6ce3dff0..07fd290f4e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2014-08-28 Ken Brown <kbrown@cornell.edu>
+
+ * configure.ac (HYBRID_MALLOC): New macro; define to use gmalloc
+ before dumping and the system malloc after dumping. Define on
+ Cygwin. (Bug#18222)
+
2014-08-28 Glenn Morris <rgm@gnu.org>
* Makefile.in (appdatadir): New variable.
diff --git a/configure.ac b/configure.ac
index 4617942409..4f17a55895 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2033,9 +2033,13 @@ AC_CACHE_CHECK(
doug_lea_malloc=$emacs_cv_var_doug_lea_malloc
system_malloc=$emacs_cv_sanitize_address
+
+hybrid_malloc=
+
case "$opsys" in
## darwin ld insists on the use of malloc routines in the System framework.
darwin|mingw32|sol2-10) system_malloc=yes ;;
+ cygwin) hybrid_malloc=yes;;
esac
GMALLOC_OBJ=
@@ -2047,6 +2051,13 @@ if test "${system_malloc}" = "yes"; then
GNU_MALLOC_reason="
(The GNU allocators don't work with this system configuration.)"
VMLIMIT_OBJ=
+elif test "$hybrid_malloc" = yes; then
+ AC_DEFINE(HYBRID_MALLOC, 1,
+ [Define to use gmalloc before dumping and the system malloc after.])
+ GNU_MALLOC=
+ GNU_MALLOC_reason="only before dumping"
+ GMALLOC_OBJ=gmalloc.o
+ VMLIMIT_OBJ=
else
test "$doug_lea_malloc" != "yes" && GMALLOC_OBJ=gmalloc.o
VMLIMIT_OBJ=vm-limit.o
@@ -3568,9 +3579,11 @@ cfmakeraw cfsetspeed copysign __executable_start log2)
LIBS=$OLD_LIBS
dnl No need to check for aligned_alloc and posix_memalign if using
-dnl gmalloc.o, as it supplies them. Don't use these functions on
-dnl Darwin as they are incompatible with unexmacosx.c.
-if test -z "$GMALLOC_OBJ" && test "$opsys" != darwin; then
+dnl gmalloc.o, as it supplies them, unless we're using hybrid_malloc.
+dnl Don't use these functions on Darwin as they are incompatible with
+dnl unexmacosx.c.
+if (test -z "$GMALLOC_OBJ" || test "$hybrid_malloc" = yes) \
+ && test "$opsys" != darwin; then
AC_CHECK_FUNCS([aligned_alloc posix_memalign], [break])
fi
diff --git a/src/ChangeLog b/src/ChangeLog
index d0eec16a60..05c3c5cf65 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,47 @@
+2014-08-28 Ken Brown <kbrown@cornell.edu>
+
+ Add support for HYBRID_MALLOC, allowing the use of gmalloc before
+ dumping and the system malloc after dumping. (Bug#18222)
+
+ * 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.
+ * 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.
+ * 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.
+ * sysdep.c (get_current_dir_name) [HYBRID_GET_CURRENT_DIR_NAME]:
+ Define as macro, expanding to gget_current_dir_name, and define
+ the latter.
+ * emacs.c (main) [HYBRID_MALLOC]: Don't call memory_warnings() or
+ malloc_enable_thread(). Don't initialize malloc.
+ * lisp.h (NONPOINTER_BITS) [CYGWIN]: Define (because GNU_MALLOC is
+ no longer defined on Cygwin).
+ (refill_memory_reserve) [HYBRID_MALLOC]: Don't declare.
+ * sheap.c (bss_sbrk_buffer_end): New variable.
+ * unexcw.c (__malloc_initialized): Remove variable.
+ * ralloc.c: Throughout, treat HYBRID_MALLOC the same as
+ SYSTEM_MALLOC.
+ * xdisp.c (decode_mode_spec) [HYBRID_MALLOC]: Don't check
+ Vmemory_full.
+
2014-08-28 Martin Rudalics <rudalics@gmx.at>
* w32term.c (w32_horizontal_scroll_bar_handle_click): In
diff --git a/src/alloc.c b/src/alloc.c
index ac154b587e..9c81ae2eed 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -80,7 +80,7 @@ static bool valgrind_p;
marked objects. */
#if (defined SYSTEM_MALLOC || defined DOUG_LEA_MALLOC \
- || defined GC_CHECK_MARKED_OBJECTS)
+ || defined HYBRID_MALLOC || defined GC_CHECK_MARKED_OBJECTS)
#undef GC_MALLOC_CHECK
#endif
@@ -285,7 +285,7 @@ static void gc_sweep (void);
static Lisp_Object make_pure_vector (ptrdiff_t);
static void mark_buffer (struct buffer *);
-#if !defined REL_ALLOC || defined SYSTEM_MALLOC
+#if !defined REL_ALLOC || defined SYSTEM_MALLOC || defined HYBRID_MALLOC
static void refill_memory_reserve (void);
#endif
static void compact_small_strings (void);
@@ -1014,10 +1014,17 @@ lisp_free (void *block)
clang 3.3 anyway. */
#if ! ADDRESS_SANITIZER
-# if !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC
+# if !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC && !defined HYBRID_MALLOC
# define USE_ALIGNED_ALLOC 1
/* Defined in gmalloc.c. */
void *aligned_alloc (size_t, size_t);
+# elif defined HYBRID_MALLOC
+# if defined ALIGNED_ALLOC || defined HAVE_POSIX_MEMALIGN
+# define USE_ALIGNED_ALLOC 1
+# define aligned_alloc hybrid_aligned_alloc
+/* Defined in gmalloc.c. */
+void *aligned_alloc (size_t, size_t);
+# endif
# elif defined HAVE_ALIGNED_ALLOC
# define USE_ALIGNED_ALLOC 1
# elif defined HAVE_POSIX_MEMALIGN
@@ -3829,7 +3836,7 @@ memory_full (size_t nbytes)
void
refill_memory_reserve (void)
{
-#ifndef SYSTEM_MALLOC
+#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
if (spare_memory[0] == 0)
spare_memory[0] = malloc (SPARE_MEMORY);
if (spare_memory[1] == 0)
diff --git a/src/conf_post.h b/src/conf_post.h
index c8e3672b22..35d9e6d138 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -80,6 +80,23 @@ typedef bool bool_bf;
#define vfork fork
#endif /* DARWIN_OS */
+/* If HYBRID_MALLOC is defined (e.g., on Cygwin), emacs will use
+ gmalloc before dumping and the system malloc after dumping.
+ hybrid_malloc and friends, defined in gmalloc.c, are wrappers that
+ accomplish this. */
+#ifdef HYBRID_MALLOC
+#ifdef emacs
+#define malloc hybrid_malloc
+#define realloc hybrid_realloc
+#define calloc hybrid_calloc
+#define free hybrid_free
+#if defined HAVE_GET_CURRENT_DIR_NAME && !defined BROKEN_GET_CURRENT_DIR_NAME
+#define HYBRID_GET_CURRENT_DIR_NAME 1
+#define get_current_dir_name hybrid_get_current_dir_name
+#endif
+#endif
+#endif /* HYBRID_MALLOC */
+
/* We have to go this route, rather than the old hpux9 approach of
renaming the functions via macros. The system's stdlib.h has fully
prototyped declarations, which yields a conflicting definition of
diff --git a/src/emacs.c b/src/emacs.c
index c381a771a6..0b52659172 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -145,7 +145,7 @@ extern int malloc_set_state (void *);
/* True if the MALLOC_CHECK_ environment variable was set while
dumping. Used to work around a bug in glibc's malloc. */
static bool malloc_using_checking;
-#elif defined HAVE_PTHREAD && !defined SYSTEM_MALLOC
+#elif defined HAVE_PTHREAD && !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
extern void malloc_enable_thread (void);
#endif
@@ -906,7 +906,7 @@ main (int argc, char **argv)
clearerr (stdin);
-#ifndef SYSTEM_MALLOC
+#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
/* Arrange to get warning messages as memory fills up. */
memory_warnings (0, malloc_warning);
@@ -914,7 +914,7 @@ main (int argc, char **argv)
Also call realloc and free for consistency. */
free (realloc (malloc (4), 4));
-#endif /* not SYSTEM_MALLOC */
+#endif /* not SYSTEM_MALLOC and not HYBRID_MALLOC */
#ifdef MSDOS
SET_BINARY (fileno (stdin));
@@ -1139,12 +1139,13 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
#endif /* DOS_NT */
}
-#if defined HAVE_PTHREAD && !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC
+#if defined HAVE_PTHREAD && !defined SYSTEM_MALLOC \
+ && !defined DOUG_LEA_MALLOC && !defined HYBRID_MALLOC
# ifndef CANNOT_DUMP
/* Do not make gmalloc thread-safe when creating bootstrap-emacs, as
- that causes an infinite recursive loop with FreeBSD. But do make
- it thread-safe when creating emacs, otherwise bootstrap-emacs
- fails on Cygwin. See Bug#14569. */
+ that causes an infinite recursive loop with FreeBSD. See
+ Bug#14569. The part of this bug involving Cygwin is no longer
+ relevant, now that Cygwin defines HYBRID_MALLOC. */
if (!noninteractive || initialized)
# endif
malloc_enable_thread ();
@@ -2131,7 +2132,7 @@ You must run Emacs in batch mode in order to dump it. */)
fflush (stdout);
/* Tell malloc where start of impure now is. */
/* Also arrange for warnings when nearly out of space. */
-#ifndef SYSTEM_MALLOC
+#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
#ifndef WINDOWSNT
/* On Windows, this was done before dumping, and that once suffices.
Meanwhile, my_edata is not valid on Windows. */
@@ -2140,7 +2141,7 @@ You must run Emacs in batch mode in order to dump it. */)
memory_warnings (my_edata, malloc_warning);
}
#endif /* not WINDOWSNT */
-#endif /* not SYSTEM_MALLOC */
+#endif /* not SYSTEM_MALLOC and not HYBRID_MALLOC */
#ifdef DOUG_LEA_MALLOC
malloc_state_ptr = malloc_get_state ();
#endif
diff --git a/src/gmalloc.c b/src/gmalloc.c
index 27965e3753..f4a32c79ca 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/>.
The author may be reached (Email) at the address mike@ai.mit.edu,
or (US mail) as Mike Haertel c/o Free Software Foundation. */
+/* If HYBRID_MALLOC is defined in config.h, then conf_post.h #defines
+ malloc and friends as macros before including stdlib.h. In this
+ file we will need the prototypes for the system malloc, so we must
+ include stdlib.h before config.h. And we have to do this
+ unconditionally, since HYBRID_MALLOC hasn't been defined yet. */
+#include <stdlib.h>
+
#include <config.h>
-#ifdef HAVE_PTHREAD
+#if defined HAVE_PTHREAD && !defined HYBRID_MALLOC
#define USE_PTHREAD
#endif
#include <string.h>
#include <limits.h>
#include <stdint.h>
+
+#ifdef HYBRID_GET_CURRENT_DIR_NAME
+#undef get_current_dir_name
+#endif
+
#include <unistd.h>
#ifdef USE_PTHREAD
@@ -42,6 +54,41 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
extern void emacs_abort (void);
#endif
+/* If HYBRID_MALLOC is defined, then temacs will use malloc,
+ realloc... as defined in this file (and renamed gmalloc,
+ grealloc... via the macros that follow). The dumped emacs,
+ however, will use the system malloc, realloc.... In other source
+ files, malloc, realloc... are renamed hybrid_malloc,
+ hybrid_realloc... via macros in conf_post.h. hybrid_malloc and
+ friends are wrapper functions defined later in this file.
+ aligned_alloc is defined as a macro only in alloc.c.
+
+ As of this writing (August 2014), Cygwin is the only platform on
+ which HYBRID_MACRO is defined. Any other platform that wants to
+ define it will have to define the macros DUMPED and
+ ALLOCATED_BEFORE_DUMPING, defined below for Cygwin. */
+#ifdef HYBRID_MALLOC
+#undef malloc
+#undef realloc
+#undef calloc
+#undef free
+#define malloc gmalloc
+#define realloc grealloc
+#define calloc gcalloc
+#define aligned_alloc galigned_alloc
+#define free gfree
+#endif /* HYBRID_MALLOC */
+
+#ifdef CYGWIN
+extern void *bss_sbrk (ptrdiff_t size);
+extern int bss_sbrk_did_unexec;
+extern char *bss_sbrk_buffer;
+extern char *bss_sbrk_buffer_end;
+#define DUMPED bss_sbrk_did_unexec
+#define ALLOCATED_BEFORE_DUMPING(P) \
+ ((char *) (P) < bss_sbrk_buffer_end && (char *) (P) >= bss_sbrk_buffer)
+#endif
+
#ifdef __cplusplus
extern "C"
{
@@ -306,22 +353,6 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
#include <errno.h>
-/* On Cygwin there are two heaps. temacs uses the static heap
- (defined in sheap.c and managed with bss_sbrk), and the dumped
- emacs uses the Cygwin heap (managed with sbrk). When emacs starts
- on Cygwin, it reinitializes malloc, and we save the old info for
- use by free and realloc if they're called with a pointer into the
- static heap.
-
- Currently (2011-08-16) the Cygwin build doesn't use ralloc.c; if
- this is changed in the future, we'll have to similarly deal with
- reinitializing ralloc. */
-#ifdef CYGWIN
-extern void *bss_sbrk (ptrdiff_t size);
-extern int bss_sbrk_did_unexec;
-char *bss_sbrk_heapbase; /* _heapbase for static heap */
-malloc_info *bss_sbrk_heapinfo; /* _heapinfo for static heap */
-#endif
void *(*__morecore) (ptrdiff_t size) = __default_morecore;
/* Debugging hook for `malloc'. */
@@ -490,18 +521,8 @@ register_heapinfo (void)
}
#ifdef USE_PTHREAD
-/* On Cygwin prior to 1.7.31, pthread_mutexes were ERRORCHECK mutexes
- by default. When the default changed to NORMAL in Cygwin-1.7.31,
- deadlocks occurred (bug#18222). As a temporary workaround, we
- explicitly set the mutexes to be of ERRORCHECK type, restoring the
- previous behavior. */
-#ifdef CYGWIN
-pthread_mutex_t _malloc_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
-pthread_mutex_t _aligned_blocks_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
-#else /* not CYGWIN */
pthread_mutex_t _malloc_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t _aligned_blocks_mutex = PTHREAD_MUTEX_INITIALIZER;
-#endif /* not CYGWIN */
int _malloc_thread_enabled_p;
static void
@@ -536,17 +557,8 @@ malloc_enable_thread (void)
initialized mutexes when they are used first. To avoid such a
situation, we initialize mutexes here while their use is
disabled in malloc etc. */
-#ifdef CYGWIN
- /* Use ERRORCHECK mutexes; see comment above. */
- pthread_mutexattr_t attr;
- pthread_mutexattr_init (&attr);
- pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK);
- pthread_mutex_init (&_malloc_mutex, &attr);
- pthread_mutex_init (&_aligned_blocks_mutex, &attr);
-#else /* not CYGWIN */
pthread_mutex_init (&_malloc_mutex, NULL);
pthread_mutex_init (&_aligned_blocks_mutex, NULL);
-#endif /* not CYGWIN */
pthread_atfork (malloc_atfork_handler_prepare,
malloc_atfork_handler_parent,
malloc_atfork_handler_child);
@@ -561,16 +573,6 @@ malloc_initialize_1 (void)
mcheck (NULL);
#endif
-#ifdef CYGWIN
- if (bss_sbrk_did_unexec)
- /* we're reinitializing the dumped emacs */
- {
- bss_sbrk_heapbase = _heapbase;
- bss_sbrk_heapinfo = _heapinfo;
- memset (_fraghead, 0, BLOCKLOG * sizeof (struct list));
- }
-#endif
-
if (__malloc_initialize_hook)
(*__malloc_initialize_hook) ();
@@ -1027,12 +1029,6 @@ _free_internal_nolock (void *ptr)
if (ptr == NULL)
return;
-#ifdef CYGWIN
- if ((char *) ptr < _heapbase)
- /* We're being asked to free something in the static heap. */
- return;
-#endif
-
PROTECT_MALLOC_STATE (0);
LOCK_ALIGNED_BLOCKS ();
@@ -1317,29 +1313,6 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
#define min(A, B) ((A) < (B) ? (A) : (B))
#endif
-/* On Cygwin the dumped emacs may try to realloc storage allocated in
- the static heap. We just malloc space in the new heap and copy the
- data. */
-#ifdef CYGWIN
-void *
-special_realloc (void *ptr, size_t size)
-{
- void *result;
- int type;
- size_t block, oldsize;
-
- block = ((char *) ptr - bss_sbrk_heapbase) / BLOCKSIZE + 1;
- type = bss_sbrk_heapinfo[block].busy.type;
- oldsize =
- type == 0 ? bss_sbrk_heapinfo[block].busy.info.size * BLOCKSIZE
- : (size_t) 1 << type;
- result = _malloc_internal_nolock (size);
- if (result)
- return memcpy (result, ptr, min (oldsize, size));
- return result;
-}
-#endif
-
/* Debugging hook for realloc. */
void *(*__realloc_hook) (void *ptr, size_t size);
@@ -1364,12 +1337,6 @@ _realloc_internal_nolock (void *ptr, size_t size)
else if (ptr == NULL)
return _malloc_internal_nolock (size);
-#ifdef CYGWIN
- if ((char *) ptr < _heapbase)
- /* ptr points into the static heap */
- return special_realloc (ptr, size);
-#endif
-
block = BLOCK (ptr);
PROTECT_MALLOC_STATE (0);
@@ -1566,7 +1533,7 @@ __default_morecore (ptrdiff_t increment)
{
void *result;
#if defined (CYGWIN)
- if (!bss_sbrk_did_unexec)
+ if (!DUMPED)
{
return bss_sbrk (increment);
}
@@ -1689,6 +1656,9 @@ memalign (size_t alignment, size_t size)
return aligned_alloc (alignment, size);
}
+/* If HYBRID_MALLOC is defined, we may want to use the system
+ posix_memalign below. */
+#ifndef HYBRID_MALLOC
int
posix_memalign (void **memptr, size_t alignment, size_t size)
{
@@ -1707,6 +1677,7 @@ posix_memalign (void **memptr, size_t alignment, size_t size)
return 0;
}
+#endif
/* Allocate memory on a page boundary.
Copyright (C) 1991, 92, 93, 94, 96 Free Software Foundation, Inc.
@@ -1747,6 +1718,102 @@ valloc (size_t size)
return aligned_alloc (pagesize, size);
}
+#ifdef HYBRID_MALLOC
+#undef malloc
+#undef realloc
+#undef calloc
+#undef aligned_alloc
+#undef free
+
+/* See the comments near the beginning of this file for explanations
+ of the following functions. */
+
+void *
+hybrid_malloc (size_t size)
+{
+ if (DUMPED)
+ return malloc (size);
+ return gmalloc (size);
+}
+
+void *
+hybrid_calloc (size_t nmemb, size_t size)
+{
+ if (DUMPED)
+ return calloc (nmemb, size);
+ return gcalloc (nmemb, size);
+}
+
+void
+hybrid_free (void *ptr)
+{
+ if (!DUMPED)
+ gfree (ptr);
+ else if (!ALLOCATED_BEFORE_DUMPING (ptr))
+ free (ptr);
+ /* Otherwise the dumped emacs is trying to free something allocated
+ before dumping; do nothing. */
+ return;
+}
+
+#if defined HAVE_ALIGNED_ALLOC || defined HAVE_POSIX_MEMALIGN
+void *
+hybrid_aligned_alloc (size_t alignment, size_t size)
+{
+ if (!DUMPED)
+ return galigned_alloc (alignment, size);
+ /* The following is copied from alloc.c */
+#ifdef HAVE_ALIGNED_ALLOC
+ return aligned_alloc (alignment, size);
+#else /* HAVE_POSIX_MEMALIGN */
+ void *p;
+ return posix_memalign (&p, alignment, size) == 0 ? p : 0;
+#endif
+}
+#endif
+
+void *
+hybrid_realloc (void *ptr, size_t size)
+{
+ void *result;
+ int type;
+ size_t block, oldsize;
+
+ if (!DUMPED)
+ return grealloc (ptr, size);
+ if (!ALLOCATED_BEFORE_DUMPING (ptr))
+ return realloc (ptr, size);
+
+ /* The dumped emacs is trying to realloc storage allocated before
+ dumping. We just malloc new space and copy the data. */
+ if (size == 0 || ptr == NULL)
+ return malloc (size);
+ block = ((char *) ptr - _heapbase) / BLOCKSIZE + 1;
+ type = _heapinfo[block].busy.type;
+ oldsize =
+ type == 0 ? _heapinfo[block].busy.info.size * BLOCKSIZE
+ : (size_t) 1 << type;
+ result = malloc (size);
+ if (result)
+ return memcpy (result, ptr, min (oldsize, size));
+ return result;
+}
+
+#ifdef HYBRID_GET_CURRENT_DIR_NAME
+/* Defined in sysdep.c. */
+char *gget_current_dir_name (void);
+
+char *
+hybrid_get_current_dir_name (void)
+{
+ if (DUMPED)
+ return get_current_dir_name ();
+ return gget_current_dir_name ();
+}
+#endif
+
+#endif /* HYBRID_MALLOC */
+
#ifdef GC_MCHECK
/* Standard debugging hooks for `malloc'.
diff --git a/src/lisp.h b/src/lisp.h
index b9f456b374..98734a5581 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -88,7 +88,8 @@ DEFINE_GDB_SYMBOL_END (GCTYPEBITS)
2. We know malloc returns a multiple of 8. */
#if (defined alignas \
&& (defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ \
- || defined DARWIN_OS || defined __sun || defined __MINGW32__))
+ || defined DARWIN_OS || defined __sun || defined __MINGW32__ \
+ || defined CYGWIN))
# define NONPOINTER_BITS 0
#else
# define NONPOINTER_BITS GCTYPEBITS
@@ -3629,7 +3630,7 @@ extern _Noreturn void memory_full (size_t);
extern _Noreturn void buffer_memory_full (ptrdiff_t);
extern bool survives_gc_p (Lisp_Object);
extern void mark_object (Lisp_Object);
-#if defined REL_ALLOC && !defined SYSTEM_MALLOC
+#if defined REL_ALLOC && !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
extern void refill_memory_reserve (void);
#endif
extern const char *pending_malloc_warning;
diff --git a/src/ralloc.c b/src/ralloc.c
index c82cd4548d..e63ed34c89 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/>. */
#define M_TOP_PAD -2
extern int mallopt (int, int);
#else /* not DOUG_LEA_MALLOC */
-#ifndef SYSTEM_MALLOC
+#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
extern size_t __malloc_extra_blocks;
-#endif /* SYSTEM_MALLOC */
+#endif /* not SYSTEM_MALLOC and not HYBRID_MALLOC */
#endif /* not DOUG_LEA_MALLOC */
#else /* not emacs */
@@ -95,7 +95,7 @@ static int extra_bytes;
/* The hook `malloc' uses for the function which gets more space
from the system. */
-#ifndef SYSTEM_MALLOC
+#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
extern void *(*__morecore) (ptrdiff_t);
#endif
@@ -1179,7 +1179,7 @@ r_alloc_init (void)
r_alloc_initialized = 1;
page_size = PAGE;
-#ifndef SYSTEM_MALLOC
+#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
real_morecore = __morecore;
__morecore = r_alloc_sbrk;
@@ -1198,7 +1198,7 @@ r_alloc_init (void)
mallopt (M_TOP_PAD, 64 * 4096);
unblock_input ();
#else
-#ifndef SYSTEM_MALLOC
+#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
/* Give GNU malloc's morecore some hysteresis so that we move all
the relocatable blocks much less often. The number used to be
64, but alloc.c would override that with 32 in code that was
@@ -1211,7 +1211,7 @@ r_alloc_init (void)
#endif
#endif
-#ifndef SYSTEM_MALLOC
+#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
first_heap->end = (void *) PAGE_ROUNDUP (first_heap->start);
/* The extra call to real_morecore guarantees that the end of the
diff --git a/src/sheap.c b/src/sheap.c
index 5069744435..dc34df5955 100644
--- a/src/sheap.c
+++ b/src/sheap.c
@@ -44,6 +44,7 @@ int debug_sheap = 0;
#define BLOCKSIZE 4096
char bss_sbrk_buffer[STATIC_HEAP_SIZE];
+char *bss_sbrk_buffer_end = bss_sbrk_buffer + STATIC_HEAP_SIZE;
char *bss_sbrk_ptr;
char *max_bss_sbrk_ptr;
int bss_sbrk_did_unexec;
diff --git a/src/sysdep.c b/src/sysdep.c
index a336a1e905..c753f84831 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/>. */
#include <config.h>
+/* If HYBRID_GET_CURRENT_DIR_NAME is defined in conf_post.h, then we
+ need the following before including unistd.h, in order to pick up
+ the right prototype for gget_current_dir_name. */
+#ifdef HYBRID_GET_CURRENT_DIR_NAME
+#undef get_current_dir_name
+#define get_current_dir_name gget_current_dir_name
+#endif
+
#include <execinfo.h>
#include "sysstdio.h"
#ifdef HAVE_PWD_H
@@ -121,9 +129,8 @@ static const int baud_convert[] =
1800, 2400, 4800, 9600, 19200, 38400
};
-
-#if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME)
-
+#if !defined HAVE_GET_CURRENT_DIR_NAME || defined BROKEN_GET_CURRENT_DIR_NAME \
+ || (defined HYBRID_GET_CURRENT_DIR_NAME)
/* Return the current working directory. Returns NULL on errors.
Any other returned value must be freed with free. This is used
only when get_current_dir_name is not defined on the system. */
diff --git a/src/unexcw.c b/src/unexcw.c
index 7636b05a12..72456b33ec 100644
--- a/src/unexcw.c
+++ b/src/unexcw.c
@@ -34,8 +34,6 @@ extern void report_sheap_usage (int);
extern int bss_sbrk_did_unexec;
-extern int __malloc_initialized;
-
/* emacs symbols that indicate where bss and data end for emacs internals */
extern char my_endbss[];
extern char my_edata[];
@@ -233,12 +231,9 @@ fixup_executable (int fd)
lseek (fd, (long) (exe_header->section_header[i].s_scnptr),
SEEK_SET);
assert (ret != -1);
- /* force the dumped emacs to reinitialize malloc */
- __malloc_initialized = 0;
ret =
write (fd, (char *) start_address,
my_endbss - (char *) start_address);
- __malloc_initialized = 1;
assert (ret == (my_endbss - (char *) start_address));
if (debug_unexcw)
printf (" .bss, mem start %#lx mem length %d\n",
diff --git a/src/xdisp.c b/src/xdisp.c
index 1f2c5a02d6..2b12dd8f55 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,
}
case 'e':
-#ifndef SYSTEM_MALLOC
+#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
{
if (NILP (Vmemory_full))
return "";