#include <config.h>
+#include <errno.h>
#include <stdio.h>
#include <limits.h> /* For CHAR_BIT. */
#include <signal.h> /* For SIGABRT, SIGDANGER. */
}
}
- malloc_set_state (malloc_state_ptr);
+ if (malloc_set_state (malloc_state_ptr) != 0)
+ emacs_abort ();
# ifndef XMALLOC_OVERRUN_CHECK
alloc_unexec_post ();
# endif
{
#ifdef DOUG_LEA_MALLOC
malloc_state_ptr = malloc_get_state ();
+ if (!malloc_state_ptr)
+ fatal ("malloc_get_state: %s", strerror (errno));
#endif
#ifdef HYBRID_MALLOC
bss_sbrk_did_unexec = true;
/* Return PTR rounded up to the next multiple of ALIGNMENT. */
static void *
-ALIGN (void *ptr, int alignment)
+pointer_align (void *ptr, int alignment)
{
return (void *) ROUNDUP ((uintptr_t) ptr, alignment);
}
char payload[BLOCK_BYTES];
struct ablock *next_free;
} x;
- /* `abase' is the aligned base of the ablocks. */
- /* It is overloaded to hold the virtual `busy' field that counts
- the number of used ablock in the parent ablocks.
- The first ablock has the `busy' field, the others have the `abase'
- field. To tell the difference, we assume that pointers will have
- integer values larger than 2 * ABLOCKS_SIZE. The lowest bit of `busy'
- is used to tell whether the real base of the parent ablocks is `abase'
- (if not, the word before the first ablock holds a pointer to the
- real base). */
+
+ /* ABASE is the aligned base of the ablocks. It is overloaded to
+ hold a virtual "busy" field that counts twice the number of used
+ ablock values in the parent ablocks, plus one if the real base of
+ the parent ablocks is ABASE (if the "busy" field is even, the
+ word before the first ablock holds a pointer to the real base).
+ The first ablock has a "busy" ABASE, and the others have an
+ ordinary pointer ABASE. To tell the difference, the code assumes
+ that pointers, when cast to uintptr_t, are at least 2 *
+ ABLOCKS_SIZE + 1. */
struct ablocks *abase;
+
/* The padding of all but the last ablock is unused. The padding of
the last ablock in an ablocks is not allocated. */
#if BLOCK_PADDING
#define ABLOCK_ABASE(block) \
(((uintptr_t) (block)->abase) <= (1 + 2 * ABLOCKS_SIZE) \
- ? (struct ablocks *)(block) \
+ ? (struct ablocks *) (block) \
: (block)->abase)
/* Virtual `busy' field. */
-#define ABLOCKS_BUSY(abase) ((abase)->blocks[0].abase)
+#define ABLOCKS_BUSY(a_base) ((a_base)->blocks[0].abase)
/* Pointer to the (not necessarily aligned) malloc block. */
#ifdef USE_ALIGNED_ALLOC
#define ABLOCKS_BASE(abase) (abase)
#else
#define ABLOCKS_BASE(abase) \
- (1 & (intptr_t) ABLOCKS_BUSY (abase) ? abase : ((void **)abase)[-1])
+ (1 & (intptr_t) ABLOCKS_BUSY (abase) ? abase : ((void **) (abase))[-1])
#endif
/* The list of free ablock. */
if (!free_ablock)
{
int i;
- intptr_t aligned; /* int gets warning casting to 64-bit pointer. */
+ bool aligned;
#ifdef DOUG_LEA_MALLOC
if (!mmap_lisp_allowed_p ())
abase = base = aligned_alloc (BLOCK_ALIGN, ABLOCKS_BYTES);
#else
base = malloc (ABLOCKS_BYTES);
- abase = ALIGN (base, BLOCK_ALIGN);
+ abase = pointer_align (base, BLOCK_ALIGN);
#endif
if (base == 0)
abase->blocks[i].x.next_free = free_ablock;
free_ablock = &abase->blocks[i];
}
- ABLOCKS_BUSY (abase) = (struct ablocks *) aligned;
+ intptr_t ialigned = aligned;
+ ABLOCKS_BUSY (abase) = (struct ablocks *) ialigned;
- eassert (0 == ((uintptr_t) abase) % BLOCK_ALIGN);
+ eassert ((uintptr_t) abase % BLOCK_ALIGN == 0);
eassert (ABLOCK_ABASE (&abase->blocks[3]) == abase); /* 3 is arbitrary */
eassert (ABLOCK_ABASE (&abase->blocks[0]) == abase);
eassert (ABLOCKS_BASE (abase) == base);
- eassert (aligned == (intptr_t) ABLOCKS_BUSY (abase));
+ eassert ((intptr_t) ABLOCKS_BUSY (abase) == aligned);
}
abase = ABLOCK_ABASE (free_ablock);
ablock->x.next_free = free_ablock;
free_ablock = ablock;
/* Update busy count. */
- ABLOCKS_BUSY (abase)
- = (struct ablocks *) (-2 + (intptr_t) ABLOCKS_BUSY (abase));
+ intptr_t busy = (intptr_t) ABLOCKS_BUSY (abase) - 2;
+ eassume (0 <= busy && busy <= 2 * ABLOCKS_SIZE - 1);
+ ABLOCKS_BUSY (abase) = (struct ablocks *) busy;
- if (2 > (intptr_t) ABLOCKS_BUSY (abase))
+ if (busy < 2)
{ /* All the blocks are free. */
- int i = 0, aligned = (intptr_t) ABLOCKS_BUSY (abase);
+ int i = 0;
+ bool aligned = busy;
struct ablock **tem = &free_ablock;
struct ablock *atop = &abase->blocks[aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1];
{
/* Allocate space for a Lisp object from the beginning of the free
space with taking account of alignment. */
- result = ALIGN (purebeg + pure_bytes_used_lisp, GCALIGNMENT);
+ result = pointer_align (purebeg + pure_bytes_used_lisp, GCALIGNMENT);
pure_bytes_used_lisp = ((char *)result - (char *)purebeg) + size;
}
else
int i, j;
for (i = 0; i < c->used; ++i)
{
- struct face *face = FACE_OPT_FROM_ID (c->f, i);
+ struct face *face = FACE_FROM_ID_OR_NULL (c->f, i);
if (face)
{