diff options
| author | Paul Eggert | 2019-03-25 14:31:31 -0700 |
|---|---|---|
| committer | Paul Eggert | 2019-03-25 14:34:44 -0700 |
| commit | db53731c5f7e11240244161623b82b55cf303043 (patch) | |
| tree | 05c9902ab67374f1b45e1f2384b669ab40f03d65 /src/alloc.c | |
| parent | 389475dbcc4fb8ac52367e103306a632ef3fd101 (diff) | |
| download | emacs-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.c | 13 |
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 | ||
| 5347 | static void * | 5348 | static void * |
| 5348 | pure_alloc (size_t size, int type) | 5349 | pure_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 | ||