#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. */
-#if defined(_LIBC) || defined(STDC_HEADERS) || defined(USG)
#include <string.h>
-#else
-#ifndef memset
-#define memset(s, zero, n) bzero ((s), (n))
-#endif
-#ifndef memcpy
-#define memcpy(d, s, n) bcopy ((s), (d), (n))
-#endif
-#endif
-
-#ifdef HAVE_LIMITS_H
#include <limits.h>
-#endif
-#ifndef CHAR_BIT
-#define CHAR_BIT 8
-#endif
-
#include <unistd.h>
#ifdef USE_PTHREAD
{
#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. */
#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;
/* This is called when `_heapinfo' and `heapsize' have just
been set to describe a new info table. Set up the table
to describe itself and account for it in the statistics. */
-static void register_heapinfo PP ((void));
-#ifdef __GNUC__
-__inline__
-#endif
-static void
-register_heapinfo ()
+static inline void
+register_heapinfo (void)
{
__malloc_size_t block, blocks;
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) ();
#endif
-/* Cope with systems lacking `memmove'. */
-#ifndef memmove
-#if (!defined(_LIBC) && !defined(STDC_HEADERS) && !defined(USG))
-#ifdef emacs
-#undef __malloc_safe_bcopy
-#define __malloc_safe_bcopy safe_bcopy
-#endif
-/* This function is defined in realloc.c. */
-extern void __malloc_safe_bcopy PP ((__ptr_t, __ptr_t, __malloc_size_t));
-#define memmove(to, from, size) __malloc_safe_bcopy ((from), (to), (size))
-#endif
-#endif
-
-
/* Debugging hook for free. */
void (*__free_hook) PP ((__ptr_t __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 ();
#endif
+#define min(A, B) ((A) < (B) ? (A) : (B))
-/* Cope with systems lacking `memmove'. */
-#if (!defined(_LIBC) && !defined(STDC_HEADERS) && !defined(USG))
-
-#ifdef emacs
-#undef __malloc_safe_bcopy
-#define __malloc_safe_bcopy safe_bcopy
-#else
-
-/* Snarfed directly from Emacs src/dispnew.c:
- XXX Should use system bcopy if it handles overlap. */
-
-/* Like bcopy except never gets confused by overlap. */
-
-void
-__malloc_safe_bcopy (afrom, ato, size)
- __ptr_t afrom;
- __ptr_t ato;
+/* 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;
{
- char *from = afrom, *to = ato;
-
- if (size <= 0 || from == to)
- return;
-
- /* If the source and destination don't overlap, then bcopy can
- handle it. If they do overlap, but the destination is lower in
- memory than the source, we'll assume bcopy can handle that. */
- if (to < from || from + size <= to)
- bcopy (from, to, size);
-
- /* Otherwise, we'll copy from the end. */
- else
- {
- register char *endf = from + size;
- register char *endt = to + size;
-
- /* If TO - FROM is large, then we should break the copy into
- nonoverlapping chunks of TO - FROM bytes each. However, if
- TO - FROM is small, then the bcopy function call overhead
- makes this not worth it. The crossover point could be about
- anywhere. Since I don't think the obvious copy loop is too
- bad, I'm trying to err in its favor. */
- if (to - from < 64)
- {
- do
- *--endt = *--endf;
- while (endf != from);
- }
- else
- {
- for (;;)
- {
- endt -= (to - from);
- endf -= (to - from);
-
- if (endt < to)
- break;
-
- bcopy (endf, endt, to - from);
- }
+ __ptr_t result;
+ int type;
+ __malloc_size_t block, oldsize;
- /* If SIZE wasn't a multiple of TO - FROM, there will be a
- little left over. The amount left over is
- (endt + (to - from)) - to, which is endt - from. */
- bcopy (from, to, endt - from);
- }
- }
+ 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 /* emacs */
-
-#ifndef memmove
-extern void __malloc_safe_bcopy PP ((__ptr_t, __ptr_t, __malloc_size_t));
-#define memmove(to, from, size) __malloc_safe_bcopy ((from), (to), (size))
-#endif
-
#endif
-
-#define min(A, B) ((A) < (B) ? (A) : (B))
-
/* Debugging hook for realloc. */
__ptr_t (*__realloc_hook) PP ((__ptr_t __ptr, __malloc_size_t __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);
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)
hdr = ((struct hdr *) ptr) - 1;
checkhdr (hdr);
hdr->magic = MAGICFREE;
- flood (ptr, FREEFLOOD, hdr->size);
+ memset (ptr, FREEFLOOD, hdr->size);
}
else
hdr = NULL;
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);
}
checkhdr (hdr);
if (size < osize)
- flood ((char *) ptr + size, FREEFLOOD, osize - size);
+ memset ((char *) ptr + size, FREEFLOOD, osize - size);
}
__free_hook = old_free_hook;
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);
}
}
#endif /* GC_MCHECK */
-