unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Ken Brown <kbrown@cornell.edu>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: "9273@debbugs.gnu.org" <9273@debbugs.gnu.org>
Subject: bug#9273: 23.3; malloc initialization should (sometimes) happen at runtime
Date: Sat, 13 Aug 2011 23:13:39 -0400	[thread overview]
Message-ID: <4E473D63.7040703@cornell.edu> (raw)
In-Reply-To: <jwvwreh2k92.fsf-monnier+emacs@gnu.org>

On 8/13/2011 3:19 PM, Stefan Monnier wrote:
>> Probably.  That would keep me from having to get involved in the details of
>> how _heapinfo works, and it would probably be less error prone.  So I would
>> do something like the following:
> 
>> 1. Temporarily restore the pre-dump malloc state.
>> 2. Call xrealloc, getting storage of the new size in the old heap.
>> 3. Copy the contents into a temporary buffer, and then free the recently
>> allocated storage in the old heap.
>> 4. Restore the malloc state, call malloc, and then copy the contents of the
>> temporary buffer into the just-acquired storage in the new heap.
> 
>> Is that what you had in mind?
> 
> No, I meant, during initialization of Emacs, make sure we get the old
> _heapinfo state, so that malloc/realloc/... just works.

No, that wouldn't be good because the old _heapinfo state uses the static heap, which is very small.  It's big enough for temacs, but not for a usable emacs.  In any case, Eli's suggestion turned out to be very easy to implement.  My revised patch is appended below, and it seems to solve all the problems I encountered.  I still want to test it further, but I think it's OK.  Eli, thanks for your help.

Ken

=== modified file 'src/gmalloc.c'
--- src/gmalloc.c       2011-08-04 17:04:39 +0000
+++ src/gmalloc.c       2011-08-13 22:32:45 +0000
@@ -351,11 +351,19 @@
 #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;
+malloc_info *bss_sbrk_heapinfo;
 #endif
+
 __ptr_t (*__morecore) PP ((__malloc_ptrdiff_t __size)) = __default_morecore;

 /* Debugging hook for `malloc'.  */
@@ -584,6 +592,16 @@
   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 +1072,12 @@
   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 ();
@@ -1346,9 +1370,33 @@
 #include <malloc.h>
 #endif

-
 #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 @@
   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);

=== modified file 'src/unexcw.c'
--- src/unexcw.c        2011-03-17 20:18:59 +0000
+++ src/unexcw.c        2011-08-12 20:10:03 +0000
@@ -33,6 +33,8 @@

 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 @@
            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",








  reply	other threads:[~2011-08-14  3:13 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-08-09 20:09 bug#9273: 23.3; malloc initialization should (sometimes) happen at runtime Ken Brown
2011-08-10  0:24 ` Richard Stallman
2011-08-10 15:56 ` Eli Zaretskii
2011-08-10 17:52   ` Ken Brown
2011-08-10 18:10     ` Eli Zaretskii
2011-08-10 18:49       ` Ken Brown
2011-08-11 21:45   ` Ken Brown
2011-08-12  6:54     ` Eli Zaretskii
2011-08-12 10:10       ` Ken Brown
2011-08-12 11:33         ` Eli Zaretskii
2011-08-12 12:18           ` Ken Brown
2011-08-12 20:24             ` Ken Brown
2011-08-13  8:05               ` Eli Zaretskii
2011-08-13 13:48                 ` Ken Brown
2011-08-13 14:41                   ` Eli Zaretskii
2011-08-13 14:53                     ` Ken Brown
2011-08-13 15:07                       ` Stefan Monnier
2011-08-13 15:33                         ` Ken Brown
2011-08-13 19:19                           ` Stefan Monnier
2011-08-14  3:13                             ` Ken Brown [this message]
2011-08-16 13:30                               ` Ken Brown
2011-08-12 23:51 ` grischka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4E473D63.7040703@cornell.edu \
    --to=kbrown@cornell.edu \
    --cc=9273@debbugs.gnu.org \
    --cc=monnier@iro.umontreal.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).