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.
This commit is contained in:
parent
a7ef7a0e53
commit
ea65250077
13 changed files with 274 additions and 115 deletions
|
@ -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.
|
||||
|
|
19
configure.ac
19
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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
15
src/alloc.c
15
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)
|
||||
|
|
|
@ -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
|
||||
|
|
19
src/emacs.c
19
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
|
||||
|
|
231
src/gmalloc.c
231
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'.
|
||||
|
|
|
@ -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;
|
||||
|
|
12
src/ralloc.c
12
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
|
||||
|
|
|
@ -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;
|
||||
|
|
13
src/sysdep.c
13
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. */
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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 "";
|
||||
|
|
Loading…
Add table
Reference in a new issue