aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2017-11-13 08:51:41 -0800
committerPaul Eggert2017-11-13 10:16:51 -0800
commitb1573a97e17b518723ab3f906eb6d521caed196d (patch)
tree2bcfe8f47a99d7ba9b46e75ed5bffd2ba37970e0 /src
parent5d68dc9a2fd1b9b883db6bc1c226541b50de8bb1 (diff)
downloademacs-b1573a97e17b518723ab3f906eb6d521caed196d.tar.gz
emacs-b1573a97e17b518723ab3f906eb6d521caed196d.zip
Use alignas to fix GCALIGN-related bugs
Use alignas and unions to specify alignments of objects needing addresses that are at least a multiple of GCALIGNMENT. Using these standard C facilities should be safer than relying on ad hoc and poorly-understood features like GCC’s __attribute__ ((aligned (N))), the root cause for recent porting bugs like Bug#29040. The alignas macro was standardized by C11 and Gnulib supports alignas for pre-C11 platforms. I have tested this on Sun Studio 12 sparc (2007) and GCC 4.4.7 x86-64 (2012) as well as on more recent platforms like GCC 7.2.1 (2017) on Fedora 26 (both x86-64 and x86). * lib-src/make-docfile.c (close_emacs_globals): lispsym is now just an array of struct Lisp_Symbol, since struct Lisp_Symbol is now properly aligned. All uses changed. * src/alloc.c (NEXT_FREE_LISP_STRING): Just use the new u.next member; this is simpler and safer than casting a pointer that might not be aligned properly. (aligned_Lisp_Symbol): Remove. No longer needed, now that struct Lisp_Symbol is aligned properly. All uses replaced with struct Lisp_Symbol. * src/lisp.h (GCALIGNED): Remove, as it does not work as expected: it can cause the natural alignment to be ignored. All uses replaced by unions with a ‘char alignas (GCALIGNMENT)’ member as described below. (struct Lisp_Symbol, struct Lisp_Cons, struct Lisp_String): Change definition from ‘struct TAG { MEMBERS };’ to ‘struct TAG { union { struct { MEMBERS } s; char alignas (GCALIGNMENT) gcaligned; } u; };’. This guarantees ‘struct TAG’ to have an alignment that at least max (GCALIGNMENT, N) where N is its old alignment. All uses like ‘PTR->MEMBER’ changed to ‘PTR->u.s.MEMBER’; these uses were supposed to be mostly private anyway. Verify that the resulting ‘struct TAG’ is properly aligned for Emacs. (union vectorlike_header): New member ‘gcaligned’ to guarantee that this type, and its containing types like ‘struct Lisp_Subr’, ‘struct buffer’ and ‘struct thread_state’, are all properly aligned for Emacs. (struct Lisp_String): New union member ‘next’, for the benefit of NEXT_FREE_LISP_STRING. (union Aligned_Cons, union Aligned_String): Remove. All uses replaced by struct Lisp_Cons and struct Lisp_String, since they are now properly aligned. (USE_STACK_CONS, USE_STACK_STRING): Simplify now that we can assume struct Lisp_Cons and struct Lisp_String are properly aligned.
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c211
-rw-r--r--src/buffer.c19
-rw-r--r--src/bytecode.c4
-rw-r--r--src/casefiddle.c4
-rw-r--r--src/cmds.c6
-rw-r--r--src/data.c76
-rw-r--r--src/doc.c2
-rw-r--r--src/eval.c59
-rw-r--r--src/fns.c4
-rw-r--r--src/keyboard.c10
-rw-r--r--src/lisp.h277
-rw-r--r--src/lread.c52
-rw-r--r--src/minibuf.c12
-rw-r--r--src/thread.c2
-rw-r--r--src/xterm.c2
15 files changed, 366 insertions, 374 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 5a44d7a9fc2..3b87195b707 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -211,9 +211,9 @@ alloc_unexec_post (void)
211/* Mark, unmark, query mark bit of a Lisp string. S must be a pointer 211/* Mark, unmark, query mark bit of a Lisp string. S must be a pointer
212 to a struct Lisp_String. */ 212 to a struct Lisp_String. */
213 213
214#define MARK_STRING(S) ((S)->size |= ARRAY_MARK_FLAG) 214#define MARK_STRING(S) ((S)->u.s.size |= ARRAY_MARK_FLAG)
215#define UNMARK_STRING(S) ((S)->size &= ~ARRAY_MARK_FLAG) 215#define UNMARK_STRING(S) ((S)->u.s.size &= ~ARRAY_MARK_FLAG)
216#define STRING_MARKED_P(S) (((S)->size & ARRAY_MARK_FLAG) != 0) 216#define STRING_MARKED_P(S) (((S)->u.s.size & ARRAY_MARK_FLAG) != 0)
217 217
218#define VECTOR_MARK(V) ((V)->header.size |= ARRAY_MARK_FLAG) 218#define VECTOR_MARK(V) ((V)->header.size |= ARRAY_MARK_FLAG)
219#define VECTOR_UNMARK(V) ((V)->header.size &= ~ARRAY_MARK_FLAG) 219#define VECTOR_UNMARK(V) ((V)->header.size &= ~ARRAY_MARK_FLAG)
@@ -1730,14 +1730,14 @@ static EMACS_INT total_string_bytes;
1730 string_free_list, return a pointer to its successor in the 1730 string_free_list, return a pointer to its successor in the
1731 free-list. */ 1731 free-list. */
1732 1732
1733#define NEXT_FREE_LISP_STRING(S) (*(struct Lisp_String **) (S)) 1733#define NEXT_FREE_LISP_STRING(S) ((S)->u.next)
1734 1734
1735/* Return a pointer to the sdata structure belonging to Lisp string S. 1735/* Return a pointer to the sdata structure belonging to Lisp string S.
1736 S must be live, i.e. S->data must not be null. S->data is actually 1736 S must be live, i.e. S->data must not be null. S->data is actually
1737 a pointer to the `u.data' member of its sdata structure; the 1737 a pointer to the `u.data' member of its sdata structure; the
1738 structure starts at a constant offset in front of that. */ 1738 structure starts at a constant offset in front of that. */
1739 1739
1740#define SDATA_OF_STRING(S) ((sdata *) ((S)->data - SDATA_DATA_OFFSET)) 1740#define SDATA_OF_STRING(S) ((sdata *) ((S)->u.s.data - SDATA_DATA_OFFSET))
1741 1741
1742 1742
1743#ifdef GC_CHECK_STRING_OVERRUN 1743#ifdef GC_CHECK_STRING_OVERRUN
@@ -1818,9 +1818,10 @@ ptrdiff_t
1818string_bytes (struct Lisp_String *s) 1818string_bytes (struct Lisp_String *s)
1819{ 1819{
1820 ptrdiff_t nbytes = 1820 ptrdiff_t nbytes =
1821 (s->size_byte < 0 ? s->size & ~ARRAY_MARK_FLAG : s->size_byte); 1821 (s->u.s.size_byte < 0 ? s->u.s.size & ~ARRAY_MARK_FLAG : s->u.s.size_byte);
1822 1822
1823 if (!PURE_P (s) && s->data && nbytes != SDATA_NBYTES (SDATA_OF_STRING (s))) 1823 if (!PURE_P (s) && s->u.s.data
1824 && nbytes != SDATA_NBYTES (SDATA_OF_STRING (s)))
1824 emacs_abort (); 1825 emacs_abort ();
1825 return nbytes; 1826 return nbytes;
1826} 1827}
@@ -1926,7 +1927,7 @@ allocate_string (void)
1926 { 1927 {
1927 s = b->strings + i; 1928 s = b->strings + i;
1928 /* Every string on a free list should have NULL data pointer. */ 1929 /* Every string on a free list should have NULL data pointer. */
1929 s->data = NULL; 1930 s->u.s.data = NULL;
1930 NEXT_FREE_LISP_STRING (s) = string_free_list; 1931 NEXT_FREE_LISP_STRING (s) = string_free_list;
1931 string_free_list = s; 1932 string_free_list = s;
1932 } 1933 }
@@ -1965,10 +1966,10 @@ allocate_string (void)
1965 1966
1966 1967
1967/* Set up Lisp_String S for holding NCHARS characters, NBYTES bytes, 1968/* Set up Lisp_String S for holding NCHARS characters, NBYTES bytes,
1968 plus a NUL byte at the end. Allocate an sdata structure for S, and 1969 plus a NUL byte at the end. Allocate an sdata structure DATA for
1969 set S->data to its `u.data' member. Store a NUL byte at the end of 1970 S, and set S->u.s.data to SDATA->u.data. Store a NUL byte at the
1970 S->data. Set S->size to NCHARS and S->size_byte to NBYTES. Free 1971 end of S->u.s.data. Set S->u.s.size to NCHARS and S->u.s.size_byte
1971 S->data if it was initially non-null. */ 1972 to NBYTES. Free S->u.s.data if it was initially non-null. */
1972 1973
1973void 1974void
1974allocate_string_data (struct Lisp_String *s, 1975allocate_string_data (struct Lisp_String *s,
@@ -1984,7 +1985,7 @@ allocate_string_data (struct Lisp_String *s,
1984 /* Determine the number of bytes needed to store NBYTES bytes 1985 /* Determine the number of bytes needed to store NBYTES bytes
1985 of string data. */ 1986 of string data. */
1986 needed = SDATA_SIZE (nbytes); 1987 needed = SDATA_SIZE (nbytes);
1987 if (s->data) 1988 if (s->u.s.data)
1988 { 1989 {
1989 old_data = SDATA_OF_STRING (s); 1990 old_data = SDATA_OF_STRING (s);
1990 old_nbytes = STRING_BYTES (s); 1991 old_nbytes = STRING_BYTES (s);
@@ -2043,13 +2044,13 @@ allocate_string_data (struct Lisp_String *s,
2043 2044
2044 MALLOC_UNBLOCK_INPUT; 2045 MALLOC_UNBLOCK_INPUT;
2045 2046
2046 s->data = SDATA_DATA (data); 2047 s->u.s.data = SDATA_DATA (data);
2047#ifdef GC_CHECK_STRING_BYTES 2048#ifdef GC_CHECK_STRING_BYTES
2048 SDATA_NBYTES (data) = nbytes; 2049 SDATA_NBYTES (data) = nbytes;
2049#endif 2050#endif
2050 s->size = nchars; 2051 s->u.s.size = nchars;
2051 s->size_byte = nbytes; 2052 s->u.s.size_byte = nbytes;
2052 s->data[nbytes] = '\0'; 2053 s->u.s.data[nbytes] = '\0';
2053#ifdef GC_CHECK_STRING_OVERRUN 2054#ifdef GC_CHECK_STRING_OVERRUN
2054 memcpy ((char *) data + needed, string_overrun_cookie, 2055 memcpy ((char *) data + needed, string_overrun_cookie,
2055 GC_STRING_OVERRUN_COOKIE_SIZE); 2056 GC_STRING_OVERRUN_COOKIE_SIZE);
@@ -2093,7 +2094,7 @@ sweep_strings (void)
2093 { 2094 {
2094 struct Lisp_String *s = b->strings + i; 2095 struct Lisp_String *s = b->strings + i;
2095 2096
2096 if (s->data) 2097 if (s->u.s.data)
2097 { 2098 {
2098 /* String was not on free-list before. */ 2099 /* String was not on free-list before. */
2099 if (STRING_MARKED_P (s)) 2100 if (STRING_MARKED_P (s))
@@ -2102,7 +2103,7 @@ sweep_strings (void)
2102 UNMARK_STRING (s); 2103 UNMARK_STRING (s);
2103 2104
2104 /* Do not use string_(set|get)_intervals here. */ 2105 /* Do not use string_(set|get)_intervals here. */
2105 s->intervals = balance_intervals (s->intervals); 2106 s->u.s.intervals = balance_intervals (s->u.s.intervals);
2106 2107
2107 ++total_strings; 2108 ++total_strings;
2108 total_string_bytes += STRING_BYTES (s); 2109 total_string_bytes += STRING_BYTES (s);
@@ -2125,7 +2126,7 @@ sweep_strings (void)
2125 2126
2126 /* Reset the strings's `data' member so that we 2127 /* Reset the strings's `data' member so that we
2127 know it's free. */ 2128 know it's free. */
2128 s->data = NULL; 2129 s->u.s.data = NULL;
2129 2130
2130 /* Put the string on the free-list. */ 2131 /* Put the string on the free-list. */
2131 NEXT_FREE_LISP_STRING (s) = string_free_list; 2132 NEXT_FREE_LISP_STRING (s) = string_free_list;
@@ -2264,7 +2265,7 @@ compact_small_strings (void)
2264 { 2265 {
2265 eassert (tb != b || to < from); 2266 eassert (tb != b || to < from);
2266 memmove (to, from, nbytes + GC_STRING_EXTRA); 2267 memmove (to, from, nbytes + GC_STRING_EXTRA);
2267 to->string->data = SDATA_DATA (to); 2268 to->string->u.s.data = SDATA_DATA (to);
2268 } 2269 }
2269 2270
2270 /* Advance past the sdata we copied to. */ 2271 /* Advance past the sdata we copied to. */
@@ -2544,7 +2545,7 @@ make_uninit_multibyte_string (EMACS_INT nchars, EMACS_INT nbytes)
2544 return empty_multibyte_string; 2545 return empty_multibyte_string;
2545 2546
2546 s = allocate_string (); 2547 s = allocate_string ();
2547 s->intervals = NULL; 2548 s->u.s.intervals = NULL;
2548 allocate_string_data (s, nchars, nbytes); 2549 allocate_string_data (s, nchars, nbytes);
2549 XSETSTRING (string, s); 2550 XSETSTRING (string, s);
2550 string_chars_consed += nbytes; 2551 string_chars_consed += nbytes;
@@ -2729,8 +2730,8 @@ static struct Lisp_Cons *cons_free_list;
2729void 2730void
2730free_cons (struct Lisp_Cons *ptr) 2731free_cons (struct Lisp_Cons *ptr)
2731{ 2732{
2732 ptr->u.chain = cons_free_list; 2733 ptr->u.s.u.chain = cons_free_list;
2733 ptr->car = Vdead; 2734 ptr->u.s.car = Vdead;
2734 cons_free_list = ptr; 2735 cons_free_list = ptr;
2735 consing_since_gc -= sizeof *ptr; 2736 consing_since_gc -= sizeof *ptr;
2736 total_free_conses++; 2737 total_free_conses++;
@@ -2749,7 +2750,7 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0,
2749 /* We use the cdr for chaining the free list 2750 /* We use the cdr for chaining the free list
2750 so that we won't use the same field that has the mark bit. */ 2751 so that we won't use the same field that has the mark bit. */
2751 XSETCONS (val, cons_free_list); 2752 XSETCONS (val, cons_free_list);
2752 cons_free_list = cons_free_list->u.chain; 2753 cons_free_list = cons_free_list->u.s.u.chain;
2753 } 2754 }
2754 else 2755 else
2755 { 2756 {
@@ -2786,7 +2787,7 @@ check_cons_list (void)
2786 struct Lisp_Cons *tail = cons_free_list; 2787 struct Lisp_Cons *tail = cons_free_list;
2787 2788
2788 while (tail) 2789 while (tail)
2789 tail = tail->u.chain; 2790 tail = tail->u.s.u.chain;
2790} 2791}
2791#endif 2792#endif
2792 2793
@@ -3543,27 +3544,17 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT
3543 Symbol Allocation 3544 Symbol Allocation
3544 ***********************************************************************/ 3545 ***********************************************************************/
3545 3546
3546/* Like struct Lisp_Symbol, but padded so that the size is a multiple
3547 of the required alignment. */
3548
3549union aligned_Lisp_Symbol
3550{
3551 struct Lisp_Symbol s;
3552 unsigned char c[(sizeof (struct Lisp_Symbol) + GCALIGNMENT - 1)
3553 & -GCALIGNMENT];
3554};
3555
3556/* Each symbol_block is just under 1020 bytes long, since malloc 3547/* Each symbol_block is just under 1020 bytes long, since malloc
3557 really allocates in units of powers of two and uses 4 bytes for its 3548 really allocates in units of powers of two and uses 4 bytes for its
3558 own overhead. */ 3549 own overhead. */
3559 3550
3560#define SYMBOL_BLOCK_SIZE \ 3551#define SYMBOL_BLOCK_SIZE \
3561 ((1020 - sizeof (struct symbol_block *)) / sizeof (union aligned_Lisp_Symbol)) 3552 ((1020 - sizeof (struct symbol_block *)) / sizeof (struct Lisp_Symbol))
3562 3553
3563struct symbol_block 3554struct symbol_block
3564{ 3555{
3565 /* Place `symbols' first, to preserve alignment. */ 3556 /* Place `symbols' first, to preserve alignment. */
3566 union aligned_Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE]; 3557 struct Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE];
3567 struct symbol_block *next; 3558 struct symbol_block *next;
3568}; 3559};
3569 3560
@@ -3587,7 +3578,7 @@ static struct Lisp_Symbol *symbol_free_list;
3587static void 3578static void
3588set_symbol_name (Lisp_Object sym, Lisp_Object name) 3579set_symbol_name (Lisp_Object sym, Lisp_Object name)
3589{ 3580{
3590 XSYMBOL (sym)->name = name; 3581 XSYMBOL (sym)->u.s.name = name;
3591} 3582}
3592 3583
3593void 3584void
@@ -3596,15 +3587,15 @@ init_symbol (Lisp_Object val, Lisp_Object name)
3596 struct Lisp_Symbol *p = XSYMBOL (val); 3587 struct Lisp_Symbol *p = XSYMBOL (val);
3597 set_symbol_name (val, name); 3588 set_symbol_name (val, name);
3598 set_symbol_plist (val, Qnil); 3589 set_symbol_plist (val, Qnil);
3599 p->redirect = SYMBOL_PLAINVAL; 3590 p->u.s.redirect = SYMBOL_PLAINVAL;
3600 SET_SYMBOL_VAL (p, Qunbound); 3591 SET_SYMBOL_VAL (p, Qunbound);
3601 set_symbol_function (val, Qnil); 3592 set_symbol_function (val, Qnil);
3602 set_symbol_next (val, NULL); 3593 set_symbol_next (val, NULL);
3603 p->gcmarkbit = false; 3594 p->u.s.gcmarkbit = false;
3604 p->interned = SYMBOL_UNINTERNED; 3595 p->u.s.interned = SYMBOL_UNINTERNED;
3605 p->trapped_write = SYMBOL_UNTRAPPED_WRITE; 3596 p->u.s.trapped_write = SYMBOL_UNTRAPPED_WRITE;
3606 p->declared_special = false; 3597 p->u.s.declared_special = false;
3607 p->pinned = false; 3598 p->u.s.pinned = false;
3608} 3599}
3609 3600
3610DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0, 3601DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0,
@@ -3621,7 +3612,7 @@ Its value is void, and its function definition and property list are nil. */)
3621 if (symbol_free_list) 3612 if (symbol_free_list)
3622 { 3613 {
3623 XSETSYMBOL (val, symbol_free_list); 3614 XSETSYMBOL (val, symbol_free_list);
3624 symbol_free_list = symbol_free_list->next; 3615 symbol_free_list = symbol_free_list->u.s.next;
3625 } 3616 }
3626 else 3617 else
3627 { 3618 {
@@ -3634,7 +3625,7 @@ Its value is void, and its function definition and property list are nil. */)
3634 symbol_block_index = 0; 3625 symbol_block_index = 0;
3635 total_free_symbols += SYMBOL_BLOCK_SIZE; 3626 total_free_symbols += SYMBOL_BLOCK_SIZE;
3636 } 3627 }
3637 XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index].s); 3628 XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index]);
3638 symbol_block_index++; 3629 symbol_block_index++;
3639 } 3630 }
3640 3631
@@ -4587,7 +4578,7 @@ live_string_holding (struct mem_node *m, void *p)
4587 if (0 <= offset && offset < STRING_BLOCK_SIZE * sizeof b->strings[0]) 4578 if (0 <= offset && offset < STRING_BLOCK_SIZE * sizeof b->strings[0])
4588 { 4579 {
4589 struct Lisp_String *s = p = cp -= offset % sizeof b->strings[0]; 4580 struct Lisp_String *s = p = cp -= offset % sizeof b->strings[0];
4590 if (s->data) 4581 if (s->u.s.data)
4591 return make_lisp_ptr (s, Lisp_String); 4582 return make_lisp_ptr (s, Lisp_String);
4592 } 4583 }
4593 } 4584 }
@@ -4621,7 +4612,7 @@ live_cons_holding (struct mem_node *m, void *p)
4621 || offset / sizeof b->conses[0] < cons_block_index)) 4612 || offset / sizeof b->conses[0] < cons_block_index))
4622 { 4613 {
4623 struct Lisp_Cons *s = p = cp -= offset % sizeof b->conses[0]; 4614 struct Lisp_Cons *s = p = cp -= offset % sizeof b->conses[0];
4624 if (!EQ (s->car, Vdead)) 4615 if (!EQ (s->u.s.car, Vdead))
4625 return make_lisp_ptr (s, Lisp_Cons); 4616 return make_lisp_ptr (s, Lisp_Cons);
4626 } 4617 }
4627 } 4618 }
@@ -4656,7 +4647,7 @@ live_symbol_holding (struct mem_node *m, void *p)
4656 || offset / sizeof b->symbols[0] < symbol_block_index)) 4647 || offset / sizeof b->symbols[0] < symbol_block_index))
4657 { 4648 {
4658 struct Lisp_Symbol *s = p = cp -= offset % sizeof b->symbols[0]; 4649 struct Lisp_Symbol *s = p = cp -= offset % sizeof b->symbols[0];
4659 if (!EQ (s->function, Vdead)) 4650 if (!EQ (s->u.s.function, Vdead))
4660 return make_lisp_symbol (s); 4651 return make_lisp_symbol (s);
4661 } 4652 }
4662 } 4653 }
@@ -4984,7 +4975,7 @@ mark_memory (void *start, void *end)
4984 Lisp_Object obj = build_string ("test"); 4975 Lisp_Object obj = build_string ("test");
4985 struct Lisp_String *s = XSTRING (obj); 4976 struct Lisp_String *s = XSTRING (obj);
4986 Fgarbage_collect (); 4977 Fgarbage_collect ();
4987 fprintf (stderr, "test '%s'\n", s->data); 4978 fprintf (stderr, "test '%s'\n", s->u.s.data);
4988 return Qnil; 4979 return Qnil;
4989 } 4980 }
4990 4981
@@ -5484,16 +5475,16 @@ make_pure_string (const char *data,
5484{ 5475{
5485 Lisp_Object string; 5476 Lisp_Object string;
5486 struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String); 5477 struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String);
5487 s->data = (unsigned char *) find_string_data_in_pure (data, nbytes); 5478 s->u.s.data = (unsigned char *) find_string_data_in_pure (data, nbytes);
5488 if (s->data == NULL) 5479 if (s->u.s.data == NULL)
5489 { 5480 {
5490 s->data = pure_alloc (nbytes + 1, -1); 5481 s->u.s.data = pure_alloc (nbytes + 1, -1);
5491 memcpy (s->data, data, nbytes); 5482 memcpy (s->u.s.data, data, nbytes);
5492 s->data[nbytes] = '\0'; 5483 s->u.s.data[nbytes] = '\0';
5493 } 5484 }
5494 s->size = nchars; 5485 s->u.s.size = nchars;
5495 s->size_byte = multibyte ? nbytes : -1; 5486 s->u.s.size_byte = multibyte ? nbytes : -1;
5496 s->intervals = NULL; 5487 s->u.s.intervals = NULL;
5497 XSETSTRING (string, s); 5488 XSETSTRING (string, s);
5498 return string; 5489 return string;
5499} 5490}
@@ -5506,10 +5497,10 @@ make_pure_c_string (const char *data, ptrdiff_t nchars)
5506{ 5497{
5507 Lisp_Object string; 5498 Lisp_Object string;
5508 struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String); 5499 struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String);
5509 s->size = nchars; 5500 s->u.s.size = nchars;
5510 s->size_byte = -1; 5501 s->u.s.size_byte = -1;
5511 s->data = (unsigned char *) data; 5502 s->u.s.data = (unsigned char *) data;
5512 s->intervals = NULL; 5503 s->u.s.intervals = NULL;
5513 XSETSTRING (string, s); 5504 XSETSTRING (string, s);
5514 return string; 5505 return string;
5515} 5506}
@@ -5620,7 +5611,7 @@ purecopy (Lisp_Object obj)
5620 || SUBRP (obj)) 5611 || SUBRP (obj))
5621 return obj; /* Already pure. */ 5612 return obj; /* Already pure. */
5622 5613
5623 if (STRINGP (obj) && XSTRING (obj)->intervals) 5614 if (STRINGP (obj) && XSTRING (obj)->u.s.intervals)
5624 message_with_string ("Dropping text-properties while making string `%s' pure", 5615 message_with_string ("Dropping text-properties while making string `%s' pure",
5625 obj, true); 5616 obj, true);
5626 5617
@@ -5675,10 +5666,10 @@ purecopy (Lisp_Object obj)
5675 } 5666 }
5676 else if (SYMBOLP (obj)) 5667 else if (SYMBOLP (obj))
5677 { 5668 {
5678 if (!XSYMBOL (obj)->pinned && !c_symbol_p (XSYMBOL (obj))) 5669 if (!XSYMBOL (obj)->u.s.pinned && !c_symbol_p (XSYMBOL (obj)))
5679 { /* We can't purify them, but they appear in many pure objects. 5670 { /* We can't purify them, but they appear in many pure objects.
5680 Mark them as `pinned' so we know to mark them at every GC cycle. */ 5671 Mark them as `pinned' so we know to mark them at every GC cycle. */
5681 XSYMBOL (obj)->pinned = true; 5672 XSYMBOL (obj)->u.s.pinned = true;
5682 symbol_block_pinned = symbol_block; 5673 symbol_block_pinned = symbol_block;
5683 } 5674 }
5684 /* Don't hash-cons it. */ 5675 /* Don't hash-cons it. */
@@ -5891,10 +5882,10 @@ mark_pinned_symbols (void)
5891 5882
5892 for (sblk = symbol_block_pinned; sblk; sblk = sblk->next) 5883 for (sblk = symbol_block_pinned; sblk; sblk = sblk->next)
5893 { 5884 {
5894 union aligned_Lisp_Symbol *sym = sblk->symbols, *end = sym + lim; 5885 struct Lisp_Symbol *sym = sblk->symbols, *end = sym + lim;
5895 for (; sym < end; ++sym) 5886 for (; sym < end; ++sym)
5896 if (sym->s.pinned) 5887 if (sym->u.s.pinned)
5897 mark_object (make_lisp_symbol (&sym->s)); 5888 mark_object (make_lisp_symbol (sym));
5898 5889
5899 lim = SYMBOL_BLOCK_SIZE; 5890 lim = SYMBOL_BLOCK_SIZE;
5900 } 5891 }
@@ -6256,7 +6247,7 @@ mark_char_table (struct Lisp_Vector *ptr, enum pvec_type pvectype)
6256 { 6247 {
6257 Lisp_Object val = ptr->contents[i]; 6248 Lisp_Object val = ptr->contents[i];
6258 6249
6259 if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->gcmarkbit)) 6250 if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->u.s.gcmarkbit))
6260 continue; 6251 continue;
6261 if (SUB_CHAR_TABLE_P (val)) 6252 if (SUB_CHAR_TABLE_P (val))
6262 { 6253 {
@@ -6499,7 +6490,7 @@ mark_object (Lisp_Object arg)
6499 break; 6490 break;
6500 CHECK_ALLOCATED_AND_LIVE (live_string_p); 6491 CHECK_ALLOCATED_AND_LIVE (live_string_p);
6501 MARK_STRING (ptr); 6492 MARK_STRING (ptr);
6502 MARK_INTERVAL_TREE (ptr->intervals); 6493 MARK_INTERVAL_TREE (ptr->u.s.intervals);
6503#ifdef GC_CHECK_STRING_BYTES 6494#ifdef GC_CHECK_STRING_BYTES
6504 /* Check that the string size recorded in the string is the 6495 /* Check that the string size recorded in the string is the
6505 same as the one recorded in the sdata structure. */ 6496 same as the one recorded in the sdata structure. */
@@ -6640,17 +6631,17 @@ mark_object (Lisp_Object arg)
6640 6631
6641 case Lisp_Symbol: 6632 case Lisp_Symbol:
6642 { 6633 {
6643 register struct Lisp_Symbol *ptr = XSYMBOL (obj); 6634 struct Lisp_Symbol *ptr = XSYMBOL (obj);
6644 nextsym: 6635 nextsym:
6645 if (ptr->gcmarkbit) 6636 if (ptr->u.s.gcmarkbit)
6646 break; 6637 break;
6647 CHECK_ALLOCATED_AND_LIVE_SYMBOL (); 6638 CHECK_ALLOCATED_AND_LIVE_SYMBOL ();
6648 ptr->gcmarkbit = 1; 6639 ptr->u.s.gcmarkbit = 1;
6649 /* Attempt to catch bogus objects. */ 6640 /* Attempt to catch bogus objects. */
6650 eassert (valid_lisp_object_p (ptr->function)); 6641 eassert (valid_lisp_object_p (ptr->u.s.function));
6651 mark_object (ptr->function); 6642 mark_object (ptr->u.s.function);
6652 mark_object (ptr->plist); 6643 mark_object (ptr->u.s.plist);
6653 switch (ptr->redirect) 6644 switch (ptr->u.s.redirect)
6654 { 6645 {
6655 case SYMBOL_PLAINVAL: mark_object (SYMBOL_VAL (ptr)); break; 6646 case SYMBOL_PLAINVAL: mark_object (SYMBOL_VAL (ptr)); break;
6656 case SYMBOL_VARALIAS: 6647 case SYMBOL_VARALIAS:
@@ -6671,11 +6662,11 @@ mark_object (Lisp_Object arg)
6671 break; 6662 break;
6672 default: emacs_abort (); 6663 default: emacs_abort ();
6673 } 6664 }
6674 if (!PURE_P (XSTRING (ptr->name))) 6665 if (!PURE_P (XSTRING (ptr->u.s.name)))
6675 MARK_STRING (XSTRING (ptr->name)); 6666 MARK_STRING (XSTRING (ptr->u.s.name));
6676 MARK_INTERVAL_TREE (string_intervals (ptr->name)); 6667 MARK_INTERVAL_TREE (string_intervals (ptr->u.s.name));
6677 /* Inner loop to mark next symbol in this bucket, if any. */ 6668 /* Inner loop to mark next symbol in this bucket, if any. */
6678 po = ptr = ptr->next; 6669 po = ptr = ptr->u.s.next;
6679 if (ptr) 6670 if (ptr)
6680 goto nextsym; 6671 goto nextsym;
6681 } 6672 }
@@ -6729,14 +6720,14 @@ mark_object (Lisp_Object arg)
6729 CHECK_ALLOCATED_AND_LIVE (live_cons_p); 6720 CHECK_ALLOCATED_AND_LIVE (live_cons_p);
6730 CONS_MARK (ptr); 6721 CONS_MARK (ptr);
6731 /* If the cdr is nil, avoid recursion for the car. */ 6722 /* If the cdr is nil, avoid recursion for the car. */
6732 if (EQ (ptr->u.cdr, Qnil)) 6723 if (EQ (ptr->u.s.u.cdr, Qnil))
6733 { 6724 {
6734 obj = ptr->car; 6725 obj = ptr->u.s.car;
6735 cdr_count = 0; 6726 cdr_count = 0;
6736 goto loop; 6727 goto loop;
6737 } 6728 }
6738 mark_object (ptr->car); 6729 mark_object (ptr->u.s.car);
6739 obj = ptr->u.cdr; 6730 obj = ptr->u.s.u.cdr;
6740 cdr_count++; 6731 cdr_count++;
6741 if (cdr_count == mark_object_loop_halt) 6732 if (cdr_count == mark_object_loop_halt)
6742 emacs_abort (); 6733 emacs_abort ();
@@ -6797,7 +6788,7 @@ survives_gc_p (Lisp_Object obj)
6797 break; 6788 break;
6798 6789
6799 case Lisp_Symbol: 6790 case Lisp_Symbol:
6800 survives_p = XSYMBOL (obj)->gcmarkbit; 6791 survives_p = XSYMBOL (obj)->u.s.gcmarkbit;
6801 break; 6792 break;
6802 6793
6803 case Lisp_Misc: 6794 case Lisp_Misc:
@@ -6873,9 +6864,9 @@ sweep_conses (void)
6873 if (!CONS_MARKED_P (&cblk->conses[pos])) 6864 if (!CONS_MARKED_P (&cblk->conses[pos]))
6874 { 6865 {
6875 this_free++; 6866 this_free++;
6876 cblk->conses[pos].u.chain = cons_free_list; 6867 cblk->conses[pos].u.s.u.chain = cons_free_list;
6877 cons_free_list = &cblk->conses[pos]; 6868 cons_free_list = &cblk->conses[pos];
6878 cons_free_list->car = Vdead; 6869 cons_free_list->u.s.car = Vdead;
6879 } 6870 }
6880 else 6871 else
6881 { 6872 {
@@ -6894,7 +6885,7 @@ sweep_conses (void)
6894 { 6885 {
6895 *cprev = cblk->next; 6886 *cprev = cblk->next;
6896 /* Unhook from the free list. */ 6887 /* Unhook from the free list. */
6897 cons_free_list = cblk->conses[0].u.chain; 6888 cons_free_list = cblk->conses[0].u.s.u.chain;
6898 lisp_align_free (cblk); 6889 lisp_align_free (cblk);
6899 } 6890 }
6900 else 6891 else
@@ -7018,39 +7009,39 @@ sweep_symbols (void)
7018 symbol_free_list = NULL; 7009 symbol_free_list = NULL;
7019 7010
7020 for (int i = 0; i < ARRAYELTS (lispsym); i++) 7011 for (int i = 0; i < ARRAYELTS (lispsym); i++)
7021 lispsym[i].s.gcmarkbit = 0; 7012 lispsym[i].u.s.gcmarkbit = 0;
7022 7013
7023 for (sblk = symbol_block; sblk; sblk = *sprev) 7014 for (sblk = symbol_block; sblk; sblk = *sprev)
7024 { 7015 {
7025 int this_free = 0; 7016 int this_free = 0;
7026 union aligned_Lisp_Symbol *sym = sblk->symbols; 7017 struct Lisp_Symbol *sym = sblk->symbols;
7027 union aligned_Lisp_Symbol *end = sym + lim; 7018 struct Lisp_Symbol *end = sym + lim;
7028 7019
7029 for (; sym < end; ++sym) 7020 for (; sym < end; ++sym)
7030 { 7021 {
7031 if (!sym->s.gcmarkbit) 7022 if (!sym->u.s.gcmarkbit)
7032 { 7023 {
7033 if (sym->s.redirect == SYMBOL_LOCALIZED) 7024 if (sym->u.s.redirect == SYMBOL_LOCALIZED)
7034 { 7025 {
7035 xfree (SYMBOL_BLV (&sym->s)); 7026 xfree (SYMBOL_BLV (sym));
7036 /* At every GC we sweep all symbol_blocks and rebuild the 7027 /* At every GC we sweep all symbol_blocks and rebuild the
7037 symbol_free_list, so those symbols which stayed unused 7028 symbol_free_list, so those symbols which stayed unused
7038 between the two will be re-swept. 7029 between the two will be re-swept.
7039 So we have to make sure we don't re-free this blv next 7030 So we have to make sure we don't re-free this blv next
7040 time we sweep this symbol_block (bug#29066). */ 7031 time we sweep this symbol_block (bug#29066). */
7041 sym->s.redirect = SYMBOL_PLAINVAL; 7032 sym->u.s.redirect = SYMBOL_PLAINVAL;
7042 } 7033 }
7043 sym->s.next = symbol_free_list; 7034 sym->u.s.next = symbol_free_list;
7044 symbol_free_list = &sym->s; 7035 symbol_free_list = sym;
7045 symbol_free_list->function = Vdead; 7036 symbol_free_list->u.s.function = Vdead;
7046 ++this_free; 7037 ++this_free;
7047 } 7038 }
7048 else 7039 else
7049 { 7040 {
7050 ++num_used; 7041 ++num_used;
7051 sym->s.gcmarkbit = 0; 7042 sym->u.s.gcmarkbit = 0;
7052 /* Attempt to catch bogus objects. */ 7043 /* Attempt to catch bogus objects. */
7053 eassert (valid_lisp_object_p (sym->s.function)); 7044 eassert (valid_lisp_object_p (sym->u.s.function));
7054 } 7045 }
7055 } 7046 }
7056 7047
@@ -7062,7 +7053,7 @@ sweep_symbols (void)
7062 { 7053 {
7063 *sprev = sblk->next; 7054 *sprev = sblk->next;
7064 /* Unhook from the free list. */ 7055 /* Unhook from the free list. */
7065 symbol_free_list = sblk->symbols[0].s.next; 7056 symbol_free_list = sblk->symbols[0].u.s.next;
7066 lisp_free (sblk); 7057 lisp_free (sblk);
7067 } 7058 }
7068 else 7059 else
@@ -7289,10 +7280,10 @@ symbol_uses_obj (Lisp_Object symbol, Lisp_Object obj)
7289 struct Lisp_Symbol *sym = XSYMBOL (symbol); 7280 struct Lisp_Symbol *sym = XSYMBOL (symbol);
7290 Lisp_Object val = find_symbol_value (symbol); 7281 Lisp_Object val = find_symbol_value (symbol);
7291 return (EQ (val, obj) 7282 return (EQ (val, obj)
7292 || EQ (sym->function, obj) 7283 || EQ (sym->u.s.function, obj)
7293 || (!NILP (sym->function) 7284 || (!NILP (sym->u.s.function)
7294 && COMPILEDP (sym->function) 7285 && COMPILEDP (sym->u.s.function)
7295 && EQ (AREF (sym->function, COMPILED_BYTECODE), obj)) 7286 && EQ (AREF (sym->u.s.function, COMPILED_BYTECODE), obj))
7296 || (!NILP (val) 7287 || (!NILP (val)
7297 && COMPILEDP (val) 7288 && COMPILEDP (val)
7298 && EQ (AREF (val, COMPILED_BYTECODE), obj))); 7289 && EQ (AREF (val, COMPILED_BYTECODE), obj)));
@@ -7323,15 +7314,15 @@ which_symbols (Lisp_Object obj, EMACS_INT find_max)
7323 7314
7324 for (sblk = symbol_block; sblk; sblk = sblk->next) 7315 for (sblk = symbol_block; sblk; sblk = sblk->next)
7325 { 7316 {
7326 union aligned_Lisp_Symbol *aligned_sym = sblk->symbols; 7317 struct Lisp_Symbol *asym = sblk->symbols;
7327 int bn; 7318 int bn;
7328 7319
7329 for (bn = 0; bn < SYMBOL_BLOCK_SIZE; bn++, aligned_sym++) 7320 for (bn = 0; bn < SYMBOL_BLOCK_SIZE; bn++, asym++)
7330 { 7321 {
7331 if (sblk == symbol_block && bn >= symbol_block_index) 7322 if (sblk == symbol_block && bn >= symbol_block_index)
7332 break; 7323 break;
7333 7324
7334 Lisp_Object sym = make_lisp_symbol (&aligned_sym->s); 7325 Lisp_Object sym = make_lisp_symbol (asym);
7335 if (symbol_uses_obj (sym, obj)) 7326 if (symbol_uses_obj (sym, obj))
7336 { 7327 {
7337 found = Fcons (sym, found); 7328 found = Fcons (sym, found);
diff --git a/src/buffer.c b/src/buffer.c
index edeed55e8be..4ae5e811b07 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -61,7 +61,7 @@ struct buffer *all_buffers;
61 Setting the default value also goes through the alist of buffers 61 Setting the default value also goes through the alist of buffers
62 and stores into each buffer that does not say it has a local value. */ 62 and stores into each buffer that does not say it has a local value. */
63 63
64struct GCALIGNED buffer buffer_defaults; 64struct buffer buffer_defaults;
65 65
66/* This structure marks which slots in a buffer have corresponding 66/* This structure marks which slots in a buffer have corresponding
67 default values in buffer_defaults. 67 default values in buffer_defaults.
@@ -84,7 +84,7 @@ struct buffer buffer_local_flags;
84/* This structure holds the names of symbols whose values may be 84/* This structure holds the names of symbols whose values may be
85 buffer-local. It is indexed and accessed in the same way as the above. */ 85 buffer-local. It is indexed and accessed in the same way as the above. */
86 86
87struct GCALIGNED buffer buffer_local_symbols; 87struct buffer buffer_local_symbols;
88 88
89/* Return the symbol of the per-buffer variable at offset OFFSET in 89/* Return the symbol of the per-buffer variable at offset OFFSET in
90 the buffer structure. */ 90 the buffer structure. */
@@ -1021,7 +1021,8 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too)
1021 newlist = Fcons (elt, newlist); 1021 newlist = Fcons (elt, newlist);
1022 } 1022 }
1023 newlist = Fnreverse (newlist); 1023 newlist = Fnreverse (newlist);
1024 if (XSYMBOL (local_var)->trapped_write == SYMBOL_TRAPPED_WRITE) 1024 if (XSYMBOL (local_var)->u.s.trapped_write
1025 == SYMBOL_TRAPPED_WRITE)
1025 notify_variable_watchers (local_var, newlist, 1026 notify_variable_watchers (local_var, newlist,
1026 Qmakunbound, Fcurrent_buffer ()); 1027 Qmakunbound, Fcurrent_buffer ());
1027 XSETCDR (XCAR (tmp), newlist); 1028 XSETCDR (XCAR (tmp), newlist);
@@ -1034,7 +1035,7 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too)
1034 else 1035 else
1035 XSETCDR (last, XCDR (tmp)); 1036 XSETCDR (last, XCDR (tmp));
1036 1037
1037 if (XSYMBOL (local_var)->trapped_write == SYMBOL_TRAPPED_WRITE) 1038 if (XSYMBOL (local_var)->u.s.trapped_write == SYMBOL_TRAPPED_WRITE)
1038 notify_variable_watchers (local_var, Qnil, 1039 notify_variable_watchers (local_var, Qnil,
1039 Qmakunbound, Fcurrent_buffer ()); 1040 Qmakunbound, Fcurrent_buffer ());
1040 } 1041 }
@@ -1166,7 +1167,7 @@ buffer_local_value (Lisp_Object variable, Lisp_Object buffer)
1166 sym = XSYMBOL (variable); 1167 sym = XSYMBOL (variable);
1167 1168
1168 start: 1169 start:
1169 switch (sym->redirect) 1170 switch (sym->u.s.redirect)
1170 { 1171 {
1171 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 1172 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1172 case SYMBOL_PLAINVAL: result = SYMBOL_VAL (sym); break; 1173 case SYMBOL_PLAINVAL: result = SYMBOL_VAL (sym); break;
@@ -2096,7 +2097,7 @@ void set_buffer_internal_2 (register struct buffer *b)
2096 { 2097 {
2097 Lisp_Object var = XCAR (XCAR (tail)); 2098 Lisp_Object var = XCAR (XCAR (tail));
2098 struct Lisp_Symbol *sym = XSYMBOL (var); 2099 struct Lisp_Symbol *sym = XSYMBOL (var);
2099 if (sym->redirect == SYMBOL_LOCALIZED /* Just to be sure. */ 2100 if (sym->u.s.redirect == SYMBOL_LOCALIZED /* Just to be sure. */
2100 && SYMBOL_BLV (sym)->fwd) 2101 && SYMBOL_BLV (sym)->fwd)
2101 /* Just reference the variable 2102 /* Just reference the variable
2102 to cause it to become set for this buffer. */ 2103 to cause it to become set for this buffer. */
@@ -2752,7 +2753,7 @@ swap_out_buffer_local_variables (struct buffer *b)
2752 for (alist = oalist; CONSP (alist); alist = XCDR (alist)) 2753 for (alist = oalist; CONSP (alist); alist = XCDR (alist))
2753 { 2754 {
2754 Lisp_Object sym = XCAR (XCAR (alist)); 2755 Lisp_Object sym = XCAR (XCAR (alist));
2755 eassert (XSYMBOL (sym)->redirect == SYMBOL_LOCALIZED); 2756 eassert (XSYMBOL (sym)->u.s.redirect == SYMBOL_LOCALIZED);
2756 /* Need not do anything if some other buffer's binding is 2757 /* Need not do anything if some other buffer's binding is
2757 now cached. */ 2758 now cached. */
2758 if (EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer)) 2759 if (EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer))
@@ -5423,8 +5424,8 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring,
5423 bo_fwd->type = Lisp_Fwd_Buffer_Obj; 5424 bo_fwd->type = Lisp_Fwd_Buffer_Obj;
5424 bo_fwd->offset = offset; 5425 bo_fwd->offset = offset;
5425 bo_fwd->predicate = predicate; 5426 bo_fwd->predicate = predicate;
5426 sym->declared_special = 1; 5427 sym->u.s.declared_special = true;
5427 sym->redirect = SYMBOL_FORWARDED; 5428 sym->u.s.redirect = SYMBOL_FORWARDED;
5428 SET_SYMBOL_FWD (sym, (union Lisp_Fwd *) bo_fwd); 5429 SET_SYMBOL_FWD (sym, (union Lisp_Fwd *) bo_fwd);
5429 XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym); 5430 XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym);
5430 5431
diff --git a/src/bytecode.c b/src/bytecode.c
index 50c7abe2891..ebaf3c3a7fc 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -489,7 +489,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
489 { 489 {
490 Lisp_Object v1 = vectorp[op], v2; 490 Lisp_Object v1 = vectorp[op], v2;
491 if (!SYMBOLP (v1) 491 if (!SYMBOLP (v1)
492 || XSYMBOL (v1)->redirect != SYMBOL_PLAINVAL 492 || XSYMBOL (v1)->u.s.redirect != SYMBOL_PLAINVAL
493 || (v2 = SYMBOL_VAL (XSYMBOL (v1)), EQ (v2, Qunbound))) 493 || (v2 = SYMBOL_VAL (XSYMBOL (v1)), EQ (v2, Qunbound)))
494 v2 = Fsymbol_value (v1); 494 v2 = Fsymbol_value (v1);
495 PUSH (v2); 495 PUSH (v2);
@@ -558,7 +558,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
558 /* Inline the most common case. */ 558 /* Inline the most common case. */
559 if (SYMBOLP (sym) 559 if (SYMBOLP (sym)
560 && !EQ (val, Qunbound) 560 && !EQ (val, Qunbound)
561 && !XSYMBOL (sym)->redirect 561 && !XSYMBOL (sym)->u.s.redirect
562 && !SYMBOL_TRAPPED_WRITE_P (sym)) 562 && !SYMBOL_TRAPPED_WRITE_P (sym))
563 SET_SYMBOL_VAL (XSYMBOL (sym), val); 563 SET_SYMBOL_VAL (XSYMBOL (sym), val);
564 else 564 else
diff --git a/src/casefiddle.c b/src/casefiddle.c
index 8f564edeb95..7b34f78a5c9 100644
--- a/src/casefiddle.c
+++ b/src/casefiddle.c
@@ -133,9 +133,9 @@ case_character_impl (struct casing_str_buf *buf,
133 struct Lisp_String *str = XSTRING (prop); 133 struct Lisp_String *str = XSTRING (prop);
134 if (STRING_BYTES (str) <= sizeof buf->data) 134 if (STRING_BYTES (str) <= sizeof buf->data)
135 { 135 {
136 buf->len_chars = str->size; 136 buf->len_chars = str->u.s.size;
137 buf->len_bytes = STRING_BYTES (str); 137 buf->len_bytes = STRING_BYTES (str);
138 memcpy (buf->data, str->data, buf->len_bytes); 138 memcpy (buf->data, str->u.s.data, buf->len_bytes);
139 return 1; 139 return 1;
140 } 140 }
141 } 141 }
diff --git a/src/cmds.c b/src/cmds.c
index e4c0c866916..1788f22fe57 100644
--- a/src/cmds.c
+++ b/src/cmds.c
@@ -421,11 +421,11 @@ internal_self_insert (int c, EMACS_INT n)
421 and the hook has a non-nil `no-self-insert' property, 421 and the hook has a non-nil `no-self-insert' property,
422 return right away--don't really self-insert. */ 422 return right away--don't really self-insert. */
423 if (SYMBOLP (sym) && ! NILP (sym) 423 if (SYMBOLP (sym) && ! NILP (sym)
424 && ! NILP (XSYMBOL (sym)->function) 424 && ! NILP (XSYMBOL (sym)->u.s.function)
425 && SYMBOLP (XSYMBOL (sym)->function)) 425 && SYMBOLP (XSYMBOL (sym)->u.s.function))
426 { 426 {
427 Lisp_Object prop; 427 Lisp_Object prop;
428 prop = Fget (XSYMBOL (sym)->function, intern ("no-self-insert")); 428 prop = Fget (XSYMBOL (sym)->u.s.function, intern ("no-self-insert"));
429 if (! NILP (prop)) 429 if (! NILP (prop))
430 return 1; 430 return 1;
431 } 431 }
diff --git a/src/data.c b/src/data.c
index ef7210fbfa0..b4f6fd5c652 100644
--- a/src/data.c
+++ b/src/data.c
@@ -670,7 +670,7 @@ global value outside of any lexical scope. */)
670 sym = XSYMBOL (symbol); 670 sym = XSYMBOL (symbol);
671 671
672 start: 672 start:
673 switch (sym->redirect) 673 switch (sym->u.s.redirect)
674 { 674 {
675 case SYMBOL_PLAINVAL: valcontents = SYMBOL_VAL (sym); break; 675 case SYMBOL_PLAINVAL: valcontents = SYMBOL_VAL (sym); break;
676 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 676 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
@@ -704,10 +704,10 @@ global value outside of any lexical scope. */)
704 expect `t' in particular, rather than any true value. */ 704 expect `t' in particular, rather than any true value. */
705DEFUN ("fboundp", Ffboundp, Sfboundp, 1, 1, 0, 705DEFUN ("fboundp", Ffboundp, Sfboundp, 1, 1, 0,
706 doc: /* Return t if SYMBOL's function definition is not void. */) 706 doc: /* Return t if SYMBOL's function definition is not void. */)
707 (register Lisp_Object symbol) 707 (Lisp_Object symbol)
708{ 708{
709 CHECK_SYMBOL (symbol); 709 CHECK_SYMBOL (symbol);
710 return NILP (XSYMBOL (symbol)->function) ? Qnil : Qt; 710 return NILP (XSYMBOL (symbol)->u.s.function) ? Qnil : Qt;
711} 711}
712 712
713DEFUN ("makunbound", Fmakunbound, Smakunbound, 1, 1, 0, 713DEFUN ("makunbound", Fmakunbound, Smakunbound, 1, 1, 0,
@@ -736,18 +736,18 @@ Return SYMBOL. */)
736 736
737DEFUN ("symbol-function", Fsymbol_function, Ssymbol_function, 1, 1, 0, 737DEFUN ("symbol-function", Fsymbol_function, Ssymbol_function, 1, 1, 0,
738 doc: /* Return SYMBOL's function definition, or nil if that is void. */) 738 doc: /* Return SYMBOL's function definition, or nil if that is void. */)
739 (register Lisp_Object symbol) 739 (Lisp_Object symbol)
740{ 740{
741 CHECK_SYMBOL (symbol); 741 CHECK_SYMBOL (symbol);
742 return XSYMBOL (symbol)->function; 742 return XSYMBOL (symbol)->u.s.function;
743} 743}
744 744
745DEFUN ("symbol-plist", Fsymbol_plist, Ssymbol_plist, 1, 1, 0, 745DEFUN ("symbol-plist", Fsymbol_plist, Ssymbol_plist, 1, 1, 0,
746 doc: /* Return SYMBOL's property list. */) 746 doc: /* Return SYMBOL's property list. */)
747 (register Lisp_Object symbol) 747 (Lisp_Object symbol)
748{ 748{
749 CHECK_SYMBOL (symbol); 749 CHECK_SYMBOL (symbol);
750 return XSYMBOL (symbol)->plist; 750 return XSYMBOL (symbol)->u.s.plist;
751} 751}
752 752
753DEFUN ("symbol-name", Fsymbol_name, Ssymbol_name, 1, 1, 0, 753DEFUN ("symbol-name", Fsymbol_name, Ssymbol_name, 1, 1, 0,
@@ -771,7 +771,7 @@ DEFUN ("fset", Ffset, Sfset, 2, 2, 0,
771 if (NILP (symbol)) 771 if (NILP (symbol))
772 xsignal1 (Qsetting_constant, symbol); 772 xsignal1 (Qsetting_constant, symbol);
773 773
774 function = XSYMBOL (symbol)->function; 774 function = XSYMBOL (symbol)->u.s.function;
775 775
776 if (!NILP (Vautoload_queue) && !NILP (function)) 776 if (!NILP (Vautoload_queue) && !NILP (function))
777 Vautoload_queue = Fcons (Fcons (symbol, function), Vautoload_queue); 777 Vautoload_queue = Fcons (Fcons (symbol, function), Vautoload_queue);
@@ -814,7 +814,7 @@ The return value is undefined. */)
814 { /* Only add autoload entries after dumping, because the ones before are 814 { /* Only add autoload entries after dumping, because the ones before are
815 not useful and else we get loads of them from the loaddefs.el. */ 815 not useful and else we get loads of them from the loaddefs.el. */
816 816
817 if (AUTOLOADP (XSYMBOL (symbol)->function)) 817 if (AUTOLOADP (XSYMBOL (symbol)->u.s.function))
818 /* Remember that the function was already an autoload. */ 818 /* Remember that the function was already an autoload. */
819 LOADHIST_ATTACH (Fcons (Qt, symbol)); 819 LOADHIST_ATTACH (Fcons (Qt, symbol));
820 LOADHIST_ATTACH (Fcons (autoload ? Qautoload : Qdefun, symbol)); 820 LOADHIST_ATTACH (Fcons (autoload ? Qautoload : Qdefun, symbol));
@@ -940,10 +940,10 @@ indirect_variable (struct Lisp_Symbol *symbol)
940 940
941 hare = tortoise = symbol; 941 hare = tortoise = symbol;
942 942
943 while (hare->redirect == SYMBOL_VARALIAS) 943 while (hare->u.s.redirect == SYMBOL_VARALIAS)
944 { 944 {
945 hare = SYMBOL_ALIAS (hare); 945 hare = SYMBOL_ALIAS (hare);
946 if (hare->redirect != SYMBOL_VARALIAS) 946 if (hare->u.s.redirect != SYMBOL_VARALIAS)
947 break; 947 break;
948 948
949 hare = SYMBOL_ALIAS (hare); 949 hare = SYMBOL_ALIAS (hare);
@@ -1247,7 +1247,7 @@ find_symbol_value (Lisp_Object symbol)
1247 sym = XSYMBOL (symbol); 1247 sym = XSYMBOL (symbol);
1248 1248
1249 start: 1249 start:
1250 switch (sym->redirect) 1250 switch (sym->u.s.redirect)
1251 { 1251 {
1252 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 1252 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1253 case SYMBOL_PLAINVAL: return SYMBOL_VAL (sym); 1253 case SYMBOL_PLAINVAL: return SYMBOL_VAL (sym);
@@ -1310,7 +1310,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
1310 1310
1311 CHECK_SYMBOL (symbol); 1311 CHECK_SYMBOL (symbol);
1312 sym = XSYMBOL (symbol); 1312 sym = XSYMBOL (symbol);
1313 switch (sym->trapped_write) 1313 switch (sym->u.s.trapped_write)
1314 { 1314 {
1315 case SYMBOL_NOWRITE: 1315 case SYMBOL_NOWRITE:
1316 if (NILP (Fkeywordp (symbol)) 1316 if (NILP (Fkeywordp (symbol))
@@ -1336,7 +1336,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
1336 } 1336 }
1337 1337
1338 start: 1338 start:
1339 switch (sym->redirect) 1339 switch (sym->u.s.redirect)
1340 { 1340 {
1341 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 1341 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1342 case SYMBOL_PLAINVAL: SET_SYMBOL_VAL (sym , newval); return; 1342 case SYMBOL_PLAINVAL: SET_SYMBOL_VAL (sym , newval); return;
@@ -1436,7 +1436,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
1436 if (voide) 1436 if (voide)
1437 { /* If storing void (making the symbol void), forward only through 1437 { /* If storing void (making the symbol void), forward only through
1438 buffer-local indicator, not through Lisp_Objfwd, etc. */ 1438 buffer-local indicator, not through Lisp_Objfwd, etc. */
1439 sym->redirect = SYMBOL_PLAINVAL; 1439 sym->u.s.redirect = SYMBOL_PLAINVAL;
1440 SET_SYMBOL_VAL (sym, newval); 1440 SET_SYMBOL_VAL (sym, newval);
1441 } 1441 }
1442 else 1442 else
@@ -1452,9 +1452,9 @@ static void
1452set_symbol_trapped_write (Lisp_Object symbol, enum symbol_trapped_write trap) 1452set_symbol_trapped_write (Lisp_Object symbol, enum symbol_trapped_write trap)
1453{ 1453{
1454 struct Lisp_Symbol *sym = XSYMBOL (symbol); 1454 struct Lisp_Symbol *sym = XSYMBOL (symbol);
1455 if (sym->trapped_write == SYMBOL_NOWRITE) 1455 if (sym->u.s.trapped_write == SYMBOL_NOWRITE)
1456 xsignal1 (Qtrapping_constant, symbol); 1456 xsignal1 (Qtrapping_constant, symbol);
1457 sym->trapped_write = trap; 1457 sym->u.s.trapped_write = trap;
1458} 1458}
1459 1459
1460static void 1460static void
@@ -1469,7 +1469,7 @@ harmonize_variable_watchers (Lisp_Object alias, Lisp_Object base_variable)
1469 if (!EQ (base_variable, alias) 1469 if (!EQ (base_variable, alias)
1470 && EQ (base_variable, Findirect_variable (alias))) 1470 && EQ (base_variable, Findirect_variable (alias)))
1471 set_symbol_trapped_write 1471 set_symbol_trapped_write
1472 (alias, XSYMBOL (base_variable)->trapped_write); 1472 (alias, XSYMBOL (base_variable)->u.s.trapped_write);
1473} 1473}
1474 1474
1475DEFUN ("add-variable-watcher", Fadd_variable_watcher, Sadd_variable_watcher, 1475DEFUN ("add-variable-watcher", Fadd_variable_watcher, Sadd_variable_watcher,
@@ -1583,7 +1583,7 @@ default_value (Lisp_Object symbol)
1583 sym = XSYMBOL (symbol); 1583 sym = XSYMBOL (symbol);
1584 1584
1585 start: 1585 start:
1586 switch (sym->redirect) 1586 switch (sym->u.s.redirect)
1587 { 1587 {
1588 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 1588 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1589 case SYMBOL_PLAINVAL: return SYMBOL_VAL (sym); 1589 case SYMBOL_PLAINVAL: return SYMBOL_VAL (sym);
@@ -1653,7 +1653,7 @@ set_default_internal (Lisp_Object symbol, Lisp_Object value,
1653 1653
1654 CHECK_SYMBOL (symbol); 1654 CHECK_SYMBOL (symbol);
1655 sym = XSYMBOL (symbol); 1655 sym = XSYMBOL (symbol);
1656 switch (sym->trapped_write) 1656 switch (sym->u.s.trapped_write)
1657 { 1657 {
1658 case SYMBOL_NOWRITE: 1658 case SYMBOL_NOWRITE:
1659 if (NILP (Fkeywordp (symbol)) 1659 if (NILP (Fkeywordp (symbol))
@@ -1665,7 +1665,7 @@ set_default_internal (Lisp_Object symbol, Lisp_Object value,
1665 1665
1666 case SYMBOL_TRAPPED_WRITE: 1666 case SYMBOL_TRAPPED_WRITE:
1667 /* Don't notify here if we're going to call Fset anyway. */ 1667 /* Don't notify here if we're going to call Fset anyway. */
1668 if (sym->redirect != SYMBOL_PLAINVAL 1668 if (sym->u.s.redirect != SYMBOL_PLAINVAL
1669 /* Setting due to thread switching doesn't count. */ 1669 /* Setting due to thread switching doesn't count. */
1670 && bindflag != SET_INTERNAL_THREAD_SWITCH) 1670 && bindflag != SET_INTERNAL_THREAD_SWITCH)
1671 notify_variable_watchers (symbol, value, Qset_default, Qnil); 1671 notify_variable_watchers (symbol, value, Qset_default, Qnil);
@@ -1677,7 +1677,7 @@ set_default_internal (Lisp_Object symbol, Lisp_Object value,
1677 } 1677 }
1678 1678
1679 start: 1679 start:
1680 switch (sym->redirect) 1680 switch (sym->u.s.redirect)
1681 { 1681 {
1682 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 1682 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1683 case SYMBOL_PLAINVAL: set_internal (symbol, value, Qnil, bindflag); return; 1683 case SYMBOL_PLAINVAL: set_internal (symbol, value, Qnil, bindflag); return;
@@ -1829,7 +1829,7 @@ The function `default-value' gets the default value and `set-default' sets it.
1829 sym = XSYMBOL (variable); 1829 sym = XSYMBOL (variable);
1830 1830
1831 start: 1831 start:
1832 switch (sym->redirect) 1832 switch (sym->u.s.redirect)
1833 { 1833 {
1834 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 1834 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1835 case SYMBOL_PLAINVAL: 1835 case SYMBOL_PLAINVAL:
@@ -1857,7 +1857,7 @@ The function `default-value' gets the default value and `set-default' sets it.
1857 if (!blv) 1857 if (!blv)
1858 { 1858 {
1859 blv = make_blv (sym, forwarded, valcontents); 1859 blv = make_blv (sym, forwarded, valcontents);
1860 sym->redirect = SYMBOL_LOCALIZED; 1860 sym->u.s.redirect = SYMBOL_LOCALIZED;
1861 SET_SYMBOL_BLV (sym, blv); 1861 SET_SYMBOL_BLV (sym, blv);
1862 } 1862 }
1863 1863
@@ -1897,7 +1897,7 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */)
1897 sym = XSYMBOL (variable); 1897 sym = XSYMBOL (variable);
1898 1898
1899 start: 1899 start:
1900 switch (sym->redirect) 1900 switch (sym->u.s.redirect)
1901 { 1901 {
1902 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 1902 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1903 case SYMBOL_PLAINVAL: 1903 case SYMBOL_PLAINVAL:
@@ -1914,7 +1914,7 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */)
1914 default: emacs_abort (); 1914 default: emacs_abort ();
1915 } 1915 }
1916 1916
1917 if (sym->trapped_write == SYMBOL_NOWRITE) 1917 if (sym->u.s.trapped_write == SYMBOL_NOWRITE)
1918 error ("Symbol %s may not be buffer-local", 1918 error ("Symbol %s may not be buffer-local",
1919 SDATA (SYMBOL_NAME (variable))); 1919 SDATA (SYMBOL_NAME (variable)));
1920 1920
@@ -1930,7 +1930,7 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */)
1930 if (!blv) 1930 if (!blv)
1931 { 1931 {
1932 blv = make_blv (sym, forwarded, valcontents); 1932 blv = make_blv (sym, forwarded, valcontents);
1933 sym->redirect = SYMBOL_LOCALIZED; 1933 sym->u.s.redirect = SYMBOL_LOCALIZED;
1934 SET_SYMBOL_BLV (sym, blv); 1934 SET_SYMBOL_BLV (sym, blv);
1935 } 1935 }
1936 1936
@@ -1987,7 +1987,7 @@ From now on the default value will apply in this buffer. Return VARIABLE. */)
1987 sym = XSYMBOL (variable); 1987 sym = XSYMBOL (variable);
1988 1988
1989 start: 1989 start:
1990 switch (sym->redirect) 1990 switch (sym->u.s.redirect)
1991 { 1991 {
1992 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 1992 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1993 case SYMBOL_PLAINVAL: return variable; 1993 case SYMBOL_PLAINVAL: return variable;
@@ -2014,7 +2014,7 @@ From now on the default value will apply in this buffer. Return VARIABLE. */)
2014 default: emacs_abort (); 2014 default: emacs_abort ();
2015 } 2015 }
2016 2016
2017 if (sym->trapped_write == SYMBOL_TRAPPED_WRITE) 2017 if (sym->u.s.trapped_write == SYMBOL_TRAPPED_WRITE)
2018 notify_variable_watchers (variable, Qnil, Qmakunbound, Fcurrent_buffer ()); 2018 notify_variable_watchers (variable, Qnil, Qmakunbound, Fcurrent_buffer ());
2019 2019
2020 /* Get rid of this buffer's alist element, if any. */ 2020 /* Get rid of this buffer's alist element, if any. */
@@ -2056,7 +2056,7 @@ BUFFER defaults to the current buffer. */)
2056 sym = XSYMBOL (variable); 2056 sym = XSYMBOL (variable);
2057 2057
2058 start: 2058 start:
2059 switch (sym->redirect) 2059 switch (sym->u.s.redirect)
2060 { 2060 {
2061 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 2061 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
2062 case SYMBOL_PLAINVAL: return Qnil; 2062 case SYMBOL_PLAINVAL: return Qnil;
@@ -2110,7 +2110,7 @@ value in BUFFER, or if VARIABLE is automatically buffer-local (see
2110 sym = XSYMBOL (variable); 2110 sym = XSYMBOL (variable);
2111 2111
2112 start: 2112 start:
2113 switch (sym->redirect) 2113 switch (sym->u.s.redirect)
2114 { 2114 {
2115 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 2115 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
2116 case SYMBOL_PLAINVAL: return Qnil; 2116 case SYMBOL_PLAINVAL: return Qnil;
@@ -2145,7 +2145,7 @@ If the current binding is global (the default), the value is nil. */)
2145 find_symbol_value (variable); 2145 find_symbol_value (variable);
2146 2146
2147 start: 2147 start:
2148 switch (sym->redirect) 2148 switch (sym->u.s.redirect)
2149 { 2149 {
2150 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 2150 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
2151 case SYMBOL_PLAINVAL: return Qnil; 2151 case SYMBOL_PLAINVAL: return Qnil;
@@ -2163,7 +2163,7 @@ If the current binding is global (the default), the value is nil. */)
2163 buffer's or frame's value we are saving. */ 2163 buffer's or frame's value we are saving. */
2164 if (!NILP (Flocal_variable_p (variable, Qnil))) 2164 if (!NILP (Flocal_variable_p (variable, Qnil)))
2165 return Fcurrent_buffer (); 2165 return Fcurrent_buffer ();
2166 else if (sym->redirect == SYMBOL_LOCALIZED 2166 else if (sym->u.s.redirect == SYMBOL_LOCALIZED
2167 && blv_found (SYMBOL_BLV (sym))) 2167 && blv_found (SYMBOL_BLV (sym)))
2168 return SYMBOL_BLV (sym)->where; 2168 return SYMBOL_BLV (sym)->where;
2169 else 2169 else
@@ -2234,12 +2234,12 @@ indirect_function (register Lisp_Object object)
2234 { 2234 {
2235 if (!SYMBOLP (hare) || NILP (hare)) 2235 if (!SYMBOLP (hare) || NILP (hare))
2236 break; 2236 break;
2237 hare = XSYMBOL (hare)->function; 2237 hare = XSYMBOL (hare)->u.s.function;
2238 if (!SYMBOLP (hare) || NILP (hare)) 2238 if (!SYMBOLP (hare) || NILP (hare))
2239 break; 2239 break;
2240 hare = XSYMBOL (hare)->function; 2240 hare = XSYMBOL (hare)->u.s.function;
2241 2241
2242 tortoise = XSYMBOL (tortoise)->function; 2242 tortoise = XSYMBOL (tortoise)->u.s.function;
2243 2243
2244 if (EQ (hare, tortoise)) 2244 if (EQ (hare, tortoise))
2245 xsignal1 (Qcyclic_function_indirection, object); 2245 xsignal1 (Qcyclic_function_indirection, object);
@@ -2261,7 +2261,7 @@ function chain of symbols. */)
2261 /* Optimize for no indirection. */ 2261 /* Optimize for no indirection. */
2262 result = object; 2262 result = object;
2263 if (SYMBOLP (result) && !NILP (result) 2263 if (SYMBOLP (result) && !NILP (result)
2264 && (result = XSYMBOL (result)->function, SYMBOLP (result))) 2264 && (result = XSYMBOL (result)->u.s.function, SYMBOLP (result)))
2265 result = indirect_function (result); 2265 result = indirect_function (result);
2266 if (!NILP (result)) 2266 if (!NILP (result))
2267 return result; 2267 return result;
@@ -3877,7 +3877,7 @@ syms_of_data (void)
3877 defsubr (&Sbool_vector_count_consecutive); 3877 defsubr (&Sbool_vector_count_consecutive);
3878 defsubr (&Sbool_vector_count_population); 3878 defsubr (&Sbool_vector_count_population);
3879 3879
3880 set_symbol_function (Qwholenump, XSYMBOL (Qnatnump)->function); 3880 set_symbol_function (Qwholenump, XSYMBOL (Qnatnump)->u.s.function);
3881 3881
3882 DEFVAR_LISP ("most-positive-fixnum", Vmost_positive_fixnum, 3882 DEFVAR_LISP ("most-positive-fixnum", Vmost_positive_fixnum,
3883 doc: /* The largest value that is representable in a Lisp integer. */); 3883 doc: /* The largest value that is representable in a Lisp integer. */);
diff --git a/src/doc.c b/src/doc.c
index e81740bfc1c..0cd62172c38 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -472,7 +472,7 @@ store_function_docstring (Lisp_Object obj, EMACS_INT offset)
472{ 472{
473 /* Don't use indirect_function here, or defaliases will apply their 473 /* Don't use indirect_function here, or defaliases will apply their
474 docstrings to the base functions (Bug#2603). */ 474 docstrings to the base functions (Bug#2603). */
475 Lisp_Object fun = SYMBOLP (obj) ? XSYMBOL (obj)->function : obj; 475 Lisp_Object fun = SYMBOLP (obj) ? XSYMBOL (obj)->u.s.function : obj;
476 476
477 /* The type determines where the docstring is stored. */ 477 /* The type determines where the docstring is stored. */
478 478
diff --git a/src/eval.c b/src/eval.c
index 52e4c96d4b2..40b47968be2 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -603,7 +603,7 @@ The return value is BASE-VARIABLE. */)
603 603
604 sym = XSYMBOL (new_alias); 604 sym = XSYMBOL (new_alias);
605 605
606 switch (sym->redirect) 606 switch (sym->u.s.redirect)
607 { 607 {
608 case SYMBOL_FORWARDED: 608 case SYMBOL_FORWARDED:
609 error ("Cannot make an internal variable an alias"); 609 error ("Cannot make an internal variable an alias");
@@ -632,14 +632,14 @@ The return value is BASE-VARIABLE. */)
632 error ("Don't know how to make a let-bound variable an alias"); 632 error ("Don't know how to make a let-bound variable an alias");
633 } 633 }
634 634
635 if (sym->trapped_write == SYMBOL_TRAPPED_WRITE) 635 if (sym->u.s.trapped_write == SYMBOL_TRAPPED_WRITE)
636 notify_variable_watchers (new_alias, base_variable, Qdefvaralias, Qnil); 636 notify_variable_watchers (new_alias, base_variable, Qdefvaralias, Qnil);
637 637
638 sym->declared_special = 1; 638 sym->u.s.declared_special = true;
639 XSYMBOL (base_variable)->declared_special = 1; 639 XSYMBOL (base_variable)->u.s.declared_special = true;
640 sym->redirect = SYMBOL_VARALIAS; 640 sym->u.s.redirect = SYMBOL_VARALIAS;
641 SET_SYMBOL_ALIAS (sym, XSYMBOL (base_variable)); 641 SET_SYMBOL_ALIAS (sym, XSYMBOL (base_variable));
642 sym->trapped_write = XSYMBOL (base_variable)->trapped_write; 642 sym->u.s.trapped_write = XSYMBOL (base_variable)->u.s.trapped_write;
643 LOADHIST_ATTACH (new_alias); 643 LOADHIST_ATTACH (new_alias);
644 /* Even if docstring is nil: remove old docstring. */ 644 /* Even if docstring is nil: remove old docstring. */
645 Fput (new_alias, Qvariable_documentation, docstring); 645 Fput (new_alias, Qvariable_documentation, docstring);
@@ -745,7 +745,7 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */)
745 tem = Fdefault_boundp (sym); 745 tem = Fdefault_boundp (sym);
746 746
747 /* Do it before evaluating the initial value, for self-references. */ 747 /* Do it before evaluating the initial value, for self-references. */
748 XSYMBOL (sym)->declared_special = 1; 748 XSYMBOL (sym)->u.s.declared_special = true;
749 749
750 if (NILP (tem)) 750 if (NILP (tem))
751 Fset_default (sym, eval_sub (XCAR (tail))); 751 Fset_default (sym, eval_sub (XCAR (tail)));
@@ -769,7 +769,7 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */)
769 LOADHIST_ATTACH (sym); 769 LOADHIST_ATTACH (sym);
770 } 770 }
771 else if (!NILP (Vinternal_interpreter_environment) 771 else if (!NILP (Vinternal_interpreter_environment)
772 && !XSYMBOL (sym)->declared_special) 772 && !XSYMBOL (sym)->u.s.declared_special)
773 /* A simple (defvar foo) with lexical scoping does "nothing" except 773 /* A simple (defvar foo) with lexical scoping does "nothing" except
774 declare that var to be dynamically scoped *locally* (i.e. within 774 declare that var to be dynamically scoped *locally* (i.e. within
775 the current file or let-block). */ 775 the current file or let-block). */
@@ -818,7 +818,7 @@ usage: (defconst SYMBOL INITVALUE [DOCSTRING]) */)
818 if (!NILP (Vpurify_flag)) 818 if (!NILP (Vpurify_flag))
819 tem = Fpurecopy (tem); 819 tem = Fpurecopy (tem);
820 Fset_default (sym, tem); 820 Fset_default (sym, tem);
821 XSYMBOL (sym)->declared_special = 1; 821 XSYMBOL (sym)->u.s.declared_special = true;
822 if (!NILP (docstring)) 822 if (!NILP (docstring))
823 { 823 {
824 if (!NILP (Vpurify_flag)) 824 if (!NILP (Vpurify_flag))
@@ -837,7 +837,7 @@ DEFUN ("internal-make-var-non-special", Fmake_var_non_special,
837 (Lisp_Object symbol) 837 (Lisp_Object symbol)
838{ 838{
839 CHECK_SYMBOL (symbol); 839 CHECK_SYMBOL (symbol);
840 XSYMBOL (symbol)->declared_special = 0; 840 XSYMBOL (symbol)->u.s.declared_special = false;
841 return Qnil; 841 return Qnil;
842} 842}
843 843
@@ -877,7 +877,7 @@ usage: (let* VARLIST BODY...) */)
877 } 877 }
878 878
879 if (!NILP (lexenv) && SYMBOLP (var) 879 if (!NILP (lexenv) && SYMBOLP (var)
880 && !XSYMBOL (var)->declared_special 880 && !XSYMBOL (var)->u.s.declared_special
881 && NILP (Fmemq (var, Vinternal_interpreter_environment))) 881 && NILP (Fmemq (var, Vinternal_interpreter_environment)))
882 /* Lexically bind VAR by adding it to the interpreter's binding 882 /* Lexically bind VAR by adding it to the interpreter's binding
883 alist. */ 883 alist. */
@@ -953,7 +953,7 @@ usage: (let VARLIST BODY...) */)
953 tem = temps[argnum]; 953 tem = temps[argnum];
954 954
955 if (!NILP (lexenv) && SYMBOLP (var) 955 if (!NILP (lexenv) && SYMBOLP (var)
956 && !XSYMBOL (var)->declared_special 956 && !XSYMBOL (var)->u.s.declared_special
957 && NILP (Fmemq (var, Vinternal_interpreter_environment))) 957 && NILP (Fmemq (var, Vinternal_interpreter_environment)))
958 /* Lexically bind VAR by adding it to the lexenv alist. */ 958 /* Lexically bind VAR by adding it to the lexenv alist. */
959 lexenv = Fcons (Fcons (var, tem), lexenv); 959 lexenv = Fcons (Fcons (var, tem), lexenv);
@@ -1022,7 +1022,7 @@ definitions to shadow the loaded ones for use in file byte-compilation. */)
1022 tem = Fassq (sym, environment); 1022 tem = Fassq (sym, environment);
1023 if (NILP (tem)) 1023 if (NILP (tem))
1024 { 1024 {
1025 def = XSYMBOL (sym)->function; 1025 def = XSYMBOL (sym)->u.s.function;
1026 if (!NILP (def)) 1026 if (!NILP (def))
1027 continue; 1027 continue;
1028 } 1028 }
@@ -1932,8 +1932,8 @@ this does nothing and returns nil. */)
1932 CHECK_STRING (file); 1932 CHECK_STRING (file);
1933 1933
1934 /* If function is defined and not as an autoload, don't override. */ 1934 /* If function is defined and not as an autoload, don't override. */
1935 if (!NILP (XSYMBOL (function)->function) 1935 if (!NILP (XSYMBOL (function)->u.s.function)
1936 && !AUTOLOADP (XSYMBOL (function)->function)) 1936 && !AUTOLOADP (XSYMBOL (function)->u.s.function))
1937 return Qnil; 1937 return Qnil;
1938 1938
1939 if (!NILP (Vpurify_flag) && EQ (docstring, make_number (0))) 1939 if (!NILP (Vpurify_flag) && EQ (docstring, make_number (0)))
@@ -2164,7 +2164,7 @@ eval_sub (Lisp_Object form)
2164 fun = original_fun; 2164 fun = original_fun;
2165 if (!SYMBOLP (fun)) 2165 if (!SYMBOLP (fun))
2166 fun = Ffunction (Fcons (fun, Qnil)); 2166 fun = Ffunction (Fcons (fun, Qnil));
2167 else if (!NILP (fun) && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) 2167 else if (!NILP (fun) && (fun = XSYMBOL (fun)->u.s.function, SYMBOLP (fun)))
2168 fun = indirect_function (fun); 2168 fun = indirect_function (fun);
2169 2169
2170 if (SUBRP (fun)) 2170 if (SUBRP (fun))
@@ -2347,7 +2347,7 @@ usage: (apply FUNCTION &rest ARGUMENTS) */)
2347 2347
2348 /* Optimize for no indirection. */ 2348 /* Optimize for no indirection. */
2349 if (SYMBOLP (fun) && !NILP (fun) 2349 if (SYMBOLP (fun) && !NILP (fun)
2350 && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) 2350 && (fun = XSYMBOL (fun)->u.s.function, SYMBOLP (fun)))
2351 { 2351 {
2352 fun = indirect_function (fun); 2352 fun = indirect_function (fun);
2353 if (NILP (fun)) 2353 if (NILP (fun))
@@ -2759,7 +2759,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
2759 /* Optimize for no indirection. */ 2759 /* Optimize for no indirection. */
2760 fun = original_fun; 2760 fun = original_fun;
2761 if (SYMBOLP (fun) && !NILP (fun) 2761 if (SYMBOLP (fun) && !NILP (fun)
2762 && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) 2762 && (fun = XSYMBOL (fun)->u.s.function, SYMBOLP (fun)))
2763 fun = indirect_function (fun); 2763 fun = indirect_function (fun);
2764 2764
2765 if (SUBRP (fun)) 2765 if (SUBRP (fun))
@@ -3075,7 +3075,7 @@ function with `&rest' args, or `unevalled' for a special form. */)
3075 function = original; 3075 function = original;
3076 if (SYMBOLP (function) && !NILP (function)) 3076 if (SYMBOLP (function) && !NILP (function))
3077 { 3077 {
3078 function = XSYMBOL (function)->function; 3078 function = XSYMBOL (function)->u.s.function;
3079 if (SYMBOLP (function)) 3079 if (SYMBOLP (function))
3080 function = indirect_function (function); 3080 function = indirect_function (function);
3081 } 3081 }
@@ -3214,7 +3214,7 @@ let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol)
3214 if ((--p)->kind > SPECPDL_LET) 3214 if ((--p)->kind > SPECPDL_LET)
3215 { 3215 {
3216 struct Lisp_Symbol *let_bound_symbol = XSYMBOL (specpdl_symbol (p)); 3216 struct Lisp_Symbol *let_bound_symbol = XSYMBOL (specpdl_symbol (p));
3217 eassert (let_bound_symbol->redirect != SYMBOL_VARALIAS); 3217 eassert (let_bound_symbol->u.s.redirect != SYMBOL_VARALIAS);
3218 if (symbol == let_bound_symbol 3218 if (symbol == let_bound_symbol
3219 && EQ (specpdl_where (p), buf)) 3219 && EQ (specpdl_where (p), buf))
3220 return 1; 3220 return 1;
@@ -3227,10 +3227,10 @@ static void
3227do_specbind (struct Lisp_Symbol *sym, union specbinding *bind, 3227do_specbind (struct Lisp_Symbol *sym, union specbinding *bind,
3228 Lisp_Object value, enum Set_Internal_Bind bindflag) 3228 Lisp_Object value, enum Set_Internal_Bind bindflag)
3229{ 3229{
3230 switch (sym->redirect) 3230 switch (sym->u.s.redirect)
3231 { 3231 {
3232 case SYMBOL_PLAINVAL: 3232 case SYMBOL_PLAINVAL:
3233 if (!sym->trapped_write) 3233 if (!sym->u.s.trapped_write)
3234 SET_SYMBOL_VAL (sym, value); 3234 SET_SYMBOL_VAL (sym, value);
3235 else 3235 else
3236 set_internal (specpdl_symbol (bind), value, Qnil, bindflag); 3236 set_internal (specpdl_symbol (bind), value, Qnil, bindflag);
@@ -3274,7 +3274,7 @@ specbind (Lisp_Object symbol, Lisp_Object value)
3274 sym = XSYMBOL (symbol); 3274 sym = XSYMBOL (symbol);
3275 3275
3276 start: 3276 start:
3277 switch (sym->redirect) 3277 switch (sym->u.s.redirect)
3278 { 3278 {
3279 case SYMBOL_VARALIAS: 3279 case SYMBOL_VARALIAS:
3280 sym = indirect_variable (sym); XSETSYMBOL (symbol, sym); goto start; 3280 sym = indirect_variable (sym); XSETSYMBOL (symbol, sym); goto start;
@@ -3298,10 +3298,10 @@ specbind (Lisp_Object symbol, Lisp_Object value)
3298 specpdl_ptr->let.where = Fcurrent_buffer (); 3298 specpdl_ptr->let.where = Fcurrent_buffer ();
3299 specpdl_ptr->let.saved_value = Qnil; 3299 specpdl_ptr->let.saved_value = Qnil;
3300 3300
3301 eassert (sym->redirect != SYMBOL_LOCALIZED 3301 eassert (sym->u.s.redirect != SYMBOL_LOCALIZED
3302 || (EQ (SYMBOL_BLV (sym)->where, Fcurrent_buffer ()))); 3302 || (EQ (SYMBOL_BLV (sym)->where, Fcurrent_buffer ())));
3303 3303
3304 if (sym->redirect == SYMBOL_LOCALIZED) 3304 if (sym->u.s.redirect == SYMBOL_LOCALIZED)
3305 { 3305 {
3306 if (!blv_found (SYMBOL_BLV (sym))) 3306 if (!blv_found (SYMBOL_BLV (sym)))
3307 specpdl_ptr->let.kind = SPECPDL_LET_DEFAULT; 3307 specpdl_ptr->let.kind = SPECPDL_LET_DEFAULT;
@@ -3412,9 +3412,9 @@ do_one_unbind (union specbinding *this_binding, bool unwinding,
3412 { /* If variable has a trivial value (no forwarding), and isn't 3412 { /* If variable has a trivial value (no forwarding), and isn't
3413 trapped, we can just set it. */ 3413 trapped, we can just set it. */
3414 Lisp_Object sym = specpdl_symbol (this_binding); 3414 Lisp_Object sym = specpdl_symbol (this_binding);
3415 if (SYMBOLP (sym) && XSYMBOL (sym)->redirect == SYMBOL_PLAINVAL) 3415 if (SYMBOLP (sym) && XSYMBOL (sym)->u.s.redirect == SYMBOL_PLAINVAL)
3416 { 3416 {
3417 if (XSYMBOL (sym)->trapped_write == SYMBOL_UNTRAPPED_WRITE) 3417 if (XSYMBOL (sym)->u.s.trapped_write == SYMBOL_UNTRAPPED_WRITE)
3418 SET_SYMBOL_VAL (XSYMBOL (sym), specpdl_old_value (this_binding)); 3418 SET_SYMBOL_VAL (XSYMBOL (sym), specpdl_old_value (this_binding));
3419 else 3419 else
3420 set_internal (sym, specpdl_old_value (this_binding), 3420 set_internal (sym, specpdl_old_value (this_binding),
@@ -3546,7 +3546,7 @@ context where binding is lexical by default. */)
3546 (Lisp_Object symbol) 3546 (Lisp_Object symbol)
3547{ 3547{
3548 CHECK_SYMBOL (symbol); 3548 CHECK_SYMBOL (symbol);
3549 return XSYMBOL (symbol)->declared_special ? Qt : Qnil; 3549 return XSYMBOL (symbol)->u.s.declared_special ? Qt : Qnil;
3550} 3550}
3551 3551
3552 3552
@@ -3702,7 +3702,8 @@ backtrace_eval_unrewind (int distance)
3702 just set it. No need to check for constant symbols here, 3702 just set it. No need to check for constant symbols here,
3703 since that was already done by specbind. */ 3703 since that was already done by specbind. */
3704 Lisp_Object sym = specpdl_symbol (tmp); 3704 Lisp_Object sym = specpdl_symbol (tmp);
3705 if (SYMBOLP (sym) && XSYMBOL (sym)->redirect == SYMBOL_PLAINVAL) 3705 if (SYMBOLP (sym)
3706 && XSYMBOL (sym)->u.s.redirect == SYMBOL_PLAINVAL)
3706 { 3707 {
3707 Lisp_Object old_value = specpdl_old_value (tmp); 3708 Lisp_Object old_value = specpdl_old_value (tmp);
3708 set_specpdl_old_value (tmp, SYMBOL_VAL (XSYMBOL (sym))); 3709 set_specpdl_old_value (tmp, SYMBOL_VAL (XSYMBOL (sym)));
diff --git a/src/fns.c b/src/fns.c
index 2311a6e041b..42859344bdc 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -1993,7 +1993,7 @@ This is the last value stored with `(put SYMBOL PROPNAME VALUE)'. */)
1993 propname); 1993 propname);
1994 if (!NILP (propval)) 1994 if (!NILP (propval))
1995 return propval; 1995 return propval;
1996 return Fplist_get (XSYMBOL (symbol)->plist, propname); 1996 return Fplist_get (XSYMBOL (symbol)->u.s.plist, propname);
1997} 1997}
1998 1998
1999DEFUN ("plist-put", Fplist_put, Splist_put, 3, 3, 0, 1999DEFUN ("plist-put", Fplist_put, Splist_put, 3, 3, 0,
@@ -2039,7 +2039,7 @@ It can be retrieved with `(get SYMBOL PROPNAME)'. */)
2039{ 2039{
2040 CHECK_SYMBOL (symbol); 2040 CHECK_SYMBOL (symbol);
2041 set_symbol_plist 2041 set_symbol_plist
2042 (symbol, Fplist_put (XSYMBOL (symbol)->plist, propname, value)); 2042 (symbol, Fplist_put (XSYMBOL (symbol)->u.s.plist, propname, value));
2043 return value; 2043 return value;
2044} 2044}
2045 2045
diff --git a/src/keyboard.c b/src/keyboard.c
index 7ddd6b96747..57757cf2112 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -7901,7 +7901,7 @@ parse_menu_item (Lisp_Object item, int inmenubar)
7901 (such as lmenu.el set it up), check if the 7901 (such as lmenu.el set it up), check if the
7902 original command matches the cached command. */ 7902 original command matches the cached command. */
7903 && !(SYMBOLP (def) 7903 && !(SYMBOLP (def)
7904 && EQ (tem, XSYMBOL (def)->function)))) 7904 && EQ (tem, XSYMBOL (def)->u.s.function))))
7905 keys = Qnil; 7905 keys = Qnil;
7906 } 7906 }
7907 7907
@@ -8761,9 +8761,9 @@ access_keymap_keyremap (Lisp_Object map, Lisp_Object key, Lisp_Object prompt,
8761 /* Handle a symbol whose function definition is a keymap 8761 /* Handle a symbol whose function definition is a keymap
8762 or an array. */ 8762 or an array. */
8763 if (SYMBOLP (next) && !NILP (Ffboundp (next)) 8763 if (SYMBOLP (next) && !NILP (Ffboundp (next))
8764 && (ARRAYP (XSYMBOL (next)->function) 8764 && (ARRAYP (XSYMBOL (next)->u.s.function)
8765 || KEYMAPP (XSYMBOL (next)->function))) 8765 || KEYMAPP (XSYMBOL (next)->u.s.function)))
8766 next = Fautoload_do_load (XSYMBOL (next)->function, next, Qnil); 8766 next = Fautoload_do_load (XSYMBOL (next)->u.s.function, next, Qnil);
8767 8767
8768 /* If the keymap gives a function, not an 8768 /* If the keymap gives a function, not an
8769 array, then call the function with one arg and use 8769 array, then call the function with one arg and use
@@ -11510,7 +11510,7 @@ for that character after that prefix key. */);
11510 doc: /* Form to evaluate when Emacs starts up. 11510 doc: /* Form to evaluate when Emacs starts up.
11511Useful to set before you dump a modified Emacs. */); 11511Useful to set before you dump a modified Emacs. */);
11512 Vtop_level = Qnil; 11512 Vtop_level = Qnil;
11513 XSYMBOL (Qtop_level)->declared_special = false; 11513 XSYMBOL (Qtop_level)->u.s.declared_special = false;
11514 11514
11515 DEFVAR_KBOARD ("keyboard-translate-table", Vkeyboard_translate_table, 11515 DEFVAR_KBOARD ("keyboard-translate-table", Vkeyboard_translate_table,
11516 doc: /* Translate table for local keyboard input, or nil. 11516 doc: /* Translate table for local keyboard input, or nil.
diff --git a/src/lisp.h b/src/lisp.h
index 1d6fd5a4fe2..e9aec4c5979 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -229,7 +229,7 @@ extern bool suppress_checking EXTERNALLY_VISIBLE;
229 USE_LSB_TAG not only requires the least 3 bits of pointers returned by 229 USE_LSB_TAG not only requires the least 3 bits of pointers returned by
230 malloc to be 0 but also needs to be able to impose a mult-of-8 alignment 230 malloc to be 0 but also needs to be able to impose a mult-of-8 alignment
231 on the few static Lisp_Objects used, all of which are aligned via 231 on the few static Lisp_Objects used, all of which are aligned via
232 the GCALIGN macro defined below. */ 232 'char alignas (GCALIGNMENT) gcaligned;' inside a union. */
233 233
234enum Lisp_Bits 234enum Lisp_Bits
235 { 235 {
@@ -277,20 +277,6 @@ DEFINE_GDB_SYMBOL_END (VALMASK)
277error !; 277error !;
278#endif 278#endif
279 279
280/* Use GCALIGNED immediately after the 'struct' keyword to require the
281 struct to have an address that is a multiple of GCALIGNMENT. This
282 is a no-op if the struct's natural alignment is already a multiple
283 of GCALIGNMENT. GCALIGNED's implementation uses the 'aligned'
284 attribute instead of 'alignas (GCALIGNMENT)', as the latter would
285 fail if an object's natural alignment exceeds GCALIGNMENT. The
286 implementation hopes that natural alignment suffices on platforms
287 lacking 'aligned'. */
288#ifdef HAVE_STRUCT_ATTRIBUTE_ALIGNED
289# define GCALIGNED __attribute__ ((aligned (GCALIGNMENT)))
290#else
291# define GCALIGNED /* empty */
292#endif
293
294/* Some operations are so commonly executed that they are implemented 280/* Some operations are so commonly executed that they are implemented
295 as macros, not functions, because otherwise runtime performance would 281 as macros, not functions, because otherwise runtime performance would
296 suffer too much when compiling with GCC without optimization. 282 suffer too much when compiling with GCC without optimization.
@@ -338,15 +324,17 @@ error !;
338#define lisp_h_MISCP(x) (XTYPE (x) == Lisp_Misc) 324#define lisp_h_MISCP(x) (XTYPE (x) == Lisp_Misc)
339#define lisp_h_NILP(x) EQ (x, Qnil) 325#define lisp_h_NILP(x) EQ (x, Qnil)
340#define lisp_h_SET_SYMBOL_VAL(sym, v) \ 326#define lisp_h_SET_SYMBOL_VAL(sym, v) \
341 (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value = (v)) 327 (eassert ((sym)->u.s.redirect == SYMBOL_PLAINVAL), \
342#define lisp_h_SYMBOL_CONSTANT_P(sym) (XSYMBOL (sym)->trapped_write == SYMBOL_NOWRITE) 328 (sym)->u.s.val.value = (v))
343#define lisp_h_SYMBOL_TRAPPED_WRITE_P(sym) (XSYMBOL (sym)->trapped_write) 329#define lisp_h_SYMBOL_CONSTANT_P(sym) \
330 (XSYMBOL (sym)->u.s.trapped_write == SYMBOL_NOWRITE)
331#define lisp_h_SYMBOL_TRAPPED_WRITE_P(sym) (XSYMBOL (sym)->u.s.trapped_write)
344#define lisp_h_SYMBOL_VAL(sym) \ 332#define lisp_h_SYMBOL_VAL(sym) \
345 (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value) 333 (eassert ((sym)->u.s.redirect == SYMBOL_PLAINVAL), (sym)->u.s.val.value)
346#define lisp_h_SYMBOLP(x) (XTYPE (x) == Lisp_Symbol) 334#define lisp_h_SYMBOLP(x) (XTYPE (x) == Lisp_Symbol)
347#define lisp_h_VECTORLIKEP(x) (XTYPE (x) == Lisp_Vectorlike) 335#define lisp_h_VECTORLIKEP(x) (XTYPE (x) == Lisp_Vectorlike)
348#define lisp_h_XCAR(c) XCONS (c)->car 336#define lisp_h_XCAR(c) XCONS (c)->u.s.car
349#define lisp_h_XCDR(c) XCONS (c)->u.cdr 337#define lisp_h_XCDR(c) XCONS (c)->u.s.u.cdr
350#define lisp_h_XCONS(a) \ 338#define lisp_h_XCONS(a) \
351 (eassert (CONSP (a)), (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons)) 339 (eassert (CONSP (a)), (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons))
352#define lisp_h_XHASH(a) XUINT (a) 340#define lisp_h_XHASH(a) XUINT (a)
@@ -677,52 +665,60 @@ enum symbol_trapped_write
677 665
678struct Lisp_Symbol 666struct Lisp_Symbol
679{ 667{
680 bool_bf gcmarkbit : 1; 668 union
681 669 {
682 /* Indicates where the value can be found: 670 struct
683 0 : it's a plain var, the value is in the `value' field. 671 {
684 1 : it's a varalias, the value is really in the `alias' symbol. 672 bool_bf gcmarkbit : 1;
685 2 : it's a localized var, the value is in the `blv' object. 673
686 3 : it's a forwarding variable, the value is in `forward'. */ 674 /* Indicates where the value can be found:
687 ENUM_BF (symbol_redirect) redirect : 3; 675 0 : it's a plain var, the value is in the `value' field.
688 676 1 : it's a varalias, the value is really in the `alias' symbol.
689 /* 0 : normal case, just set the value 677 2 : it's a localized var, the value is in the `blv' object.
690 1 : constant, cannot set, e.g. nil, t, :keywords. 678 3 : it's a forwarding variable, the value is in `forward'. */
691 2 : trap the write, call watcher functions. */ 679 ENUM_BF (symbol_redirect) redirect : 3;
692 ENUM_BF (symbol_trapped_write) trapped_write : 2; 680
693 681 /* 0 : normal case, just set the value
694 /* Interned state of the symbol. This is an enumerator from 682 1 : constant, cannot set, e.g. nil, t, :keywords.
695 enum symbol_interned. */ 683 2 : trap the write, call watcher functions. */
696 unsigned interned : 2; 684 ENUM_BF (symbol_trapped_write) trapped_write : 2;
697 685
698 /* True means that this variable has been explicitly declared 686 /* Interned state of the symbol. This is an enumerator from
699 special (with `defvar' etc), and shouldn't be lexically bound. */ 687 enum symbol_interned. */
700 bool_bf declared_special : 1; 688 unsigned interned : 2;
701 689
702 /* True if pointed to from purespace and hence can't be GC'd. */ 690 /* True means that this variable has been explicitly declared
703 bool_bf pinned : 1; 691 special (with `defvar' etc), and shouldn't be lexically bound. */
704 692 bool_bf declared_special : 1;
705 /* The symbol's name, as a Lisp string. */ 693
706 Lisp_Object name; 694 /* True if pointed to from purespace and hence can't be GC'd. */
707 695 bool_bf pinned : 1;
708 /* Value of the symbol or Qunbound if unbound. Which alternative of the 696
709 union is used depends on the `redirect' field above. */ 697 /* The symbol's name, as a Lisp string. */
710 union { 698 Lisp_Object name;
711 Lisp_Object value; 699
712 struct Lisp_Symbol *alias; 700 /* Value of the symbol or Qunbound if unbound. Which alternative of the
713 struct Lisp_Buffer_Local_Value *blv; 701 union is used depends on the `redirect' field above. */
714 union Lisp_Fwd *fwd; 702 union {
715 } val; 703 Lisp_Object value;
716 704 struct Lisp_Symbol *alias;
717 /* Function value of the symbol or Qnil if not fboundp. */ 705 struct Lisp_Buffer_Local_Value *blv;
718 Lisp_Object function; 706 union Lisp_Fwd *fwd;
707 } val;
708
709 /* Function value of the symbol or Qnil if not fboundp. */
710 Lisp_Object function;
719 711
720 /* The symbol's property list. */ 712 /* The symbol's property list. */
721 Lisp_Object plist; 713 Lisp_Object plist;
722 714
723 /* Next symbol in obarray bucket, if the symbol is interned. */ 715 /* Next symbol in obarray bucket, if the symbol is interned. */
724 struct Lisp_Symbol *next; 716 struct Lisp_Symbol *next;
717 } s;
718 char alignas (GCALIGNMENT) gcaligned;
719 } u;
725}; 720};
721verify (alignof (struct Lisp_Symbol) % GCALIGNMENT == 0);
726 722
727/* Declare a Lisp-callable function. The MAXARGS parameter has the same 723/* Declare a Lisp-callable function. The MAXARGS parameter has the same
728 meaning as in the DEFUN macro, and is used to construct a prototype. */ 724 meaning as in the DEFUN macro, and is used to construct a prototype. */
@@ -802,7 +798,7 @@ struct Lisp_Symbol
802 Bug#8546. */ 798 Bug#8546. */
803union vectorlike_header 799union vectorlike_header
804 { 800 {
805 /* The only field contains various pieces of information: 801 /* The main member contains various pieces of information:
806 - The MSB (ARRAY_MARK_FLAG) holds the gcmarkbit. 802 - The MSB (ARRAY_MARK_FLAG) holds the gcmarkbit.
807 - The next bit (PSEUDOVECTOR_FLAG) indicates whether this is a plain 803 - The next bit (PSEUDOVECTOR_FLAG) indicates whether this is a plain
808 vector (0) or a pseudovector (1). 804 vector (0) or a pseudovector (1).
@@ -822,7 +818,9 @@ union vectorlike_header
822 Current layout limits the pseudovectors to 63 PVEC_xxx subtypes, 818 Current layout limits the pseudovectors to 63 PVEC_xxx subtypes,
823 4095 Lisp_Objects in GC-ed area and 4095 word-sized other slots. */ 819 4095 Lisp_Objects in GC-ed area and 4095 word-sized other slots. */
824 ptrdiff_t size; 820 ptrdiff_t size;
821 char alignas (GCALIGNMENT) gcaligned;
825 }; 822 };
823verify (alignof (union vectorlike_header) % GCALIGNMENT == 0);
826 824
827INLINE bool 825INLINE bool
828(SYMBOLP) (Lisp_Object x) 826(SYMBOLP) (Lisp_Object x)
@@ -854,7 +852,7 @@ make_lisp_symbol (struct Lisp_Symbol *sym)
854INLINE Lisp_Object 852INLINE Lisp_Object
855builtin_lisp_symbol (int index) 853builtin_lisp_symbol (int index)
856{ 854{
857 return make_lisp_symbol (&lispsym[index].s); 855 return make_lisp_symbol (&lispsym[index]);
858} 856}
859 857
860INLINE void 858INLINE void
@@ -1144,20 +1142,28 @@ make_pointer_integer (void *p)
1144 1142
1145typedef struct interval *INTERVAL; 1143typedef struct interval *INTERVAL;
1146 1144
1147struct GCALIGNED Lisp_Cons 1145struct Lisp_Cons
1146{
1147 union
1148 { 1148 {
1149 /* Car of this cons cell. */ 1149 struct
1150 Lisp_Object car;
1151
1152 union
1153 { 1150 {
1154 /* Cdr of this cons cell. */ 1151 /* Car of this cons cell. */
1155 Lisp_Object cdr; 1152 Lisp_Object car;
1156 1153
1157 /* Used to chain conses on a free list. */ 1154 union
1158 struct Lisp_Cons *chain; 1155 {
1159 } u; 1156 /* Cdr of this cons cell. */
1160 }; 1157 Lisp_Object cdr;
1158
1159 /* Used to chain conses on a free list. */
1160 struct Lisp_Cons *chain;
1161 } u;
1162 } s;
1163 char alignas (GCALIGNMENT) gcaligned;
1164 } u;
1165};
1166verify (alignof (struct Lisp_Cons) % GCALIGNMENT == 0);
1161 1167
1162INLINE bool 1168INLINE bool
1163(NILP) (Lisp_Object x) 1169(NILP) (Lisp_Object x)
@@ -1193,12 +1199,12 @@ INLINE struct Lisp_Cons *
1193INLINE Lisp_Object * 1199INLINE Lisp_Object *
1194xcar_addr (Lisp_Object c) 1200xcar_addr (Lisp_Object c)
1195{ 1201{
1196 return &XCONS (c)->car; 1202 return &XCONS (c)->u.s.car;
1197} 1203}
1198INLINE Lisp_Object * 1204INLINE Lisp_Object *
1199xcdr_addr (Lisp_Object c) 1205xcdr_addr (Lisp_Object c)
1200{ 1206{
1201 return &XCONS (c)->u.cdr; 1207 return &XCONS (c)->u.s.u.cdr;
1202} 1208}
1203 1209
1204/* Use these from normal code. */ 1210/* Use these from normal code. */
@@ -1262,15 +1268,24 @@ CDR_SAFE (Lisp_Object c)
1262 return CONSP (c) ? XCDR (c) : Qnil; 1268 return CONSP (c) ? XCDR (c) : Qnil;
1263} 1269}
1264 1270
1265/* In a string or vector, the sign bit of the `size' is the gc mark bit. */ 1271/* In a string or vector, the sign bit of u.s.size is the gc mark bit. */
1266 1272
1267struct GCALIGNED Lisp_String 1273struct Lisp_String
1274{
1275 union
1268 { 1276 {
1269 ptrdiff_t size; 1277 struct
1270 ptrdiff_t size_byte; 1278 {
1271 INTERVAL intervals; /* Text properties in this string. */ 1279 ptrdiff_t size;
1272 unsigned char *data; 1280 ptrdiff_t size_byte;
1273 }; 1281 INTERVAL intervals; /* Text properties in this string. */
1282 unsigned char *data;
1283 } s;
1284 struct Lisp_String *next;
1285 char alignas (GCALIGNMENT) gcaligned;
1286 } u;
1287};
1288verify (alignof (struct Lisp_String) % GCALIGNMENT == 0);
1274 1289
1275INLINE bool 1290INLINE bool
1276STRINGP (Lisp_Object x) 1291STRINGP (Lisp_Object x)
@@ -1295,7 +1310,7 @@ XSTRING (Lisp_Object a)
1295INLINE bool 1310INLINE bool
1296STRING_MULTIBYTE (Lisp_Object str) 1311STRING_MULTIBYTE (Lisp_Object str)
1297{ 1312{
1298 return 0 <= XSTRING (str)->size_byte; 1313 return 0 <= XSTRING (str)->u.s.size_byte;
1299} 1314}
1300 1315
1301/* An upper bound on the number of bytes in a Lisp string, not 1316/* An upper bound on the number of bytes in a Lisp string, not
@@ -1317,20 +1332,20 @@ STRING_MULTIBYTE (Lisp_Object str)
1317/* Mark STR as a unibyte string. */ 1332/* Mark STR as a unibyte string. */
1318#define STRING_SET_UNIBYTE(STR) \ 1333#define STRING_SET_UNIBYTE(STR) \
1319 do { \ 1334 do { \
1320 if (XSTRING (STR)->size == 0) \ 1335 if (XSTRING (STR)->u.s.size == 0) \
1321 (STR) = empty_unibyte_string; \ 1336 (STR) = empty_unibyte_string; \
1322 else \ 1337 else \
1323 XSTRING (STR)->size_byte = -1; \ 1338 XSTRING (STR)->u.s.size_byte = -1; \
1324 } while (false) 1339 } while (false)
1325 1340
1326/* Mark STR as a multibyte string. Assure that STR contains only 1341/* Mark STR as a multibyte string. Assure that STR contains only
1327 ASCII characters in advance. */ 1342 ASCII characters in advance. */
1328#define STRING_SET_MULTIBYTE(STR) \ 1343#define STRING_SET_MULTIBYTE(STR) \
1329 do { \ 1344 do { \
1330 if (XSTRING (STR)->size == 0) \ 1345 if (XSTRING (STR)->u.s.size == 0) \
1331 (STR) = empty_multibyte_string; \ 1346 (STR) = empty_multibyte_string; \
1332 else \ 1347 else \
1333 XSTRING (STR)->size_byte = XSTRING (STR)->size; \ 1348 XSTRING (STR)->u.s.size_byte = XSTRING (STR)->u.s.size; \
1334 } while (false) 1349 } while (false)
1335 1350
1336/* Convenience functions for dealing with Lisp strings. */ 1351/* Convenience functions for dealing with Lisp strings. */
@@ -1338,7 +1353,7 @@ STRING_MULTIBYTE (Lisp_Object str)
1338INLINE unsigned char * 1353INLINE unsigned char *
1339SDATA (Lisp_Object string) 1354SDATA (Lisp_Object string)
1340{ 1355{
1341 return XSTRING (string)->data; 1356 return XSTRING (string)->u.s.data;
1342} 1357}
1343INLINE char * 1358INLINE char *
1344SSDATA (Lisp_Object string) 1359SSDATA (Lisp_Object string)
@@ -1359,7 +1374,7 @@ SSET (Lisp_Object string, ptrdiff_t index, unsigned char new)
1359INLINE ptrdiff_t 1374INLINE ptrdiff_t
1360SCHARS (Lisp_Object string) 1375SCHARS (Lisp_Object string)
1361{ 1376{
1362 ptrdiff_t nchars = XSTRING (string)->size; 1377 ptrdiff_t nchars = XSTRING (string)->u.s.size;
1363 eassume (0 <= nchars); 1378 eassume (0 <= nchars);
1364 return nchars; 1379 return nchars;
1365} 1380}
@@ -1373,7 +1388,7 @@ STRING_BYTES (struct Lisp_String *s)
1373#ifdef GC_CHECK_STRING_BYTES 1388#ifdef GC_CHECK_STRING_BYTES
1374 ptrdiff_t nbytes = string_bytes (s); 1389 ptrdiff_t nbytes = string_bytes (s);
1375#else 1390#else
1376 ptrdiff_t nbytes = s->size_byte < 0 ? s->size : s->size_byte; 1391 ptrdiff_t nbytes = s->u.s.size_byte < 0 ? s->u.s.size : s->u.s.size_byte;
1377#endif 1392#endif
1378 eassume (0 <= nbytes); 1393 eassume (0 <= nbytes);
1379 return nbytes; 1394 return nbytes;
@@ -1392,7 +1407,7 @@ STRING_SET_CHARS (Lisp_Object string, ptrdiff_t newsize)
1392 eassert (STRING_MULTIBYTE (string) 1407 eassert (STRING_MULTIBYTE (string)
1393 ? 0 <= newsize && newsize <= SBYTES (string) 1408 ? 0 <= newsize && newsize <= SBYTES (string)
1394 : newsize == SCHARS (string)); 1409 : newsize == SCHARS (string));
1395 XSTRING (string)->size = newsize; 1410 XSTRING (string)->u.s.size = newsize;
1396} 1411}
1397 1412
1398/* A regular vector is just a header plus an array of Lisp_Objects. */ 1413/* A regular vector is just a header plus an array of Lisp_Objects. */
@@ -1910,20 +1925,20 @@ INLINE Lisp_Object
1910INLINE struct Lisp_Symbol * 1925INLINE struct Lisp_Symbol *
1911SYMBOL_ALIAS (struct Lisp_Symbol *sym) 1926SYMBOL_ALIAS (struct Lisp_Symbol *sym)
1912{ 1927{
1913 eassume (sym->redirect == SYMBOL_VARALIAS && sym->val.alias); 1928 eassume (sym->u.s.redirect == SYMBOL_VARALIAS && sym->u.s.val.alias);
1914 return sym->val.alias; 1929 return sym->u.s.val.alias;
1915} 1930}
1916INLINE struct Lisp_Buffer_Local_Value * 1931INLINE struct Lisp_Buffer_Local_Value *
1917SYMBOL_BLV (struct Lisp_Symbol *sym) 1932SYMBOL_BLV (struct Lisp_Symbol *sym)
1918{ 1933{
1919 eassume (sym->redirect == SYMBOL_LOCALIZED && sym->val.blv); 1934 eassume (sym->u.s.redirect == SYMBOL_LOCALIZED && sym->u.s.val.blv);
1920 return sym->val.blv; 1935 return sym->u.s.val.blv;
1921} 1936}
1922INLINE union Lisp_Fwd * 1937INLINE union Lisp_Fwd *
1923SYMBOL_FWD (struct Lisp_Symbol *sym) 1938SYMBOL_FWD (struct Lisp_Symbol *sym)
1924{ 1939{
1925 eassume (sym->redirect == SYMBOL_FORWARDED && sym->val.fwd); 1940 eassume (sym->u.s.redirect == SYMBOL_FORWARDED && sym->u.s.val.fwd);
1926 return sym->val.fwd; 1941 return sym->u.s.val.fwd;
1927} 1942}
1928 1943
1929INLINE void 1944INLINE void
@@ -1935,26 +1950,26 @@ INLINE void
1935INLINE void 1950INLINE void
1936SET_SYMBOL_ALIAS (struct Lisp_Symbol *sym, struct Lisp_Symbol *v) 1951SET_SYMBOL_ALIAS (struct Lisp_Symbol *sym, struct Lisp_Symbol *v)
1937{ 1952{
1938 eassume (sym->redirect == SYMBOL_VARALIAS && v); 1953 eassume (sym->u.s.redirect == SYMBOL_VARALIAS && v);
1939 sym->val.alias = v; 1954 sym->u.s.val.alias = v;
1940} 1955}
1941INLINE void 1956INLINE void
1942SET_SYMBOL_BLV (struct Lisp_Symbol *sym, struct Lisp_Buffer_Local_Value *v) 1957SET_SYMBOL_BLV (struct Lisp_Symbol *sym, struct Lisp_Buffer_Local_Value *v)
1943{ 1958{
1944 eassume (sym->redirect == SYMBOL_LOCALIZED && v); 1959 eassume (sym->u.s.redirect == SYMBOL_LOCALIZED && v);
1945 sym->val.blv = v; 1960 sym->u.s.val.blv = v;
1946} 1961}
1947INLINE void 1962INLINE void
1948SET_SYMBOL_FWD (struct Lisp_Symbol *sym, union Lisp_Fwd *v) 1963SET_SYMBOL_FWD (struct Lisp_Symbol *sym, union Lisp_Fwd *v)
1949{ 1964{
1950 eassume (sym->redirect == SYMBOL_FORWARDED && v); 1965 eassume (sym->u.s.redirect == SYMBOL_FORWARDED && v);
1951 sym->val.fwd = v; 1966 sym->u.s.val.fwd = v;
1952} 1967}
1953 1968
1954INLINE Lisp_Object 1969INLINE Lisp_Object
1955SYMBOL_NAME (Lisp_Object sym) 1970SYMBOL_NAME (Lisp_Object sym)
1956{ 1971{
1957 return XSYMBOL (sym)->name; 1972 return XSYMBOL (sym)->u.s.name;
1958} 1973}
1959 1974
1960/* Value is true if SYM is an interned symbol. */ 1975/* Value is true if SYM is an interned symbol. */
@@ -1962,7 +1977,7 @@ SYMBOL_NAME (Lisp_Object sym)
1962INLINE bool 1977INLINE bool
1963SYMBOL_INTERNED_P (Lisp_Object sym) 1978SYMBOL_INTERNED_P (Lisp_Object sym)
1964{ 1979{
1965 return XSYMBOL (sym)->interned != SYMBOL_UNINTERNED; 1980 return XSYMBOL (sym)->u.s.interned != SYMBOL_UNINTERNED;
1966} 1981}
1967 1982
1968/* Value is true if SYM is interned in initial_obarray. */ 1983/* Value is true if SYM is interned in initial_obarray. */
@@ -1970,7 +1985,7 @@ SYMBOL_INTERNED_P (Lisp_Object sym)
1970INLINE bool 1985INLINE bool
1971SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (Lisp_Object sym) 1986SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (Lisp_Object sym)
1972{ 1987{
1973 return XSYMBOL (sym)->interned == SYMBOL_INTERNED_IN_INITIAL_OBARRAY; 1988 return XSYMBOL (sym)->u.s.interned == SYMBOL_INTERNED_IN_INITIAL_OBARRAY;
1974} 1989}
1975 1990
1976/* Value is non-zero if symbol cannot be changed through a simple set, 1991/* Value is non-zero if symbol cannot be changed through a simple set,
@@ -2948,7 +2963,7 @@ CHECK_NUMBER_CDR (Lisp_Object x)
2948#ifdef _MSC_VER 2963#ifdef _MSC_VER
2949#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ 2964#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \
2950 Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \ 2965 Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \
2951 static struct GCALIGNED Lisp_Subr sname = \ 2966 static struct Lisp_Subr sname = \
2952 { { (PVEC_SUBR << PSEUDOVECTOR_AREA_BITS) \ 2967 { { (PVEC_SUBR << PSEUDOVECTOR_AREA_BITS) \
2953 | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)) }, \ 2968 | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)) }, \
2954 { (Lisp_Object (__cdecl *)(void))fnname }, \ 2969 { (Lisp_Object (__cdecl *)(void))fnname }, \
@@ -2956,7 +2971,7 @@ CHECK_NUMBER_CDR (Lisp_Object x)
2956 Lisp_Object fnname 2971 Lisp_Object fnname
2957#else /* not _MSC_VER */ 2972#else /* not _MSC_VER */
2958#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ 2973#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \
2959 static struct GCALIGNED Lisp_Subr sname = \ 2974 static struct Lisp_Subr sname = \
2960 { { PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, \ 2975 { { PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, \
2961 { .a ## maxargs = fnname }, \ 2976 { .a ## maxargs = fnname }, \
2962 minargs, maxargs, lname, intspec, 0}; \ 2977 minargs, maxargs, lname, intspec, 0}; \
@@ -3224,25 +3239,25 @@ set_hash_value_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val)
3224INLINE void 3239INLINE void
3225set_symbol_function (Lisp_Object sym, Lisp_Object function) 3240set_symbol_function (Lisp_Object sym, Lisp_Object function)
3226{ 3241{
3227 XSYMBOL (sym)->function = function; 3242 XSYMBOL (sym)->u.s.function = function;
3228} 3243}
3229 3244
3230INLINE void 3245INLINE void
3231set_symbol_plist (Lisp_Object sym, Lisp_Object plist) 3246set_symbol_plist (Lisp_Object sym, Lisp_Object plist)
3232{ 3247{
3233 XSYMBOL (sym)->plist = plist; 3248 XSYMBOL (sym)->u.s.plist = plist;
3234} 3249}
3235 3250
3236INLINE void 3251INLINE void
3237set_symbol_next (Lisp_Object sym, struct Lisp_Symbol *next) 3252set_symbol_next (Lisp_Object sym, struct Lisp_Symbol *next)
3238{ 3253{
3239 XSYMBOL (sym)->next = next; 3254 XSYMBOL (sym)->u.s.next = next;
3240} 3255}
3241 3256
3242INLINE void 3257INLINE void
3243make_symbol_constant (Lisp_Object sym) 3258make_symbol_constant (Lisp_Object sym)
3244{ 3259{
3245 XSYMBOL (sym)->trapped_write = SYMBOL_NOWRITE; 3260 XSYMBOL (sym)->u.s.trapped_write = SYMBOL_NOWRITE;
3246} 3261}
3247 3262
3248/* Buffer-local variable access functions. */ 3263/* Buffer-local variable access functions. */
@@ -3267,7 +3282,7 @@ set_overlay_plist (Lisp_Object overlay, Lisp_Object plist)
3267INLINE INTERVAL 3282INLINE INTERVAL
3268string_intervals (Lisp_Object s) 3283string_intervals (Lisp_Object s)
3269{ 3284{
3270 return XSTRING (s)->intervals; 3285 return XSTRING (s)->u.s.intervals;
3271} 3286}
3272 3287
3273/* Set text properties of S to I. */ 3288/* Set text properties of S to I. */
@@ -3275,7 +3290,7 @@ string_intervals (Lisp_Object s)
3275INLINE void 3290INLINE void
3276set_string_intervals (Lisp_Object s, INTERVAL i) 3291set_string_intervals (Lisp_Object s, INTERVAL i)
3277{ 3292{
3278 XSTRING (s)->intervals = i; 3293 XSTRING (s)->u.s.intervals = i;
3279} 3294}
3280 3295
3281/* Set a Lisp slot in TABLE to VAL. Most code should use this instead 3296/* Set a Lisp slot in TABLE to VAL. Most code should use this instead
@@ -4600,20 +4615,6 @@ enum { defined_GC_CHECK_STRING_BYTES = true };
4600enum { defined_GC_CHECK_STRING_BYTES = false }; 4615enum { defined_GC_CHECK_STRING_BYTES = false };
4601#endif 4616#endif
4602 4617
4603/* Struct inside unions that are typically no larger and aligned enough. */
4604
4605union Aligned_Cons
4606{
4607 struct Lisp_Cons s;
4608 double d; intmax_t i; void *p;
4609};
4610
4611union Aligned_String
4612{
4613 struct Lisp_String s;
4614 double d; intmax_t i; void *p;
4615};
4616
4617/* True for stack-based cons and string implementations, respectively. 4618/* True for stack-based cons and string implementations, respectively.
4618 Use stack-based strings only if stack-based cons also works. 4619 Use stack-based strings only if stack-based cons also works.
4619 Otherwise, STACK_CONS would create heap-based cons cells that 4620 Otherwise, STACK_CONS would create heap-based cons cells that
@@ -4621,18 +4622,16 @@ union Aligned_String
4621 4622
4622enum 4623enum
4623 { 4624 {
4624 USE_STACK_CONS = (USE_STACK_LISP_OBJECTS 4625 USE_STACK_CONS = USE_STACK_LISP_OBJECTS,
4625 && alignof (union Aligned_Cons) % GCALIGNMENT == 0),
4626 USE_STACK_STRING = (USE_STACK_CONS 4626 USE_STACK_STRING = (USE_STACK_CONS
4627 && !defined_GC_CHECK_STRING_BYTES 4627 && !defined_GC_CHECK_STRING_BYTES)
4628 && alignof (union Aligned_String) % GCALIGNMENT == 0)
4629 }; 4628 };
4630 4629
4631/* Auxiliary macros used for auto allocation of Lisp objects. Please 4630/* Auxiliary macros used for auto allocation of Lisp objects. Please
4632 use these only in macros like AUTO_CONS that declare a local 4631 use these only in macros like AUTO_CONS that declare a local
4633 variable whose lifetime will be clear to the programmer. */ 4632 variable whose lifetime will be clear to the programmer. */
4634#define STACK_CONS(a, b) \ 4633#define STACK_CONS(a, b) \
4635 make_lisp_ptr (&((union Aligned_Cons) { { a, { b } } }).s, Lisp_Cons) 4634 make_lisp_ptr (&((struct Lisp_Cons) {{{a, {b}}}}), Lisp_Cons)
4636#define AUTO_CONS_EXPR(a, b) \ 4635#define AUTO_CONS_EXPR(a, b) \
4637 (USE_STACK_CONS ? STACK_CONS (a, b) : Fcons (a, b)) 4636 (USE_STACK_CONS ? STACK_CONS (a, b) : Fcons (a, b))
4638 4637
@@ -4678,7 +4677,7 @@ enum
4678 Lisp_Object name = \ 4677 Lisp_Object name = \
4679 (USE_STACK_STRING \ 4678 (USE_STACK_STRING \
4680 ? (make_lisp_ptr \ 4679 ? (make_lisp_ptr \
4681 ((&((union Aligned_String) {{len, -1, 0, (unsigned char *) (str)}}).s), \ 4680 ((&(struct Lisp_String) {{{len, -1, 0, (unsigned char *) (str)}}}), \
4682 Lisp_String)) \ 4681 Lisp_String)) \
4683 : make_unibyte_string (str, len)) 4682 : make_unibyte_string (str, len))
4684 4683
diff --git a/src/lread.c b/src/lread.c
index 33da8667228..b056f4aaf38 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -4043,14 +4043,14 @@ intern_sym (Lisp_Object sym, Lisp_Object obarray, Lisp_Object index)
4043{ 4043{
4044 Lisp_Object *ptr; 4044 Lisp_Object *ptr;
4045 4045
4046 XSYMBOL (sym)->interned = (EQ (obarray, initial_obarray) 4046 XSYMBOL (sym)->u.s.interned = (EQ (obarray, initial_obarray)
4047 ? SYMBOL_INTERNED_IN_INITIAL_OBARRAY 4047 ? SYMBOL_INTERNED_IN_INITIAL_OBARRAY
4048 : SYMBOL_INTERNED); 4048 : SYMBOL_INTERNED);
4049 4049
4050 if (SREF (SYMBOL_NAME (sym), 0) == ':' && EQ (obarray, initial_obarray)) 4050 if (SREF (SYMBOL_NAME (sym), 0) == ':' && EQ (obarray, initial_obarray))
4051 { 4051 {
4052 make_symbol_constant (sym); 4052 make_symbol_constant (sym);
4053 XSYMBOL (sym)->redirect = SYMBOL_PLAINVAL; 4053 XSYMBOL (sym)->u.s.redirect = SYMBOL_PLAINVAL;
4054 SET_SYMBOL_VAL (XSYMBOL (sym), sym); 4054 SET_SYMBOL_VAL (XSYMBOL (sym), sym);
4055 } 4055 }
4056 4056
@@ -4203,16 +4203,16 @@ usage: (unintern NAME OBARRAY) */)
4203 /* if (EQ (tem, Qnil) || EQ (tem, Qt)) 4203 /* if (EQ (tem, Qnil) || EQ (tem, Qt))
4204 error ("Attempt to unintern t or nil"); */ 4204 error ("Attempt to unintern t or nil"); */
4205 4205
4206 XSYMBOL (tem)->interned = SYMBOL_UNINTERNED; 4206 XSYMBOL (tem)->u.s.interned = SYMBOL_UNINTERNED;
4207 4207
4208 hash = oblookup_last_bucket_number; 4208 hash = oblookup_last_bucket_number;
4209 4209
4210 if (EQ (AREF (obarray, hash), tem)) 4210 if (EQ (AREF (obarray, hash), tem))
4211 { 4211 {
4212 if (XSYMBOL (tem)->next) 4212 if (XSYMBOL (tem)->u.s.next)
4213 { 4213 {
4214 Lisp_Object sym; 4214 Lisp_Object sym;
4215 XSETSYMBOL (sym, XSYMBOL (tem)->next); 4215 XSETSYMBOL (sym, XSYMBOL (tem)->u.s.next);
4216 ASET (obarray, hash, sym); 4216 ASET (obarray, hash, sym);
4217 } 4217 }
4218 else 4218 else
@@ -4223,13 +4223,13 @@ usage: (unintern NAME OBARRAY) */)
4223 Lisp_Object tail, following; 4223 Lisp_Object tail, following;
4224 4224
4225 for (tail = AREF (obarray, hash); 4225 for (tail = AREF (obarray, hash);
4226 XSYMBOL (tail)->next; 4226 XSYMBOL (tail)->u.s.next;
4227 tail = following) 4227 tail = following)
4228 { 4228 {
4229 XSETSYMBOL (following, XSYMBOL (tail)->next); 4229 XSETSYMBOL (following, XSYMBOL (tail)->u.s.next);
4230 if (EQ (following, tem)) 4230 if (EQ (following, tem))
4231 { 4231 {
4232 set_symbol_next (tail, XSYMBOL (following)->next); 4232 set_symbol_next (tail, XSYMBOL (following)->u.s.next);
4233 break; 4233 break;
4234 } 4234 }
4235 } 4235 }
@@ -4264,13 +4264,13 @@ oblookup (Lisp_Object obarray, register const char *ptr, ptrdiff_t size, ptrdiff
4264 else if (!SYMBOLP (bucket)) 4264 else if (!SYMBOLP (bucket))
4265 error ("Bad data in guts of obarray"); /* Like CADR error message. */ 4265 error ("Bad data in guts of obarray"); /* Like CADR error message. */
4266 else 4266 else
4267 for (tail = bucket; ; XSETSYMBOL (tail, XSYMBOL (tail)->next)) 4267 for (tail = bucket; ; XSETSYMBOL (tail, XSYMBOL (tail)->u.s.next))
4268 { 4268 {
4269 if (SBYTES (SYMBOL_NAME (tail)) == size_byte 4269 if (SBYTES (SYMBOL_NAME (tail)) == size_byte
4270 && SCHARS (SYMBOL_NAME (tail)) == size 4270 && SCHARS (SYMBOL_NAME (tail)) == size
4271 && !memcmp (SDATA (SYMBOL_NAME (tail)), ptr, size_byte)) 4271 && !memcmp (SDATA (SYMBOL_NAME (tail)), ptr, size_byte))
4272 return tail; 4272 return tail;
4273 else if (XSYMBOL (tail)->next == 0) 4273 else if (XSYMBOL (tail)->u.s.next == 0)
4274 break; 4274 break;
4275 } 4275 }
4276 XSETINT (tem, hash); 4276 XSETINT (tem, hash);
@@ -4290,9 +4290,9 @@ map_obarray (Lisp_Object obarray, void (*fn) (Lisp_Object, Lisp_Object), Lisp_Ob
4290 while (1) 4290 while (1)
4291 { 4291 {
4292 (*fn) (tail, arg); 4292 (*fn) (tail, arg);
4293 if (XSYMBOL (tail)->next == 0) 4293 if (XSYMBOL (tail)->u.s.next == 0)
4294 break; 4294 break;
4295 XSETSYMBOL (tail, XSYMBOL (tail)->next); 4295 XSETSYMBOL (tail, XSYMBOL (tail)->u.s.next);
4296 } 4296 }
4297 } 4297 }
4298} 4298}
@@ -4332,12 +4332,12 @@ init_obarray (void)
4332 DEFSYM (Qnil, "nil"); 4332 DEFSYM (Qnil, "nil");
4333 SET_SYMBOL_VAL (XSYMBOL (Qnil), Qnil); 4333 SET_SYMBOL_VAL (XSYMBOL (Qnil), Qnil);
4334 make_symbol_constant (Qnil); 4334 make_symbol_constant (Qnil);
4335 XSYMBOL (Qnil)->declared_special = true; 4335 XSYMBOL (Qnil)->u.s.declared_special = true;
4336 4336
4337 DEFSYM (Qt, "t"); 4337 DEFSYM (Qt, "t");
4338 SET_SYMBOL_VAL (XSYMBOL (Qt), Qt); 4338 SET_SYMBOL_VAL (XSYMBOL (Qt), Qt);
4339 make_symbol_constant (Qt); 4339 make_symbol_constant (Qt);
4340 XSYMBOL (Qt)->declared_special = true; 4340 XSYMBOL (Qt)->u.s.declared_special = true;
4341 4341
4342 /* Qt is correct even if CANNOT_DUMP. loadup.el will set to nil at end. */ 4342 /* Qt is correct even if CANNOT_DUMP. loadup.el will set to nil at end. */
4343 Vpurify_flag = Qt; 4343 Vpurify_flag = Qt;
@@ -4361,7 +4361,7 @@ defalias (struct Lisp_Subr *sname, char *string)
4361{ 4361{
4362 Lisp_Object sym; 4362 Lisp_Object sym;
4363 sym = intern (string); 4363 sym = intern (string);
4364 XSETSUBR (XSYMBOL (sym)->function, sname); 4364 XSETSUBR (XSYMBOL (sym)->u.s.function, sname);
4365} 4365}
4366#endif /* NOTDEF */ 4366#endif /* NOTDEF */
4367 4367
@@ -4376,8 +4376,8 @@ defvar_int (struct Lisp_Intfwd *i_fwd,
4376 sym = intern_c_string (namestring); 4376 sym = intern_c_string (namestring);
4377 i_fwd->type = Lisp_Fwd_Int; 4377 i_fwd->type = Lisp_Fwd_Int;
4378 i_fwd->intvar = address; 4378 i_fwd->intvar = address;
4379 XSYMBOL (sym)->declared_special = 1; 4379 XSYMBOL (sym)->u.s.declared_special = true;
4380 XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; 4380 XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED;
4381 SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)i_fwd); 4381 SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)i_fwd);
4382} 4382}
4383 4383
@@ -4391,8 +4391,8 @@ defvar_bool (struct Lisp_Boolfwd *b_fwd,
4391 sym = intern_c_string (namestring); 4391 sym = intern_c_string (namestring);
4392 b_fwd->type = Lisp_Fwd_Bool; 4392 b_fwd->type = Lisp_Fwd_Bool;
4393 b_fwd->boolvar = address; 4393 b_fwd->boolvar = address;
4394 XSYMBOL (sym)->declared_special = 1; 4394 XSYMBOL (sym)->u.s.declared_special = true;
4395 XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; 4395 XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED;
4396 SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)b_fwd); 4396 SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)b_fwd);
4397 Vbyte_boolean_vars = Fcons (sym, Vbyte_boolean_vars); 4397 Vbyte_boolean_vars = Fcons (sym, Vbyte_boolean_vars);
4398} 4398}
@@ -4410,8 +4410,8 @@ defvar_lisp_nopro (struct Lisp_Objfwd *o_fwd,
4410 sym = intern_c_string (namestring); 4410 sym = intern_c_string (namestring);
4411 o_fwd->type = Lisp_Fwd_Obj; 4411 o_fwd->type = Lisp_Fwd_Obj;
4412 o_fwd->objvar = address; 4412 o_fwd->objvar = address;
4413 XSYMBOL (sym)->declared_special = 1; 4413 XSYMBOL (sym)->u.s.declared_special = true;
4414 XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; 4414 XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED;
4415 SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)o_fwd); 4415 SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)o_fwd);
4416} 4416}
4417 4417
@@ -4434,8 +4434,8 @@ defvar_kboard (struct Lisp_Kboard_Objfwd *ko_fwd,
4434 sym = intern_c_string (namestring); 4434 sym = intern_c_string (namestring);
4435 ko_fwd->type = Lisp_Fwd_Kboard_Obj; 4435 ko_fwd->type = Lisp_Fwd_Kboard_Obj;
4436 ko_fwd->offset = offset; 4436 ko_fwd->offset = offset;
4437 XSYMBOL (sym)->declared_special = 1; 4437 XSYMBOL (sym)->u.s.declared_special = true;
4438 XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; 4438 XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED;
4439 SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)ko_fwd); 4439 SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)ko_fwd);
4440} 4440}
4441 4441
@@ -4769,7 +4769,7 @@ to find all the symbols in an obarray, use `mapatoms'. */);
4769 DEFVAR_LISP ("values", Vvalues, 4769 DEFVAR_LISP ("values", Vvalues,
4770 doc: /* List of values of all expressions which were read, evaluated and printed. 4770 doc: /* List of values of all expressions which were read, evaluated and printed.
4771Order is reverse chronological. */); 4771Order is reverse chronological. */);
4772 XSYMBOL (intern ("values"))->declared_special = 0; 4772 XSYMBOL (intern ("values"))->u.s.declared_special = true;
4773 4773
4774 DEFVAR_LISP ("standard-input", Vstandard_input, 4774 DEFVAR_LISP ("standard-input", Vstandard_input,
4775 doc: /* Stream for read to get input from. 4775 doc: /* Stream for read to get input from.
diff --git a/src/minibuf.c b/src/minibuf.c
index a2f3324f99f..913c93001ef 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -1280,8 +1280,8 @@ is used to further constrain the set of candidates. */)
1280 error ("Bad data in guts of obarray"); 1280 error ("Bad data in guts of obarray");
1281 elt = bucket; 1281 elt = bucket;
1282 eltstring = elt; 1282 eltstring = elt;
1283 if (XSYMBOL (bucket)->next) 1283 if (XSYMBOL (bucket)->u.s.next)
1284 XSETSYMBOL (bucket, XSYMBOL (bucket)->next); 1284 XSETSYMBOL (bucket, XSYMBOL (bucket)->u.s.next);
1285 else 1285 else
1286 XSETFASTINT (bucket, 0); 1286 XSETFASTINT (bucket, 0);
1287 } 1287 }
@@ -1533,8 +1533,8 @@ with a space are ignored unless STRING itself starts with a space. */)
1533 error ("Bad data in guts of obarray"); 1533 error ("Bad data in guts of obarray");
1534 elt = bucket; 1534 elt = bucket;
1535 eltstring = elt; 1535 eltstring = elt;
1536 if (XSYMBOL (bucket)->next) 1536 if (XSYMBOL (bucket)->u.s.next)
1537 XSETSYMBOL (bucket, XSYMBOL (bucket)->next); 1537 XSETSYMBOL (bucket, XSYMBOL (bucket)->u.s.next);
1538 else 1538 else
1539 XSETFASTINT (bucket, 0); 1539 XSETFASTINT (bucket, 0);
1540 } 1540 }
@@ -1754,9 +1754,9 @@ the values STRING, PREDICATE and `lambda'. */)
1754 tem = tail; 1754 tem = tail;
1755 break; 1755 break;
1756 } 1756 }
1757 if (XSYMBOL (tail)->next == 0) 1757 if (XSYMBOL (tail)->u.s.next == 0)
1758 break; 1758 break;
1759 XSETSYMBOL (tail, XSYMBOL (tail)->next); 1759 XSETSYMBOL (tail, XSYMBOL (tail)->u.s.next);
1760 } 1760 }
1761 } 1761 }
1762 } 1762 }
diff --git a/src/thread.c b/src/thread.c
index 7335833cf94..c03cdda0fae 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -26,7 +26,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
26#include "coding.h" 26#include "coding.h"
27#include "syssignal.h" 27#include "syssignal.h"
28 28
29static struct GCALIGNED thread_state main_thread; 29static struct thread_state main_thread;
30 30
31struct thread_state *current_thread = &main_thread; 31struct thread_state *current_thread = &main_thread;
32 32
diff --git a/src/xterm.c b/src/xterm.c
index 5e2fc6d20a8..28abfaecde9 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -12515,7 +12515,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
12515 { 12515 {
12516 terminal->kboard = allocate_kboard (Qx); 12516 terminal->kboard = allocate_kboard (Qx);
12517 12517
12518 if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->function, Qunbound)) 12518 if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->u.s.function, Qunbound))
12519 { 12519 {
12520 char *vendor = ServerVendor (dpy); 12520 char *vendor = ServerVendor (dpy);
12521 12521