From 000f846876d84adf1a71f72a129b072593893c5b Mon Sep 17 00:00:00 2001 From: Steve Youngs Date: Sun, 26 May 2019 16:15:34 +1000 Subject: [PATCH] Always use the system malloc (removes gmalloc.c malloc.c). This changeset removes our in-house malloc.c and gmalloc.c and switches to always using the system provided malloc. * src/mem/gmalloc.c: Removed. * src/mem/malloc.c: Removed. * info/internals/internals.texi (Low-Level Modules): Nuke descriptions for gmalloc.c and malloc.c, update description for free-hook.c * src/ui/X11/device-x.c (x_delete_device): 'FREE_CHECKING' is never defined and __free_hook is never used so remove crusty bits of code conditional to it. * src/mem/Makefile.am (EXTRA_libmemalloc_a_SOURCES): Remove gmalloc.c and malloc.c. * src/mem/free-hook.c: Remove all of the old gmalloc debugging stuff. * src/mem/ralloc.c: Use HAVE_GLIBC instead of DOUG_LEA_MALLOC. (Free_Addr_Block): Use void because caddr_t hasn't been a thing for at least a hundred years. * src/regex.c: Use HAVE_GLIBC instead of DOUG_LEA_MALLOC. * src/alloc.c: Use HAVE_GLIBC instead of DOUG_LEA_MALLOC. Ditto for GNU_MALLOC. (malloced_storage_size): Because it's always system malloc, update this to use GNU malloc accounting when on a glibc system. * m4/sxe-summary.m4 (SXE_SUMMARY): It's always system malloc now so no need to say if GNU malloc is used. * src/emacs.c (main): Use HAVE_MALLOC_WARNING instead of _NO_MALLOC_WARNING_ Use HAVE_GLIBC instead of DOUG_LEA_MALLOC. (Fdump_emacs): Don't use disable_free_hook(). * src/mem/vm-limit.c: Use HAVE_MALLOC_WARNING instead of _NO_MALLOC_WARNING_ and reverse the condition sense. * m4/sxe-libc.m4 (SXE_CHECK_LIBC): Define HAVE_GLIBC. * configure.ac: Removed --with-dlmalloc, --with-system-malloc Define HAVE_MALLOC_WARNING instead of _NO_MALLOC_WARNING_. Remove check for malloc_set_state() it's not used anywhere. Don't give reasons why or not GNU malloc is used because it's not. Don't define DOUG_LEA_MALLOC. Don't add gmalloc.o or malloc.o to MEMALLOC_OBJS. Define HAVE_LIBMCHECK. Add -lmcheck to MEMALLOC_LIBS. Signed-off-by: Steve Youngs --- configure.ac | 118 +--- info/internals/internals.texi | 16 +- m4/sxe-libc.m4 | 1 + m4/sxe-summary.m4 | 1 - src/alloc.c | 40 +- src/emacs.c | 116 +-- src/mem/Makefile.am | 3 +- src/mem/free-hook.c | 378 +--------- src/mem/gmalloc.c | 1250 --------------------------------- src/mem/malloc.c | 813 --------------------- src/mem/ralloc.c | 12 +- src/mem/vm-limit.c | 8 +- src/regex.c | 2 +- src/ui/X11/device-x.c | 15 - 14 files changed, 64 insertions(+), 2709 deletions(-) delete mode 100644 src/mem/gmalloc.c delete mode 100644 src/mem/malloc.c diff --git a/configure.ac b/configure.ac index 48a1d29..b63a2b9 100644 --- a/configure.ac +++ b/configure.ac @@ -295,21 +295,11 @@ OG_ARG_WITH([rel-alloc], [Relocating allocator for buffers.]), [default], [Autodetect]) -OG_ARG_WITH([dlmalloc], - AS_HELP_STRING([--with-dlmalloc], - [Use Doug Lea's malloc.]), - [default], [Autodetect]) - OG_ARG_WITH([debug-malloc], AS_HELP_STRING([--with-debug-malloc], [Use a debugging malloc.]), [no], [NO]) -OG_ARG_WITH([system-malloc], - AS_HELP_STRING([--with-system-malloc], - [Use a system malloc instead of GNU.]), - [yes], [YES]) - OG_ARG_WITH([regex-malloc], AS_HELP_STRING([--with-regex-malloc], [Use malloc for regex failure stack.]), @@ -1583,26 +1573,22 @@ esac AC_MSG_RESULT($have_mmap) test "$have_mmap" = "yes" && AC_DEFINE([HAVE_MMAP], [1], [Description here!]) -dnl rel_alloc requires either GNU malloc or system malloc with mmap +dnl rel_alloc requires a malloc with mmap dnl We only turn rel_alloc on by default if mmap is available. -test "$GNU_MALLOC" != "yes" -a "$have_mmap" != "yes" && with_rel_alloc=no +test "$have_mmap" != "yes" && with_rel_alloc=no if test "$with_rel_alloc $have_mmap" = "default yes"; then - if test "$doug_lea_malloc" = "yes"; then - dnl Check if malloc() calls mmap(), making rel_alloc pointless. - AC_MSG_CHECKING(for M_MMAP_THRESHOLD) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]],[[ + dnl Check if malloc() calls mmap(), making rel_alloc pointless. + AC_MSG_CHECKING(for M_MMAP_THRESHOLD) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]],[[ #ifndef M_MMAP_THRESHOLD #error No M_MMAP_THRESHOLD :-( !@+$%^&*_)(_ - unlikely to compile... #endif - ]])], [ - with_rel_alloc=no - AC_MSG_RESULT(yes)], [ - with_rel_alloc=yes - AC_MSG_RESULT(no)]) - else + ]])], [ + with_rel_alloc=no + AC_MSG_RESULT(yes)], [ with_rel_alloc=yes - fi + AC_MSG_RESULT(no)]) fi if test "$with_rel_alloc" = "yes"; then AC_DEFINE([REL_ALLOC], [1], [Description here!]) @@ -1729,16 +1715,7 @@ dnl ----------------------------------- dnl Do some misc autoconf-special tests dnl ----------------------------------- -dnl Do the opsystem or machine files prohibit the use of the GNU malloc? -dnl Assume not, until told otherwise. -GNU_MALLOC=yes -if test "$with_dlmalloc" != "no"; then - doug_lea_malloc=yes -else - doug_lea_malloc=no -fi after_morecore_hook_exists=yes -AC_CHECK_FUNC(malloc_set_state, ,doug_lea_malloc=no) AC_MSG_CHECKING(whether __after_morecore_hook exists) AC_LINK_IFELSE([AC_LANG_SOURCE([ [extern void (* __after_morecore_hook)();] @@ -1748,59 +1725,29 @@ AC_LINK_IFELSE([AC_LANG_SOURCE([ [AC_MSG_RESULT(no) after_morecore_hook_exists=no]) if test "$after_morecore_hook_exists" = "yes" ; then - AC_DEFINE([HAVE_MORECORE_HOOK], [1], [Define if __after_morecore_hook is available]) + AC_DEFINE([HAVE_MORECORE_HOOK], [1], + [Define if __after_morecore_hook is available]) + AC_DEFINE([HAVE_MALLOC_WARNING], [1], + [Define if __after_morecore_hook is available]) fi AC_SUBST(HAVE_MORECORE_HOOK) -free_hook_exists=yes -AC_MSG_CHECKING(whether __free_hook exists) -AC_LINK_IFELSE([AC_LANG_SOURCE([ - [extern void (* __free_hook)();] - [main() {__free_hook = 0;}] - ])], - [AC_MSG_RESULT(yes)], - [AC_MSG_RESULT(no) - free_hook_exists=no]) -if test "$free_hook_exists" = "yes" ; then - AC_DEFINE([HAVE_FREE_HOOK], [1], [Define if __free_hook is available]) -fi -AC_SUBST(HAVE_FREE_HOOK) -if test "$system_malloc" = "yes" ; then - GNU_MALLOC=no - GNU_MALLOC_reason=" - - The GNU allocators don't work with this system configuration." -elif test "$with_system_malloc" = "yes" ; then - GNU_MALLOC=no - GNU_MALLOC_reason=" - - User chose not to use GNU allocators." -elif test "$with_debug_malloc" = "yes" ; then - GNU_MALLOC=no - GNU_MALLOC_reason=" - - User chose to use Debugging Malloc." -fi -if test "$doug_lea_malloc" = "yes" -a "$GNU_MALLOC" = "yes" ; then - GNU_MALLOC_reason=" - - Using Doug Lea's new malloc from the GNU C Library." - AC_DEFINE([DOUG_LEA_MALLOC], [1], [Description here!]) - if test "$after_morecore_hook_exists" = "no" ; then - GNU_MALLOC_reason=" - - Using Doug Lea's new malloc from the Linux C Library." - AC_DEFINE([_NO_MALLOC_WARNING_], [1], [Description here!]) - fi -fi AM_CONDITIONAL([USE_MEMALLOC], [test -n "${libmemalloc_objs}"]) -dnl #### mcheck is broken in all versions of Linux libc and glibc. -dnl Try this again when 2.1 hits the streets. -dnl Avoid using free-hook.c if support exists for malloc debugging in libc +dnl Use the support for for malloc debugging in libc if available. have_libmcheck=no if test "$with_error_checking_malloc" = "yes" -a \ - "$have_glibc" = "yes" -a \ - "$doug_lea_malloc" = "yes"; then + "$have_glibc" = "yes" -a; then AC_CHECK_HEADERS(mcheck.h) AC_CHECK_LIB(mcheck, mcheck, [have_libmcheck=yes], [have_libmcheck=no]) fi +if test "have_libmcheck" = "yes"; then + AC_DEFINE([HAVE_LIBMCHECK], [1], + [Define if malloc debugging via libmcheck is available]) + SXE_PREPEND(-lmcheck, MEMALLOC_LIBS) +fi + if test "$with_module_support" != "no"; then AS_MESSAGE([checking for module support]) if test "$sxe_cv_feat_libltdl" = "yes"; then @@ -4102,29 +4049,12 @@ dnl at the point where the autodetection occurs or would occur, dnl so that the user gets immediate feedback on the results of the dnl autodetection. -if test "$GNU_MALLOC" = "yes"; then - AC_DEFINE([GNU_MALLOC], [1], [Description here!]) +AC_DEFINE([SYSTEM_MALLOC], [1], [Description here!]) +test "$after_morecore_hook_exists" = "yes" && \ SXE_ADD_MEMALLOC_OBJS(vm-limit.o) - if test "$doug_lea_malloc" != "yes"; then - SXE_ADD_MEMALLOC_OBJS(gmalloc.o) - fi - if test "$with_error_checking_malloc" = "yes"; then - dnl SXE_ADD_MEMALLOC_OBJS(free-hook.o) - : - fi -elif test "$with_system_malloc" = "yes" -o "$system_malloc" = "yes"; then - if test "$after_morecore_hook_exists" = "yes"; then - SXE_ADD_MEMALLOC_OBJS(vm-limit.o) - fi - AC_DEFINE([USE_SYSTEM_MALLOC], [1], [Description here!]) - AC_DEFINE([SYSTEM_MALLOC], [1], [Description here!]) -elif test "$with_debug_malloc" = "yes"; then +if test "$with_debug_malloc" = "yes"; then AC_DEFINE([USE_DEBUG_MALLOC], [1], [Description here!]) - AC_DEFINE([USE_SYSTEM_MALLOC], [1], [Description here!]) - AC_DEFINE([SYSTEM_MALLOC], [1], [Description here!]) SXE_APPEND(-ldmalloc, MEMALLOC_LIBS) -else - SXE_ADD_MEMALLOC_OBJS([malloc.o]) fi test "$GCC" = "yes" && \ AC_DEFINE([USE_GCC], [1], [Description here!]) diff --git a/info/internals/internals.texi b/info/internals/internals.texi index 486a906..33dcc3c 100644 --- a/info/internals/internals.texi +++ b/info/internals/internals.texi @@ -3676,8 +3676,6 @@ data space when dumping. alloca.c free-hook.c getpagesize.h -gmalloc.c -malloc.c mem-limits.h ralloc.c vm-limit.c @@ -3687,16 +3685,6 @@ These handle basic C allocation of memory. @file{alloca.c} is an emulation of the stack allocation function @code{alloca()} on machines that lack this. (SXEmacs makes extensive use of @code{alloca()} in its code.) -@file{gmalloc.c} and @file{malloc.c} are two implementations of the standard C -functions @code{malloc()}, @code{realloc()} and @code{free()}. They are -often used in place of the standard system-provided @code{malloc()} -because they usually provide a much faster implementation, at the -expense of additional memory use. @file{gmalloc.c} is a newer implementation -that is much more memory-efficient for large allocations than @file{malloc.c}, -and should always be preferred if it works. (At one point, @file{gmalloc.c} -didn't work on some systems where @file{malloc.c} worked; but this should be -fixed now.) - @cindex relocating allocator @file{ralloc.c} is the @dfn{relocating allocator}. It provides functions similar to @code{malloc()}, @code{realloc()} and @code{free()} @@ -3715,7 +3703,9 @@ which can speed things up; but it can still cause noticeable performance degradation.) @file{free-hook.c} contains some debugging functions for checking for invalid -arguments to @code{free()}. +arguments to @code{free()}. Or, at least, it use to. Now it contains +code to aid in debugging GCPRO functions. Although, at the time of +writing, they aren't yet being used. @file{vm-limit.c} contains some functions that warn the user when memory is getting low. These are callback functions that are called by @file{gmalloc.c} diff --git a/m4/sxe-libc.m4 b/m4/sxe-libc.m4 index cebc256..10a414b 100644 --- a/m4/sxe-libc.m4 +++ b/m4/sxe-libc.m4 @@ -51,6 +51,7 @@ AC_DEFUN([SXE_CHECK_LIBC], [dnl if test "$have_glibc" = "yes"; then AC_DEFINE([_GNU_SOURCE], [1], [Enable GNU extensions on systems that have them.]) + AC_DEFINE([HAVE_GLIBC], [1], [Define if libc is glibc]) AH_VERBATIM([_ALL_SOURCE], [dnl /* WTF?! */ #ifndef _ALL_SOURCE diff --git a/m4/sxe-summary.m4 b/m4/sxe-summary.m4 index 9d67c28..3667edb 100644 --- a/m4/sxe-summary.m4 +++ b/m4/sxe-summary.m4 @@ -59,7 +59,6 @@ echo " All: $ld_libs_all" echo "" echo " libc version: $libc_version" echo " Relocating allocator for buffers: $with_rel_alloc" -echo " GNU version of malloc: ${GNU_MALLOC}${GNU_MALLOC_reason}" case "$ld_switch_site" in *nocombreloc*) echo " Linking with \`-z nocombreloc'. - Consider configuring with --with-pdump." ;; diff --git a/src/alloc.c b/src/alloc.c index 9c07f16..d02732a 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -63,7 +63,7 @@ along with this program. If not, see . */ #include #include -#ifdef DOUG_LEA_MALLOC +#ifdef HAVE_GLIBC #include #endif @@ -704,7 +704,7 @@ int dbg_eq(Lisp_Object obj1, Lisp_Object obj2) an object of that type is allocated. */ #ifndef MALLOC_OVERHEAD -#ifdef GNU_MALLOC +#ifdef HAVE_GLIBC #define MALLOC_OVERHEAD 0 #elif defined (rcheck) #define MALLOC_OVERHEAD 20 @@ -713,7 +713,7 @@ int dbg_eq(Lisp_Object obj1, Lisp_Object obj2) #endif #endif /* MALLOC_OVERHEAD */ -#if !defined(HAVE_MMAP) || defined(DOUG_LEA_MALLOC) +#if !defined(HAVE_MMAP) || defined(HAVE_GLIBC) /* If we released our reserve (due to running out of memory), and we have a fair amount free once again, try to set aside another reserve in case we run out once more. @@ -726,7 +726,7 @@ void refill_memory_reserve(void) breathing_space = malloc(0xFFFF - MALLOC_OVERHEAD); } } -#endif /* !HAVE_MMAP || DOUG_LEA_MALLOC */ +#endif /* !HAVE_MMAP || HAVE_GLIBC */ #ifdef ALLOC_NO_POOLS # define TYPE_ALLOC_SIZE(type, structtype) 1 @@ -5197,7 +5197,7 @@ malloced_storage_size(void *ptr, size_t claimed_size, { size_t orig_claimed_size = claimed_size; -#ifdef GNU_MALLOC +#ifdef HAVE_GLIBC if (claimed_size < 2 * sizeof(void *)) claimed_size = 2 * sizeof(void *); @@ -5230,37 +5230,13 @@ malloced_storage_size(void *ptr, size_t claimed_size, claimed_size += (claimed_size / 4096) * 3 * sizeof(size_t); } -#elif defined (SYSTEM_MALLOC) +#else if (claimed_size < 16) claimed_size = 16; claimed_size += 2 * sizeof(void *); -#else /* old GNU allocator */ - -# ifdef rcheck /* #### may not be defined here */ - claimed_size += 20; -# else - claimed_size += 8; -# endif - { - int _log_ = 1; - - /* compute the log base two, more or less, then use it to compute - the block size needed. */ - claimed_size--; - /* It's big, it's heavy, it's wood! */ - while ((claimed_size /= 2) != 0) - ++_log_; - claimed_size = 1; - /* It's better than bad, it's good! */ - while (_log_ > 0) { - claimed_size *= 2; - _log_--; - } - } - -#endif /* old GNU allocator */ +#endif /* HAVE_GLIBC */ if (stats) { stats->was_requested += orig_claimed_size; @@ -5387,7 +5363,7 @@ void reinit_alloc_once_early(void) all_lcrecords = 0; #endif /* !BDWGC */ ignore_malloc_warnings = 1; -#ifdef DOUG_LEA_MALLOC +#ifdef HAVE_GLIBC mallopt(M_TRIM_THRESHOLD, 128 * 1024); /* trim threshold */ mallopt(M_MMAP_THRESHOLD, 64 * 1024); /* mmap threshold */ #if 1 /* Moved to emacs.c */ diff --git a/src/emacs.c b/src/emacs.c index 49fa20d..f4583ff 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -229,12 +229,6 @@ extern void *GC_init(void); # endif #endif /* HAVE_BDWGC */ -#if !defined (SYSTEM_MALLOC) && !defined (DOUG_LEA_MALLOC) -extern void *(*__malloc_hook) (size_t); -extern void *(*__realloc_hook) (void *, size_t); -extern void (*__free_hook) (void *); -#endif /* not SYSTEM_MALLOC && not DOUG_LEA_MALLOC */ - /* Command line args from shell, as list of strings */ Lisp_Object Vcommand_line_args; @@ -243,12 +237,12 @@ Lisp_Object Vcommand_line_args; on subsequent starts. */ int initialized; -#ifdef DOUG_LEA_MALLOC +#ifdef HAVE_GLIBC # include /* Preserves a pointer to the memory allocated that copies that static data inside glibc's malloc. */ static void *malloc_state_ptr; -#endif /* DOUG_LEA_MALLOC */ +#endif /* HAVE_GLIBC */ # ifdef REL_ALLOC void r_alloc_reinit(void); @@ -914,17 +908,6 @@ DOESNT_RETURN main_1(int argc, char **argv, char **envp, int restart) extern int malloc_cookie; #endif -#if (!defined (SYSTEM_MALLOC) && !defined (HAVE_LIBMCHECK) \ - && !defined (DOUG_LEA_MALLOC)) - /* Make sure that any libraries we link against haven't installed a - hook for a gmalloc of a potentially incompatible version. */ - /* If we're using libmcheck, the hooks have already been initialized, */ - /* don't touch them. -slb */ - __malloc_hook = NULL; - __realloc_hook = NULL; - __free_hook = NULL; -#endif /* not SYSTEM_MALLOC or HAVE_LIBMCHECK or DOUG_LEA_MALLOC */ - noninteractive = 0; inhibit_non_essential_printing_operations = 1; @@ -941,21 +924,6 @@ DOESNT_RETURN main_1(int argc, char **argv, char **envp, int restart) stderr_out("malloc jumpstart failed!\n"); #endif /* NeXT */ - /* - #if defined (GNU_MALLOC) && \ - defined (ERROR_CHECK_MALLOC) && \ - !defined (HAVE_LIBMCHECK) - */ -#if defined(LOSING_GCC_DESTRUCTOR_FREE_BUG) - /* Prior to SXEmacs 21, this was `#if 0'ed out. */ - /* I'm enabling this because it is the only reliable way I've found to */ - /* prevent a very annoying problem where GCC will attempt to free(3) */ - /* memory at exit() and cause a coredump. */ -#if 0 - init_free_hook(); -#endif -#endif - sort_args(argc, argv); #if defined(_SCO_DS) @@ -977,7 +945,7 @@ DOESNT_RETURN main_1(int argc, char **argv, char **envp, int restart) #if defined (HAVE_MMAP) && defined (REL_ALLOC) /* ralloc can only be used if using the GNU memory allocator. */ init_ralloc(); -#elif defined (REL_ALLOC) && !defined(DOUG_LEA_MALLOC) +#elif defined (REL_ALLOC) && !defined(HAVE_GLIBC) if (initialized) init_ralloc(); #endif @@ -1432,7 +1400,7 @@ DOESNT_RETURN main_1(int argc, char **argv, char **envp, int restart) syms_of_process(); #endif syms_of_profile(); -#if defined (HAVE_MMAP) && defined (REL_ALLOC) && !defined(DOUG_LEA_MALLOC) +#if defined (HAVE_MMAP) && defined (REL_ALLOC) && !defined(HAVE_GLIBC) syms_of_ralloc(); #endif /* HAVE_MMAP && REL_ALLOC */ syms_of_rangetab(); @@ -1510,16 +1478,6 @@ DOESNT_RETURN main_1(int argc, char **argv, char **envp, int restart) SYMS_MACHINE; #endif - /* - #if defined (GNU_MALLOC) && \ - defined (ERROR_CHECK_MALLOC) && \ - !defined (HAVE_LIBMCHECK) - */ - /* Prior to SXEmacs 21, this was `#if 0'ed out. -slb */ -#if defined (LOSING_GCC_DESTRUCTOR_FREE_BUG) - syms_of_free_hook(); -#endif - #ifdef SUNPRO syms_of_sunpro(); #endif @@ -1825,7 +1783,7 @@ DOESNT_RETURN main_1(int argc, char **argv, char **envp, int restart) #endif vars_of_profile(); -#if defined (HAVE_MMAP) && defined (REL_ALLOC) && !defined(DOUG_LEA_MALLOC) +#if defined (HAVE_MMAP) && defined (REL_ALLOC) && !defined(HAVE_GLIBC) vars_of_ralloc(); #endif /* HAVE_MMAP && REL_ALLOC */ vars_of_redisplay(); @@ -2698,7 +2656,7 @@ main(int argc, char **argv, char **envp) init_bdwgc(); if (!initialized) { -#ifdef DOUG_LEA_MALLOC +#ifdef HAVE_GLIBC if (mallopt(M_MMAP_MAX, 0) != 1) abort(); #endif @@ -2739,7 +2697,7 @@ main(int argc, char **argv, char **envp) run_time_remap(argv[0]); #endif -#ifdef DOUG_LEA_MALLOC +#ifdef HAVE_GLIBC if (initialized && (malloc_state_ptr != NULL)) { int rc = malloc_set_state(malloc_state_ptr); if (rc != 0) { @@ -2753,9 +2711,8 @@ main(int argc, char **argv, char **envp) /* mmap works in glibc-2.1, glibc-2.0 (Non-Mule only) * and Linux libc5 */ #if (defined(__GLIBC__) && __GLIBC_MINOR__ >= 1) || \ - defined(_NO_MALLOC_WARNING_) || \ - (defined(__GLIBC__) && __GLIBC_MINOR__ < 1 && !defined(MULE)) || \ - defined(DEBUG_DOUG_LEA_MALLOC) + defined(HAVE_MALLOC_WARNING) || \ + (defined(__GLIBC__) && __GLIBC_MINOR__ < 1 && !defined(MULE)) if (mallopt(M_MMAP_MAX, 0) != 1) abort(); #endif @@ -2763,7 +2720,7 @@ main(int argc, char **argv, char **envp) r_alloc_reinit(); #endif } - #endif /* DOUG_LEA_MALLOC */ +#endif /* HAVE_GLIBC */ run_temacs_argc = -1; @@ -2773,32 +2730,6 @@ main(int argc, char **argv, char **envp) } -/* Dumping apparently isn't supported by versions of GCC >= 2.8. */ -/* The following needs conditionalization on whether either SXEmacs or */ -/* various system shared libraries have been built and linked with */ -/* GCC >= 2.8. -slb */ -#if defined(GNU_MALLOC) -#if defined(HAVE_MORECORE_HOOK) -static void voodoo_free_hook(void *mem) -{ - /* If it no longer works, we'll know about it. For now there is really no - good alternatic. Shut the warning off - */ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - - /* Disable all calls to free() when SXEmacs is exiting and it doesn't */ - /* matter. */ - __free_hook = -#if defined __GNUC__ || defined __INTEL_COMPILER -/* prototype of __free_hook varies with glibc version */ - (__typeof__(__free_hook)) -#endif - voodoo_free_hook; -#pragma GCC diagnostic pop -} -#endif -#endif /* GNU_MALLOC */ DEFUN("kill-emacs", Fkill_emacs, 0, 1, "P", /* Exit the SXEmacs job and kill it. Ask for confirmation, without argument. @@ -2851,20 +2782,6 @@ all of which are called before SXEmacs is actually killed. shut_down_emacs(0, STRINGP(arg) ? arg : Qnil, 0); -#if defined(GNU_MALLOC) -#if defined(HAVE_MORECORE_HOOK) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - __free_hook = -#if defined __GNUC__ || defined __INTEL_COMPILER -/* prototype of __free_hook varies with glibc version */ - (__typeof__(__free_hook)) -#endif - voodoo_free_hook; -#pragma GCC diagnostic pop -#endif -#endif - exit(INTP(arg) ? XINT(arg) : 0); /* NOTREACHED */ return Qnil; /* I'm sick of the compiler warning */ @@ -3000,8 +2917,6 @@ static void shut_down_emacs(int sig, Lisp_Object stuff, int no_auto_save) extern char my_edata[]; #endif -extern void disable_free_hook(void); - DEFUN("dump-emacs", Fdump_emacs, 2, 2, 0, /* Dump current state of SXEmacs into executable file FILENAME. Take symbols from SYMFILE (presumably the file you executed to run SXEmacs). @@ -3025,13 +2940,6 @@ and announce itself normally when it is run. Vcommand_line_args = Qnil; #endif -#ifdef FREE_CHECKING - Freally_free(Qnil); - - /* When we're dumping, we can't use the debugging free() */ - disable_free_hook(); -#endif - CHECK_STRING(filename); filename = Fexpand_file_name(filename, Qnil); if (!NILP(symfile)) { @@ -3082,7 +2990,7 @@ and announce itself normally when it is run. pdump(filename_ext); #else -#ifdef DOUG_LEA_MALLOC +#ifdef HAVE_GLIBC malloc_state_ptr = malloc_get_state(); #endif /* here we break our rule that the filename conversion should @@ -3092,7 +3000,7 @@ and announce itself normally when it is run. conversion is applied everywhere. Don't worry about memory leakage because this call only happens once. */ unexec(filename_ext, symfile_ext, (uintptr_t) my_edata, 0, 0); -#ifdef DOUG_LEA_MALLOC +#ifdef HAVE_GLIBC free(malloc_state_ptr); #endif #endif /* not PDUMP */ diff --git a/src/mem/Makefile.am b/src/mem/Makefile.am index b8f7fc3..566f773 100644 --- a/src/mem/Makefile.am +++ b/src/mem/Makefile.am @@ -64,8 +64,7 @@ if USE_MEMALLOC libmemalloc_a_headers = libmemalloc_a_sources = libmemalloc_a_SOURCES = $(libmemalloc_a_headers) $(libmemalloc_a_sources) -EXTRA_libmemalloc_a_SOURCES = \ - free-hook.c gmalloc.c malloc.c vm-limit.c ralloc.c +EXTRA_libmemalloc_a_SOURCES = free-hook.c vm-limit.c ralloc.c libmemalloc_a_CPPFLAGS = $(AM_CPPFLAGS) libmemalloc_a_LIBADD = $(libmemalloc_objs) libmemalloc_a_DEPENDENCIES = $(libmemalloc_a_LIBADD) diff --git a/src/mem/free-hook.c b/src/mem/free-hook.c index 8634f9f..9b88f7d 100644 --- a/src/mem/free-hook.c +++ b/src/mem/free-hook.c @@ -17,383 +17,13 @@ along with this program. If not, see . */ /* Synched up with: Not in FSF. */ -/* Debugging hooks for malloc. */ - -/* These hooks work with gmalloc to catch allocation errors. - In particular, the following is trapped: - - * Freeing the same pointer twice. - * Trying to free a pointer not returned by malloc. - * Trying to realloc a pointer not returned by malloc. - - In addition, every word of every block freed is set to - 0xdeadbeef. This causes many uses of freed storage to be - trapped or recognized. - - When you use this, the storage used by the last FREE_QUEUE_LIMIT - calls to free() is not recycled. When you call free for the Nth - time, the (N - FREE_QUEUE_LIMIT)'th block is actually recycled. - - For these last FREE_QUEUE_LIMIT calls to free() a backtrace is - saved showing where it was called from. The function - find_backtrace() is provided here to be called from GDB with a - pointer (such as would be passed to free()) as argument, e.g. - (gdb) p/a *find_backtrace (0x234000). If SAVE_ARGS is defined, - the first three arguments to each function are saved as well as the - return addresses. - - If UNMAPPED_FREE is defined, instead of setting every word of freed - storage to 0xdeadbeef, every call to malloc goes on its own page(s). - When free() is called, the block is read and write protected. This - is very useful when debugging, since it usually generates a bus error - when the deadbeef hack might only cause some garbage to be printed. - However, this is too slow for everyday use, since it takes an enormous - number of pages. - - Some other features that would be useful are: - - * Checking for storage leaks. - This could be done by a GC-like facility that would scan the data - segment looking for pointers to allocated storage and tell you - about those that are no longer referenced. This could be invoked - at any time. Another possibility is to report on what allocated - storage is still in use when the process is exited. Typically - there will be a large amount, so this might not be very useful. -*/ - -#ifdef emacs + #include #include "lisp.h" -#else -void *malloc(size_t); -#endif - -#if !defined(HAVE_LIBMCHECK) -#include - -#include "hash.h" - -#ifdef UNMAPPED_FREE -#include -#include -#define ROUND_UP_TO_PAGE(i) (((i) + PAGEOFFSET) & PAGEMASK) -#endif - -#include - -/* System function prototypes don't belong in C source files */ -/* extern void free (void *); */ - -static struct hash_table *pointer_table; - -extern void (*__free_hook) (void *); -extern void *(*__malloc_hook) (size_t); - -static void *check_malloc(size_t); - -typedef void (*fun_ptr) (void); - -/* free_queue is not too useful without backtrace logging */ -#define FREE_QUEUE_LIMIT 1 -#define TRACE_LIMIT 20 - -typedef struct { - fun_ptr return_pc; -#ifdef SAVE_ARGS - void *arg[3]; -#endif -} fun_entry; - -typedef struct { - void *address; - unsigned long length; -} free_queue_entry; - -static free_queue_entry free_queue[FREE_QUEUE_LIMIT]; - -static int current_free; - -static int strict_free_check; - -static void check_free(void *ptr) -{ - __free_hook = 0; - __malloc_hook = 0; - if (!pointer_table) - pointer_table = make_hash_table(max(100, FREE_QUEUE_LIMIT * 2)); - if (ptr != 0) { - long size; -#ifdef UNMAPPED_FREE - unsigned long rounded_up_size; -#endif - - EMACS_INT present = - (EMACS_INT)gethash(ptr, pointer_table, - (const void **)((void*)&size)); - - if (!present) { - /* This can only happen if you try to free something that didn't - come from malloc */ -#if !defined(__linux__) - /* I originally wrote: "There's really no need to drop core." - I have seen the error of my ways. -slb */ - if (strict_free_check) - abort(); -#endif - printf("Freeing unmalloc'ed memory at %p\n", ptr); - __free_hook = check_free; - __malloc_hook = check_malloc; - goto end; - } - - if (size < 0) { - /* This happens when you free twice */ -#if !defined(__linux__) - /* See above comment. */ - if (strict_free_check) - abort(); -#endif - printf("Freeing %p twice\n", ptr); - __free_hook = check_free; - __malloc_hook = check_malloc; - goto end; - } - - puthash(ptr, (void *)-size, pointer_table); -#ifdef UNMAPPED_FREE - /* Round up size to an even number of pages. */ - rounded_up_size = ROUND_UP_TO_PAGE(size); - /* Protect the pages freed from all access */ - if (strict_free_check) - mprotect(ptr, rounded_up_size, PROT_NONE); -#else - /* Set every word in the block to 0xdeadbeef */ - if (strict_free_check) { - unsigned long long_length = (size + (sizeof(long) - 1)) - / sizeof(long); - unsigned long i; - - for (i = 0; i < long_length; i++) - ((unsigned long *)ptr)[i] = 0xdeadbeef; - } -#endif - free_queue[current_free].address = ptr; - free_queue[current_free].length = size; - - current_free++; - if (current_free >= FREE_QUEUE_LIMIT) - current_free = 0; - /* Really free this if there's something there */ - { - void *old = free_queue[current_free].address; - - if (old) { -#ifdef UNMAPPED_FREE - unsigned long old_len = - free_queue[current_free].length; - - mprotect(old, old_len, - PROT_READ | PROT_WRITE | PROT_EXEC); -#endif - free(old); - remhash(old, pointer_table); - } - } - } - __free_hook = check_free; - __malloc_hook = check_malloc; - - end: - return; -} - -static void *check_malloc(size_t size) -{ - size_t rounded_up_size; - void *result; - - __free_hook = 0; - __malloc_hook = 0; - if (size == 0) { - result = 0; - goto end; - } -#ifdef UNMAPPED_FREE - /* Round up to an even number of pages. */ - rounded_up_size = ROUND_UP_TO_PAGE(size); -#else - rounded_up_size = size; -#endif - result = malloc(rounded_up_size); - if (!pointer_table) - pointer_table = make_hash_table(FREE_QUEUE_LIMIT * 2); - puthash(result, (void *)size, pointer_table); - __free_hook = check_free; - __malloc_hook = check_malloc; - end: - return result; -} - -extern void *(*__realloc_hook) (void *, size_t); - -#ifdef MIN -#undef MIN -#endif -#define MIN(A, B) ((A) < (B) ? (A) : (B)) - -/* Don't optimize realloc */ - -static void *check_realloc(void *ptr, size_t size) -{ - EMACS_INT present; - size_t old_size; - void *result = malloc(size); - - if (!ptr) - return result; - present = - (EMACS_INT)gethash(ptr, pointer_table, - (const void **)((void*)&old_size)); - if (!present) { - /* This can only happen by reallocing a pointer that didn't - come from malloc. */ -#if !defined(__linux__) - /* see comment in check_free(). */ - abort(); -#endif - printf("Realloc'ing unmalloc'ed pointer at %p\n", ptr); - } - - if (result == 0) - goto end; - memcpy(result, ptr, MIN(size, old_size)); - free(ptr); - end: - return result; -} - -void enable_strict_free_check(void); -void enable_strict_free_check(void) -{ - strict_free_check = 1; -} - -void disable_strict_free_check(void); -void disable_strict_free_check(void) -{ - strict_free_check = 0; -} - -/* Note: All BLOCK_INPUT stuff removed from this file because it's - completely gone in XEmacs */ - -static void *block_input_malloc(size_t size); - -static void block_input_free(void *ptr) -{ - __free_hook = 0; - __malloc_hook = 0; - free(ptr); - __free_hook = block_input_free; - __malloc_hook = block_input_malloc; -} - -static void *block_input_malloc(size_t size) -{ - void *result; - __free_hook = 0; - __malloc_hook = 0; - result = malloc(size); - __free_hook = block_input_free; - __malloc_hook = block_input_malloc; - return result; -} - -static void *block_input_realloc(void *ptr, size_t size) -{ - void *result; - __free_hook = 0; - __malloc_hook = 0; - __realloc_hook = 0; - result = realloc(ptr, size); - __free_hook = block_input_free; - __malloc_hook = block_input_malloc; - __realloc_hook = block_input_realloc; - return result; -} - -#ifdef emacs - -void disable_free_hook(void); -void disable_free_hook(void) -{ - __free_hook = block_input_free; - __malloc_hook = block_input_malloc; - __realloc_hook = block_input_realloc; -} - -void init_free_hook(void) -{ - __free_hook = check_free; - __malloc_hook = check_malloc; - __realloc_hook = check_realloc; - current_free = 0; - strict_free_check = 1; -} - -void really_free_one_entry(void *, int, int *); - -DEFUN("really-free", Freally_free, 0, 1, "P", /* -Actually free the storage held by the free() debug hook. -A no-op if the free hook is disabled. -*/ - (arg)) -{ - int count[2]; - Lisp_Object lisp_count[2]; - - if ((__free_hook != 0) && pointer_table) { - count[0] = 0; - count[1] = 0; - __free_hook = 0; - maphash((maphash_function) really_free_one_entry, - pointer_table, (void *)&count); - memset(free_queue, 0, - sizeof(free_queue_entry) * FREE_QUEUE_LIMIT); - current_free = 0; - __free_hook = check_free; - XSETINT(lisp_count[0], count[0]); - XSETINT(lisp_count[1], count[1]); - return Fcons(lisp_count[0], lisp_count[1]); - } else - return Fcons(make_int(0), make_int(0)); -} - -void really_free_one_entry(void *key, int contents, int *countp) -{ - if (contents < 0) { - free(key); -#ifdef UNMAPPED_FREE - mprotect(key, -contents, PROT_READ | PROT_WRITE | PROT_EXEC); -#endif - remhash(key, pointer_table); - countp[0]++; - countp[1] += -contents; - } -} - -void syms_of_free_hook(void) -{ - DEFSUBR(Freally_free); -} - -#else -void (*__free_hook) (void *) = check_free; -void *(*__malloc_hook) (size_t) = check_malloc; -void *(*__realloc_hook) (void *, size_t) = check_realloc; -#endif -#endif /* !defined(HAVE_LIBMCHECK) */ +/* This file used to include debugging hooks for malloc(), back when we + shipped our own copy of gmalloc.c. Now we just use the system malloc, and + this file has code to debug GCPROs. */ #if defined(DEBUG_INPUT_BLOCKING) || defined (DEBUG_GCPRO) diff --git a/src/mem/gmalloc.c b/src/mem/gmalloc.c deleted file mode 100644 index c78dc2c..0000000 --- a/src/mem/gmalloc.c +++ /dev/null @@ -1,1250 +0,0 @@ -/* Synched up with: Not synched up with FSF 19.28, even though I - thought I did so. */ - -/* Get the configuration files if we're being compiled for Emacs. */ -#ifdef emacs -# include -# include "ui/getpagesize.h" -# ifndef HAVE_CONFIG_H -# define HAVE_CONFIG_H -# endif -#endif - -#if defined (__STDC__) && !defined (STDC_HEADERS) - /* The ANSI standard says that defining __STDC__ to a non-zero value means - that the compiler conforms to that standard. The standard requires - certain header files and library functions to be present. Therefore, - if your compiler defines __STDC__ to non-0 but does not have ANSI headers - and the ANSI library routines, then your compiler is buggy. Conversely, - an ANSI-conforming environment (which has both the ANSI headers and - library routines, i.e., stdlib.h and `memmove') does not necessarily - define the STDC_HEADERS flag. Lucid Emacs requires an ANSI compiler. - Therefore, there is no need to consult the abominable STDC_HEADERS flag. - -- jwz - */ -# define STDC_HEADERS -#endif - -/* DO NOT EDIT THIS FILE -- it is automagically generated. -*- C -*- */ -/* Bwaa-haa-haa! Not a chance that this is actually true! */ - -#define _MALLOC_INTERNAL - -/* The malloc headers and source files from the C library follow here. */ - -/* Declarations for `malloc' and friends. - Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - Written May 1989 by Mike Haertel. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this library; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation, Inc. */ - -#ifndef _MALLOC_H - -#define _MALLOC_H 1 - -#ifdef _MALLOC_INTERNAL - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#ifdef HAVE_UNISTD_H -#include -#endif - -#endif /* _MALLOC_INTERNAL. */ - -#ifdef __cplusplus -extern "C" { -#endif - -#undef __P -#define __P(args) args -#undef __ptr_t -#define __ptr_t void * - -#include -#define __malloc_size_t size_t - -#ifndef NULL -#define NULL 0 -#endif - -/* XEmacs: I thought this should be int under SunOS, but that - apparently fails. Curses on all this shit. */ -#define __free_ret_t void - -/* XEmacs: I tried commenting these out and including stdlib.h, - but that fails badly. Urk! This sucks. */ -/* Allocate SIZE bytes of memory. */ - extern __ptr_t malloc __P((size_t __size)); -/* Re-allocate the previously allocated block - in __ptr_t, making the new block SIZE bytes long. */ - extern __ptr_t realloc __P((__ptr_t __ptr, size_t __size)); -/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */ - extern __ptr_t calloc __P((size_t __nmemb, size_t __size)); -/* Free a block allocated by `malloc', `realloc' or `calloc'. */ - extern __free_ret_t free __P((__ptr_t __ptr)); - -/* Allocate SIZE bytes allocated to ALIGNMENT bytes. */ - extern __ptr_t memalign __P((size_t __alignment, size_t __size)); - -/* Allocate SIZE bytes on a page boundary. */ - extern __ptr_t valloc __P((size_t __size)); - -#ifdef _MALLOC_INTERNAL - -/* The allocator divides the heap into blocks of fixed size; large - requests receive one or more whole blocks, and small requests - receive a fragment of a block. Fragment sizes are powers of two, - and all fragments of a block are the same size. When all the - fragments in a block have been freed, the block itself is freed. */ -#define INT_BIT (CHAR_BIT * sizeof(int)) -#define BLOCKLOG (INT_BIT > 16 ? 12 : 9) -#define BLOCKSIZE (1 << BLOCKLOG) -#define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE) - -/* Determine the amount of memory spanned by the initial heap table - (not an absolute limit). */ -#define HEAP (INT_BIT > 16 ? 4194304 : 65536) - -/* Number of contiguous free blocks allowed to build up at the end of - memory before they will be returned to the system. */ -#define FINAL_FREE_BLOCKS 8 - -/* Data structure giving per-block information. */ - typedef union { - /* Heap information for a busy block. */ - struct { - /* Zero for a large block, or positive giving the - logarithm to the base two of the fragment size. */ - int type; - union { - struct { - __malloc_size_t nfree; /* Free frags in a fragmented block. */ - __malloc_size_t first; /* First free fragment of the block. */ - } frag; - /* Size (in blocks) of a large cluster. */ - __malloc_size_t size; - } info; - } busy; - /* Heap information for a free block - (that may be the first of a free cluster). */ - struct { - __malloc_size_t size; /* Size (in blocks) of a free cluster. */ - __malloc_size_t next; /* Index of next free cluster. */ - __malloc_size_t prev; /* Index of previous free cluster. */ - } free; - } malloc_info; - -/* Pointer to first block of the heap. */ - extern char *_heapbase; - -/* Table indexed by block number giving per-block information. */ - extern malloc_info *_heapinfo; - -/* Address to block number and vice versa. */ -#define BLOCK(A) (((char *) (A) - _heapbase) / BLOCKSIZE + 1) -#define ADDRESS(B) ((__ptr_t) (((B) - 1) * BLOCKSIZE + _heapbase)) - -/* Current search index for the heap table. */ - extern __malloc_size_t _heapindex; - -/* Limit of valid info table indices. */ - extern __malloc_size_t _heaplimit; - -/* Doubly linked lists of free fragments. */ - struct list { - struct list *next; - struct list *prev; - }; - -/* Free list headers for each fragment size. */ - extern struct list _fraghead[]; - -/* List of blocks allocated with `memalign' (or `valloc'). */ - struct alignlist { - struct alignlist *next; - __ptr_t aligned; /* The address that memaligned returned. */ - __ptr_t exact; /* The address that malloc returned. */ - }; - extern struct alignlist *_aligned_blocks; - -/* Instrumentation. */ - extern __malloc_size_t _chunks_used; - extern __malloc_size_t _bytes_used; - extern __malloc_size_t _chunks_free; - extern __malloc_size_t _bytes_free; - -/* Internal version of `free' used in `morecore' (malloc.c). */ - extern void _free_internal __P((__ptr_t __ptr)); - -#endif /* _MALLOC_INTERNAL. */ - -/* Underlying allocation function; successive calls should - return contiguous pieces of memory. */ - extern __ptr_t(*__morecore) __P((ptrdiff_t __size)); - -/* Default value of `__morecore'. */ - extern __ptr_t __default_morecore __P((ptrdiff_t __size)); - -/* If not NULL, this function is called after each time - `__morecore' is called to increase the data size. */ - extern void (*__after_morecore_hook) __P((void)); - -/* Nonzero if `malloc' has been called and done its initialization. */ - /* extern int __malloc_initialized; */ - -/* Hooks for debugging versions. */ - extern void (*__free_hook) __P((__ptr_t __ptr)); - extern __ptr_t(*__malloc_hook) __P((size_t __size)); - extern __ptr_t(*__realloc_hook) __P((__ptr_t __ptr, size_t __size)); - -/* Return values for `mprobe': these are the kinds of inconsistencies that - `mcheck' enables detection of. */ - enum mcheck_status { - MCHECK_DISABLED = -1, /* Consistency checking is not turned on. */ - MCHECK_OK, /* Block is fine. */ - MCHECK_FREE, /* Block freed twice. */ - MCHECK_HEAD, /* Memory before the block was clobbered. */ - MCHECK_TAIL /* Memory after the block was clobbered. */ - }; - -/* Activate a standard collection of debugging hooks. This must be called - before `malloc' is ever called. ABORTFUNC is called with an error code - (see enum above) when an inconsistency is detected. If ABORTFUNC is - null, the standard function prints on stderr and then calls `abort'. */ - extern int mcheck __P((void (*__abortfunc) __P((enum mcheck_status)))); - -/* Check for aberrations in a particular malloc'd block. You must have - called `mcheck' already. These are the same checks that `mcheck' does - when you free or reallocate a block. */ - extern enum mcheck_status mprobe __P((__ptr_t __ptr)); - -/* Activate a standard collection of tracing hooks. */ - extern void mtrace __P((void)); - extern void muntrace __P((void)); - -/* Statistics available to the user. */ - struct mstats { - __malloc_size_t bytes_total; /* Total size of the heap. */ - __malloc_size_t chunks_used; /* Chunks allocated by the user. */ - __malloc_size_t bytes_used; /* Byte total of user-allocated chunks. */ - __malloc_size_t chunks_free; /* Chunks in the free list. */ - __malloc_size_t bytes_free; /* Byte total of chunks in the free list. */ - }; - -/* Pick up the current statistics. */ - extern struct mstats mstats __P((void)); - -/* Call WARNFUN with a warning message when memory usage is high. */ - extern void memory_warnings __P((__ptr_t __start, - void (*__warnfun) - __P((const char *)))); - -#if 0 /* unused in this file, and conflicting prototypes anyway */ -/* Relocating allocator. */ - -/* Allocate SIZE bytes, and store the address in *HANDLEPTR. */ - extern __ptr_t r_alloc __P((__ptr_t * __handleptr, size_t __size)); - -/* Free the storage allocated in HANDLEPTR. */ - extern void r_alloc_free __P((__ptr_t * __handleptr)); - -/* Adjust the block at HANDLEPTR to be SIZE bytes long. */ - extern __ptr_t r_re_alloc __P((__ptr_t * __handleptr, size_t __size)); -#endif /* 0 */ - -#ifdef __cplusplus -} -#endif -#endif /* malloc.h */ -/* Allocate memory on a page boundary. - Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this library; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation, Inc. */ -#if defined (__GNU_LIBRARY__) || defined (_LIBC) -#include -#include -#if ! (defined (__GLIBC__) && (__GLIBC__ >= 2)) -extern size_t __getpagesize __P((void)); -#endif -#else -#include "ui/getpagesize.h" -#define __getpagesize() getpagesize() -#endif -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include -#endif -static __malloc_size_t pagesize; - -__ptr_t valloc(__malloc_size_t size) -{ - if (pagesize == 0) - pagesize = __getpagesize(); - - return memalign(pagesize, size); -} - -/* Memory allocator `malloc'. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation - Written May 1989 by Mike Haertel. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this library; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation, Inc. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include -#endif - -/* How to really get more memory. */ -#if defined (HEAP_IN_DATA) && !defined(PDUMP) -/* once dumped, free() & realloc() on static heap space will fail */ -#define PURE_DATA(x) \ -((static_heap_dumped && (char*)x >= static_heap_base \ - && (char*)x <= (static_heap_base + static_heap_size) ) ? 1 : 0) -extern int initialized; -extern int purify_flag; -extern char *static_heap_base; -extern char *static_heap_ptr; -extern char *static_heap_dumped; -extern unsigned long static_heap_size; -extern __ptr_t more_static_core __P((ptrdiff_t __size)); -__ptr_t(*__morecore) __P((ptrdiff_t __size)) = more_static_core; -#else -__ptr_t(*__morecore) __P((ptrdiff_t __size)) = __default_morecore; -#define PURE_DATA(x) 0 -#endif - -/* Debugging hook for `malloc'. */ -__ptr_t(*__malloc_hook) __P((__malloc_size_t __size)); - -/* Pointer to the base of the first block. */ -char *_heapbase; - -/* Block information table. Allocated with align/__free (not malloc/free). */ -malloc_info *_heapinfo; - -/* Number of info entries. */ -static __malloc_size_t heapsize; - -/* Search index in the info table. */ -__malloc_size_t _heapindex; - -/* Limit of valid info table indices. */ -__malloc_size_t _heaplimit; - -/* Free lists for each fragment size. */ -struct list _fraghead[BLOCKLOG]; - -/* Instrumentation. */ -__malloc_size_t _chunks_used; -__malloc_size_t _bytes_used; -__malloc_size_t _chunks_free; -__malloc_size_t _bytes_free; - -/* Are you experienced? */ -int __malloc_initialized; - -void (*__after_morecore_hook) __P((void)); - -/* Aligned allocation. */ -static __ptr_t align __P((__malloc_size_t)); -static __ptr_t align(__malloc_size_t size) -{ - __ptr_t result; - unsigned long int adj; - - result = (*__morecore) (size); - adj = (unsigned long int)((unsigned long int)((char *)result - - (char *)NULL)) % - BLOCKSIZE; - if (adj != 0) { - adj = BLOCKSIZE - adj; - (void)(*__morecore) (adj); - result = (char *)result + adj; - } - - if (__after_morecore_hook) - (*__after_morecore_hook) (); - - return result; -} - -/* Set everything up and remember that we have. */ -static int initialize __P((void)); -static int initialize() -{ -#if defined (HEAP_IN_DATA) && !defined(PDUMP) - if (static_heap_dumped && __morecore == more_static_core) { - __morecore = __default_morecore; - } -#endif - heapsize = HEAP / BLOCKSIZE; - _heapinfo = (malloc_info *) align(heapsize * sizeof(malloc_info)); - if (_heapinfo == NULL) - return 0; - memset(_heapinfo, 0, heapsize * sizeof(malloc_info)); - memset(_fraghead, 0, BLOCKLOG * sizeof(struct list)); - _heapinfo[0].free.size = 0; - _heapinfo[0].free.next = _heapinfo[0].free.prev = 0; - _heapindex = 0; - _heaplimit = 0; - _heapbase = (char *)_heapinfo; - - /* Account for the _heapinfo block itself in the statistics. */ - _bytes_used = heapsize * sizeof(malloc_info); - _chunks_used = 1; - _chunks_free = 0; - _bytes_free = 0; - _aligned_blocks = 0; - - __malloc_initialized = 1; - return 1; -} - -/* Get neatly aligned memory, initializing or - growing the heap info table as necessary. */ -static __ptr_t morecore __P((__malloc_size_t)); -static __ptr_t morecore(__malloc_size_t size) -{ - __ptr_t result; - malloc_info *newinfo, *oldinfo; - __malloc_size_t newsize; - - result = align(size); - if (result == NULL) - return NULL; - - /* Check if we need to grow the info table. */ - if ((__malloc_size_t) BLOCK((char *)result + size) > heapsize) { - newsize = heapsize; - while ((__malloc_size_t) BLOCK((char *)result + size) > newsize) - newsize *= 2; - newinfo = (malloc_info *) align(newsize * sizeof(malloc_info)); - if (newinfo == NULL) { - (*__morecore) (-(int)size); - return NULL; - } - memcpy(newinfo, _heapinfo, heapsize * sizeof(malloc_info)); - memset(&newinfo[heapsize], 0, - (newsize - heapsize) * sizeof(malloc_info)); - oldinfo = _heapinfo; - newinfo[BLOCK(oldinfo)].busy.type = 0; - newinfo[BLOCK(oldinfo)].busy.info.size - = BLOCKIFY(heapsize * sizeof(malloc_info)); - _heapinfo = newinfo; - /* Account for the _heapinfo block itself in the statistics. */ - _bytes_used += newsize * sizeof(malloc_info); - ++_chunks_used; - _free_internal(oldinfo); - heapsize = newsize; - } - - _heaplimit = BLOCK((char *)result + size); - return result; -} - -/* Allocate memory from the heap. */ -__ptr_t malloc(__malloc_size_t size) -{ - __ptr_t result; - __malloc_size_t block, blocks, lastblocks, start; - __malloc_size_t i; - struct list *next; - - /* ANSI C allows `malloc (0)' to either return NULL, or to return a - valid address you can realloc and free (though not dereference). - - It turns out that some extant code (sunrpc, at least Ultrix's version) - expects `malloc (0)' to return non-NULL and breaks otherwise. - Be compatible. */ - -#ifdef HAVE_X_WINDOWS - /* there is at least one Xt bug where calloc(n,x) is blindly called - where n can be 0, and yet if 0 is returned, Xt barfs */ - if (size == 0) - size = sizeof(struct list); -#else - if (size == 0) - return NULL; -#endif - - if (__malloc_hook != NULL) - return (*__malloc_hook) (size); - - if (!__malloc_initialized) - if (!initialize()) - return NULL; - -#ifdef SUNOS_LOCALTIME_BUG - /* Workaround for localtime() allocating 8 bytes and writing 9 bug... */ - if (size < 16) - size = 16; -#endif - - if (size < sizeof(struct list)) - size = sizeof(struct list); - - /* Determine the allocation policy based on the request size. */ - if (size <= BLOCKSIZE / 2) { - /* Small allocation to receive a fragment of a block. - Determine the logarithm to base two of the fragment size. */ - __malloc_size_t log = 1; - --size; - while ((size /= 2) != 0) - ++log; - - /* Look in the fragment lists for a - free fragment of the desired size. */ - next = _fraghead[log].next; - if (next != NULL) { - /* There are free fragments of this size. - Pop a fragment out of the fragment list and return it. - Update the block's nfree and first counters. */ - result = (__ptr_t) next; - next->prev->next = next->next; - if (next->next != NULL) - next->next->prev = next->prev; - block = BLOCK(result); - if (--_heapinfo[block].busy.info.frag.nfree != 0) - _heapinfo[block].busy.info.frag.first = - (unsigned long int) - ((unsigned long int)((char *)next->next - - (char *)NULL) - % BLOCKSIZE) >> log; - - /* Update the statistics. */ - ++_chunks_used; - _bytes_used += 1 << log; - --_chunks_free; - _bytes_free -= 1 << log; - } else { - /* No free fragments of the desired size, so get a new block - and break it into fragments, returning the first. */ - result = malloc(BLOCKSIZE); - if (result == NULL) - return NULL; - - /* Link all fragments but the first into the free list. */ - for (i = 1; i < (__malloc_size_t) (BLOCKSIZE >> log); - ++i) { - next = - (struct list *)((char *)result + - (i << log)); - next->next = _fraghead[log].next; - next->prev = &_fraghead[log]; - next->prev->next = next; - if (next->next != NULL) - next->next->prev = next; - } - - /* Initialize the nfree and first counters for this block. */ - block = BLOCK(result); - _heapinfo[block].busy.type = log; - _heapinfo[block].busy.info.frag.nfree = i - 1; - _heapinfo[block].busy.info.frag.first = i - 1; - - _chunks_free += (BLOCKSIZE >> log) - 1; - _bytes_free += BLOCKSIZE - (1 << log); - _bytes_used -= BLOCKSIZE - (1 << log); - } - } else { - /* Large allocation to receive one or more blocks. - Search the free list in a circle starting at the last place visited. - If we loop completely around without finding a large enough - space we will have to get more memory from the system. */ - blocks = BLOCKIFY(size); - start = block = _heapindex; - while (_heapinfo[block].free.size < blocks) { - block = _heapinfo[block].free.next; - if (block == start) { - /* Need to get more from the system. Check to see if - the new core will be contiguous with the final free - block; if so we don't need to get as much. */ - block = _heapinfo[0].free.prev; - lastblocks = _heapinfo[block].free.size; - if (_heaplimit != 0 - && block + lastblocks == _heaplimit - && (*__morecore) (0) == - ADDRESS(block + lastblocks) - && - (morecore - ((blocks - lastblocks) * BLOCKSIZE)) != - NULL) { - /* Which block we are extending (the `final free - block' referred to above) might have changed, if - it got combined with a freed info table. */ - block = _heapinfo[0].free.prev; - _heapinfo[block].free.size += - (blocks - lastblocks); - _bytes_free += - (blocks - lastblocks) * BLOCKSIZE; - continue; - } - result = morecore(blocks * BLOCKSIZE); - if (result == NULL) - return NULL; - block = BLOCK(result); - _heapinfo[block].busy.type = 0; - _heapinfo[block].busy.info.size = blocks; - ++_chunks_used; - _bytes_used += blocks * BLOCKSIZE; - return result; - } - } - - /* At this point we have found a suitable free list entry. - Figure out how to remove what we need from the list. */ - result = ADDRESS(block); - if (_heapinfo[block].free.size > blocks) { - /* The block we found has a bit left over, - so relink the tail end back into the free list. */ - _heapinfo[block + blocks].free.size - = _heapinfo[block].free.size - blocks; - _heapinfo[block + blocks].free.next - = _heapinfo[block].free.next; - _heapinfo[block + blocks].free.prev - = _heapinfo[block].free.prev; - _heapinfo[_heapinfo[block].free.prev].free.next - = _heapinfo[_heapinfo[block].free.next].free.prev - = _heapindex = block + blocks; - } else { - /* The block exactly matches our requirements, - so just remove it from the list. */ - _heapinfo[_heapinfo[block].free.next].free.prev - = _heapinfo[block].free.prev; - _heapinfo[_heapinfo[block].free.prev].free.next - = _heapindex = _heapinfo[block].free.next; - --_chunks_free; - } - - _heapinfo[block].busy.type = 0; - _heapinfo[block].busy.info.size = blocks; - ++_chunks_used; - _bytes_used += blocks * BLOCKSIZE; - _bytes_free -= blocks * BLOCKSIZE; - } - - return result; -} - -#ifndef _LIBC - -/* On some ANSI C systems, some libc functions call _malloc, _free - and _realloc. Make them use the GNU functions. */ - -__ptr_t _malloc(__malloc_size_t size); -__ptr_t _malloc(__malloc_size_t size) -{ - return malloc(size); -} - -void _free(__ptr_t ptr); -void _free(__ptr_t ptr) -{ - free(ptr); -} - -__ptr_t _realloc(__ptr_t ptr, __malloc_size_t size); -__ptr_t _realloc(__ptr_t ptr, __malloc_size_t size) -{ - return realloc(ptr, size); -} - -#endif -/* Free a block of memory allocated by `malloc'. - Copyright 1990, 1991, 1992, 1994 Free Software Foundation - Written May 1989 by Mike Haertel. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this library; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation, Inc. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include -#endif - -/* Debugging hook for free. */ -void (*__free_hook) __P((__ptr_t __ptr)); - -/* List of blocks allocated by memalign. */ -struct alignlist *_aligned_blocks = NULL; - -/* Return memory to the heap. - Like `free' but don't call a __free_hook if there is one. */ -void _free_internal(__ptr_t ptr) -{ - int type; - __malloc_size_t block, blocks; - __malloc_size_t i; - struct list *prev, *next; - - block = BLOCK(ptr); - - type = _heapinfo[block].busy.type; - switch (type) { - case 0: - /* Get as many statistics as early as we can. */ - --_chunks_used; - _bytes_used -= _heapinfo[block].busy.info.size * BLOCKSIZE; - _bytes_free += _heapinfo[block].busy.info.size * BLOCKSIZE; - - /* Find the free cluster previous to this one in the free list. - Start searching at the last block referenced; this may benefit - programs with locality of allocation. */ - i = _heapindex; - if (i > block) - while (i > block) - i = _heapinfo[i].free.prev; - else { - do - i = _heapinfo[i].free.next; - while (i > 0 && i < block); - i = _heapinfo[i].free.prev; - } - - /* Determine how to link this block into the free list. */ - if (block == i + _heapinfo[i].free.size) { - /* Coalesce this block with its predecessor. */ - _heapinfo[i].free.size += - _heapinfo[block].busy.info.size; - block = i; - } else { - /* Really link this block back into the free list. */ - _heapinfo[block].free.size = - _heapinfo[block].busy.info.size; - _heapinfo[block].free.next = _heapinfo[i].free.next; - _heapinfo[block].free.prev = i; - _heapinfo[i].free.next = block; - _heapinfo[_heapinfo[block].free.next].free.prev = block; - ++_chunks_free; - } - - /* Now that the block is linked in, see if we can coalesce it - with its successor (by deleting its successor from the list - and adding in its size). */ - if (block + _heapinfo[block].free.size == - _heapinfo[block].free.next) { - _heapinfo[block].free.size += - _heapinfo[_heapinfo[block].free.next].free.size; - _heapinfo[block].free.next = - _heapinfo[_heapinfo[block].free.next].free.next; - _heapinfo[_heapinfo[block].free.next].free.prev = block; - --_chunks_free; - } - - /* Now see if we can return stuff to the system. */ - blocks = _heapinfo[block].free.size; - if (blocks >= FINAL_FREE_BLOCKS && block + blocks == _heaplimit - && (*__morecore) (0) == ADDRESS(block + blocks)) { - __malloc_size_t bytes = blocks * BLOCKSIZE; - _heaplimit -= blocks; - (*__morecore) (-(int)bytes); - _heapinfo[_heapinfo[block].free.prev].free.next - = _heapinfo[block].free.next; - _heapinfo[_heapinfo[block].free.next].free.prev - = _heapinfo[block].free.prev; - block = _heapinfo[block].free.prev; - --_chunks_free; - _bytes_free -= bytes; - } - - /* Set the next search to begin at this block. */ - _heapindex = block; - break; - - default: - /* Do some of the statistics. */ - --_chunks_used; - _bytes_used -= 1 << type; - ++_chunks_free; - _bytes_free += 1 << type; - - /* Get the address of the first free fragment in this block. */ - prev = (struct list *)((char *)ADDRESS(block) + - (_heapinfo[block].busy.info.frag. - first << type)); - - if (_heapinfo[block].busy.info.frag.nfree == - (BLOCKSIZE >> type) - 1) { - /* If all fragments of this block are free, remove them - from the fragment list and free the whole block. */ - next = prev; - for (i = 1; i < (__malloc_size_t) (BLOCKSIZE >> type); - ++i) - next = next->next; - prev->prev->next = next; - if (next != NULL) - next->prev = prev->prev; - _heapinfo[block].busy.type = 0; - _heapinfo[block].busy.info.size = 1; - - /* Keep the statistics accurate. */ - ++_chunks_used; - _bytes_used += BLOCKSIZE; - _chunks_free -= BLOCKSIZE >> type; - _bytes_free -= BLOCKSIZE; - - free(ADDRESS(block)); - } else if (_heapinfo[block].busy.info.frag.nfree != 0) { - /* If some fragments of this block are free, link this - fragment into the fragment list after the first free - fragment of this block. */ - next = (struct list *)ptr; - next->next = prev->next; - next->prev = prev; - prev->next = next; - if (next->next != NULL) - next->next->prev = next; - ++_heapinfo[block].busy.info.frag.nfree; - } else { - /* No fragments of this block are free, so link this - fragment into the fragment list and announce that - it is the first free fragment of this block. */ - prev = (struct list *)ptr; - _heapinfo[block].busy.info.frag.nfree = 1; - _heapinfo[block].busy.info.frag.first = - (unsigned long int) - ((unsigned long int)((char *)ptr - (char *)NULL) - % BLOCKSIZE >> type); - prev->next = _fraghead[type].next; - prev->prev = &_fraghead[type]; - prev->prev->next = prev; - if (prev->next != NULL) - prev->next->prev = prev; - } - break; - } -} - -/* Return memory to the heap. */ -__free_ret_t free(__ptr_t ptr) -{ - struct alignlist *l; - - if (ptr == NULL) - return; - - if (PURE_DATA(ptr)) { - return; - } - - for (l = _aligned_blocks; l != NULL; l = l->next) - if (l->aligned == ptr) { - l->aligned = NULL; /* Mark the slot in the list as free. */ - ptr = l->exact; - break; - } - - if (__free_hook != NULL) - (*__free_hook) (ptr); - else - _free_internal(ptr); -} - -/* Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc. -This file is part of the GNU C Library. - -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this library; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include -#endif - -#ifdef _LIBC - -#include -#include - -#undef cfree - -function_alias(cfree, free, void, (ptr), DEFUN(cfree, (ptr), PTR ptr)) -#else - -void cfree(__ptr_t ptr); -void cfree(__ptr_t ptr) -{ - free(ptr); -} - -#endif -/* Change the size of a block allocated by `malloc'. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written May 1989 by Mike Haertel. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this library; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation, Inc. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include -#endif - -#ifndef min -#define min(A, B) ((A) < (B) ? (A) : (B)) -#endif - -/* Debugging hook for realloc. */ -__ptr_t(*__realloc_hook) __P((__ptr_t __ptr, __malloc_size_t __size)); - -/* Resize the given region to the new size, returning a pointer - to the (possibly moved) region. This is optimized for speed; - some benchmarks seem to indicate that greater compactness is - achieved by unconditionally allocating and copying to a - new region. This module has incestuous knowledge of the - internals of both free and malloc. */ -__ptr_t realloc(__ptr_t ptr, __malloc_size_t size) -{ - __ptr_t result; - int type; - __malloc_size_t block, blocks, oldlimit; - - if (PURE_DATA(ptr)) { - result = malloc(size); - memcpy(result, ptr, size); - return result; - } - - else if (size == 0) { - free(ptr); - return malloc(0); - } else if (ptr == NULL) - return malloc(size); - - if (__realloc_hook != NULL) - return (*__realloc_hook) (ptr, size); - - block = BLOCK(ptr); - - type = _heapinfo[block].busy.type; - switch (type) { - case 0: - /* Maybe reallocate a large block to a small fragment. */ - if (size <= BLOCKSIZE / 2) { - result = malloc(size); - if (result != NULL) { - memcpy(result, ptr, size); - _free_internal(ptr); - return result; - } - } - - /* The new size is a large allocation as well; - see if we can hold it in place. */ - blocks = BLOCKIFY(size); - if (blocks < _heapinfo[block].busy.info.size) { - /* The new size is smaller; return - excess memory to the free list. */ - _heapinfo[block + blocks].busy.type = 0; - _heapinfo[block + blocks].busy.info.size - = _heapinfo[block].busy.info.size - blocks; - _heapinfo[block].busy.info.size = blocks; - /* We have just created a new chunk by splitting a chunk in two. - Now we will free this chunk; increment the statistics counter - so it doesn't become wrong when _free_internal decrements it. */ - ++_chunks_used; - _free_internal(ADDRESS(block + blocks)); - result = ptr; - } else if (blocks == _heapinfo[block].busy.info.size) - /* No size change necessary. */ - result = ptr; - else { - /* Won't fit, so allocate a new region that will. - Free the old region first in case there is sufficient - adjacent free space to grow without moving. */ - blocks = _heapinfo[block].busy.info.size; - /* Prevent free from actually returning memory to the system. */ - oldlimit = _heaplimit; - _heaplimit = 0; - free(ptr); - _heaplimit = oldlimit; - result = malloc(size); - if (result == NULL) { - /* Now we're really in trouble. We have to unfree - the thing we just freed. Unfortunately it might - have been coalesced with its neighbors. */ - if (_heapindex == block) - (void)malloc(blocks * BLOCKSIZE); - else { - __ptr_t previous = - malloc((block - - _heapindex) * BLOCKSIZE); - (void)malloc(blocks * BLOCKSIZE); - free(previous); - } - return NULL; - } - if (ptr != result) - memmove(result, ptr, blocks * BLOCKSIZE); - } - break; - - default: - /* Old size is a fragment; type is logarithm - to base two of the fragment size. */ - if (size > (__malloc_size_t) (1 << (type - 1)) && - size <= (__malloc_size_t) (1 << type)) - /* The new size is the same kind of fragment. */ - result = ptr; - else { - /* The new size is different; allocate a new space, - and copy the lesser of the new size and the old. */ - result = malloc(size); - if (result == NULL) - return NULL; - memcpy(result, ptr, - min(size, (__malloc_size_t) 1 << type)); - free(ptr); - } - break; - } - - return result; -} - -/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this library; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. - - The author may be reached (Email) at the address mike@ai.mit.edu, - or (US mail) as Mike Haertel c/o Free Software Foundation, Inc. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include -#endif - -/* Allocate an array of NMEMB elements each SIZE bytes long. - The entire array is initialized to zeros. */ -__ptr_t calloc(__malloc_size_t nmemb, __malloc_size_t size) -{ - __ptr_t result = malloc(nmemb * size); - - if (result != NULL) - (void)memset(result, 0, nmemb * size); - - return result; -} - -/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. -This file is part of the GNU C Library. - -The GNU C Library is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with the GNU C Library; see the file COPYING. If not, write to -the Free the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include -#endif - -/* #ifndef __GNU_LIBRARY__ */ -#define __sbrk sbrk -/* #endif */ - -#ifdef GMALLOC_NEEDS_SBRK_DECL -/* some versions of OSF1 need this */ -extern __ptr_t __sbrk __P((ssize_t increment)); -#else -#ifdef __GNU_LIBRARY__ -/* It is best not to declare this and cast its result on foreign operating - systems with potentially hostile include files. */ -#if !(defined(linux) && defined(sparc)) -extern __ptr_t __sbrk __P((int increment)); -#endif -#endif -#endif - -#ifndef NULL -#define NULL 0 -#endif - -/* Allocate INCREMENT more bytes of data space, - and return the start of data space, or NULL on errors. - If INCREMENT is negative, shrink data space. */ -__ptr_t __default_morecore(ptrdiff_t increment) -{ - __ptr_t result = (__ptr_t) __sbrk(increment); - if (result == (__ptr_t) - 1) - return NULL; - return result; -} - -/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this library; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#ifndef _MALLOC_INTERNAL -#define _MALLOC_INTERNAL -#include -#endif - -__ptr_t memalign(__malloc_size_t alignment, __malloc_size_t size) -{ - __ptr_t result; - unsigned long int adj; - - size = ((size + alignment - 1) / alignment) * alignment; - - result = malloc(size); - if (result == NULL) - return NULL; - adj = (unsigned long int)((unsigned long int)((char *)result - - (char *)NULL)) % - alignment; - if (adj != 0) { - struct alignlist *l; - for (l = _aligned_blocks; l != NULL; l = l->next) - if (l->aligned == NULL) - /* This slot is free. Use it. */ - break; - if (l == NULL) { - l = (struct alignlist *) - malloc(sizeof(struct alignlist)); - if (l == NULL) { - free(result); - return NULL; - } - l->next = _aligned_blocks; - _aligned_blocks = l; - } - l->exact = result; - result = l->aligned = (char *)result + alignment - adj; - } - - return result; -} diff --git a/src/mem/malloc.c b/src/mem/malloc.c deleted file mode 100644 index ad052f8..0000000 --- a/src/mem/malloc.c +++ /dev/null @@ -1,813 +0,0 @@ -/* dynamic memory allocation for GNU. - Copyright (C) 1985, 1987 Free Software Foundation, Inc. - - NO WARRANTY - - BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY -NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT -WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, -RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS" -WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY -AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE -DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR -CORRECTION. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M. -STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY -WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE -LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR -OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR -DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR -A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS -PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. - - GENERAL PUBLIC LICENSE TO COPY - - 1. You may copy and distribute verbatim copies of this source file -as you receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy a valid copyright notice "Copyright -(C) 1985 Free Software Foundation, Inc."; and include following the -copyright notice a verbatim copy of the above disclaimer of warranty -and of this License. You may charge a distribution fee for the -physical act of transferring a copy. - - 2. You may modify your copy or copies of this source file or -any portion of it, and copy and distribute such modifications under -the terms of Paragraph 1 above, provided that you also do the following: - - a) cause the modified files to carry prominent notices stating - that you changed the files and the date of any change; and - - b) cause the whole of any work that you distribute or publish, - that in whole or in part contains or is a derivative of this - program or any part thereof, to be licensed at no charge to all - third parties on terms identical to those contained in this - License Agreement (except that you may choose to grant more extensive - warranty protection to some or all third parties, at your option). - - c) You may charge a distribution fee for the physical act of - transferring a copy, and you may at your option offer warranty - protection in exchange for a fee. - -Mere aggregation of another unrelated program with this program (or its -derivative) on a volume of a storage or distribution medium does not bring -the other program under the scope of these terms. - - 3. You may copy and distribute this program (or a portion or derivative -of it, under Paragraph 2) in object code or executable form under the terms -of Paragraphs 1 and 2 above provided that you also do one of the following: - - a) accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of - Paragraphs 1 and 2 above; or, - - b) accompany it with a written offer, valid for at least three - years, to give any third party free (except for a nominal - shipping charge) a complete machine-readable copy of the - corresponding source code, to be distributed under the terms of - Paragraphs 1 and 2 above; or, - - c) accompany it with the information you received as to where the - corresponding source code may be obtained. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form alone.) - -For an executable file, complete source code means all the source code for -all modules it contains; but, as a special exception, it need not include -source code for modules which are standard libraries that accompany the -operating system on which the executable file runs. - - 4. You may not copy, sublicense, distribute or transfer this program -except as expressly provided under this License Agreement. Any attempt -otherwise to copy, sublicense, distribute or transfer this program is void and -your rights to use the program under this License agreement shall be -automatically terminated. However, parties who have received computer -software programs from you with this License Agreement will not have -their licenses terminated so long as such parties remain in full compliance. - - 5. If you wish to incorporate parts of this program into other free -programs whose distribution conditions are different, write to the -Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, -MA 02111-1307, USA.. We have not yet worked out a simple rule that -can be stated here, but we will often permit this. We will be guided -by the two goals of preserving the free status of all derivatives of -our free software and of promoting the sharing and reuse of software. - -In other words, you are welcome to use, share and improve this program. -You are forbidden to forbid anyone else to use, share and improve -what you give them. Help stamp out software-hoarding! */ - -/* Synched up with: Not synched with FSF. */ - -/* - * @(#)nmalloc.c 1 (Caltech) 2/21/82 - * - * U of M Modified: 20 Jun 1983 ACT: strange hacks for Emacs - * - * Nov 1983, Mike@BRL, Added support for 4.1C/4.2 BSD. - * - * This is a very fast storage allocator. It allocates blocks of a small - * number of different sizes, and keeps free lists of each size. Blocks - * that don't exactly fit are passed up to the next larger size. In this - * implementation, the available sizes are (2^n)-4 (or -16) bytes long. - * This is designed for use in a program that uses vast quantities of - * memory, but bombs when it runs out. To make it a little better, it - * warns the user when he starts to get near the end. - * - * June 84, ACT: modified rcheck code to check the range given to malloc, - * rather than the range determined by the 2-power used. - * - * Jan 85, RMS: calls malloc_warning to issue warning on nearly full. - * No longer Emacs-specific; can serve as all-purpose malloc for GNU. - * You should call malloc_init to reinitialize after loading dumped Emacs. - * Call malloc_stats to get info on memory stats if MSTATS turned on. - * realloc knows how to return same block given, just changing its size, - * if the power of 2 is correct. - */ - -/* - * nextf[i] is the pointer to the next free block of size 2^(i+3). The - * smallest allocatable block is 8 bytes. The overhead information will - * go in the first int of the block, and the returned pointer will point - * to the second. - * -#ifdef MSTATS - * nmalloc[i] is the difference between the number of mallocs and frees - * for a given block size. -#endif MSTATS - */ - -#ifdef emacs -/* config.h specifies which kind of system this is. */ -#include -#else - -/* Determine which kind of system this is. */ -#include -#ifndef SIGTSTP -#ifndef USG -#define USG -#endif -#else /* SIGTSTP */ -#ifdef SIGIO -#define BSD4_2 -#endif /* SIGIO */ -#endif /* SIGTSTP */ - -#if defined(hpux) -#define USG -#endif - -#endif /* not emacs */ - -#include - -/* Define getpagesize () if the system does not. */ -#include "ui/getpagesize.h" - -#ifdef HAVE_ULIMIT_H -#include -#endif - -#ifndef BSD4_2 -#ifndef USG -#include /* warn the user when near the end */ -#endif /* not USG */ -#else /* if BSD4_2 */ -#include -#include -#endif /* BSD4_2 */ - -#ifdef __STDC__ -#ifndef HPUX -/* not sure where this for NetBSD should really go - and it probably applies to other systems */ -#if !defined(__NetBSD__) && !defined(__bsdi__) && !defined(__OpenBSD__) -extern void *sbrk(ptrdiff_t); -#else -extern char *sbrk(); -#endif /* __NetBSD__ or __OpenBSD__ */ -#endif /* HPUX */ -#else -extern void *sbrk(); -#endif /* __STDC__ */ - -extern char *start_of_data(void); - -#ifdef BSD -#define start_of_data() &etext -#endif - -#ifndef emacs -#define start_of_data() &etext -#endif - -#define ISALLOC ((char) 0xf7) /* magic byte that implies allocation */ -#define ISFREE ((char) 0x54) /* magic byte that implies free block */ - /* this is for error checking only */ -#define ISMEMALIGN ((char) 0xd6) /* Stored before the value returned by - memalign, with the rest of the word - being the distance to the true - beginning of the block. */ - -extern char etext; - -/* These two are for user programs to look at, when they are interested. */ - -unsigned int malloc_sbrk_used; /* amount of data space used now */ -unsigned int malloc_sbrk_unused; /* amount more we can have */ - -/* start of data space; can be changed by calling init_malloc */ -static char *data_space_start; - -#ifdef MSTATS -static int nmalloc[30]; -static int nmal, nfre; -#endif /* MSTATS */ - -/* If range checking is not turned on, all we have is a flag indicating - whether memory is allocated, an index in nextf[], and a size field; to - realloc() memory we copy either size bytes or 1<<(index+3) bytes depending - on whether the former can hold the exact size (given the value of - 'index'). If range checking is on, we always need to know how much space - is allocated, so the 'size' field is never used. */ - -struct mhead { - char mh_alloc; /* ISALLOC or ISFREE */ - char mh_index; /* index in nextf[] */ -/* Remainder are valid only when block is allocated */ - unsigned short mh_size; /* size, if < 0x10000 */ -#ifdef rcheck - unsigned mh_nbytes; /* number of bytes allocated */ - int mh_magic4; /* should be == MAGIC4 */ -#endif /* rcheck */ -}; - -/* Access free-list pointer of a block. - It is stored at block + 4. - This is not a field in the mhead structure - because we want sizeof (struct mhead) - to describe the overhead for when the block is in use, - and we do not want the free-list pointer to count in that. */ - -#define CHAIN(a) \ - (*(struct mhead **) (sizeof (char *) + (char *) (a))) - -#ifdef rcheck - -/* To implement range checking, we write magic values in at the beginning and - end of each allocated block, and make sure they are undisturbed whenever a - free or a realloc occurs. */ -/* Written in each of the 4 bytes following the block's real space */ -#define MAGIC1 0x55 -/* Written in the 4 bytes before the block's real space */ -#define MAGIC4 0x55555555 -#define ASSERT(p) if (!(p)) botch("p"); else -#define EXTRA 4 /* 4 bytes extra for MAGIC1s */ -#else -#define ASSERT(p) -#define EXTRA 0 -#endif /* rcheck */ - -/* nextf[i] is free list of blocks of size 2**(i + 3) */ - -static struct mhead *nextf[30]; - -/* busy[i] is nonzero while allocation of block size i is in progress. */ - -static char busy[30]; - -/* Number of bytes of writable memory we can expect to be able to get */ -#ifdef _RLIM_T_DECLARED -extern rlim_t lim_data; -#else -extern unsigned long lim_data; -#endif - -/* Level number of warnings already issued. - 0 -- no warnings issued. - 1 -- 75% warning already issued. - 2 -- 85% warning already issued. -*/ -static int warnlevel; - -/* Function to call to issue a warning; - 0 means don't issue them. */ -static void (*warnfunction) (); - -/* nonzero once initial bunch of free blocks made */ -static int gotpool; - -char *_malloc_base; - -static void getpool(void); - -/* Cause reinitialization based on job parameters; - also declare where the end of pure storage is. */ -void malloc_init(start, warnfun) -char *start; -void (*warnfun) (); -{ - if (start) - data_space_start = start; - lim_data = 0; - warnlevel = 0; - warnfunction = warnfun; -} - -/* Return the maximum size to which MEM can be realloc'd - without actually requiring copying. */ - -int malloc_usable_size(mem) -char *mem; -{ - int blocksize = 8 << (((struct mhead *)mem) - 1)->mh_index; - - return blocksize - sizeof(struct mhead) - EXTRA; -} - -static void get_lim_data(); - -static void morecore(nu) /* ask system for more memory */ -int nu; /* size index to get more of */ -{ - char *cp; - int nblks; - unsigned long siz; - int oldmask; - -#ifdef BSD -#ifndef BSD4_1 - /* ?? There was a suggestion not to block SIGILL, somehow for GDB's sake. */ - oldmask = sigsetmask(-1); -#endif -#endif - - if (!data_space_start) { - data_space_start = start_of_data(); - } - - if (lim_data == 0) - get_lim_data(); - - /* On initial startup, get two blocks of each size up to 1k bytes */ - if (!gotpool) { - getpool(); - getpool(); - gotpool = 1; - } - - /* Find current end of memory and issue warning if getting near max */ - - cp = sbrk(0); - siz = cp - data_space_start; - - if (warnfunction) - switch (warnlevel) { - case 0: - if (siz > (lim_data / 4) * 3) { - warnlevel++; - (*warnfunction) - ("Warning: past 75% of memory limit"); - } - break; - case 1: - if (siz > (lim_data / 20) * 17) { - warnlevel++; - (*warnfunction) - ("Warning: past 85% of memory limit"); - } - break; - case 2: - if (siz > (lim_data / 20) * 19) { - warnlevel++; - (*warnfunction) - ("Warning: past 95% of memory limit"); - } - break; - } - - if ((int)cp & 0x3ff) /* land on 1K boundaries */ - sbrk(1024 - ((int)cp & 0x3ff)); - - /* Take at least 2k, and figure out how many blocks of the desired size - we're about to get */ - nblks = 1; - if ((siz = nu) < 8) - nblks = 1 << ((siz = 8) - nu); - - if ((cp = sbrk(1 << (siz + 3))) == (char *)-1) { -#ifdef BSD -#ifndef BSD4_1 - sigsetmask(oldmask); -#endif -#endif - return; /* no more room! */ - } - malloc_sbrk_used = siz; - malloc_sbrk_unused = lim_data - siz; - - if ((int)cp & 7) { /* shouldn't happen, but just in case */ - cp = (char *)(((int)cp + 8) & ~7); - nblks--; - } - - /* save new header and link the nblks blocks together */ - nextf[nu] = (struct mhead *)cp; - siz = 1 << (nu + 3); - while (1) { - ((struct mhead *)cp)->mh_alloc = ISFREE; - ((struct mhead *)cp)->mh_index = nu; - if (--nblks <= 0) - break; - CHAIN((struct mhead *)cp) = (struct mhead *)(cp + siz); - cp += siz; - } - CHAIN((struct mhead *)cp) = 0; - -#ifdef BSD -#ifndef BSD4_1 - sigsetmask(oldmask); -#endif -#endif -} - -static void getpool(void) -{ - int nu; - char *cp = sbrk(0); - - if ((int)cp & 0x3ff) /* land on 1K boundaries */ - sbrk(1024 - ((int)cp & 0x3ff)); - - /* Record address of start of space allocated by malloc. */ - if (_malloc_base == 0) - _malloc_base = cp; - - /* Get 2k of storage */ - - cp = sbrk(04000); - if (cp == (char *)-1) - return; - - /* Divide it into an initial 8-word block - plus one block of size 2**nu for nu = 3 ... 10. */ - - CHAIN(cp) = nextf[0]; - nextf[0] = (struct mhead *)cp; - ((struct mhead *)cp)->mh_alloc = ISFREE; - ((struct mhead *)cp)->mh_index = 0; - cp += 8; - - for (nu = 0; nu < 7; nu++) { - CHAIN(cp) = nextf[nu]; - nextf[nu] = (struct mhead *)cp; - ((struct mhead *)cp)->mh_alloc = ISFREE; - ((struct mhead *)cp)->mh_index = nu; - cp += 8 << nu; - } -} - -char *malloc(n) /* get a block */ -unsigned n; -{ - struct mhead *p; - unsigned int nbytes; - int nunits = 0; - - /* Figure out how many bytes are required, rounding up to the nearest - multiple of 8, then figure out which nestf[] area to use. - Both the beginning of the header and the beginning of the - block should be on an eight byte boundary. */ - nbytes = (n + ((sizeof *p + 7) & ~7) + EXTRA + 7) & ~7; - { - unsigned int shiftr = (nbytes - 1) >> 2; - - while (shiftr >>= 1) - nunits++; - } - - /* In case this is reentrant use of malloc from signal handler, - pick a block size that no other malloc level is currently - trying to allocate. That's the easiest harmless way not to - interfere with the other level of execution. */ - while (busy[nunits]) - nunits++; - busy[nunits] = 1; - - /* If there are no blocks of the appropriate size, go get some */ - /* COULD SPLIT UP A LARGER BLOCK HERE ... ACT */ - if (nextf[nunits] == 0) - morecore(nunits); - - /* Get one block off the list, and set the new list head */ - if ((p = nextf[nunits]) == 0) { - busy[nunits] = 0; - return 0; - } - nextf[nunits] = CHAIN(p); - busy[nunits] = 0; - - /* Check for free block clobbered */ - /* If not for this check, we would gobble a clobbered free chain ptr */ - /* and bomb out on the NEXT allocate of this size block */ - if (p->mh_alloc != ISFREE || p->mh_index != nunits) -#ifdef rcheck - botch("block on free list clobbered"); -#else /* not rcheck */ - abort(); -#endif /* not rcheck */ - - /* Fill in the info, and if range checking, set up the magic numbers */ - p->mh_alloc = ISALLOC; -#ifdef rcheck - p->mh_nbytes = n; - p->mh_magic4 = MAGIC4; - { - /* Get the location n after the beginning of the user's space. */ - char *m = (char *)p + ((sizeof *p + 7) & ~7) + n; - - *m++ = MAGIC1, *m++ = MAGIC1, *m++ = MAGIC1, *m = MAGIC1; - } -#else /* not rcheck */ - p->mh_size = n; -#endif /* not rcheck */ -#ifdef MSTATS - nmalloc[nunits]++; - nmal++; -#endif /* MSTATS */ - return (char *)p + ((sizeof *p + 7) & ~7); -} - -void free(mem) -char *mem; -{ - struct mhead *p; - { - char *ap = mem; - - if (ap == 0) - return; - - p = (struct mhead *)(ap - ((sizeof *p + 7) & ~7)); - if (p->mh_alloc == ISMEMALIGN) { - ap -= p->mh_size; - p = (struct mhead *)(ap - ((sizeof *p + 7) & ~7)); - } -#ifndef rcheck - if (p->mh_alloc != ISALLOC) - abort(); - -#else /* rcheck */ - if (p->mh_alloc != ISALLOC) { - if (p->mh_alloc == ISFREE) - botch - ("free: Called with already freed block argument\n"); - else - botch("free: Called with bad argument\n"); - } - - ASSERT(p->mh_magic4 == MAGIC4); - ap += p->mh_nbytes; - ASSERT(*ap++ == MAGIC1); - ASSERT(*ap++ == MAGIC1); - ASSERT(*ap++ == MAGIC1); - ASSERT(*ap == MAGIC1); -#endif /* rcheck */ - } - { - int nunits = p->mh_index; - - ASSERT(nunits <= 29); - p->mh_alloc = ISFREE; - - /* Protect against signal handlers calling malloc. */ - busy[nunits] = 1; - /* Put this block on the free list. */ - CHAIN(p) = nextf[nunits]; - nextf[nunits] = p; - busy[nunits] = 0; - -#ifdef MSTATS - nmalloc[nunits]--; - nfre++; -#endif /* MSTATS */ - } -} - -char *realloc(mem, n) -char *mem; -unsigned n; -{ - struct mhead *p; - unsigned int tocopy; - unsigned int nbytes; - int nunits; - - if (mem == 0) - return malloc(n); - p = (struct mhead *)(mem - ((sizeof *p + 7) & ~7)); - nunits = p->mh_index; - ASSERT(p->mh_alloc == ISALLOC); -#ifdef rcheck - ASSERT(p->mh_magic4 == MAGIC4); - { - char *m = mem + (tocopy = p->mh_nbytes); - ASSERT(*m++ == MAGIC1); - ASSERT(*m++ == MAGIC1); - ASSERT(*m++ == MAGIC1); - ASSERT(*m == MAGIC1); - } -#else /* not rcheck */ - if (p->mh_index >= 13) - tocopy = (1 << (p->mh_index + 3)) - ((sizeof *p + 7) & ~7); - else - tocopy = p->mh_size; -#endif /* not rcheck */ - - /* See if desired size rounds to same power of 2 as actual size. */ - nbytes = (n + ((sizeof *p + 7) & ~7) + EXTRA + 7) & ~7; - - /* If ok, use the same block, just marking its size as changed. */ - if (nbytes > (4 << nunits) && nbytes <= (8 << nunits)) { -#ifdef rcheck - char *m = mem + tocopy; - *m++ = 0; - *m++ = 0; - *m++ = 0; - *m++ = 0; - p->mh_nbytes = n; - m = mem + n; - *m++ = MAGIC1; - *m++ = MAGIC1; - *m++ = MAGIC1; - *m++ = MAGIC1; -#else /* not rcheck */ - p->mh_size = n; -#endif /* not rcheck */ - return mem; - } - - if (n < tocopy) - tocopy = n; - { - char *new; - - if ((new = malloc(n)) == 0) - return 0; - memcpy(new, mem, tocopy); - free(mem); - return new; - } -} - -char *memalign(alignment, size) -unsigned alignment, size; -{ - char *ptr = malloc(size + alignment); - char *aligned; - struct mhead *p; - - if (ptr == 0) - return 0; - /* If entire block has the desired alignment, just accept it. */ - if (((int)ptr & (alignment - 1)) == 0) - return ptr; - /* Otherwise, get address of byte in the block that has that alignment. */ - aligned = (char *)(((int)ptr + alignment - 1) & -alignment); - - /* Store a suitable indication of how to free the block, - so that free can find the true beginning of it. */ - p = (struct mhead *)aligned - 1; - p->mh_size = aligned - ptr; - p->mh_alloc = ISMEMALIGN; - return aligned; -} - -#ifndef __hpux -/* This runs into trouble with getpagesize on HPUX. - Patching out seems cleaner than the ugly fix needed. */ -char *valloc(size) -unsigned size; -{ - return memalign(getpagesize(), size); -} -#endif /* not __hpux */ - -#ifdef MSTATS -/* Return statistics describing allocation of blocks of size 2**n. */ - -struct mstats_value { - int blocksize; - int nfree; - int nused; -}; - -struct mstats_value malloc_stats(size) -int size; -{ - struct mstats_value v; - int i; - struct mhead *p; - - v.nfree = 0; - - if (size < 0 || size >= 30) { - v.blocksize = 0; - v.nused = 0; - return v; - } - - v.blocksize = 1 << (size + 3); - v.nused = nmalloc[size]; - - for (p = nextf[size]; p; p = CHAIN(p)) - v.nfree++; - - return v; -} -int malloc_mem_used(void) -{ - int i; - int size_used; - - size_used = 0; - - for (i = 0; i < 30; i++) { - int allocation_size = 1 << (i + 3); - struct mhead *p; - - size_used += nmalloc[i] * allocation_size; - } - - return size_used; -} - -int malloc_mem_free(void) -{ - int i; - int size_unused; - - size_unused = 0; - - for (i = 0; i < 30; i++) { - int allocation_size = 1 << (i + 3); - struct mhead *p; - - for (p = nextf[i]; p; p = CHAIN(p)) - size_unused += allocation_size; - } - - return size_unused; -} -#endif /* MSTATS */ - -/* - * This function returns the total number of bytes that the process - * will be allowed to allocate via the sbrk(2) system call. On - * BSD systems this is the total space allocatable to stack and - * data. On USG systems this is the data space only. - */ - -#ifdef USG - -static void get_lim_data(void) -{ -#ifdef ULIMIT_BREAK_VALUE - lim_data = ULIMIT_BREAK_VALUE; -#else - lim_data = ulimit(3, 0); -#endif - - lim_data -= (long)data_space_start; -} - -#else /* not USG */ -#ifndef BSD4_2 - -static void get_lim_data(void) -{ - lim_data = vlimit(LIM_DATA, -1); -} - -#else /* BSD4_2 */ - -static void get_lim_data(void) -{ - struct rlimit XXrlimit; - - getrlimit(RLIMIT_DATA, &XXrlimit); -#ifdef RLIM_INFINITY - lim_data = XXrlimit.rlim_cur & RLIM_INFINITY; /* soft limit */ -#else - lim_data = XXrlimit.rlim_cur; /* soft limit */ -#endif -} - -#endif /* BSD4_2 */ -#endif /* not USG */ - diff --git a/src/mem/ralloc.c b/src/mem/ralloc.c index 62a4b17..8a34dae 100644 --- a/src/mem/ralloc.c +++ b/src/mem/ralloc.c @@ -49,7 +49,7 @@ typedef unsigned char *POINTER; /* Unconditionally use unsigned char * for this. */ typedef unsigned char *POINTER; -#ifdef DOUG_LEA_MALLOC +#ifdef HAVE_GLIBC #define M_TOP_PAD -2 #include #endif @@ -75,7 +75,7 @@ void init_ralloc(void); #define NIL ((POINTER) 0) -#if !defined(HAVE_MMAP) || defined(DOUG_LEA_MALLOC) +#if !defined(HAVE_MMAP) || defined(HAVE_GLIBC) /* A flag to indicate whether we have initialized ralloc yet. For Emacs's sake, please do not make this local to malloc_init; on some @@ -1028,7 +1028,7 @@ void r_alloc_thaw(void) /* The hook `malloc' uses for the function which gets more space from the system. */ -#ifndef DOUG_LEA_MALLOC +#ifndef HAVE_GLIBC extern POINTER(*__morecore) (ptrdiff_t size); #endif @@ -1057,7 +1057,7 @@ void init_ralloc(void) page_size = PAGE; extra_bytes = ROUNDUP(50000); -#ifdef DOUG_LEA_MALLOC +#ifdef HAVE_GLIBC mallopt(M_TOP_PAD, 64 * 4096); #else #if 0 /* Hasn't been synched yet */ @@ -1087,7 +1087,7 @@ void init_ralloc(void) use_relocatable_buffers = 1; } -#if defined (emacs) && defined (DOUG_LEA_MALLOC) +#if defined (emacs) && defined (HAVE_GLIBC) /* Reinitialize the morecore hook variables after restarting a dumped Emacs. This is needed when using Doug Lea's malloc from GNU libc. */ @@ -1728,7 +1728,7 @@ static VM_ADDR New_Addr_Block(size_t sz) static void Free_Addr_Block(VM_ADDR addr, size_t sz) { - munmap((caddr_t) addr, sz); + munmap((void *) addr, sz); } #endif /* MMAP_GENERATE_ADDRESSES */ diff --git a/src/mem/vm-limit.c b/src/mem/vm-limit.c index 510f356..dd6d268 100644 --- a/src/mem/vm-limit.c +++ b/src/mem/vm-limit.c @@ -33,7 +33,7 @@ typedef void *POINTER; #include "mem-limits.h" -#if !defined _NO_MALLOC_WARNING_ +#ifdef HAVE_MALLOC_WARNING /* Level number of warnings already issued. 0 -- no warnings issued. @@ -128,14 +128,14 @@ static void check_memory_limits(void) } } } -#endif /* !_NO_MALLOC_WARNING_ */ +#endif /* HAVE_MALLOC_WARNING */ /* Cause reinitialization based on job parameters; also declare where the end of pure storage is. */ void memory_warnings(void *start, void (*warnfun) (const char *)) { -#ifndef _NO_MALLOC_WARNING_ +#ifdef HAVE_MALLOC_WARNING extern void (*__after_morecore_hook) (void); /* From gmalloc.c */ #endif @@ -144,7 +144,7 @@ void memory_warnings(void *start, void (*warnfun) (const char *)) else data_space_start = start_of_data(); -#if !defined _NO_MALLOC_WARNING_ +#ifdef HAVE_MALLOC_WARNING warn_function = warnfun; __after_morecore_hook = check_memory_limits; #endif diff --git a/src/regex.c b/src/regex.c index 61d324c..253097b 100644 --- a/src/regex.c +++ b/src/regex.c @@ -79,7 +79,7 @@ along with this program. If not, see . */ /* XEmacs: the current mmap-based ralloc handles small blocks very poorly, so we disable it here. */ -#if (defined (REL_ALLOC) && defined (HAVE_MMAP)) || defined(DOUG_LEA_MALLOC) +#if (defined (REL_ALLOC) && defined (HAVE_MMAP)) || defined(HAVE_GLIBC) # undef REL_ALLOC #endif diff --git a/src/ui/X11/device-x.c b/src/ui/X11/device-x.c index 07a07de..fe904bd 100644 --- a/src/ui/X11/device-x.c +++ b/src/ui/X11/device-x.c @@ -921,22 +921,11 @@ static void x_delete_device(struct device *d) { Lisp_Object device; Display *display; -#ifdef FREE_CHECKING - extern void (*__free_hook) (void *); - int checking_free; -#endif XSETDEVICE(device, d); display = DEVICE_X_DISPLAY(d); if (display) { -#ifdef FREE_CHECKING - checking_free = (__free_hook != 0); - - /* Disable strict free checking, to avoid bug in X library */ - if (checking_free) - disable_strict_free_check(); -#endif free_gc_cache(DEVICE_X_GC_CACHE(d)); if (DEVICE_X_DATA(d)->x_modifier_keymap) @@ -951,10 +940,6 @@ static void x_delete_device(struct device *d) XtCloseDisplay(display); DEVICE_X_DISPLAY(d) = 0; -#ifdef FREE_CHECKING - if (checking_free) - enable_strict_free_check(); -#endif } if (EQ(device, Vdefault_x_device)) { -- 2.25.1