diff options
| author | Paul Eggert | 2015-06-24 20:10:03 -0700 |
|---|---|---|
| committer | Paul Eggert | 2015-06-24 20:10:44 -0700 |
| commit | 93f4f67ba93b78e8b31e498e8ce7bce4c8298b76 (patch) | |
| tree | 788c0808926664ea23de2f903f4c233c5febf7ab /src/lisp.h | |
| parent | f230b2ff3136120a9be544a5d3a974f7087ce55b (diff) | |
| download | emacs-93f4f67ba93b78e8b31e498e8ce7bce4c8298b76.tar.gz emacs-93f4f67ba93b78e8b31e498e8ce7bce4c8298b76.zip | |
Fix GC bugs --with-wide-int and Qnil == 0
Use the same alignment for the !USE_LSB_TAG case as for the
more-typical USE_LSB_TAG case. The attempt to support arbitrary
alignments with !USE_LSB_TAG had subtle bugs in garbage collection
once we changed the representation of symbols so that Qnil == 0.
Problem reported by Eli Zaretskii (Bug#20862).
* src/alloc.c (XMALLOC_HEADER_ALIGNMENT) [XMALLOC_OVERRUN_CHECK]:
* src/alloc.c (vector_alignment, union aligned_Lisp_Symbol)
(union aligned_Lisp_Misc, maybe_lisp_pointer, pure_alloc):
Use same alignment for !USE_LSB_TAG as for USE_LSB_TAG.
* src/alloc.c (POINTERS_MIGHT_HIDE_IN_OBJECTS): Remove.
This optimization in the !USE_LSB_TAG case is no longer valid when
symbols are represented via offsets. Change the only use to
assume that pointers might hide in objects.
* src/lisp.h (alignas) [!USE_LSB_TAG]:
Require support in this case, too.
(TAG_SYMOFFSET, XSYMBOL) [!USE_LSB_TAG]: Do not shift the offset.
This is OK, because the !USE_LSB_TAG case now applies only when
Lisp_Object is wider than void *, so there's no longer any need
to shift the offset. Not shifting the offset means that
symbol representations have the same alignment as pointers,
which the GC assumes.
Diffstat (limited to 'src/lisp.h')
| -rw-r--r-- | src/lisp.h | 11 |
1 files changed, 2 insertions, 9 deletions
diff --git a/src/lisp.h b/src/lisp.h index 198f116fe02..c3289c9d700 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -278,10 +278,7 @@ error !; | |||
| 278 | #endif | 278 | #endif |
| 279 | 279 | ||
| 280 | #ifndef alignas | 280 | #ifndef alignas |
| 281 | # define alignas(alignment) /* empty */ | 281 | # error "alignas not defined" |
| 282 | # if USE_LSB_TAG | ||
| 283 | # error "USE_LSB_TAG requires alignas" | ||
| 284 | # endif | ||
| 285 | #endif | 282 | #endif |
| 286 | 283 | ||
| 287 | #ifdef HAVE_STRUCT_ATTRIBUTE_ALIGNED | 284 | #ifdef HAVE_STRUCT_ATTRIBUTE_ALIGNED |
| @@ -731,9 +728,7 @@ struct Lisp_Symbol | |||
| 731 | 728 | ||
| 732 | /* Yield an integer that contains a symbol tag along with OFFSET. | 729 | /* Yield an integer that contains a symbol tag along with OFFSET. |
| 733 | OFFSET should be the offset in bytes from 'lispsym' to the symbol. */ | 730 | OFFSET should be the offset in bytes from 'lispsym' to the symbol. */ |
| 734 | #define TAG_SYMOFFSET(offset) \ | 731 | #define TAG_SYMOFFSET(offset) TAG_PTR (Lisp_Symbol, offset) |
| 735 | TAG_PTR (Lisp_Symbol, \ | ||
| 736 | ((uintptr_t) (offset) >> (USE_LSB_TAG ? 0 : GCTYPEBITS))) | ||
| 737 | 732 | ||
| 738 | /* XLI_BUILTIN_LISPSYM (iQwhatever) is equivalent to | 733 | /* XLI_BUILTIN_LISPSYM (iQwhatever) is equivalent to |
| 739 | XLI (builtin_lisp_symbol (Qwhatever)), | 734 | XLI (builtin_lisp_symbol (Qwhatever)), |
| @@ -899,8 +894,6 @@ INLINE struct Lisp_Symbol * | |||
| 899 | XSYMBOL (Lisp_Object a) | 894 | XSYMBOL (Lisp_Object a) |
| 900 | { | 895 | { |
| 901 | uintptr_t i = (uintptr_t) XUNTAG (a, Lisp_Symbol); | 896 | uintptr_t i = (uintptr_t) XUNTAG (a, Lisp_Symbol); |
| 902 | if (! USE_LSB_TAG) | ||
| 903 | i <<= GCTYPEBITS; | ||
| 904 | void *p = (char *) lispsym + i; | 897 | void *p = (char *) lispsym + i; |
| 905 | return p; | 898 | return p; |
| 906 | } | 899 | } |