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.
This commit is contained in:
parent
37eae51767
commit
463a8eae61
2 changed files with 66 additions and 23 deletions
70
src/alloc.c
70
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
|
||||
|
|
19
src/lisp.h
19
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;
|
||||
|
|
Loading…
Add table
Reference in a new issue