]> code.delx.au - gnu-emacs/blobdiff - src/ralloc.c
*** empty log message ***
[gnu-emacs] / src / ralloc.c
index b6fcb32339504f42f8571038fe4eaeed1c723273..183db755412fd663d56ef8f290c11572d6ea7434 100644 (file)
@@ -15,7 +15,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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 /* NOTES:
 
@@ -56,7 +57,12 @@ typedef unsigned long SIZE;
    overlap.  */
 extern void safe_bcopy ();
 
+#ifdef DOUG_LEA_MALLOC
+#define M_TOP_PAD           -2 
+extern int mallopt ();
+#else
 extern int __malloc_extra_blocks;
+#endif
 
 #else /* not emacs */
 
@@ -131,7 +137,7 @@ static int extra_bytes;
    but they never move.
 
    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 continguous
+   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
@@ -171,7 +177,7 @@ static heap_ptr first_heap, last_heap;
    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
    freed when the arena is thawed.  Currently, these blocs are not reusable,
-   while the arena is frozen.  Very inefficent.  */
+   while the arena is frozen.  Very inefficient.  */
 
 typedef struct bp
 {
@@ -180,7 +186,7 @@ typedef struct bp
   POINTER *variable;
   POINTER data;
   SIZE size;
-  POINTER new_data;            /* tmporarily used for relocation */
+  POINTER new_data;            /* temporarily used for relocation */
   struct heap *heap;           /* Heap this bloc is in.  */
 } *bloc_ptr;
 
@@ -220,8 +226,8 @@ find_heap (address)
    if we can get that many within one heap.
 
    If enough space is not presently available in our reserve, this means
-   getting more page-aligned space from the system. If the retuned space
-   is not contiguos to the last heap, allocate a new heap, and append it
+   getting more page-aligned space from the system.  If the returned space
+   is not contiguous to the last heap, allocate a new heap, and append it
 
    obtain does not try to keep track of whether space is in use
    or not in use.  It just returns the address of SIZE bytes that
@@ -357,7 +363,18 @@ relinquish ()
        }
 
       if ((*real_morecore) (- excess) == 0)
-       abort ();
+       {
+         /* 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;
+         /* 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
+             unlikely to trigger this mode of failure.  */
+         if (last_heap->end != (*real_morecore) (0))
+           abort ();
+       }
     }
 }
 
@@ -795,7 +812,7 @@ r_alloc_sbrk (size)
     {
       /* Allocate a page-aligned space.  GNU malloc would reclaim an
         extra space if we passed an unaligned one.  But we could
-        not always find a space which is contiguos to the previous.  */
+        not always find a space which is contiguous to the previous.  */
       POINTER new_bloc_start;
       heap_ptr h = first_heap;
       SIZE get = ROUNDUP (size);
@@ -978,7 +995,7 @@ r_alloc_free (ptr)
    do nothing.
 
    In case r_alloc_freeze is set, a new bloc is allocated, and the
-   memory copied to it.  Not very efficent.  We could traverse the
+   memory copied to it.  Not very efficient.  We could traverse the
    bloc_list for a best fit of free blocs first.
 
    Change *PTR to reflect the new bloc, and return this value.
@@ -1077,7 +1094,7 @@ r_alloc_thaw ()
   if (--r_alloc_freeze_level < 0)
     abort ();
 
-  /* This frees all unused blocs.  It is not too inefficent, as the resize 
+  /* 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) 
@@ -1118,9 +1135,13 @@ r_alloc_init ()
   page_size = PAGE;
   extra_bytes = ROUNDUP (50000);
 
+#ifdef DOUG_LEA_MALLOC
+    mallopt (M_TOP_PAD, 64 * 4096);
+#else
   /* Give GNU malloc's morecore some hysteresis
      so that we move all the relocatable blocks much less often.  */
   __malloc_extra_blocks = 64;
+#endif
 
   first_heap->end = (POINTER) ROUNDUP (first_heap->start);
 
@@ -1140,6 +1161,24 @@ r_alloc_init ()
   virtual_break_value = break_value = first_heap->bloc_start = first_heap->end;
   use_relocatable_buffers = 1;
 }
+
+#if defined (emacs) && defined (DOUG_LEA_MALLOC)
+
+/* Reinitialize the morecore hook variables after restarting a dumped
+   Emacs.  This is needed when using Doug Lea's malloc from GNU libc.  */
+void
+r_alloc_reinit ()
+{
+  /* Only do this if the hook has been reset, so that we don't get an
+     infinite loop, in case Emacs was linked statically.  */
+  if (__morecore != r_alloc_sbrk)
+    {
+      real_morecore = __morecore;
+      __morecore = r_alloc_sbrk;
+    }
+}
+#endif
+
 #ifdef DEBUG
 #include <assert.h>
 
@@ -1163,7 +1202,11 @@ r_alloc_check ()
     {
       assert (h->prev == ph);
       assert ((POINTER) ROUNDUP (h->end) == h->end);
+#if 0 /* ??? The code in ralloc.c does not really try to ensure
+        the heap start has any sort of alignment.
+        Perhaps it should.  */
       assert ((POINTER) MEM_ROUNDUP (h->start) == h->start);
+#endif
       assert ((POINTER) MEM_ROUNDUP (h->bloc_start) == h->bloc_start);
       assert (h->start <= h->bloc_start && h->bloc_start <= h->end);