Update years in copyright notice; nfc.
[bpt/emacs.git] / src / ralloc.c
index ae2d70e..fea9ea5 100644 (file)
@@ -1,5 +1,6 @@
-/* Block-relocating memory allocator. 
-   Copyright (C) 1993, 1995, 2000 Free Software Foundation, Inc.
+/* Block-relocating memory allocator.
+   Copyright (C) 1993, 1995, 2000, 2002, 2003, 2004,
+                 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -15,8 +16,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 /* NOTES:
 
@@ -28,6 +29,7 @@ Boston, MA 02111-1307, USA.  */
 
 #include <config.h>
 #include "lisp.h"              /* Needed for VALBITS.  */
+#include "blockinput.h"
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
@@ -42,10 +44,12 @@ typedef size_t SIZE;
 extern void safe_bcopy ();
 
 #ifdef DOUG_LEA_MALLOC
-#define M_TOP_PAD           -2 
+#define M_TOP_PAD           -2
 extern int mallopt ();
 #else /* not DOUG_LEA_MALLOC */
-extern int __malloc_extra_blocks;
+#ifndef SYSTEM_MALLOC
+extern size_t __malloc_extra_blocks;
+#endif /* SYSTEM_MALLOC */
 #endif /* not DOUG_LEA_MALLOC */
 
 #else /* not emacs */
@@ -57,7 +61,6 @@ typedef void *POINTER;
 
 #include <unistd.h>
 #include <malloc.h>
-#include <string.h>
 
 #define safe_bcopy(x, y, z) memmove (y, x, z)
 #define bzero(x, len) memset (x, 0, len)
@@ -97,7 +100,7 @@ static POINTER break_value;
 /* This is the size of a page.  We round memory requests to this boundary.  */
 static int page_size;
 
-/* Whenever we get memory from the system, get this many extra bytes.  This 
+/* Whenever we get memory from the system, get this many extra bytes.  This
    must be a multiple of page_size.  */
 static int extra_bytes;
 
@@ -113,6 +116,14 @@ static int extra_bytes;
 #define MEM_ROUNDUP(addr) (((unsigned long int)(addr) + MEM_ALIGN - 1) \
                                   & ~(MEM_ALIGN - 1))
 
+/* The hook `malloc' uses for the function which gets more space
+   from the system.  */
+
+#ifndef SYSTEM_MALLOC
+extern POINTER (*__morecore) ();
+#endif
+
+
 \f
 /***********************************************************************
                      Implementation using sbrk
@@ -132,7 +143,7 @@ static int extra_bytes;
    We try to make just one heap and make it larger as necessary.
    But sometimes we can't do that, because we can't get contiguous
    space to add onto the heap.  When that happens, we start a new heap.  */
-   
+
 typedef struct heap
 {
   struct heap *next;
@@ -165,7 +176,7 @@ static heap_ptr first_heap, last_heap;
 /* These structures are allocated in the malloc arena.
    The linked list is kept in order of increasing '.data' members.
    The data blocks abut each other; if b->next is non-nil, then
-   b->data + b->size == b->next->data.  
+   b->data + b->size == b->next->data.
 
    An element with variable==NIL denotes a freed block, which has not yet
    been collected.  They may only appear while r_alloc_freeze > 0, and will be
@@ -252,7 +263,7 @@ obtain (address, size)
 
   /* If we can't fit SIZE bytes in that heap,
      try successive later heaps.  */
-  while (heap && address + size > heap->end)
+  while (heap && (char *) address + size > (char *) heap->end)
     {
       heap = heap->next;
       if (heap == NIL_HEAP)
@@ -276,7 +287,7 @@ obtain (address, size)
          heap_ptr new_heap = (heap_ptr) MEM_ROUNDUP (new);
          POINTER bloc_start = (POINTER) MEM_ROUNDUP ((POINTER)(new_heap + 1));
 
-         if ((*real_morecore) (bloc_start - new) != new)
+         if ((*real_morecore) ((char *) bloc_start - (char *) new) != new)
            return 0;
 
          new_heap->start = new;
@@ -304,7 +315,7 @@ obtain (address, size)
       if ((*real_morecore) (get) != last_heap->end)
        return 0;
 
-      last_heap->end += get;
+      last_heap->end = (char *) last_heap->end + get;
     }
 
   return address;
@@ -352,7 +363,7 @@ relinquish ()
        {
          excess = (char *) last_heap->end
                        - (char *) ROUNDUP ((char *)last_heap->end - excess);
-         last_heap->end -= excess;
+         last_heap->end = (char *) last_heap->end - excess;
        }
 
       if ((*real_morecore) (- excess) == 0)
@@ -360,7 +371,7 @@ relinquish ()
          /* If the system didn't want that much memory back, adjust
              the end of the last heap to reflect that.  This can occur
              if break_value is still within the original data segment.  */
-         last_heap->end += excess;
+         last_heap->end = (char *) last_heap->end + excess;
          /* Make sure that the result of the adjustment is accurate.
              It should be, for the else clause above; the other case,
              which returns the entire last heap to the system, seems
@@ -377,7 +388,7 @@ relinquish ()
 long
 r_alloc_size_in_use ()
 {
-  return break_value - virtual_break_value;
+  return (char *) break_value - (char *) virtual_break_value;
 }
 \f
 /* The meat - allocating, freeing, and relocating blocs.  */
@@ -422,7 +433,7 @@ get_bloc (size)
       return 0;
     }
 
-  break_value = new_bloc->data + size;
+  break_value = (char *) new_bloc->data + size;
 
   new_bloc->size = size;
   new_bloc->next = NIL_BLOC;
@@ -458,8 +469,8 @@ get_bloc (size)
 /* Calculate new locations of blocs in the list beginning with BLOC,
    relocating it to start at ADDRESS, in heap HEAP.  If enough space is
    not presently available in our reserve, call obtain for
-   more space. 
-   
+   more space.
+
    Store the new location of each bloc in its new_data field.
    Do not touch the contents of blocs or break_value.  */
 
@@ -472,14 +483,14 @@ relocate_blocs (bloc, heap, address)
   register bloc_ptr b = bloc;
 
   /* No need to ever call this if arena is frozen, bug somewhere!  */
-  if (r_alloc_freeze_level) 
+  if (r_alloc_freeze_level)
     abort();
 
   while (b)
     {
       /* If bloc B won't fit within HEAP,
         move to the next heap and try again.  */
-      while (heap && address + b->size > heap->end)
+      while (heap && (char *) address + b->size > (char *) heap->end)
        {
          heap = heap->next;
          if (heap == NIL_HEAP)
@@ -497,7 +508,7 @@ relocate_blocs (bloc, heap, address)
          /* Add up the size of all the following blocs.  */
          while (tb != NIL_BLOC)
            {
-             if (tb->variable) 
+             if (tb->variable)
                s += tb->size;
 
              tb = tb->next;
@@ -514,8 +525,8 @@ relocate_blocs (bloc, heap, address)
       /* Record the new address of this bloc
         and update where the next bloc can start.  */
       b->new_data = address;
-      if (b->variable) 
-       address += b->size;
+      if (b->variable)
+       address = (char *) address + b->size;
       b = b->next;
     }
 
@@ -567,7 +578,7 @@ update_heap_bloc_correspondence (bloc, heap)
     {
       /* The previous bloc is in HEAP.  */
       heap->last_bloc = bloc->prev;
-      heap->free = bloc->prev->data + bloc->prev->size;
+      heap->free = (char *) bloc->prev->data + bloc->prev->size;
     }
   else
     {
@@ -595,7 +606,7 @@ update_heap_bloc_correspondence (bloc, heap)
        }
 
       /* Update HEAP's status for bloc B.  */
-      heap->free = b->data + b->size;
+      heap->free = (char *) b->data + b->size;
       heap->last_bloc = b;
       if (heap->first_bloc == NIL_BLOC)
        heap->first_bloc = b;
@@ -630,7 +641,7 @@ resize_bloc (bloc, size)
   SIZE old_size;
 
   /* No need to ever call this if arena is frozen, bug somewhere!  */
-  if (r_alloc_freeze_level) 
+  if (r_alloc_freeze_level)
     abort();
 
   if (bloc == NIL_BLOC || size == bloc->size)
@@ -649,8 +660,8 @@ resize_bloc (bloc, size)
   bloc->size = size;
 
   /* Note that bloc could be moved into the previous heap.  */
-  address = (bloc->prev ? bloc->prev->data + bloc->prev->size
-            : first_heap->bloc_start);
+  address = (bloc->prev ? (char *) bloc->prev->data + bloc->prev->size
+            : (char *) first_heap->bloc_start);
   while (heap)
     {
       if (heap->bloc_start <= address && address <= heap->end)
@@ -672,8 +683,8 @@ resize_bloc (bloc, size)
            {
              b->size = 0;
              b->data = b->new_data;
-            } 
-         else 
+            }
+         else
            {
              safe_bcopy (b->data, b->new_data, b->size);
              *b->variable = b->data = b->new_data;
@@ -687,7 +698,7 @@ resize_bloc (bloc, size)
       else
        {
          safe_bcopy (bloc->data, bloc->new_data, old_size);
-         bzero (bloc->new_data + old_size, size - old_size);
+         bzero ((char *) bloc->new_data + old_size, size - old_size);
          *bloc->variable = bloc->data = bloc->new_data;
        }
     }
@@ -699,8 +710,8 @@ resize_bloc (bloc, size)
            {
              b->size = 0;
              b->data = b->new_data;
-            } 
-         else 
+            }
+         else
            {
              safe_bcopy (b->data, b->new_data, b->size);
              *b->variable = b->data = b->new_data;
@@ -710,8 +721,8 @@ resize_bloc (bloc, size)
 
   update_heap_bloc_correspondence (bloc, heap);
 
-  break_value = (last_bloc ? last_bloc->data + last_bloc->size
-                : first_heap->bloc_start);
+  break_value = (last_bloc ? (char *) last_bloc->data + last_bloc->size
+                : (char *) first_heap->bloc_start);
   return 1;
 }
 \f
@@ -729,7 +740,7 @@ free_bloc (bloc)
       bloc->variable = (POINTER *) NIL;
       return;
     }
-  
+
   resize_bloc (bloc, 0);
 
   if (bloc == first_bloc && bloc == last_bloc)
@@ -785,7 +796,7 @@ free_bloc (bloc)
    __morecore hook values - in particular, __default_morecore in the
    GNU malloc package.  */
 
-POINTER 
+POINTER
 r_alloc_sbrk (size)
      long size;
 {
@@ -841,7 +852,7 @@ r_alloc_sbrk (size)
       if (first_heap->bloc_start < new_bloc_start)
        {
          /* This is no clean solution - no idea how to do it better.  */
-         if (r_alloc_freeze_level) 
+         if (r_alloc_freeze_level)
            return NIL;
 
          /* There is a bug here: if the above obtain call succeeded, but the
@@ -917,15 +928,14 @@ r_alloc_sbrk (size)
 
   virtual_break_value = (POINTER) ((char *)address + size);
   break_value = (last_bloc
-                ? last_bloc->data + last_bloc->size
-                : first_heap->bloc_start);
+                ? (char *) last_bloc->data + last_bloc->size
+                : (char *) first_heap->bloc_start);
   if (size < 0)
     relinquish ();
 
   return address;
 }
 
-#ifndef REL_ALLOC_MMAP
 
 /* Allocate a relocatable bloc of storage of size SIZE.  A pointer to
    the data is returned in *PTR.  PTR is thus the address of some variable
@@ -1010,7 +1020,7 @@ r_re_alloc (ptr, size)
 
   if (!*ptr)
     return r_alloc (ptr, size);
-  if (!size) 
+  if (!size)
     {
       r_alloc_free (ptr);
       return r_alloc (ptr, 0);
@@ -1020,12 +1030,12 @@ r_re_alloc (ptr, size)
   if (bloc == NIL_BLOC)
     abort ();
 
-  if (size < bloc->size) 
+  if (size < bloc->size)
     {
       /* Wouldn't it be useful to actually resize the bloc here?  */
       /* I think so too, but not if it's too expensive...  */
-      if ((bloc->size - MEM_ROUNDUP (size) >= page_size) 
-          && r_alloc_freeze_level == 0) 
+      if ((bloc->size - MEM_ROUNDUP (size) >= page_size)
+          && r_alloc_freeze_level == 0)
        {
          resize_bloc (bloc, MEM_ROUNDUP (size));
          /* Never mind if this fails, just do nothing...  */
@@ -1047,7 +1057,7 @@ r_re_alloc (ptr, size)
           else
            return NIL;
        }
-      else 
+      else
        {
          if (! resize_bloc (bloc, MEM_ROUNDUP (size)))
            return NIL;
@@ -1083,22 +1093,22 @@ void
 r_alloc_thaw ()
 {
 
-  if (! r_alloc_initialized) 
+  if (! r_alloc_initialized)
     r_alloc_init ();
 
   if (--r_alloc_freeze_level < 0)
     abort ();
 
-  /* This frees all unused blocs.  It is not too inefficient, as the resize 
-     and bcopy is done only once.  Afterwards, all unreferenced blocs are 
+  /* This frees all unused blocs.  It is not too inefficient, as the resize
+     and bcopy is done only once.  Afterwards, all unreferenced blocs are
      already shrunk to zero size.  */
-  if (!r_alloc_freeze_level) 
+  if (!r_alloc_freeze_level)
     {
       bloc_ptr *b = &first_bloc;
-      while (*b) 
-       if (!(*b)->variable) 
-         free_bloc (*b); 
-       else 
+      while (*b)
+       if (!(*b)->variable)
+         free_bloc (*b);
+       else
          b = &(*b)->next;
     }
 }
@@ -1216,412 +1226,12 @@ r_alloc_check ()
 
 #endif /* DEBUG */
 
-#endif /* not REL_ALLOC_MMAP */
-
-\f
-/***********************************************************************
-                    Implementation based on mmap
- ***********************************************************************/
-
-#ifdef REL_ALLOC_MMAP
-
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <stdio.h>
-#include <errno.h>
-
-/* Memory is allocated in regions which are mapped using mmap(2).
-   The current implementation let's the system select mapped
-   addresses;  we're not using MAP_FIXED in general, except when
-   trying to enlarge regions.
-
-   Each mapped region starts with a mmap_region structure, the user
-   area starts after that structure, aligned to MEM_ALIGN.
-
-       +-----------------------+
-       | struct mmap_info +    |
-       | padding               |
-       +-----------------------+
-       | user data             |
-       |                       |
-       |                       |
-       +-----------------------+  */
-
-struct mmap_region
-{
-  /* User-specified size.  */
-  size_t nbytes_specified;
-  
-  /* Number of bytes mapped */
-  size_t nbytes_mapped;
-
-  /* Pointer to the location holding the address of the memory
-     allocated with the mmap'd block.  The variable actually points
-     after this structure.  */
-  POINTER_TYPE **var;
-
-  /* Next and previous in list of all mmap'd regions.  */
-  struct mmap_region *next, *prev;
-};
-
-/* Doubly-linked list of mmap'd regions.  */
-
-static struct mmap_region *mmap_regions;
-
-/* Temporary storage for mmap_set_vars, see there.  */
-
-static struct mmap_region *mmap_regions_1;
-
-/* Value is X rounded up to the next multiple of N.  */
-
-#define ROUND(X, N)    (((X) + (N) - 1) / (N) * (N))
-
-/* Size of mmap_region structure plus padding.  */
-
-#define MMAP_REGION_STRUCT_SIZE        \
-     ROUND (sizeof (struct mmap_region), MEM_ALIGN)
-
-/* Given a pointer P to the start of the user-visible part of a mapped
-   region, return a pointer to the start of the region.  */
-
-#define MMAP_REGION(P) \
-     ((struct mmap_region *) ((char *) (P) - MMAP_REGION_STRUCT_SIZE))
-
-/* Given a pointer P to the start of a mapped region, return a pointer
-   to the start of the user-visible part of the region.  */
-
-#define MMAP_USER_AREA(P) \
-     ((POINTER_TYPE *) ((char *) (P) + MMAP_REGION_STRUCT_SIZE))
-
-/* Function prototypes.  */
-
-static int mmap_free P_ ((struct mmap_region *));
-static int mmap_enlarge P_ ((struct mmap_region *, int));
-static struct mmap_region *mmap_find P_ ((POINTER_TYPE *, POINTER_TYPE *));
-POINTER_TYPE *r_alloc P_ ((POINTER_TYPE **, size_t));
-POINTER_TYPE *r_re_alloc P_ ((POINTER_TYPE **, size_t));
-void r_alloc_free P_ ((POINTER_TYPE **ptr));
-
-
-/* Return a region overlapping address range START...END, or null if
-   none.  END is not including, i.e. the last byte in the range
-   is at END - 1.  */
-
-static struct mmap_region *
-mmap_find (start, end)
-     POINTER_TYPE *start, *end;
-{
-  struct mmap_region *r;
-  char *s = (char *) start, *e = (char *) end;
-  
-  for (r = mmap_regions; r; r = r->next)
-    {
-      char *rstart = (char *) r;
-      char *rend   = rstart + r->nbytes_mapped;
-
-      if (/* First byte of range, i.e. START, in this region?  */
-         (s >= rstart && s < rend)
-         /* Last byte of range, i.e. END - 1, in this region?  */
-         || (e > rstart && e <= rend)
-         /* First byte of this region in the range?  */
-         || (rstart >= s && rstart < e)
-         /* Last byte of this region in the range?  */
-         || (rend > s && rend <= e))
-       break;
-    }
-
-  return r;
-}
-
-
-/* Unmap a region.  P is a pointer to the start of the user-araa of
-   the region.  Value is non-zero if successful.  */
-
-static int
-mmap_free (r)
-     struct mmap_region *r;
-{
-  if (r->next)
-    r->next->prev = r->prev;
-  if (r->prev)
-    r->prev->next = r->next;
-  else
-    mmap_regions = r->next;
-  
-  if (munmap (r, r->nbytes_mapped) == -1)
-    {
-      fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
-      return 0;
-    }
-
-  return 1;
-}
-
-
-/* Enlarge region R by NPAGES pages.  NPAGES < 0 means shrink R.
-   Value is non-zero if successful.  */
-
-static int
-mmap_enlarge (r, npages)
-     struct mmap_region *r;
-     int npages;
-{
-  char *region_end = (char *) r + r->nbytes_mapped;
-  size_t nbytes;
-  int success = 1;
-
-  if (npages < 0)
-    {
-      /* Unmap pages at the end of the region.  */
-      nbytes = - npages * page_size;
-      if (munmap (region_end - nbytes, nbytes) == -1)
-       {
-         fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
-         success = 0;
-       }
-      else
-       r->nbytes_mapped -= nbytes;
-    }
-  else if (npages > 0)
-    {
-      nbytes = npages * page_size;
-      
-      /* Try to map additional pages at the end of the region.  We
-        cannot do this if the address range is already occupied by
-        something else because mmap deletes any previous mapping.
-        I'm not sure this is worth doing, let's see.  */
-      if (mmap_find (region_end, region_end + nbytes))
-       success = 0;
-      else
-       {
-         POINTER_TYPE *p;
-      
-         p = mmap (region_end, nbytes, PROT_READ | PROT_WRITE,
-                   MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0);
-         if (p == MAP_FAILED)
-           {
-             fprintf (stderr, "mmap: %s\n", emacs_strerror (errno));
-             success = 0;
-           }
-         else if (p != (POINTER_TYPE *) region_end)
-           {
-             /* Kernels are free to choose a different address.  In
-                that case, unmap what we've mapped above; we have
-                no use for it.  */
-             if (munmap (p, nbytes) == -1)
-               fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
-             success = 0;
-           }
-         else
-           r->nbytes_mapped += nbytes;
-       }
-      
-      success = 0;
-    }
-
-  return success;
-}
-
-
-/* Set or reset variables holding references to mapped regions.  If
-   RESTORE_P is zero, set all variables to null.  If RESTORE_P is
-   non-zero, set all variables to the start of the user-areas
-   of mapped regions.
-
-   This function is called from Fdump_emacs to ensure that the dumped
-   Emacs doesn't contain references to memory that won't be mapped
-   when Emacs starts.  */
-
-void
-mmap_set_vars (restore_p)
-     int restore_p;
-{
-  struct mmap_region *r;
-
-  if (restore_p)
-    {
-      mmap_regions = mmap_regions_1;
-      for (r = mmap_regions; r; r = r->next)
-       *r->var = MMAP_USER_AREA (r);
-    }
-  else
-    {
-      for (r = mmap_regions; r; r = r->next)
-       *r->var = NULL;
-      mmap_regions_1 = mmap_regions;
-      mmap_regions = NULL;
-    }
-}
-
-
-/* Return total number of bytes mapped.  */
-
-size_t
-mmap_mapped_bytes ()
-{
-  struct mmap_region *r;
-  size_t n = 0;
-  
-  for (r = mmap_regions; r; r = r->next)
-    n += r->nbytes_mapped;
-
-  return n;
-}
-
-
-/* Allocate a block of storage large enough to hold NBYTES bytes of
-   data.  A pointer to the data is returned in *VAR.  VAR is thus the
-   address of some variable which will use the data area.
-
-   The allocation of 0 bytes is valid.
-
-   If we can't allocate the necessary memory, set *VAR to null, and
-   return null.  */
-
-POINTER_TYPE *
-r_alloc (var, nbytes)
-     POINTER_TYPE **var;
-     size_t nbytes;
-{
-  void *p;
-  size_t map;
-
-  if (!r_alloc_initialized)
-    r_alloc_init ();
-
-  map = ROUND (nbytes + MMAP_REGION_STRUCT_SIZE, page_size);
-  p = mmap (NULL, map, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
-  
-  if (p == MAP_FAILED)
-    {
-      if (errno != ENOMEM)
-       fprintf (stderr, "mmap: %s\n", emacs_strerror (errno));
-      p = NULL;
-    }
-  else
-    {
-      struct mmap_region *r = (struct mmap_region *) p;
-      
-      r->nbytes_specified = nbytes;
-      r->nbytes_mapped = map;
-      r->var = var;
-      r->prev = NULL;
-      r->next = mmap_regions;
-      if (r->next)
-       r->next->prev = r;
-      mmap_regions = r;
-      
-      p = MMAP_USER_AREA (p);
-    }
-  
-  return *var = p;
-}
-
-
-/* Given a pointer at address VAR to data allocated with r_alloc,
-   resize it to size NBYTES.  Change *VAR to reflect the new block,
-   and return this value.  If more memory cannot be allocated, then
-   leave *VAR unchanged, and return null.  */
-
-POINTER_TYPE *
-r_re_alloc (var, nbytes)
-     POINTER_TYPE **var;
-     size_t nbytes;
-{
-  POINTER_TYPE *result;
-  
-  if (!r_alloc_initialized)
-    r_alloc_init ();
-
-  if (*var == NULL)
-    result = r_alloc (var, nbytes);
-  else if (nbytes == 0) 
-    {
-      r_alloc_free (var);
-      result = r_alloc (var, nbytes);
-    }
-  else
-    {
-      struct mmap_region *r = MMAP_REGION (*var);
-      size_t room = r->nbytes_mapped - MMAP_REGION_STRUCT_SIZE;
-      
-      if (room < nbytes)
-       {
-         /* Must enlarge.  */
-         POINTER_TYPE *old_ptr = *var;
-
-         /* Try to map additional pages at the end of the region.
-            If that fails, allocate a new region,  copy data
-            from the old region, then free it.  */
-         if (mmap_enlarge (r, ROUND (nbytes - room, page_size) / page_size))
-           {
-             r->nbytes_specified = nbytes;
-             *var = result = old_ptr;
-           }
-         else if (r_alloc (var, nbytes))
-           {
-             bcopy (old_ptr, *var, r->nbytes_specified);
-             mmap_free (MMAP_REGION (old_ptr));
-             result = *var;
-             r = MMAP_REGION (result);
-             r->nbytes_specified = nbytes;
-           }
-         else
-           {
-             *var = old_ptr;
-             result = NULL;
-           }
-       }
-      else if (room - nbytes >= page_size)
-       {
-         /* Shrinking by at least a page.  Let's give some
-            memory back to the system.  */
-         mmap_enlarge (r, - (room - nbytes) / page_size);
-         result = *var;
-         r->nbytes_specified = nbytes;
-       }
-      else
-       {
-         /* Leave it alone.  */
-         result = *var;
-         r->nbytes_specified = nbytes;
-       }
-    }
-
-  return result;
-}
-
-
-/* Free a block of relocatable storage whose data is pointed to by
-   PTR.  Store 0 in *PTR to show there's no block allocated.  */
-
-void
-r_alloc_free (var)
-     POINTER_TYPE **var;
-{
-  if (!r_alloc_initialized)
-    r_alloc_init ();
-
-  if (*var)
-    {
-      mmap_free (MMAP_REGION (*var));
-      *var = NULL;
-    }
-}
-
-#endif /* REL_ALLOC_MMAP */
-
 
 \f
 /***********************************************************************
                            Initialization
  ***********************************************************************/
 
-/* The hook `malloc' uses for the function which gets more space
-   from the system.  */
-
-extern POINTER (*__morecore) ();
-
 /* Initialize various things for memory allocation.  */
 
 static void
@@ -1629,8 +1239,10 @@ r_alloc_init ()
 {
   if (r_alloc_initialized)
     return;
-
   r_alloc_initialized = 1;
+
+  page_size = PAGE;
+#ifndef SYSTEM_MALLOC
   real_morecore = __morecore;
   __morecore = r_alloc_sbrk;
 
@@ -1641,17 +1253,22 @@ r_alloc_init ()
   if (break_value == NIL)
     abort ();
 
-  page_size = PAGE;
   extra_bytes = ROUNDUP (50000);
+#endif
 
 #ifdef DOUG_LEA_MALLOC
-    mallopt (M_TOP_PAD, 64 * 4096);
+  BLOCK_INPUT;
+  mallopt (M_TOP_PAD, 64 * 4096);
+  UNBLOCK_INPUT;
 #else
+#ifndef SYSTEM_MALLOC
   /* Give GNU malloc's morecore some hysteresis
      so that we move all the relocatable blocks much less often.  */
   __malloc_extra_blocks = 64;
 #endif
+#endif
 
+#ifndef SYSTEM_MALLOC
   first_heap->end = (POINTER) ROUNDUP (first_heap->start);
 
   /* The extra call to real_morecore guarantees that the end of the
@@ -1660,13 +1277,19 @@ r_alloc_init ()
      which page_size is stored.  This allows a binary to be built on a
      system with one page size and run on a system with a smaller page
      size.  */
-  (*real_morecore) (first_heap->end - first_heap->start);
+  (*real_morecore) ((char *) first_heap->end - (char *) first_heap->start);
 
   /* Clear the rest of the last page; this memory is in our address space
      even though it is after the sbrk value.  */
   /* Doubly true, with the additional call that explicitly adds the
      rest of that page to the address space.  */
-  bzero (first_heap->start, first_heap->end - first_heap->start);
+  bzero (first_heap->start,
+        (char *) first_heap->end - (char *) first_heap->start);
   virtual_break_value = break_value = first_heap->bloc_start = first_heap->end;
+#endif
+
   use_relocatable_buffers = 1;
 }
+
+/* arch-tag: 6a524a15-faff-44c8-95d4-a5da6f55110f
+   (do not change this comment) */