]> code.delx.au - gnu-emacs/blobdiff - src/gmalloc.c
Merge from trunk.
[gnu-emacs] / src / gmalloc.c
index 4f27ea3079ad48e7aab34860ba8f13f86323b1bc..d49259b8ed7e20bd3620c2b7006f296d67e63bd5 100644 (file)
@@ -37,32 +37,17 @@ Fifth Floor, Boston, MA 02110-1301, USA.
 #include <config.h>
 #endif
 
-#ifdef HAVE_GTK_AND_PTHREAD
+#ifdef HAVE_PTHREAD
 #define USE_PTHREAD
 #endif
 
-#if ((defined __cplusplus || (defined (__STDC__) && __STDC__) \
-      || defined STDC_HEADERS || defined PROTOTYPES))
 #undef PP
 #define        PP(args)        args
 #undef __ptr_t
 #define        __ptr_t         void *
-#else /* Not C++ or ANSI C.  */
-#undef PP
-#define        PP(args)        ()
-#undef __ptr_t
-#define        __ptr_t         char *
-#endif /* C++ or ANSI C.  */
 
 #include <string.h>
-
-#ifdef HAVE_LIMITS_H
 #include <limits.h>
-#endif
-#ifndef CHAR_BIT
-#define        CHAR_BIT        8
-#endif
-
 #include <unistd.h>
 
 #ifdef USE_PTHREAD
@@ -77,26 +62,9 @@ extern "C"
 {
 #endif
 
-#ifdef STDC_HEADERS
 #include <stddef.h>
 #define        __malloc_size_t         size_t
 #define        __malloc_ptrdiff_t      ptrdiff_t
-#else
-#ifdef __GNUC__
-#include <stddef.h>
-#ifdef __SIZE_TYPE__
-#define        __malloc_size_t         __SIZE_TYPE__
-#endif
-#endif
-#ifndef __malloc_size_t
-#define        __malloc_size_t         unsigned int
-#endif
-#define        __malloc_ptrdiff_t      int
-#endif
-
-#ifndef        NULL
-#define        NULL    0
-#endif
 
 
 /* Allocate SIZE bytes of memory.  */
@@ -383,10 +351,21 @@ Fifth Floor, Boston, MA 02110-1301, USA.
 #endif
 #include <errno.h>
 
-/* How to really get more memory.  */
-#if defined(CYGWIN)
+/* On Cygwin there are two heaps.  temacs uses the static heap
+   (defined in sheap.c and managed with bss_sbrk), and the dumped
+   emacs uses the Cygwin heap (managed with sbrk).  When emacs starts
+   on Cygwin, it reinitializes malloc, and we save the old info for
+   use by free and realloc if they're called with a pointer into the
+   static heap.
+
+   Currently (2011-08-16) the Cygwin build doesn't use ralloc.c; if
+   this is changed in the future, we'll have to similarly deal with
+   reinitializing ralloc. */
+#ifdef CYGWIN
 extern __ptr_t bss_sbrk PP ((ptrdiff_t __size));
 extern int bss_sbrk_did_unexec;
+char *bss_sbrk_heapbase;       /* _heapbase for static heap */
+malloc_info *bss_sbrk_heapinfo;        /* _heapinfo for static heap */
 #endif
 __ptr_t (*__morecore) PP ((__malloc_ptrdiff_t __size)) = __default_morecore;
 
@@ -616,6 +595,16 @@ malloc_initialize_1 ()
   mcheck (NULL);
 #endif
 
+#ifdef CYGWIN
+  if (bss_sbrk_did_unexec)
+    /* we're reinitializing the dumped emacs */
+    {
+      bss_sbrk_heapbase = _heapbase;
+      bss_sbrk_heapinfo = _heapinfo;
+      memset (_fraghead, 0, BLOCKLOG * sizeof (struct list));
+    }
+#endif
+
   if (__malloc_initialize_hook)
     (*__malloc_initialize_hook) ();
 
@@ -1086,6 +1075,12 @@ _free_internal_nolock (ptr)
   if (ptr == NULL)
     return;
 
+#ifdef CYGWIN
+  if (ptr < _heapbase)
+    /* We're being asked to free something in the static heap. */
+    return;
+#endif
+
   PROTECT_MALLOC_STATE (0);
 
   LOCK_ALIGNED_BLOCKS ();
@@ -1381,6 +1376,31 @@ Fifth Floor, Boston, MA 02110-1301, USA.
 
 #define min(A, B) ((A) < (B) ? (A) : (B))
 
+/* On Cygwin the dumped emacs may try to realloc storage allocated in
+   the static heap.  We just malloc space in the new heap and copy the
+   data.  */
+#ifdef CYGWIN
+__ptr_t
+special_realloc (ptr, size)
+     __ptr_t ptr;
+     __malloc_size_t size;
+{
+  __ptr_t result;
+  int type;
+  __malloc_size_t block, oldsize;
+
+  block = ((char *) ptr - bss_sbrk_heapbase) / BLOCKSIZE + 1;
+  type = bss_sbrk_heapinfo[block].busy.type;
+  oldsize =
+    type == 0 ? bss_sbrk_heapinfo[block].busy.info.size * BLOCKSIZE
+    : (__malloc_size_t) 1 << type;
+  result = _malloc_internal_nolock (size);
+  if (result != NULL)
+    memcpy (result, ptr, min (oldsize, size));
+  return result;
+}
+#endif
+
 /* Debugging hook for realloc.  */
 __ptr_t (*__realloc_hook) PP ((__ptr_t __ptr, __malloc_size_t __size));
 
@@ -1407,6 +1427,12 @@ _realloc_internal_nolock (ptr, size)
   else if (ptr == NULL)
     return _malloc_internal_nolock (size);
 
+#ifdef CYGWIN
+  if (ptr < _heapbase)
+    /* ptr points into the static heap */
+    return special_realloc (ptr, size);
+#endif
+
   block = BLOCK (ptr);
 
   PROTECT_MALLOC_STATE (0);
@@ -1881,22 +1907,6 @@ struct hdr
     unsigned long int magic;   /* Magic number to check header integrity.  */
   };
 
-#if    defined(_LIBC) || defined(STDC_HEADERS) || defined(USG)
-#define flood memset
-#else
-static void flood (__ptr_t, int, __malloc_size_t);
-static void
-flood (ptr, val, size)
-     __ptr_t ptr;
-     int val;
-     __malloc_size_t size;
-{
-  char *cp = ptr;
-  while (size--)
-    *cp++ = val;
-}
-#endif
-
 static enum mcheck_status checkhdr (const struct hdr *);
 static enum mcheck_status
 checkhdr (hdr)
@@ -1935,7 +1945,7 @@ freehook (ptr)
       hdr = ((struct hdr *) ptr) - 1;
       checkhdr (hdr);
       hdr->magic = MAGICFREE;
-      flood (ptr, FREEFLOOD, hdr->size);
+      memset (ptr, FREEFLOOD, hdr->size);
     }
   else
     hdr = NULL;
@@ -1961,7 +1971,7 @@ mallochook (size)
   hdr->size = size;
   hdr->magic = MAGICWORD;
   ((char *) &hdr[1])[size] = MAGICBYTE;
-  flood ((__ptr_t) (hdr + 1), MALLOCFLOOD, size);
+  memset ((__ptr_t) (hdr + 1), MALLOCFLOOD, size);
   return (__ptr_t) (hdr + 1);
 }
 
@@ -1981,7 +1991,7 @@ reallochook (ptr, size)
 
       checkhdr (hdr);
       if (size < osize)
-       flood ((char *) ptr + size, FREEFLOOD, osize - size);
+       memset ((char *) ptr + size, FREEFLOOD, osize - size);
     }
 
   __free_hook = old_free_hook;
@@ -1998,7 +2008,7 @@ reallochook (ptr, size)
   hdr->magic = MAGICWORD;
   ((char *) &hdr[1])[size] = MAGICBYTE;
   if (size > osize)
-    flood ((char *) (hdr + 1) + osize, MALLOCFLOOD, size - osize);
+    memset ((char *) (hdr + 1) + osize, MALLOCFLOOD, size - osize);
   return (__ptr_t) (hdr + 1);
 }