aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorPaul Eggert2019-03-25 14:31:31 -0700
committerPaul Eggert2019-03-25 14:34:44 -0700
commitdb53731c5f7e11240244161623b82b55cf303043 (patch)
tree05c9902ab67374f1b45e1f2384b669ab40f03d65 /src/alloc.c
parent389475dbcc4fb8ac52367e103306a632ef3fd101 (diff)
downloademacs-db53731c5f7e11240244161623b82b55cf303043.tar.gz
emacs-db53731c5f7e11240244161623b82b55cf303043.zip
Fix alignment bug with pure bignums
Problem found on 32-bit sparc, which has stricter alignment checking than x86-64. * src/alloc.c (pure_alloc): When TYPE is negative it now specifies the negation of the required alignment of the result. (make_pure_bignum): Specify bignum limb alignment.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/src/alloc.c b/src/alloc.c
index f929a37271b..3a8bd30c34b 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -5342,7 +5342,8 @@ valid_lisp_object_p (Lisp_Object obj)
5342 5342
5343/* Allocate room for SIZE bytes from pure Lisp storage and return a 5343/* Allocate room for SIZE bytes from pure Lisp storage and return a
5344 pointer to it. TYPE is the Lisp type for which the memory is 5344 pointer to it. TYPE is the Lisp type for which the memory is
5345 allocated. TYPE < 0 means it's not used for a Lisp object. */ 5345 allocated. TYPE < 0 means it's not used for a Lisp object,
5346 and that the result should have an alignment of -TYPE. */
5346 5347
5347static void * 5348static void *
5348pure_alloc (size_t size, int type) 5349pure_alloc (size_t size, int type)
@@ -5361,8 +5362,11 @@ pure_alloc (size_t size, int type)
5361 { 5362 {
5362 /* Allocate space for a non-Lisp object from the end of the free 5363 /* Allocate space for a non-Lisp object from the end of the free
5363 space. */ 5364 space. */
5364 pure_bytes_used_non_lisp += size; 5365 ptrdiff_t unaligned_non_lisp = pure_bytes_used_non_lisp + size;
5365 result = purebeg + pure_size - pure_bytes_used_non_lisp; 5366 char *unaligned = purebeg + pure_size - unaligned_non_lisp;
5367 int decr = (intptr_t) unaligned & (-1 - type);
5368 pure_bytes_used_non_lisp = unaligned_non_lisp + decr;
5369 result = unaligned - decr;
5366 } 5370 }
5367 pure_bytes_used = pure_bytes_used_lisp + pure_bytes_used_non_lisp; 5371 pure_bytes_used = pure_bytes_used_lisp + pure_bytes_used_non_lisp;
5368 5372
@@ -5549,7 +5553,8 @@ make_pure_bignum (struct Lisp_Bignum *value)
5549 struct Lisp_Bignum *b = pure_alloc (sizeof *b, Lisp_Vectorlike); 5553 struct Lisp_Bignum *b = pure_alloc (sizeof *b, Lisp_Vectorlike);
5550 XSETPVECTYPESIZE (b, PVEC_BIGNUM, 0, VECSIZE (struct Lisp_Bignum)); 5554 XSETPVECTYPESIZE (b, PVEC_BIGNUM, 0, VECSIZE (struct Lisp_Bignum));
5551 5555
5552 pure_limbs = pure_alloc (nbytes, -1); 5556 int limb_alignment = alignof (mp_limb_t);
5557 pure_limbs = pure_alloc (nbytes, - limb_alignment);
5553 for (i = 0; i < nlimbs; ++i) 5558 for (i = 0; i < nlimbs; ++i)
5554 pure_limbs[i] = mpz_getlimbn (value->value, i); 5559 pure_limbs[i] = mpz_getlimbn (value->value, i);
5555 5560