aboutsummaryrefslogtreecommitdiffstats
path: root/src/gmalloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gmalloc.c')
-rw-r--r--src/gmalloc.c224
1 files changed, 66 insertions, 158 deletions
diff --git a/src/gmalloc.c b/src/gmalloc.c
index a023d2d78e5..7b5e6df009b 100644
--- a/src/gmalloc.c
+++ b/src/gmalloc.c
@@ -37,41 +37,17 @@ Fifth Floor, Boston, MA 02110-1301, USA.
37#include <config.h> 37#include <config.h>
38#endif 38#endif
39 39
40#ifdef HAVE_GTK_AND_PTHREAD 40#ifdef HAVE_PTHREAD
41#define USE_PTHREAD 41#define USE_PTHREAD
42#endif 42#endif
43 43
44#if ((defined __cplusplus || (defined (__STDC__) && __STDC__) \
45 || defined STDC_HEADERS || defined PROTOTYPES))
46#undef PP 44#undef PP
47#define PP(args) args 45#define PP(args) args
48#undef __ptr_t 46#undef __ptr_t
49#define __ptr_t void * 47#define __ptr_t void *
50#else /* Not C++ or ANSI C. */
51#undef PP
52#define PP(args) ()
53#undef __ptr_t
54#define __ptr_t char *
55#endif /* C++ or ANSI C. */
56 48
57#if defined(_LIBC) || defined(STDC_HEADERS) || defined(USG)
58#include <string.h> 49#include <string.h>
59#else
60#ifndef memset
61#define memset(s, zero, n) bzero ((s), (n))
62#endif
63#ifndef memcpy
64#define memcpy(d, s, n) bcopy ((s), (d), (n))
65#endif
66#endif
67
68#ifdef HAVE_LIMITS_H
69#include <limits.h> 50#include <limits.h>
70#endif
71#ifndef CHAR_BIT
72#define CHAR_BIT 8
73#endif
74
75#include <unistd.h> 51#include <unistd.h>
76 52
77#ifdef USE_PTHREAD 53#ifdef USE_PTHREAD
@@ -86,26 +62,9 @@ extern "C"
86{ 62{
87#endif 63#endif
88 64
89#ifdef STDC_HEADERS
90#include <stddef.h> 65#include <stddef.h>
91#define __malloc_size_t size_t 66#define __malloc_size_t size_t
92#define __malloc_ptrdiff_t ptrdiff_t 67#define __malloc_ptrdiff_t ptrdiff_t
93#else
94#ifdef __GNUC__
95#include <stddef.h>
96#ifdef __SIZE_TYPE__
97#define __malloc_size_t __SIZE_TYPE__
98#endif
99#endif
100#ifndef __malloc_size_t
101#define __malloc_size_t unsigned int
102#endif
103#define __malloc_ptrdiff_t int
104#endif
105
106#ifndef NULL
107#define NULL 0
108#endif
109 68
110 69
111/* Allocate SIZE bytes of memory. */ 70/* Allocate SIZE bytes of memory. */
@@ -143,7 +102,7 @@ extern void malloc_enable_thread PP ((void));
143 receive a fragment of a block. Fragment sizes are powers of two, 102 receive a fragment of a block. Fragment sizes are powers of two,
144 and all fragments of a block are the same size. When all the 103 and all fragments of a block are the same size. When all the
145 fragments in a block have been freed, the block itself is freed. */ 104 fragments in a block have been freed, the block itself is freed. */
146#define INT_BIT (CHAR_BIT * sizeof(int)) 105#define INT_BIT (CHAR_BIT * sizeof (int))
147#define BLOCKLOG (INT_BIT > 16 ? 12 : 9) 106#define BLOCKLOG (INT_BIT > 16 ? 12 : 9)
148#define BLOCKSIZE (1 << BLOCKLOG) 107#define BLOCKSIZE (1 << BLOCKLOG)
149#define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE) 108#define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
@@ -392,10 +351,21 @@ Fifth Floor, Boston, MA 02110-1301, USA.
392#endif 351#endif
393#include <errno.h> 352#include <errno.h>
394 353
395/* How to really get more memory. */ 354/* On Cygwin there are two heaps. temacs uses the static heap
396#if defined(CYGWIN) 355 (defined in sheap.c and managed with bss_sbrk), and the dumped
356 emacs uses the Cygwin heap (managed with sbrk). When emacs starts
357 on Cygwin, it reinitializes malloc, and we save the old info for
358 use by free and realloc if they're called with a pointer into the
359 static heap.
360
361 Currently (2011-08-16) the Cygwin build doesn't use ralloc.c; if
362 this is changed in the future, we'll have to similarly deal with
363 reinitializing ralloc. */
364#ifdef CYGWIN
397extern __ptr_t bss_sbrk PP ((ptrdiff_t __size)); 365extern __ptr_t bss_sbrk PP ((ptrdiff_t __size));
398extern int bss_sbrk_did_unexec; 366extern int bss_sbrk_did_unexec;
367char *bss_sbrk_heapbase; /* _heapbase for static heap */
368malloc_info *bss_sbrk_heapinfo; /* _heapinfo for static heap */
399#endif 369#endif
400__ptr_t (*__morecore) PP ((__malloc_ptrdiff_t __size)) = __default_morecore; 370__ptr_t (*__morecore) PP ((__malloc_ptrdiff_t __size)) = __default_morecore;
401 371
@@ -475,7 +445,7 @@ protect_malloc_state (protect_p)
475 } 445 }
476} 446}
477 447
478#define PROTECT_MALLOC_STATE(PROT) protect_malloc_state(PROT) 448#define PROTECT_MALLOC_STATE(PROT) protect_malloc_state (PROT)
479 449
480#else 450#else
481#define PROTECT_MALLOC_STATE(PROT) /* empty */ 451#define PROTECT_MALLOC_STATE(PROT) /* empty */
@@ -625,6 +595,16 @@ malloc_initialize_1 ()
625 mcheck (NULL); 595 mcheck (NULL);
626#endif 596#endif
627 597
598#ifdef CYGWIN
599 if (bss_sbrk_did_unexec)
600 /* we're reinitializing the dumped emacs */
601 {
602 bss_sbrk_heapbase = _heapbase;
603 bss_sbrk_heapinfo = _heapinfo;
604 memset (_fraghead, 0, BLOCKLOG * sizeof (struct list));
605 }
606#endif
607
628 if (__malloc_initialize_hook) 608 if (__malloc_initialize_hook)
629 (*__malloc_initialize_hook) (); 609 (*__malloc_initialize_hook) ();
630 610
@@ -1069,20 +1049,6 @@ Fifth Floor, Boston, MA 02110-1301, USA.
1069#endif 1049#endif
1070 1050
1071 1051
1072/* Cope with systems lacking `memmove'. */
1073#ifndef memmove
1074#if (!defined(_LIBC) && !defined(STDC_HEADERS) && !defined(USG))
1075#ifdef emacs
1076#undef __malloc_safe_bcopy
1077#define __malloc_safe_bcopy safe_bcopy
1078#endif
1079/* This function is defined in realloc.c. */
1080extern void __malloc_safe_bcopy PP ((__ptr_t, __ptr_t, __malloc_size_t));
1081#define memmove(to, from, size) __malloc_safe_bcopy ((from), (to), (size))
1082#endif
1083#endif
1084
1085
1086/* Debugging hook for free. */ 1052/* Debugging hook for free. */
1087void (*__free_hook) PP ((__ptr_t __ptr)); 1053void (*__free_hook) PP ((__ptr_t __ptr));
1088 1054
@@ -1109,6 +1075,12 @@ _free_internal_nolock (ptr)
1109 if (ptr == NULL) 1075 if (ptr == NULL)
1110 return; 1076 return;
1111 1077
1078#ifdef CYGWIN
1079 if (ptr < _heapbase)
1080 /* We're being asked to free something in the static heap. */
1081 return;
1082#endif
1083
1112 PROTECT_MALLOC_STATE (0); 1084 PROTECT_MALLOC_STATE (0);
1113 1085
1114 LOCK_ALIGNED_BLOCKS (); 1086 LOCK_ALIGNED_BLOCKS ();
@@ -1402,87 +1374,33 @@ Fifth Floor, Boston, MA 02110-1301, USA.
1402#endif 1374#endif
1403 1375
1404 1376
1377#define min(A, B) ((A) < (B) ? (A) : (B))
1405 1378
1406/* Cope with systems lacking `memmove'. */ 1379/* On Cygwin the dumped emacs may try to realloc storage allocated in
1407#if (!defined(_LIBC) && !defined(STDC_HEADERS) && !defined(USG)) 1380 the static heap. We just malloc space in the new heap and copy the
1408 1381 data. */
1409#ifdef emacs 1382#ifdef CYGWIN
1410#undef __malloc_safe_bcopy 1383__ptr_t
1411#define __malloc_safe_bcopy safe_bcopy 1384special_realloc (ptr, size)
1412#else 1385 __ptr_t ptr;
1413
1414/* Snarfed directly from Emacs src/dispnew.c:
1415 XXX Should use system bcopy if it handles overlap. */
1416
1417/* Like bcopy except never gets confused by overlap. */
1418
1419void
1420__malloc_safe_bcopy (afrom, ato, size)
1421 __ptr_t afrom;
1422 __ptr_t ato;
1423 __malloc_size_t size; 1386 __malloc_size_t size;
1424{ 1387{
1425 char *from = afrom, *to = ato; 1388 __ptr_t result;
1426 1389 int type;
1427 if (size <= 0 || from == to) 1390 __malloc_size_t block, oldsize;
1428 return;
1429
1430 /* If the source and destination don't overlap, then bcopy can
1431 handle it. If they do overlap, but the destination is lower in
1432 memory than the source, we'll assume bcopy can handle that. */
1433 if (to < from || from + size <= to)
1434 bcopy (from, to, size);
1435
1436 /* Otherwise, we'll copy from the end. */
1437 else
1438 {
1439 register char *endf = from + size;
1440 register char *endt = to + size;
1441
1442 /* If TO - FROM is large, then we should break the copy into
1443 nonoverlapping chunks of TO - FROM bytes each. However, if
1444 TO - FROM is small, then the bcopy function call overhead
1445 makes this not worth it. The crossover point could be about
1446 anywhere. Since I don't think the obvious copy loop is too
1447 bad, I'm trying to err in its favor. */
1448 if (to - from < 64)
1449 {
1450 do
1451 *--endt = *--endf;
1452 while (endf != from);
1453 }
1454 else
1455 {
1456 for (;;)
1457 {
1458 endt -= (to - from);
1459 endf -= (to - from);
1460
1461 if (endt < to)
1462 break;
1463
1464 bcopy (endf, endt, to - from);
1465 }
1466 1391
1467 /* If SIZE wasn't a multiple of TO - FROM, there will be a 1392 block = ((char *) ptr - bss_sbrk_heapbase) / BLOCKSIZE + 1;
1468 little left over. The amount left over is 1393 type = bss_sbrk_heapinfo[block].busy.type;
1469 (endt + (to - from)) - to, which is endt - from. */ 1394 oldsize =
1470 bcopy (from, to, endt - from); 1395 type == 0 ? bss_sbrk_heapinfo[block].busy.info.size * BLOCKSIZE
1471 } 1396 : (__malloc_size_t) 1 << type;
1472 } 1397 result = _malloc_internal_nolock (size);
1398 if (result != NULL)
1399 memcpy (result, ptr, min (oldsize, size));
1400 return result;
1473} 1401}
1474#endif /* emacs */
1475
1476#ifndef memmove
1477extern void __malloc_safe_bcopy PP ((__ptr_t, __ptr_t, __malloc_size_t));
1478#define memmove(to, from, size) __malloc_safe_bcopy ((from), (to), (size))
1479#endif
1480
1481#endif 1402#endif
1482 1403
1483
1484#define min(A, B) ((A) < (B) ? (A) : (B))
1485
1486/* Debugging hook for realloc. */ 1404/* Debugging hook for realloc. */
1487__ptr_t (*__realloc_hook) PP ((__ptr_t __ptr, __malloc_size_t __size)); 1405__ptr_t (*__realloc_hook) PP ((__ptr_t __ptr, __malloc_size_t __size));
1488 1406
@@ -1509,6 +1427,12 @@ _realloc_internal_nolock (ptr, size)
1509 else if (ptr == NULL) 1427 else if (ptr == NULL)
1510 return _malloc_internal_nolock (size); 1428 return _malloc_internal_nolock (size);
1511 1429
1430#ifdef CYGWIN
1431 if (ptr < _heapbase)
1432 /* ptr points into the static heap */
1433 return special_realloc (ptr, size);
1434#endif
1435
1512 block = BLOCK (ptr); 1436 block = BLOCK (ptr);
1513 1437
1514 PROTECT_MALLOC_STATE (0); 1438 PROTECT_MALLOC_STATE (0);
@@ -1617,7 +1541,7 @@ _realloc_internal (ptr, size)
1617{ 1541{
1618 __ptr_t result; 1542 __ptr_t result;
1619 1543
1620 LOCK(); 1544 LOCK ();
1621 result = _realloc_internal_nolock (ptr, size); 1545 result = _realloc_internal_nolock (ptr, size);
1622 UNLOCK (); 1546 UNLOCK ();
1623 1547
@@ -1701,7 +1625,7 @@ MA 02110-1301, USA. */
1701 1625
1702/* uClibc defines __GNU_LIBRARY__, but it is not completely 1626/* uClibc defines __GNU_LIBRARY__, but it is not completely
1703 compatible. */ 1627 compatible. */
1704#if !defined(__GNU_LIBRARY__) || defined(__UCLIBC__) 1628#if !defined (__GNU_LIBRARY__) || defined (__UCLIBC__)
1705#define __sbrk sbrk 1629#define __sbrk sbrk
1706#else /* __GNU_LIBRARY__ && ! defined (__UCLIBC__) */ 1630#else /* __GNU_LIBRARY__ && ! defined (__UCLIBC__) */
1707/* It is best not to declare this and cast its result on foreign operating 1631/* It is best not to declare this and cast its result on foreign operating
@@ -1723,7 +1647,7 @@ __default_morecore (increment)
1723 __malloc_ptrdiff_t increment; 1647 __malloc_ptrdiff_t increment;
1724{ 1648{
1725 __ptr_t result; 1649 __ptr_t result;
1726#if defined(CYGWIN) 1650#if defined (CYGWIN)
1727 if (!bss_sbrk_did_unexec) 1651 if (!bss_sbrk_did_unexec)
1728 { 1652 {
1729 return bss_sbrk (increment); 1653 return bss_sbrk (increment);
@@ -1906,7 +1830,7 @@ extern size_t __getpagesize PP ((void));
1906#endif 1830#endif
1907#else 1831#else
1908#include "getpagesize.h" 1832#include "getpagesize.h"
1909#define __getpagesize() getpagesize() 1833#define __getpagesize() getpagesize ()
1910#endif 1834#endif
1911 1835
1912#ifndef _MALLOC_INTERNAL 1836#ifndef _MALLOC_INTERNAL
@@ -1983,22 +1907,6 @@ struct hdr
1983 unsigned long int magic; /* Magic number to check header integrity. */ 1907 unsigned long int magic; /* Magic number to check header integrity. */
1984 }; 1908 };
1985 1909
1986#if defined(_LIBC) || defined(STDC_HEADERS) || defined(USG)
1987#define flood memset
1988#else
1989static void flood (__ptr_t, int, __malloc_size_t);
1990static void
1991flood (ptr, val, size)
1992 __ptr_t ptr;
1993 int val;
1994 __malloc_size_t size;
1995{
1996 char *cp = ptr;
1997 while (size--)
1998 *cp++ = val;
1999}
2000#endif
2001
2002static enum mcheck_status checkhdr (const struct hdr *); 1910static enum mcheck_status checkhdr (const struct hdr *);
2003static enum mcheck_status 1911static enum mcheck_status
2004checkhdr (hdr) 1912checkhdr (hdr)
@@ -2037,7 +1945,7 @@ freehook (ptr)
2037 hdr = ((struct hdr *) ptr) - 1; 1945 hdr = ((struct hdr *) ptr) - 1;
2038 checkhdr (hdr); 1946 checkhdr (hdr);
2039 hdr->magic = MAGICFREE; 1947 hdr->magic = MAGICFREE;
2040 flood (ptr, FREEFLOOD, hdr->size); 1948 memset (ptr, FREEFLOOD, hdr->size);
2041 } 1949 }
2042 else 1950 else
2043 hdr = NULL; 1951 hdr = NULL;
@@ -2063,7 +1971,7 @@ mallochook (size)
2063 hdr->size = size; 1971 hdr->size = size;
2064 hdr->magic = MAGICWORD; 1972 hdr->magic = MAGICWORD;
2065 ((char *) &hdr[1])[size] = MAGICBYTE; 1973 ((char *) &hdr[1])[size] = MAGICBYTE;
2066 flood ((__ptr_t) (hdr + 1), MALLOCFLOOD, size); 1974 memset ((__ptr_t) (hdr + 1), MALLOCFLOOD, size);
2067 return (__ptr_t) (hdr + 1); 1975 return (__ptr_t) (hdr + 1);
2068} 1976}
2069 1977
@@ -2083,7 +1991,7 @@ reallochook (ptr, size)
2083 1991
2084 checkhdr (hdr); 1992 checkhdr (hdr);
2085 if (size < osize) 1993 if (size < osize)
2086 flood ((char *) ptr + size, FREEFLOOD, osize - size); 1994 memset ((char *) ptr + size, FREEFLOOD, osize - size);
2087 } 1995 }
2088 1996
2089 __free_hook = old_free_hook; 1997 __free_hook = old_free_hook;
@@ -2100,7 +2008,7 @@ reallochook (ptr, size)
2100 hdr->magic = MAGICWORD; 2008 hdr->magic = MAGICWORD;
2101 ((char *) &hdr[1])[size] = MAGICBYTE; 2009 ((char *) &hdr[1])[size] = MAGICBYTE;
2102 if (size > osize) 2010 if (size > osize)
2103 flood ((char *) (hdr + 1) + osize, MALLOCFLOOD, size - osize); 2011 memset ((char *) (hdr + 1) + osize, MALLOCFLOOD, size - osize);
2104 return (__ptr_t) (hdr + 1); 2012 return (__ptr_t) (hdr + 1);
2105} 2013}
2106 2014