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.
This commit is contained in:
Paul Eggert 2013-11-06 21:31:04 -08:00
parent e6e4db3cac
commit aea07e2c6e
6 changed files with 88 additions and 28 deletions

View file

@ -1,3 +1,12 @@
2013-11-07 Paul Eggert <eggert@cs.ucla.edu>
Port to C11 aligned_alloc.
* 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.
2013-11-05 Glenn Morris <rgm@gnu.org>
* configure.ac (abs_srcdir) [MINGW32]: No point setting it here,

View file

@ -1895,12 +1895,14 @@ case "$opsys" in
darwin|sol2-10) system_malloc=yes ;;
esac
GMALLOC_OBJ=
if test "${system_malloc}" = "yes"; then
AC_DEFINE(SYSTEM_MALLOC, 1, [Define to use system malloc.])
AC_DEFINE([SYSTEM_MALLOC], 1,
[Define to 1 to use the system memory allocator, even if it is not
Doug Lea style.])
GNU_MALLOC=no
GNU_MALLOC_reason="
(The GNU allocators don't work with this system configuration.)"
GMALLOC_OBJ=
VMLIMIT_OBJ=
else
test "$doug_lea_malloc" != "yes" && GMALLOC_OBJ=gmalloc.o
@ -1929,7 +1931,8 @@ if test "$doug_lea_malloc" = "yes" ; then
(Using Doug Lea's new malloc from the GNU C Library.)"
fi
AC_DEFINE(DOUG_LEA_MALLOC, 1,
[Define to 1 if you are using the GNU C Library.])
[Define to 1 if the system memory allocator is Doug Lea style,
with malloc hooks and malloc_set_state.])
## Use mmap directly for allocating larger buffers.
## FIXME this comes from src/s/{gnu,gnu-linux}.h:
@ -3372,11 +3375,18 @@ getrlimit setrlimit shutdown getaddrinfo \
strsignal setitimer \
sendto recvfrom getsockname getpeername getifaddrs freeifaddrs \
gai_strerror getline getdelim sync \
difftime posix_memalign \
difftime \
getpwent endpwent getgrent endgrent \
touchlock \
cfmakeraw cfsetspeed copysign __executable_start log2)
dnl No need to check for aligned_alloc and posix_memalign if using
dnl gmalloc.o, as it supplies them. Don't use these functions on
dnl Darwin as they are incompatible with unexmacosx.c.
if test -z "$GMALLOC_OBJ" && test "$opsys" != darwin; then
AC_CHECK_FUNCS([aligned_alloc posix_memalign], [break])
fi
## Eric Backus <ericb@lsid.hp.com> says, HP-UX 9.x on HP 700 machines
## has a broken `rint' in some library versions including math library
## version number A.09.05.

View file

@ -1,3 +1,17 @@
2013-11-07 Paul Eggert <eggert@cs.ucla.edu>
Port to C11 aligned_alloc, and fix some integer overflows.
* 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.
* conf_post.h (HAVE_POSIX_MEMALIGN) [DARWIN_OS]:
Don't undef; configure.ac now does this.
* 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.
2013-11-06 Stefan Monnier <monnier@iro.umontreal.ca>
* xdisp.c (redisplay_internal): Fix typo in last change.

View file

@ -920,8 +920,20 @@ lisp_free (void *block)
/* The entry point is lisp_align_malloc which returns blocks of at most
BLOCK_BYTES and guarantees they are aligned on a BLOCK_ALIGN boundary. */
#if defined (HAVE_POSIX_MEMALIGN) && defined (SYSTEM_MALLOC)
#define USE_POSIX_MEMALIGN 1
#if !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC
# define USE_ALIGNED_ALLOC 1
/* Defined in gmalloc.c. */
void *aligned_alloc (size_t, size_t);
#elif defined HAVE_ALIGNED_ALLOC
# define USE_ALIGNED_ALLOC 1
#elif defined HAVE_POSIX_MEMALIGN
# define USE_ALIGNED_ALLOC 1
static void *
aligned_alloc (size_t alignment, size_t size)
{
void *p;
return posix_memalign (&p, alignment, size) == 0 ? p : 0;
}
#endif
/* BLOCK_ALIGN has to be a power of 2. */
@ -931,7 +943,7 @@ lisp_free (void *block)
malloc a chance to minimize the amount of memory wasted to alignment.
It should be tuned to the particular malloc library used.
On glibc-2.3.2, malloc never tries to align, so a padding of 0 is best.
posix_memalign on the other hand would ideally prefer a value of 4
aligned_alloc on the other hand would ideally prefer a value of 4
because otherwise, there's 1020 bytes wasted between each ablocks.
In Emacs, testing shows that those 1020 can most of the time be
efficiently used by malloc to place other objects, so a value of 0 can
@ -976,7 +988,7 @@ struct ablocks
struct ablock blocks[ABLOCKS_SIZE];
};
/* Size of the block requested from malloc or posix_memalign. */
/* Size of the block requested from malloc or aligned_alloc. */
#define ABLOCKS_BYTES (sizeof (struct ablocks) - BLOCK_PADDING)
#define ABLOCK_ABASE(block) \
@ -988,7 +1000,7 @@ struct ablocks
#define ABLOCKS_BUSY(abase) ((abase)->blocks[0].abase)
/* Pointer to the (not necessarily aligned) malloc block. */
#ifdef USE_POSIX_MEMALIGN
#ifdef USE_ALIGNED_ALLOC
#define ABLOCKS_BASE(abase) (abase)
#else
#define ABLOCKS_BASE(abase) \
@ -1027,13 +1039,8 @@ lisp_align_malloc (size_t nbytes, enum mem_type type)
mallopt (M_MMAP_MAX, 0);
#endif
#ifdef USE_POSIX_MEMALIGN
{
int err = posix_memalign (&base, BLOCK_ALIGN, ABLOCKS_BYTES);
if (err)
base = NULL;
abase = base;
}
#ifdef USE_ALIGNED_ALLOC
abase = base = aligned_alloc (BLOCK_ALIGN, ABLOCKS_BYTES);
#else
base = malloc (ABLOCKS_BYTES);
abase = ALIGN (base, BLOCK_ALIGN);

View file

@ -49,8 +49,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#define malloc unexec_malloc
#define realloc unexec_realloc
#define free unexec_free
/* Don't use posix_memalign because it is not compatible with unexmacosx.c. */
#undef HAVE_POSIX_MEMALIGN
#endif
/* The following solves the problem that Emacs hangs when evaluating
(make-comint "test0" "/nodir/nofile" nil "") when /nodir/nofile

View file

@ -58,6 +58,7 @@ extern void free (void *ptr);
/* Allocate SIZE bytes allocated to ALIGNMENT bytes. */
#ifdef MSDOS
extern void *aligned_alloc (size_t, size_t);
extern void *memalign (size_t, size_t);
extern int posix_memalign (void **, size_t, size_t);
#endif
@ -143,11 +144,11 @@ struct list
/* Free list headers for each fragment size. */
extern struct list _fraghead[];
/* List of blocks allocated with `memalign' (or `valloc'). */
/* List of blocks allocated with aligned_alloc and friends. */
struct alignlist
{
struct alignlist *next;
void *aligned; /* The address that memaligned returned. */
void *aligned; /* The address that aligned_alloc returned. */
void *exact; /* The address that malloc returned. */
};
extern struct alignlist *_aligned_blocks;
@ -977,7 +978,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
/* Debugging hook for free. */
void (*__free_hook) (void *__ptr);
/* List of blocks allocated by memalign. */
/* List of blocks allocated by aligned_alloc. */
struct alignlist *_aligned_blocks = NULL;
/* Return memory to the heap.
@ -1487,13 +1488,20 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
/* Allocate an array of NMEMB elements each SIZE bytes long.
The entire array is initialized to zeros. */
void *
calloc (register size_t nmemb, register size_t size)
calloc (size_t nmemb, size_t size)
{
register void *result = malloc (nmemb * size);
void *result;
size_t bytes = nmemb * size;
if (result != NULL)
(void) memset (result, 0, nmemb * size);
if (size != 0 && bytes / size != nmemb)
{
errno = ENOMEM;
return NULL;
}
result = malloc (bytes);
if (result)
memset (result, 0, bytes);
return result;
}
/* 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/>. *
void *(*__memalign_hook) (size_t size, size_t alignment);
void *
memalign (size_t alignment, size_t size)
aligned_alloc (size_t alignment, size_t size)
{
void *result;
size_t adj, lastadj;
@ -1570,6 +1578,11 @@ memalign (size_t alignment, size_t size)
/* Allocate a block with enough extra space to pad the block with up to
(ALIGNMENT - 1) bytes if necessary. */
if (- size < alignment)
{
errno = ENOMEM;
return NULL;
}
result = malloc (size + alignment - 1);
if (result == NULL)
return NULL;
@ -1631,6 +1644,15 @@ memalign (size_t alignment, size_t size)
return result;
}
/* An obsolete alias for aligned_alloc, for any old libraries that use
this alias. */
void *
memalign (size_t alignment, size_t size)
{
return aligned_alloc (alignment, size);
}
int
posix_memalign (void **memptr, size_t alignment, size_t size)
{
@ -1641,7 +1663,7 @@ posix_memalign (void **memptr, size_t alignment, size_t size)
|| (alignment & (alignment - 1)) != 0)
return EINVAL;
mem = memalign (alignment, size);
mem = aligned_alloc (alignment, size);
if (mem == NULL)
return ENOMEM;
@ -1686,7 +1708,7 @@ valloc (size_t size)
if (pagesize == 0)
pagesize = getpagesize ();
return memalign (pagesize, size);
return aligned_alloc (pagesize, size);
}
#ifdef GC_MCHECK