Always use the system malloc (removes gmalloc.c malloc.c).
authorSteve Youngs <steve@sxemacs.org>
Sun, 26 May 2019 06:15:34 +0000 (16:15 +1000)
committerSteve Youngs <steve@sxemacs.org>
Sun, 26 May 2019 06:15:34 +0000 (16:15 +1000)
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 <steve@sxemacs.org>
14 files changed:
configure.ac
info/internals/internals.texi
m4/sxe-libc.m4
m4/sxe-summary.m4
src/alloc.c
src/emacs.c
src/mem/Makefile.am
src/mem/free-hook.c
src/mem/gmalloc.c [deleted file]
src/mem/malloc.c [deleted file]
src/mem/ralloc.c
src/mem/vm-limit.c
src/regex.c
src/ui/X11/device-x.c

index 48a1d29..b63a2b9 100644 (file)
@@ -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 <malloc.h>]],[[
+       dnl Check if malloc() calls mmap(), making rel_alloc pointless.
+       AC_MSG_CHECKING(for M_MMAP_THRESHOLD)
+       AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <malloc.h>]],[[
 #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!])
index 486a906..33dcc3c 100644 (file)
@@ -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}
index cebc256..10a414b 100644 (file)
@@ -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
index 9d67c28..3667edb 100644 (file)
@@ -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." ;;
index 9c07f16..d02732a 100644 (file)
@@ -63,7 +63,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 #include <ent/ent.h>
 #include <ent/ent-float.h>
 
-#ifdef DOUG_LEA_MALLOC
+#ifdef HAVE_GLIBC
 #include <malloc.h>
 #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 */
index 49fa20d..f4583ff 100644 (file)
@@ -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 <malloc.h>
 /* 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)
 }
 
 \f
-/* 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 */
index b8f7fc3..566f773 100644 (file)
@@ -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)
index 8634f9f..9b88f7d 100644 (file)
@@ -17,383 +17,13 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
 /* 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 <config.h>
 #include "lisp.h"
-#else
-void *malloc(size_t);
-#endif
-
-#if !defined(HAVE_LIBMCHECK)
-#include <stdio.h>
-
-#include "hash.h"
-
-#ifdef UNMAPPED_FREE
-#include <sys/mman.h>
-#include <sys/param.h>
-#define ROUND_UP_TO_PAGE(i) (((i) + PAGEOFFSET) & PAGEMASK)
-#endif
-
-#include <sys/types.h>
-
-/* 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 (file)
index c78dc2c..0000000
+++ /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 <config.h>
-# 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
-\f
-/* 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 <config.h>
-#endif
-
-#include <string.h>
-#include <limits.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#endif                         /* _MALLOC_INTERNAL.  */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#undef __P
-#define        __P(args)       args
-#undef __ptr_t
-#define        __ptr_t         void *
-
-#include <stddef.h>
-#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 <stddef.h>
-#include <sys/cdefs.h>
-#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 <malloc.h>
-#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 <malloc.h>
-#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;
-}
-\f
-#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 <malloc.h>
-#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 <malloc.h>
-#endif
-
-#ifdef _LIBC
-
-#include <ansidecl.h>
-#include <gnu-stabs.h>
-
-#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 <malloc.h>
-#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 <malloc.h>
-#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 <malloc.h>
-#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 <malloc.h>
-#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 (file)
index ad052f8..0000000
+++ /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 <config.h>
-#else
-
-/* Determine which kind of system this is.  */
-#include <signal.h>
-#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 <stddef.h>
-
-/* Define getpagesize () if the system does not.  */
-#include "ui/getpagesize.h"
-
-#ifdef HAVE_ULIMIT_H
-#include <ulimit.h>
-#endif
-
-#ifndef BSD4_2
-#ifndef USG
-#include <sys/vlimit.h>                /* warn the user when near the end */
-#endif                         /* not USG */
-#else                          /* if BSD4_2 */
-#include <sys/time.h>
-#include <sys/resource.h>
-#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;
-}
-\f
-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;
-       }
-}
-\f
-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 */
-\f
-#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 */
-\f
-/*
- *     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 */
-\f
index 62a4b17..8a34dae 100644 (file)
@@ -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 <malloc.h>
 #endif
@@ -75,7 +75,7 @@ void init_ralloc(void);
 
 #define NIL ((POINTER) 0)
 \f
-#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)
 \f
 /* 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 */
index 510f356..dd6d268 100644 (file)
@@ -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
index 61d324c..253097b 100644 (file)
@@ -79,7 +79,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 /* 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
 
index 07a07de..fe904bd 100644 (file)
@@ -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)) {