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:
parent
e6e4db3cac
commit
aea07e2c6e
6 changed files with 88 additions and 28 deletions
|
@ -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,
|
||||
|
|
18
configure.ac
18
configure.ac
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
31
src/alloc.c
31
src/alloc.c
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue