From 463a8eae61ef3d5ae98452f4ee133c1f9b957462 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 8 Feb 2016 11:38:35 -0800 Subject: [PATCH] Port to FreeBSD 11-CURRENT i386 Problem reported by Herbert J. Skuhra in: http://lists.gnu.org/archive/html/emacs-devel/2016-02/msg00354.html Instead of trying * src/alloc.c (lmalloc, lrealloc, laligned): New functions. (xmalloc, xzalloc, xrealloc, lisp_malloc): Use them. (__alignof__) [!__GNUC__ && !__alignof__]: New macro. (MALLOC_IS_GC_ALIGNED): New macro. * src/lisp.h (NONPOINTER_BITS): Remove. All uses removed. No longer needed now that alloc.c uses lmalloc and lrealloc. --- src/alloc.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++----- src/lisp.h | 19 ++------------- 2 files changed, 66 insertions(+), 23 deletions(-) diff --git a/src/alloc.c b/src/alloc.c index 6c6c1aade8e..8816411bcaf 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -802,8 +802,10 @@ malloc_unblock_input (void) malloc_probe (size); \ } while (0) +static void *lmalloc (size_t) ATTRIBUTE_MALLOC_SIZE ((1)); +static void *lrealloc (void *, size_t); -/* Like malloc but check for no memory and block interrupt input.. */ +/* Like malloc but check for no memory and block interrupt input. */ void * xmalloc (size_t size) @@ -811,7 +813,7 @@ xmalloc (size_t size) void *val; MALLOC_BLOCK_INPUT; - val = malloc (size); + val = lmalloc (size); MALLOC_UNBLOCK_INPUT; if (!val && size) @@ -828,7 +830,7 @@ xzalloc (size_t size) void *val; MALLOC_BLOCK_INPUT; - val = malloc (size); + val = lmalloc (size); MALLOC_UNBLOCK_INPUT; if (!val && size) @@ -849,9 +851,9 @@ xrealloc (void *block, size_t size) /* We must call malloc explicitly when BLOCK is 0, since some reallocs don't do this. */ if (! block) - val = malloc (size); + val = lmalloc (size); else - val = realloc (block, size); + val = lrealloc (block, size); MALLOC_UNBLOCK_INPUT; if (!val && size) @@ -1053,7 +1055,7 @@ lisp_malloc (size_t nbytes, enum mem_type type) allocated_mem_type = type; #endif - val = malloc (nbytes); + val = lmalloc (nbytes); #if ! USE_LSB_TAG /* If the memory just allocated cannot be addressed thru a Lisp @@ -1356,6 +1358,62 @@ lisp_align_free (void *block) MALLOC_UNBLOCK_INPUT; } +#if !defined __GNUC__ && !defined __alignof__ +# define __alignof__(type) alignof (type) +#endif + +/* True if malloc returns a multiple of GCALIGNMENT. In practice this + holds if __alignof__ (max_align_t) is a multiple. Use __alignof__ + if available, as otherwise this check would fail with GCC x86. + This is a macro, not an enum constant, for portability to HP-UX + 10.20 cc and AIX 3.2.5 xlc. */ +#define MALLOC_IS_GC_ALIGNED (__alignof__ (max_align_t) % GCALIGNMENT == 0) + +/* True if P is suitably aligned for SIZE, where Lisp alignment may be + needed if SIZE is Lisp-aligned. */ + +static bool +laligned (void *p, size_t size) +{ + return (MALLOC_IS_GC_ALIGNED || size % GCALIGNMENT != 0 + || (intptr_t) p % GCALIGNMENT == 0); +} + +/* Like malloc and realloc except that if SIZE is Lisp-aligned, make + sure the result is too. */ + +static void * +lmalloc (size_t size) +{ +#if USE_ALIGNED_ALLOC + if (! MALLOC_IS_GC_ALIGNED) + return aligned_alloc (GCALIGNMENT, size); +#endif + + void *p; + while (true) + { + p = malloc (size); + if (laligned (p, size)) + break; + free (p); + } + + eassert ((intptr_t) p % GCALIGNMENT == 0); + return p; +} + +static void * +lrealloc (void *p, size_t size) +{ + do + p = realloc (p, size); + while (! laligned (p, size)); + + eassert ((intptr_t) p % GCALIGNMENT == 0); + return p; +} + /*********************************************************************** Interval Allocation diff --git a/src/lisp.h b/src/lisp.h index 82cbca8e6ba..e8eab7be9eb 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -67,19 +67,6 @@ DEFINE_GDB_SYMBOL_BEGIN (int, GCTYPEBITS) #define GCTYPEBITS 3 DEFINE_GDB_SYMBOL_END (GCTYPEBITS) -/* The number of bits needed in an EMACS_INT over and above the number - of bits in a pointer. This is 0 on systems where: - 1. We can specify multiple-of-8 alignment on static variables. - 2. We know malloc returns a multiple of 8. */ -#if (defined alignas \ - && (defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ \ - || defined DARWIN_OS || defined __sun || defined __MINGW32__ \ - || defined CYGWIN)) -# define NONPOINTER_BITS 0 -#else -# define NONPOINTER_BITS GCTYPEBITS -#endif - /* EMACS_INT - signed integer wide enough to hold an Emacs value EMACS_INT_MAX - maximum value of EMACS_INT; can be used in #if pI - printf length modifier for EMACS_INT @@ -87,18 +74,16 @@ DEFINE_GDB_SYMBOL_END (GCTYPEBITS) #ifndef EMACS_INT_MAX # if INTPTR_MAX <= 0 # error "INTPTR_MAX misconfigured" -# elif INTPTR_MAX <= INT_MAX >> NONPOINTER_BITS && !defined WIDE_EMACS_INT +# elif INTPTR_MAX <= INT_MAX && !defined WIDE_EMACS_INT typedef int EMACS_INT; typedef unsigned int EMACS_UINT; # define EMACS_INT_MAX INT_MAX # define pI "" -# elif INTPTR_MAX <= LONG_MAX >> NONPOINTER_BITS && !defined WIDE_EMACS_INT +# elif INTPTR_MAX <= LONG_MAX && !defined WIDE_EMACS_INT typedef long int EMACS_INT; typedef unsigned long EMACS_UINT; # define EMACS_INT_MAX LONG_MAX # define pI "l" -/* Check versus LLONG_MAX, not LLONG_MAX >> NONPOINTER_BITS. - In theory this is not safe, but in practice it seems to be OK. */ # elif INTPTR_MAX <= LLONG_MAX typedef long long int EMACS_INT; typedef unsigned long long int EMACS_UINT; -- 2.39.5