]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix memory allocation problems in Cygwin build (Bug#9273).
authorKen Brown <kbrown@cornell.edu>
Tue, 16 Aug 2011 13:27:12 +0000 (09:27 -0400)
committerKen Brown <kbrown@cornell.edu>
Tue, 16 Aug 2011 13:27:12 +0000 (09:27 -0400)
* src/gmalloc.c [CYGWIN] (bss_sbrk_heapbase, bss_sbrk_heapinfo): New
variables.
(malloc_initialize_1) [CYGWIN]: Prepare for reinitializing the
dumped emacs.
(_free_internal_nolock) [CYGWIN]: Ignore requests to free storage
in the static heap.
[CYGWIN] (special_realloc): New function.
(_realloc_internal_nolock) [CYGWIN]: Use the new function on
requests to realloc storage in the static heap.

* src/unexcw.c ( __malloc_initialized): Declare external variable.
(fixup_executable): Force the dumped emacs to reinitialize malloc.

src/ChangeLog
src/gmalloc.c
src/unexcw.c

index b16606ce121f9572fc3d4b0d5538e28a0c28fbf6..2364f71c6a4ca0112134fb8d439085f3232ff14c 100644 (file)
@@ -1,3 +1,20 @@
+2011-08-16  Ken Brown  <kbrown@cornell.edu>
+
+       Fix memory allocation problems in Cygwin build (Bug#9273).
+
+       * unexcw.c ( __malloc_initialized): Declare external variable.
+       (fixup_executable): Force the dumped emacs to reinitialize malloc.
+
+       * gmalloc.c [CYGWIN] (bss_sbrk_heapbase, bss_sbrk_heapinfo): New
+       variables.
+       (malloc_initialize_1) [CYGWIN]: Prepare for reinitializing the
+       dumped emacs.
+       (_free_internal_nolock) [CYGWIN]: Ignore requests to free storage
+       in the static heap.
+       [CYGWIN] (special_realloc): New function.
+       (_realloc_internal_nolock) [CYGWIN]: Use the new function on
+       requests to realloc storage in the static heap.
+
 2011-08-15  Paul Eggert  <eggert@cs.ucla.edu>
 
        * bidi.c (bidi_initialize): Remove unused local.
index 916bb300fe15f691e4cca57baafa04f2d22bcbb6..61046ad9d1b3d66fe7e3e980dbc5d1bc0f87dc30 100644 (file)
@@ -351,10 +351,17 @@ 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. */
+#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;
 
@@ -584,6 +591,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) ();
 
@@ -1054,6 +1071,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 ();
@@ -1349,6 +1372,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));
 
@@ -1375,6 +1423,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);
index f643c196de0f82d3ce62303084e99469bb30d6c9..62df82ec3bc629c23392f6d88108239ede9bf3cf 100644 (file)
@@ -33,6 +33,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 extern int bss_sbrk_did_unexec;
 
+extern int __malloc_initialized;
+
 /* emacs symbols that indicate where bss and data end for emacs internals */
 extern char my_endbss[];
 extern char my_edata[];
@@ -210,9 +212,12 @@ fixup_executable (int fd)
            lseek (fd, (long) (exe_header->section_header[i].s_scnptr),
                   SEEK_SET);
          assert (ret != -1);
+         /* force the dumped emacs to reinitialize malloc */
+         __malloc_initialized = 0;
          ret =
            write (fd, (char *) start_address,
                   my_endbss - (char *) start_address);
+         __malloc_initialized = 1;
          assert (ret == (my_endbss - (char *) start_address));
          if (debug_unexcw)
            printf ("         .bss, mem start 0x%08x mem length %d\n",