aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2013-11-06 21:31:04 -0800
committerPaul Eggert2013-11-06 21:31:04 -0800
commitaea07e2c6e54733804d0be54e97d44fcb3df63dd (patch)
tree1f84e37d28aa136603322428a81c2f0046bf9844 /src
parente6e4db3cac4630fc83e4bc520f99823572c3e592 (diff)
downloademacs-aea07e2c6e54733804d0be54e97d44fcb3df63dd.tar.gz
emacs-aea07e2c6e54733804d0be54e97d44fcb3df63dd.zip
Port to C11 aligned_alloc, and fix some integer overflows.
* configure.ac (GMALLOC_OBJ): Initialize to empty if !system_malloc and doug_lea_malloc. (aligned_alloc): Test for existence if !GMALLOC_OBJ and not darwin. (posix_memalign): Test for existence only if !GMALLOC_OBJ and not darwin and !aligned_alloc. * src/alloc.c (USE_ALIGNED_ALLOC): New symbol. (USE_POSIX_MEMALIGN): Remove. All uses replaced with USE_ALIGNED_ALLOC, and use of posix_memalign replaced with aligned_alloc. (aligned_alloc): New function, defined or declared as needed. * src/conf_post.h (HAVE_POSIX_MEMALIGN) [DARWIN_OS]: Don't undef; configure.ac now does this. * src/gmalloc.c (aligned_alloc) [MSDOS]: New decl. (calloc, aligned_alloc): Check for integer overflow. (aligned_alloc): Rename from memalign. All uses changed. (memalign): New function, an alias for aligned_alloc.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog14
-rw-r--r--src/alloc.c31
-rw-r--r--src/conf_post.h2
-rw-r--r--src/gmalloc.c42
4 files changed, 65 insertions, 24 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index d008f670867..2f774b87b13 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,17 @@
12013-11-07 Paul Eggert <eggert@cs.ucla.edu>
2
3 Port to C11 aligned_alloc, and fix some integer overflows.
4 * alloc.c (USE_ALIGNED_ALLOC): New symbol.
5 (USE_POSIX_MEMALIGN): Remove. All uses replaced with USE_ALIGNED_ALLOC,
6 and use of posix_memalign replaced with aligned_alloc.
7 (aligned_alloc): New function, defined or declared as needed.
8 * conf_post.h (HAVE_POSIX_MEMALIGN) [DARWIN_OS]:
9 Don't undef; configure.ac now does this.
10 * gmalloc.c (aligned_alloc) [MSDOS]: New decl.
11 (calloc, aligned_alloc): Check for integer overflow.
12 (aligned_alloc): Rename from memalign. All uses changed.
13 (memalign): New function, an alias for aligned_alloc.
14
12013-11-06 Stefan Monnier <monnier@iro.umontreal.ca> 152013-11-06 Stefan Monnier <monnier@iro.umontreal.ca>
2 16
3 * xdisp.c (redisplay_internal): Fix typo in last change. 17 * xdisp.c (redisplay_internal): Fix typo in last change.
diff --git a/src/alloc.c b/src/alloc.c
index 7054083acba..bc5ed6d94bb 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -920,8 +920,20 @@ lisp_free (void *block)
920/* The entry point is lisp_align_malloc which returns blocks of at most 920/* The entry point is lisp_align_malloc which returns blocks of at most
921 BLOCK_BYTES and guarantees they are aligned on a BLOCK_ALIGN boundary. */ 921 BLOCK_BYTES and guarantees they are aligned on a BLOCK_ALIGN boundary. */
922 922
923#if defined (HAVE_POSIX_MEMALIGN) && defined (SYSTEM_MALLOC) 923#if !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC
924#define USE_POSIX_MEMALIGN 1 924# define USE_ALIGNED_ALLOC 1
925/* Defined in gmalloc.c. */
926void *aligned_alloc (size_t, size_t);
927#elif defined HAVE_ALIGNED_ALLOC
928# define USE_ALIGNED_ALLOC 1
929#elif defined HAVE_POSIX_MEMALIGN
930# define USE_ALIGNED_ALLOC 1
931static void *
932aligned_alloc (size_t alignment, size_t size)
933{
934 void *p;
935 return posix_memalign (&p, alignment, size) == 0 ? p : 0;
936}
925#endif 937#endif
926 938
927/* BLOCK_ALIGN has to be a power of 2. */ 939/* BLOCK_ALIGN has to be a power of 2. */
@@ -931,7 +943,7 @@ lisp_free (void *block)
931 malloc a chance to minimize the amount of memory wasted to alignment. 943 malloc a chance to minimize the amount of memory wasted to alignment.
932 It should be tuned to the particular malloc library used. 944 It should be tuned to the particular malloc library used.
933 On glibc-2.3.2, malloc never tries to align, so a padding of 0 is best. 945 On glibc-2.3.2, malloc never tries to align, so a padding of 0 is best.
934 posix_memalign on the other hand would ideally prefer a value of 4 946 aligned_alloc on the other hand would ideally prefer a value of 4
935 because otherwise, there's 1020 bytes wasted between each ablocks. 947 because otherwise, there's 1020 bytes wasted between each ablocks.
936 In Emacs, testing shows that those 1020 can most of the time be 948 In Emacs, testing shows that those 1020 can most of the time be
937 efficiently used by malloc to place other objects, so a value of 0 can 949 efficiently used by malloc to place other objects, so a value of 0 can
@@ -976,7 +988,7 @@ struct ablocks
976 struct ablock blocks[ABLOCKS_SIZE]; 988 struct ablock blocks[ABLOCKS_SIZE];
977}; 989};
978 990
979/* Size of the block requested from malloc or posix_memalign. */ 991/* Size of the block requested from malloc or aligned_alloc. */
980#define ABLOCKS_BYTES (sizeof (struct ablocks) - BLOCK_PADDING) 992#define ABLOCKS_BYTES (sizeof (struct ablocks) - BLOCK_PADDING)
981 993
982#define ABLOCK_ABASE(block) \ 994#define ABLOCK_ABASE(block) \
@@ -988,7 +1000,7 @@ struct ablocks
988#define ABLOCKS_BUSY(abase) ((abase)->blocks[0].abase) 1000#define ABLOCKS_BUSY(abase) ((abase)->blocks[0].abase)
989 1001
990/* Pointer to the (not necessarily aligned) malloc block. */ 1002/* Pointer to the (not necessarily aligned) malloc block. */
991#ifdef USE_POSIX_MEMALIGN 1003#ifdef USE_ALIGNED_ALLOC
992#define ABLOCKS_BASE(abase) (abase) 1004#define ABLOCKS_BASE(abase) (abase)
993#else 1005#else
994#define ABLOCKS_BASE(abase) \ 1006#define ABLOCKS_BASE(abase) \
@@ -1027,13 +1039,8 @@ lisp_align_malloc (size_t nbytes, enum mem_type type)
1027 mallopt (M_MMAP_MAX, 0); 1039 mallopt (M_MMAP_MAX, 0);
1028#endif 1040#endif
1029 1041
1030#ifdef USE_POSIX_MEMALIGN 1042#ifdef USE_ALIGNED_ALLOC
1031 { 1043 abase = base = aligned_alloc (BLOCK_ALIGN, ABLOCKS_BYTES);
1032 int err = posix_memalign (&base, BLOCK_ALIGN, ABLOCKS_BYTES);
1033 if (err)
1034 base = NULL;
1035 abase = base;
1036 }
1037#else 1044#else
1038 base = malloc (ABLOCKS_BYTES); 1045 base = malloc (ABLOCKS_BYTES);
1039 abase = ALIGN (base, BLOCK_ALIGN); 1046 abase = ALIGN (base, BLOCK_ALIGN);
diff --git a/src/conf_post.h b/src/conf_post.h
index 786105864f2..2d967c0fefc 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -49,8 +49,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
49#define malloc unexec_malloc 49#define malloc unexec_malloc
50#define realloc unexec_realloc 50#define realloc unexec_realloc
51#define free unexec_free 51#define free unexec_free
52/* Don't use posix_memalign because it is not compatible with unexmacosx.c. */
53#undef HAVE_POSIX_MEMALIGN
54#endif 52#endif
55/* The following solves the problem that Emacs hangs when evaluating 53/* The following solves the problem that Emacs hangs when evaluating
56 (make-comint "test0" "/nodir/nofile" nil "") when /nodir/nofile 54 (make-comint "test0" "/nodir/nofile" nil "") when /nodir/nofile
diff --git a/src/gmalloc.c b/src/gmalloc.c
index bc1d85ac5fb..fc728eeea7e 100644
--- a/src/gmalloc.c
+++ b/src/gmalloc.c
@@ -58,6 +58,7 @@ extern void free (void *ptr);
58 58
59/* Allocate SIZE bytes allocated to ALIGNMENT bytes. */ 59/* Allocate SIZE bytes allocated to ALIGNMENT bytes. */
60#ifdef MSDOS 60#ifdef MSDOS
61extern void *aligned_alloc (size_t, size_t);
61extern void *memalign (size_t, size_t); 62extern void *memalign (size_t, size_t);
62extern int posix_memalign (void **, size_t, size_t); 63extern int posix_memalign (void **, size_t, size_t);
63#endif 64#endif
@@ -143,11 +144,11 @@ struct list
143/* Free list headers for each fragment size. */ 144/* Free list headers for each fragment size. */
144extern struct list _fraghead[]; 145extern struct list _fraghead[];
145 146
146/* List of blocks allocated with `memalign' (or `valloc'). */ 147/* List of blocks allocated with aligned_alloc and friends. */
147struct alignlist 148struct alignlist
148 { 149 {
149 struct alignlist *next; 150 struct alignlist *next;
150 void *aligned; /* The address that memaligned returned. */ 151 void *aligned; /* The address that aligned_alloc returned. */
151 void *exact; /* The address that malloc returned. */ 152 void *exact; /* The address that malloc returned. */
152 }; 153 };
153extern struct alignlist *_aligned_blocks; 154extern struct alignlist *_aligned_blocks;
@@ -977,7 +978,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
977/* Debugging hook for free. */ 978/* Debugging hook for free. */
978void (*__free_hook) (void *__ptr); 979void (*__free_hook) (void *__ptr);
979 980
980/* List of blocks allocated by memalign. */ 981/* List of blocks allocated by aligned_alloc. */
981struct alignlist *_aligned_blocks = NULL; 982struct alignlist *_aligned_blocks = NULL;
982 983
983/* Return memory to the heap. 984/* Return memory to the heap.
@@ -1487,13 +1488,20 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
1487/* Allocate an array of NMEMB elements each SIZE bytes long. 1488/* Allocate an array of NMEMB elements each SIZE bytes long.
1488 The entire array is initialized to zeros. */ 1489 The entire array is initialized to zeros. */
1489void * 1490void *
1490calloc (register size_t nmemb, register size_t size) 1491calloc (size_t nmemb, size_t size)
1491{ 1492{
1492 register void *result = malloc (nmemb * size); 1493 void *result;
1494 size_t bytes = nmemb * size;
1493 1495
1494 if (result != NULL) 1496 if (size != 0 && bytes / size != nmemb)
1495 (void) memset (result, 0, nmemb * size); 1497 {
1498 errno = ENOMEM;
1499 return NULL;
1500 }
1496 1501
1502 result = malloc (bytes);
1503 if (result)
1504 memset (result, 0, bytes);
1497 return result; 1505 return result;
1498} 1506}
1499/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. 1507/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
@@ -1559,7 +1567,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>. *
1559void *(*__memalign_hook) (size_t size, size_t alignment); 1567void *(*__memalign_hook) (size_t size, size_t alignment);
1560 1568
1561void * 1569void *
1562memalign (size_t alignment, size_t size) 1570aligned_alloc (size_t alignment, size_t size)
1563{ 1571{
1564 void *result; 1572 void *result;
1565 size_t adj, lastadj; 1573 size_t adj, lastadj;
@@ -1570,6 +1578,11 @@ memalign (size_t alignment, size_t size)
1570 1578
1571 /* Allocate a block with enough extra space to pad the block with up to 1579 /* Allocate a block with enough extra space to pad the block with up to
1572 (ALIGNMENT - 1) bytes if necessary. */ 1580 (ALIGNMENT - 1) bytes if necessary. */
1581 if (- size < alignment)
1582 {
1583 errno = ENOMEM;
1584 return NULL;
1585 }
1573 result = malloc (size + alignment - 1); 1586 result = malloc (size + alignment - 1);
1574 if (result == NULL) 1587 if (result == NULL)
1575 return NULL; 1588 return NULL;
@@ -1631,6 +1644,15 @@ memalign (size_t alignment, size_t size)
1631 return result; 1644 return result;
1632} 1645}
1633 1646
1647/* An obsolete alias for aligned_alloc, for any old libraries that use
1648 this alias. */
1649
1650void *
1651memalign (size_t alignment, size_t size)
1652{
1653 return aligned_alloc (alignment, size);
1654}
1655
1634int 1656int
1635posix_memalign (void **memptr, size_t alignment, size_t size) 1657posix_memalign (void **memptr, size_t alignment, size_t size)
1636{ 1658{
@@ -1641,7 +1663,7 @@ posix_memalign (void **memptr, size_t alignment, size_t size)
1641 || (alignment & (alignment - 1)) != 0) 1663 || (alignment & (alignment - 1)) != 0)
1642 return EINVAL; 1664 return EINVAL;
1643 1665
1644 mem = memalign (alignment, size); 1666 mem = aligned_alloc (alignment, size);
1645 if (mem == NULL) 1667 if (mem == NULL)
1646 return ENOMEM; 1668 return ENOMEM;
1647 1669
@@ -1686,7 +1708,7 @@ valloc (size_t size)
1686 if (pagesize == 0) 1708 if (pagesize == 0)
1687 pagesize = getpagesize (); 1709 pagesize = getpagesize ();
1688 1710
1689 return memalign (pagesize, size); 1711 return aligned_alloc (pagesize, size);
1690} 1712}
1691 1713
1692#ifdef GC_MCHECK 1714#ifdef GC_MCHECK