aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2017-11-13 10:54:20 -0800
committerPaul Eggert2017-11-13 10:54:20 -0800
commit99ceefa8ec4f9993663492cfcce6bb82a94569c1 (patch)
tree507f76715b3086f34672b7c984dc09befaa57fc6 /src
parenta7b7b85567f766ff510a5eaaaf32dbbbec15efd0 (diff)
parent79108894dbcd642121466bb6af6c98c6a56e9233 (diff)
downloademacs-99ceefa8ec4f9993663492cfcce6bb82a94569c1.tar.gz
emacs-99ceefa8ec4f9993663492cfcce6bb82a94569c1.zip
Merge from origin/emacs-26
79108894db Port to IBM xlc 12.01 d14956099d Simplify by removing HAVE_STRUCT_ATTRIBUTE_ALIGNED b1573a97e1 Use alignas to fix GCALIGN-related bugs 5d68dc9a2f Change vectorlike from struct to union 6aa0a26b46 Don't enable cursor-sensor-mode in mhtml-mode 2b8ef8dddf * lisp/files.el (abbreviate-file-name): Doc fix. (Bug#29267) fe85ce1e16 Unbreak interactive run of a flymake test (bug#29267) 48ad00390d Fix Bug#29225 42daf83f08 CC Mode: Fix defun-open being recognized as brace-list-ope... 7775c47298 Merge from Gnulib e470d16448 Pacify GCC when configured --with-x-toolkit=no 49450d0951 * lisp/find-dired.el (find-grep-dired): Doc fix. (Bug#29262) e286b3381f Fix more flymake-diag-region eob corner cases and add test... # Conflicts: # src/lisp.h
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c234
-rw-r--r--src/buffer.c19
-rw-r--r--src/buffer.h2
-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/emacs-module.c17
-rw-r--r--src/eval.c59
-rw-r--r--src/fileio.c3
-rw-r--r--src/fns.c4
-rw-r--r--src/font.h6
-rw-r--r--src/frame.h2
-rw-r--r--src/keyboard.c10
-rw-r--r--src/lisp.h303
-rw-r--r--src/lread.c52
-rw-r--r--src/minibuf.c12
-rw-r--r--src/process.h2
-rw-r--r--src/termhooks.h2
-rw-r--r--src/thread.c2
-rw-r--r--src/thread.h6
-rw-r--r--src/w32term.h2
-rw-r--r--src/window.c8
-rw-r--r--src/window.h2
-rw-r--r--src/xterm.c7
-rw-r--r--src/xterm.h2
-rw-r--r--src/xwidget.h4
28 files changed, 414 insertions, 438 deletions
diff --git a/src/alloc.c b/src/alloc.c
index ae892e49d7d..15a3d34d40f 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. */
@@ -2546,7 +2547,7 @@ make_uninit_multibyte_string (EMACS_INT nchars, EMACS_INT nbytes)
2546 return empty_multibyte_string; 2547 return empty_multibyte_string;
2547 2548
2548 s = allocate_string (); 2549 s = allocate_string ();
2549 s->intervals = NULL; 2550 s->u.s.intervals = NULL;
2550 allocate_string_data (s, nchars, nbytes); 2551 allocate_string_data (s, nchars, nbytes);
2551 XSETSTRING (string, s); 2552 XSETSTRING (string, s);
2552 string_chars_consed += nbytes; 2553 string_chars_consed += nbytes;
@@ -2731,8 +2732,8 @@ static struct Lisp_Cons *cons_free_list;
2731void 2732void
2732free_cons (struct Lisp_Cons *ptr) 2733free_cons (struct Lisp_Cons *ptr)
2733{ 2734{
2734 ptr->u.chain = cons_free_list; 2735 ptr->u.s.u.chain = cons_free_list;
2735 ptr->car = Vdead; 2736 ptr->u.s.car = Vdead;
2736 cons_free_list = ptr; 2737 cons_free_list = ptr;
2737 consing_since_gc -= sizeof *ptr; 2738 consing_since_gc -= sizeof *ptr;
2738 total_free_conses++; 2739 total_free_conses++;
@@ -2751,7 +2752,7 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0,
2751 /* We use the cdr for chaining the free list 2752 /* We use the cdr for chaining the free list
2752 so that we won't use the same field that has the mark bit. */ 2753 so that we won't use the same field that has the mark bit. */
2753 XSETCONS (val, cons_free_list); 2754 XSETCONS (val, cons_free_list);
2754 cons_free_list = cons_free_list->u.chain; 2755 cons_free_list = cons_free_list->u.s.u.chain;
2755 } 2756 }
2756 else 2757 else
2757 { 2758 {
@@ -2788,7 +2789,7 @@ check_cons_list (void)
2788 struct Lisp_Cons *tail = cons_free_list; 2789 struct Lisp_Cons *tail = cons_free_list;
2789 2790
2790 while (tail) 2791 while (tail)
2791 tail = tail->u.chain; 2792 tail = tail->u.s.u.chain;
2792} 2793}
2793#endif 2794#endif
2794 2795
@@ -2923,19 +2924,16 @@ set_next_vector (struct Lisp_Vector *v, struct Lisp_Vector *p)
2923 2924
2924#define VECTOR_BLOCK_SIZE 4096 2925#define VECTOR_BLOCK_SIZE 4096
2925 2926
2926enum 2927/* Alignment of struct Lisp_Vector objects. Because pseudovectors
2927 { 2928 can contain any C type, align at least as strictly as
2928 /* Alignment of struct Lisp_Vector objects. Because pseudovectors 2929 max_align_t. On x86 and x86-64 this can waste up to 8 bytes
2929 can contain any C type, align at least as strictly as 2930 for typical vectors, since alignof (max_align_t) is 16 but
2930 max_align_t. On x86 and x86-64 this can waste up to 8 bytes 2931 typical vectors need only an alignment of 8. However, it is
2931 for typical vectors, since alignof (max_align_t) is 16 but 2932 not worth the hassle to avoid wasting those bytes. */
2932 typical vectors need only an alignment of 8. However, it is 2933enum {vector_alignment = COMMON_MULTIPLE (alignof (max_align_t), GCALIGNMENT)};
2933 not worth the hassle to avoid wasting those bytes. */ 2934
2934 vector_alignment = COMMON_MULTIPLE (alignof (max_align_t), GCALIGNMENT), 2935/* Vector size requests are a multiple of this. */
2935 2936enum { roundup_size = COMMON_MULTIPLE (vector_alignment, word_size) };
2936 /* Vector size requests are a multiple of this. */
2937 roundup_size = COMMON_MULTIPLE (vector_alignment, word_size)
2938 };
2939 2937
2940/* Verify assumptions described above. */ 2938/* Verify assumptions described above. */
2941verify (VECTOR_BLOCK_SIZE % roundup_size == 0); 2939verify (VECTOR_BLOCK_SIZE % roundup_size == 0);
@@ -3545,27 +3543,17 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT
3545 Symbol Allocation 3543 Symbol Allocation
3546 ***********************************************************************/ 3544 ***********************************************************************/
3547 3545
3548/* Like struct Lisp_Symbol, but padded so that the size is a multiple
3549 of the required alignment. */
3550
3551union aligned_Lisp_Symbol
3552{
3553 struct Lisp_Symbol s;
3554 unsigned char c[(sizeof (struct Lisp_Symbol) + GCALIGNMENT - 1)
3555 & -GCALIGNMENT];
3556};
3557
3558/* Each symbol_block is just under 1020 bytes long, since malloc 3546/* Each symbol_block is just under 1020 bytes long, since malloc
3559 really allocates in units of powers of two and uses 4 bytes for its 3547 really allocates in units of powers of two and uses 4 bytes for its
3560 own overhead. */ 3548 own overhead. */
3561 3549
3562#define SYMBOL_BLOCK_SIZE \ 3550#define SYMBOL_BLOCK_SIZE \
3563 ((1020 - sizeof (struct symbol_block *)) / sizeof (union aligned_Lisp_Symbol)) 3551 ((1020 - sizeof (struct symbol_block *)) / sizeof (struct Lisp_Symbol))
3564 3552
3565struct symbol_block 3553struct symbol_block
3566{ 3554{
3567 /* Place `symbols' first, to preserve alignment. */ 3555 /* Place `symbols' first, to preserve alignment. */
3568 union aligned_Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE]; 3556 struct Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE];
3569 struct symbol_block *next; 3557 struct symbol_block *next;
3570}; 3558};
3571 3559
@@ -3589,7 +3577,7 @@ static struct Lisp_Symbol *symbol_free_list;
3589static void 3577static void
3590set_symbol_name (Lisp_Object sym, Lisp_Object name) 3578set_symbol_name (Lisp_Object sym, Lisp_Object name)
3591{ 3579{
3592 XSYMBOL (sym)->name = name; 3580 XSYMBOL (sym)->u.s.name = name;
3593} 3581}
3594 3582
3595void 3583void
@@ -3598,15 +3586,15 @@ init_symbol (Lisp_Object val, Lisp_Object name)
3598 struct Lisp_Symbol *p = XSYMBOL (val); 3586 struct Lisp_Symbol *p = XSYMBOL (val);
3599 set_symbol_name (val, name); 3587 set_symbol_name (val, name);
3600 set_symbol_plist (val, Qnil); 3588 set_symbol_plist (val, Qnil);
3601 p->redirect = SYMBOL_PLAINVAL; 3589 p->u.s.redirect = SYMBOL_PLAINVAL;
3602 SET_SYMBOL_VAL (p, Qunbound); 3590 SET_SYMBOL_VAL (p, Qunbound);
3603 set_symbol_function (val, Qnil); 3591 set_symbol_function (val, Qnil);
3604 set_symbol_next (val, NULL); 3592 set_symbol_next (val, NULL);
3605 p->gcmarkbit = false; 3593 p->u.s.gcmarkbit = false;
3606 p->interned = SYMBOL_UNINTERNED; 3594 p->u.s.interned = SYMBOL_UNINTERNED;
3607 p->trapped_write = SYMBOL_UNTRAPPED_WRITE; 3595 p->u.s.trapped_write = SYMBOL_UNTRAPPED_WRITE;
3608 p->declared_special = false; 3596 p->u.s.declared_special = false;
3609 p->pinned = false; 3597 p->u.s.pinned = false;
3610} 3598}
3611 3599
3612DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0, 3600DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0,
@@ -3623,7 +3611,7 @@ Its value is void, and its function definition and property list are nil. */)
3623 if (symbol_free_list) 3611 if (symbol_free_list)
3624 { 3612 {
3625 XSETSYMBOL (val, symbol_free_list); 3613 XSETSYMBOL (val, symbol_free_list);
3626 symbol_free_list = symbol_free_list->next; 3614 symbol_free_list = symbol_free_list->u.s.next;
3627 } 3615 }
3628 else 3616 else
3629 { 3617 {
@@ -3636,7 +3624,7 @@ Its value is void, and its function definition and property list are nil. */)
3636 symbol_block_index = 0; 3624 symbol_block_index = 0;
3637 total_free_symbols += SYMBOL_BLOCK_SIZE; 3625 total_free_symbols += SYMBOL_BLOCK_SIZE;
3638 } 3626 }
3639 XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index].s); 3627 XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index]);
3640 symbol_block_index++; 3628 symbol_block_index++;
3641 } 3629 }
3642 3630
@@ -4589,7 +4577,7 @@ live_string_holding (struct mem_node *m, void *p)
4589 if (0 <= offset && offset < STRING_BLOCK_SIZE * sizeof b->strings[0]) 4577 if (0 <= offset && offset < STRING_BLOCK_SIZE * sizeof b->strings[0])
4590 { 4578 {
4591 struct Lisp_String *s = p = cp -= offset % sizeof b->strings[0]; 4579 struct Lisp_String *s = p = cp -= offset % sizeof b->strings[0];
4592 if (s->data) 4580 if (s->u.s.data)
4593 return make_lisp_ptr (s, Lisp_String); 4581 return make_lisp_ptr (s, Lisp_String);
4594 } 4582 }
4595 } 4583 }
@@ -4623,7 +4611,7 @@ live_cons_holding (struct mem_node *m, void *p)
4623 || offset / sizeof b->conses[0] < cons_block_index)) 4611 || offset / sizeof b->conses[0] < cons_block_index))
4624 { 4612 {
4625 struct Lisp_Cons *s = p = cp -= offset % sizeof b->conses[0]; 4613 struct Lisp_Cons *s = p = cp -= offset % sizeof b->conses[0];
4626 if (!EQ (s->car, Vdead)) 4614 if (!EQ (s->u.s.car, Vdead))
4627 return make_lisp_ptr (s, Lisp_Cons); 4615 return make_lisp_ptr (s, Lisp_Cons);
4628 } 4616 }
4629 } 4617 }
@@ -4658,7 +4646,7 @@ live_symbol_holding (struct mem_node *m, void *p)
4658 || offset / sizeof b->symbols[0] < symbol_block_index)) 4646 || offset / sizeof b->symbols[0] < symbol_block_index))
4659 { 4647 {
4660 struct Lisp_Symbol *s = p = cp -= offset % sizeof b->symbols[0]; 4648 struct Lisp_Symbol *s = p = cp -= offset % sizeof b->symbols[0];
4661 if (!EQ (s->function, Vdead)) 4649 if (!EQ (s->u.s.function, Vdead))
4662 return make_lisp_symbol (s); 4650 return make_lisp_symbol (s);
4663 } 4651 }
4664 } 4652 }
@@ -4986,7 +4974,7 @@ mark_memory (void *start, void *end)
4986 Lisp_Object obj = build_string ("test"); 4974 Lisp_Object obj = build_string ("test");
4987 struct Lisp_String *s = XSTRING (obj); 4975 struct Lisp_String *s = XSTRING (obj);
4988 Fgarbage_collect (); 4976 Fgarbage_collect ();
4989 fprintf (stderr, "test '%s'\n", s->data); 4977 fprintf (stderr, "test '%s'\n", s->u.s.data);
4990 return Qnil; 4978 return Qnil;
4991 } 4979 }
4992 4980
@@ -5486,16 +5474,16 @@ make_pure_string (const char *data,
5486{ 5474{
5487 Lisp_Object string; 5475 Lisp_Object string;
5488 struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String); 5476 struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String);
5489 s->data = (unsigned char *) find_string_data_in_pure (data, nbytes); 5477 s->u.s.data = (unsigned char *) find_string_data_in_pure (data, nbytes);
5490 if (s->data == NULL) 5478 if (s->u.s.data == NULL)
5491 { 5479 {
5492 s->data = pure_alloc (nbytes + 1, -1); 5480 s->u.s.data = pure_alloc (nbytes + 1, -1);
5493 memcpy (s->data, data, nbytes); 5481 memcpy (s->u.s.data, data, nbytes);
5494 s->data[nbytes] = '\0'; 5482 s->u.s.data[nbytes] = '\0';
5495 } 5483 }
5496 s->size = nchars; 5484 s->u.s.size = nchars;
5497 s->size_byte = multibyte ? nbytes : -1; 5485 s->u.s.size_byte = multibyte ? nbytes : -1;
5498 s->intervals = NULL; 5486 s->u.s.intervals = NULL;
5499 XSETSTRING (string, s); 5487 XSETSTRING (string, s);
5500 return string; 5488 return string;
5501} 5489}
@@ -5508,10 +5496,10 @@ make_pure_c_string (const char *data, ptrdiff_t nchars)
5508{ 5496{
5509 Lisp_Object string; 5497 Lisp_Object string;
5510 struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String); 5498 struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String);
5511 s->size = nchars; 5499 s->u.s.size = nchars;
5512 s->size_byte = -1; 5500 s->u.s.size_byte = -1;
5513 s->data = (unsigned char *) data; 5501 s->u.s.data = (unsigned char *) data;
5514 s->intervals = NULL; 5502 s->u.s.intervals = NULL;
5515 XSETSTRING (string, s); 5503 XSETSTRING (string, s);
5516 return string; 5504 return string;
5517} 5505}
@@ -5622,7 +5610,7 @@ purecopy (Lisp_Object obj)
5622 || SUBRP (obj)) 5610 || SUBRP (obj))
5623 return obj; /* Already pure. */ 5611 return obj; /* Already pure. */
5624 5612
5625 if (STRINGP (obj) && XSTRING (obj)->intervals) 5613 if (STRINGP (obj) && XSTRING (obj)->u.s.intervals)
5626 message_with_string ("Dropping text-properties while making string `%s' pure", 5614 message_with_string ("Dropping text-properties while making string `%s' pure",
5627 obj, true); 5615 obj, true);
5628 5616
@@ -5677,10 +5665,10 @@ purecopy (Lisp_Object obj)
5677 } 5665 }
5678 else if (SYMBOLP (obj)) 5666 else if (SYMBOLP (obj))
5679 { 5667 {
5680 if (!XSYMBOL (obj)->pinned && !c_symbol_p (XSYMBOL (obj))) 5668 if (!XSYMBOL (obj)->u.s.pinned && !c_symbol_p (XSYMBOL (obj)))
5681 { /* We can't purify them, but they appear in many pure objects. 5669 { /* We can't purify them, but they appear in many pure objects.
5682 Mark them as `pinned' so we know to mark them at every GC cycle. */ 5670 Mark them as `pinned' so we know to mark them at every GC cycle. */
5683 XSYMBOL (obj)->pinned = true; 5671 XSYMBOL (obj)->u.s.pinned = true;
5684 symbol_block_pinned = symbol_block; 5672 symbol_block_pinned = symbol_block;
5685 } 5673 }
5686 /* Don't hash-cons it. */ 5674 /* Don't hash-cons it. */
@@ -5893,10 +5881,10 @@ mark_pinned_symbols (void)
5893 5881
5894 for (sblk = symbol_block_pinned; sblk; sblk = sblk->next) 5882 for (sblk = symbol_block_pinned; sblk; sblk = sblk->next)
5895 { 5883 {
5896 union aligned_Lisp_Symbol *sym = sblk->symbols, *end = sym + lim; 5884 struct Lisp_Symbol *sym = sblk->symbols, *end = sym + lim;
5897 for (; sym < end; ++sym) 5885 for (; sym < end; ++sym)
5898 if (sym->s.pinned) 5886 if (sym->u.s.pinned)
5899 mark_object (make_lisp_symbol (&sym->s)); 5887 mark_object (make_lisp_symbol (sym));
5900 5888
5901 lim = SYMBOL_BLOCK_SIZE; 5889 lim = SYMBOL_BLOCK_SIZE;
5902 } 5890 }
@@ -6258,7 +6246,7 @@ mark_char_table (struct Lisp_Vector *ptr, enum pvec_type pvectype)
6258 { 6246 {
6259 Lisp_Object val = ptr->contents[i]; 6247 Lisp_Object val = ptr->contents[i];
6260 6248
6261 if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->gcmarkbit)) 6249 if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->u.s.gcmarkbit))
6262 continue; 6250 continue;
6263 if (SUB_CHAR_TABLE_P (val)) 6251 if (SUB_CHAR_TABLE_P (val))
6264 { 6252 {
@@ -6501,7 +6489,7 @@ mark_object (Lisp_Object arg)
6501 break; 6489 break;
6502 CHECK_ALLOCATED_AND_LIVE (live_string_p); 6490 CHECK_ALLOCATED_AND_LIVE (live_string_p);
6503 MARK_STRING (ptr); 6491 MARK_STRING (ptr);
6504 MARK_INTERVAL_TREE (ptr->intervals); 6492 MARK_INTERVAL_TREE (ptr->u.s.intervals);
6505#ifdef GC_CHECK_STRING_BYTES 6493#ifdef GC_CHECK_STRING_BYTES
6506 /* Check that the string size recorded in the string is the 6494 /* Check that the string size recorded in the string is the
6507 same as the one recorded in the sdata structure. */ 6495 same as the one recorded in the sdata structure. */
@@ -6642,17 +6630,17 @@ mark_object (Lisp_Object arg)
6642 6630
6643 case Lisp_Symbol: 6631 case Lisp_Symbol:
6644 { 6632 {
6645 register struct Lisp_Symbol *ptr = XSYMBOL (obj); 6633 struct Lisp_Symbol *ptr = XSYMBOL (obj);
6646 nextsym: 6634 nextsym:
6647 if (ptr->gcmarkbit) 6635 if (ptr->u.s.gcmarkbit)
6648 break; 6636 break;
6649 CHECK_ALLOCATED_AND_LIVE_SYMBOL (); 6637 CHECK_ALLOCATED_AND_LIVE_SYMBOL ();
6650 ptr->gcmarkbit = 1; 6638 ptr->u.s.gcmarkbit = 1;
6651 /* Attempt to catch bogus objects. */ 6639 /* Attempt to catch bogus objects. */
6652 eassert (valid_lisp_object_p (ptr->function)); 6640 eassert (valid_lisp_object_p (ptr->u.s.function));
6653 mark_object (ptr->function); 6641 mark_object (ptr->u.s.function);
6654 mark_object (ptr->plist); 6642 mark_object (ptr->u.s.plist);
6655 switch (ptr->redirect) 6643 switch (ptr->u.s.redirect)
6656 { 6644 {
6657 case SYMBOL_PLAINVAL: mark_object (SYMBOL_VAL (ptr)); break; 6645 case SYMBOL_PLAINVAL: mark_object (SYMBOL_VAL (ptr)); break;
6658 case SYMBOL_VARALIAS: 6646 case SYMBOL_VARALIAS:
@@ -6673,11 +6661,11 @@ mark_object (Lisp_Object arg)
6673 break; 6661 break;
6674 default: emacs_abort (); 6662 default: emacs_abort ();
6675 } 6663 }
6676 if (!PURE_P (XSTRING (ptr->name))) 6664 if (!PURE_P (XSTRING (ptr->u.s.name)))
6677 MARK_STRING (XSTRING (ptr->name)); 6665 MARK_STRING (XSTRING (ptr->u.s.name));
6678 MARK_INTERVAL_TREE (string_intervals (ptr->name)); 6666 MARK_INTERVAL_TREE (string_intervals (ptr->u.s.name));
6679 /* Inner loop to mark next symbol in this bucket, if any. */ 6667 /* Inner loop to mark next symbol in this bucket, if any. */
6680 po = ptr = ptr->next; 6668 po = ptr = ptr->u.s.next;
6681 if (ptr) 6669 if (ptr)
6682 goto nextsym; 6670 goto nextsym;
6683 } 6671 }
@@ -6731,14 +6719,14 @@ mark_object (Lisp_Object arg)
6731 CHECK_ALLOCATED_AND_LIVE (live_cons_p); 6719 CHECK_ALLOCATED_AND_LIVE (live_cons_p);
6732 CONS_MARK (ptr); 6720 CONS_MARK (ptr);
6733 /* If the cdr is nil, avoid recursion for the car. */ 6721 /* If the cdr is nil, avoid recursion for the car. */
6734 if (EQ (ptr->u.cdr, Qnil)) 6722 if (EQ (ptr->u.s.u.cdr, Qnil))
6735 { 6723 {
6736 obj = ptr->car; 6724 obj = ptr->u.s.car;
6737 cdr_count = 0; 6725 cdr_count = 0;
6738 goto loop; 6726 goto loop;
6739 } 6727 }
6740 mark_object (ptr->car); 6728 mark_object (ptr->u.s.car);
6741 obj = ptr->u.cdr; 6729 obj = ptr->u.s.u.cdr;
6742 cdr_count++; 6730 cdr_count++;
6743 if (cdr_count == mark_object_loop_halt) 6731 if (cdr_count == mark_object_loop_halt)
6744 emacs_abort (); 6732 emacs_abort ();
@@ -6799,7 +6787,7 @@ survives_gc_p (Lisp_Object obj)
6799 break; 6787 break;
6800 6788
6801 case Lisp_Symbol: 6789 case Lisp_Symbol:
6802 survives_p = XSYMBOL (obj)->gcmarkbit; 6790 survives_p = XSYMBOL (obj)->u.s.gcmarkbit;
6803 break; 6791 break;
6804 6792
6805 case Lisp_Misc: 6793 case Lisp_Misc:
@@ -6875,9 +6863,9 @@ sweep_conses (void)
6875 if (!CONS_MARKED_P (&cblk->conses[pos])) 6863 if (!CONS_MARKED_P (&cblk->conses[pos]))
6876 { 6864 {
6877 this_free++; 6865 this_free++;
6878 cblk->conses[pos].u.chain = cons_free_list; 6866 cblk->conses[pos].u.s.u.chain = cons_free_list;
6879 cons_free_list = &cblk->conses[pos]; 6867 cons_free_list = &cblk->conses[pos];
6880 cons_free_list->car = Vdead; 6868 cons_free_list->u.s.car = Vdead;
6881 } 6869 }
6882 else 6870 else
6883 { 6871 {
@@ -6896,7 +6884,7 @@ sweep_conses (void)
6896 { 6884 {
6897 *cprev = cblk->next; 6885 *cprev = cblk->next;
6898 /* Unhook from the free list. */ 6886 /* Unhook from the free list. */
6899 cons_free_list = cblk->conses[0].u.chain; 6887 cons_free_list = cblk->conses[0].u.s.u.chain;
6900 lisp_align_free (cblk); 6888 lisp_align_free (cblk);
6901 } 6889 }
6902 else 6890 else
@@ -7020,39 +7008,39 @@ sweep_symbols (void)
7020 symbol_free_list = NULL; 7008 symbol_free_list = NULL;
7021 7009
7022 for (int i = 0; i < ARRAYELTS (lispsym); i++) 7010 for (int i = 0; i < ARRAYELTS (lispsym); i++)
7023 lispsym[i].s.gcmarkbit = 0; 7011 lispsym[i].u.s.gcmarkbit = 0;
7024 7012
7025 for (sblk = symbol_block; sblk; sblk = *sprev) 7013 for (sblk = symbol_block; sblk; sblk = *sprev)
7026 { 7014 {
7027 int this_free = 0; 7015 int this_free = 0;
7028 union aligned_Lisp_Symbol *sym = sblk->symbols; 7016 struct Lisp_Symbol *sym = sblk->symbols;
7029 union aligned_Lisp_Symbol *end = sym + lim; 7017 struct Lisp_Symbol *end = sym + lim;
7030 7018
7031 for (; sym < end; ++sym) 7019 for (; sym < end; ++sym)
7032 { 7020 {
7033 if (!sym->s.gcmarkbit) 7021 if (!sym->u.s.gcmarkbit)
7034 { 7022 {
7035 if (sym->s.redirect == SYMBOL_LOCALIZED) 7023 if (sym->u.s.redirect == SYMBOL_LOCALIZED)
7036 { 7024 {
7037 xfree (SYMBOL_BLV (&sym->s)); 7025 xfree (SYMBOL_BLV (sym));
7038 /* At every GC we sweep all symbol_blocks and rebuild the 7026 /* At every GC we sweep all symbol_blocks and rebuild the
7039 symbol_free_list, so those symbols which stayed unused 7027 symbol_free_list, so those symbols which stayed unused
7040 between the two will be re-swept. 7028 between the two will be re-swept.
7041 So we have to make sure we don't re-free this blv next 7029 So we have to make sure we don't re-free this blv next
7042 time we sweep this symbol_block (bug#29066). */ 7030 time we sweep this symbol_block (bug#29066). */
7043 sym->s.redirect = SYMBOL_PLAINVAL; 7031 sym->u.s.redirect = SYMBOL_PLAINVAL;
7044 } 7032 }
7045 sym->s.next = symbol_free_list; 7033 sym->u.s.next = symbol_free_list;
7046 symbol_free_list = &sym->s; 7034 symbol_free_list = sym;
7047 symbol_free_list->function = Vdead; 7035 symbol_free_list->u.s.function = Vdead;
7048 ++this_free; 7036 ++this_free;
7049 } 7037 }
7050 else 7038 else
7051 { 7039 {
7052 ++num_used; 7040 ++num_used;
7053 sym->s.gcmarkbit = 0; 7041 sym->u.s.gcmarkbit = 0;
7054 /* Attempt to catch bogus objects. */ 7042 /* Attempt to catch bogus objects. */
7055 eassert (valid_lisp_object_p (sym->s.function)); 7043 eassert (valid_lisp_object_p (sym->u.s.function));
7056 } 7044 }
7057 } 7045 }
7058 7046
@@ -7064,7 +7052,7 @@ sweep_symbols (void)
7064 { 7052 {
7065 *sprev = sblk->next; 7053 *sprev = sblk->next;
7066 /* Unhook from the free list. */ 7054 /* Unhook from the free list. */
7067 symbol_free_list = sblk->symbols[0].s.next; 7055 symbol_free_list = sblk->symbols[0].u.s.next;
7068 lisp_free (sblk); 7056 lisp_free (sblk);
7069 } 7057 }
7070 else 7058 else
@@ -7291,10 +7279,10 @@ symbol_uses_obj (Lisp_Object symbol, Lisp_Object obj)
7291 struct Lisp_Symbol *sym = XSYMBOL (symbol); 7279 struct Lisp_Symbol *sym = XSYMBOL (symbol);
7292 Lisp_Object val = find_symbol_value (symbol); 7280 Lisp_Object val = find_symbol_value (symbol);
7293 return (EQ (val, obj) 7281 return (EQ (val, obj)
7294 || EQ (sym->function, obj) 7282 || EQ (sym->u.s.function, obj)
7295 || (!NILP (sym->function) 7283 || (!NILP (sym->u.s.function)
7296 && COMPILEDP (sym->function) 7284 && COMPILEDP (sym->u.s.function)
7297 && EQ (AREF (sym->function, COMPILED_BYTECODE), obj)) 7285 && EQ (AREF (sym->u.s.function, COMPILED_BYTECODE), obj))
7298 || (!NILP (val) 7286 || (!NILP (val)
7299 && COMPILEDP (val) 7287 && COMPILEDP (val)
7300 && EQ (AREF (val, COMPILED_BYTECODE), obj))); 7288 && EQ (AREF (val, COMPILED_BYTECODE), obj)));
@@ -7325,15 +7313,15 @@ which_symbols (Lisp_Object obj, EMACS_INT find_max)
7325 7313
7326 for (sblk = symbol_block; sblk; sblk = sblk->next) 7314 for (sblk = symbol_block; sblk; sblk = sblk->next)
7327 { 7315 {
7328 union aligned_Lisp_Symbol *aligned_sym = sblk->symbols; 7316 struct Lisp_Symbol *asym = sblk->symbols;
7329 int bn; 7317 int bn;
7330 7318
7331 for (bn = 0; bn < SYMBOL_BLOCK_SIZE; bn++, aligned_sym++) 7319 for (bn = 0; bn < SYMBOL_BLOCK_SIZE; bn++, asym++)
7332 { 7320 {
7333 if (sblk == symbol_block && bn >= symbol_block_index) 7321 if (sblk == symbol_block && bn >= symbol_block_index)
7334 break; 7322 break;
7335 7323
7336 Lisp_Object sym = make_lisp_symbol (&aligned_sym->s); 7324 Lisp_Object sym = make_lisp_symbol (asym);
7337 if (symbol_uses_obj (sym, obj)) 7325 if (symbol_uses_obj (sym, obj))
7338 { 7326 {
7339 found = Fcons (sym, found); 7327 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/buffer.h b/src/buffer.h
index ac7c5a54679..46c7c6e5ad6 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -504,7 +504,7 @@ struct buffer_text
504 504
505struct buffer 505struct buffer
506{ 506{
507 struct vectorlike_header header; 507 union vectorlike_header header;
508 508
509 /* The name of this buffer. */ 509 /* The name of this buffer. */
510 Lisp_Object name_; 510 Lisp_Object name_;
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 f76fe873720..6a7a0fa50a1 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 00d1eb43033..4a3afed6f71 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;
@@ -3894,7 +3894,7 @@ syms_of_data (void)
3894 defsubr (&Sbool_vector_count_consecutive); 3894 defsubr (&Sbool_vector_count_consecutive);
3895 defsubr (&Sbool_vector_count_population); 3895 defsubr (&Sbool_vector_count_population);
3896 3896
3897 set_symbol_function (Qwholenump, XSYMBOL (Qnatnump)->function); 3897 set_symbol_function (Qwholenump, XSYMBOL (Qnatnump)->u.s.function);
3898 3898
3899 DEFVAR_LISP ("most-positive-fixnum", Vmost_positive_fixnum, 3899 DEFVAR_LISP ("most-positive-fixnum", Vmost_positive_fixnum,
3900 doc: /* The largest value that is representable in a Lisp integer. */); 3900 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/emacs-module.c b/src/emacs-module.c
index 6bc91a7e06a..b351515c3bd 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -998,10 +998,6 @@ lisp_to_value_bits (Lisp_Object o)
998 return (emacs_value) p; 998 return (emacs_value) p;
999} 999}
1000 1000
1001#ifndef HAVE_STRUCT_ATTRIBUTE_ALIGNED
1002enum { HAVE_STRUCT_ATTRIBUTE_ALIGNED = 0 };
1003#endif
1004
1005/* Convert O to an emacs_value. Allocate storage if needed; this can 1001/* Convert O to an emacs_value. Allocate storage if needed; this can
1006 signal if memory is exhausted. Must be an injective function. */ 1002 signal if memory is exhausted. Must be an injective function. */
1007static emacs_value 1003static emacs_value
@@ -1029,19 +1025,6 @@ lisp_to_value (emacs_env *env, Lisp_Object o)
1029 /* Package the incompressible object pointer inside a pair 1025 /* Package the incompressible object pointer inside a pair
1030 that is compressible. */ 1026 that is compressible. */
1031 Lisp_Object pair = Fcons (o, ltv_mark); 1027 Lisp_Object pair = Fcons (o, ltv_mark);
1032
1033 if (! HAVE_STRUCT_ATTRIBUTE_ALIGNED)
1034 {
1035 /* Keep calling Fcons until it returns a compressible pair.
1036 This shouldn't take long. */
1037 while ((intptr_t) XCONS (pair) & (GCALIGNMENT - 1))
1038 pair = Fcons (o, pair);
1039
1040 /* Plant the mark. The garbage collector will eventually
1041 reclaim any just-allocated incompressible pairs. */
1042 XSETCDR (pair, ltv_mark);
1043 }
1044
1045 v = (emacs_value) ((intptr_t) XCONS (pair) + Lisp_Cons); 1028 v = (emacs_value) ((intptr_t) XCONS (pair) + Lisp_Cons);
1046 } 1029 }
1047 1030
diff --git a/src/eval.c b/src/eval.c
index 063deb4ba03..ec507dd2042 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)))
@@ -2165,7 +2165,7 @@ eval_sub (Lisp_Object form)
2165 fun = original_fun; 2165 fun = original_fun;
2166 if (!SYMBOLP (fun)) 2166 if (!SYMBOLP (fun))
2167 fun = Ffunction (Fcons (fun, Qnil)); 2167 fun = Ffunction (Fcons (fun, Qnil));
2168 else if (!NILP (fun) && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) 2168 else if (!NILP (fun) && (fun = XSYMBOL (fun)->u.s.function, SYMBOLP (fun)))
2169 fun = indirect_function (fun); 2169 fun = indirect_function (fun);
2170 2170
2171 if (SUBRP (fun)) 2171 if (SUBRP (fun))
@@ -2348,7 +2348,7 @@ usage: (apply FUNCTION &rest ARGUMENTS) */)
2348 2348
2349 /* Optimize for no indirection. */ 2349 /* Optimize for no indirection. */
2350 if (SYMBOLP (fun) && !NILP (fun) 2350 if (SYMBOLP (fun) && !NILP (fun)
2351 && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) 2351 && (fun = XSYMBOL (fun)->u.s.function, SYMBOLP (fun)))
2352 { 2352 {
2353 fun = indirect_function (fun); 2353 fun = indirect_function (fun);
2354 if (NILP (fun)) 2354 if (NILP (fun))
@@ -2760,7 +2760,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
2760 /* Optimize for no indirection. */ 2760 /* Optimize for no indirection. */
2761 fun = original_fun; 2761 fun = original_fun;
2762 if (SYMBOLP (fun) && !NILP (fun) 2762 if (SYMBOLP (fun) && !NILP (fun)
2763 && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) 2763 && (fun = XSYMBOL (fun)->u.s.function, SYMBOLP (fun)))
2764 fun = indirect_function (fun); 2764 fun = indirect_function (fun);
2765 2765
2766 if (SUBRP (fun)) 2766 if (SUBRP (fun))
@@ -3076,7 +3076,7 @@ function with `&rest' args, or `unevalled' for a special form. */)
3076 function = original; 3076 function = original;
3077 if (SYMBOLP (function) && !NILP (function)) 3077 if (SYMBOLP (function) && !NILP (function))
3078 { 3078 {
3079 function = XSYMBOL (function)->function; 3079 function = XSYMBOL (function)->u.s.function;
3080 if (SYMBOLP (function)) 3080 if (SYMBOLP (function))
3081 function = indirect_function (function); 3081 function = indirect_function (function);
3082 } 3082 }
@@ -3215,7 +3215,7 @@ let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol)
3215 if ((--p)->kind > SPECPDL_LET) 3215 if ((--p)->kind > SPECPDL_LET)
3216 { 3216 {
3217 struct Lisp_Symbol *let_bound_symbol = XSYMBOL (specpdl_symbol (p)); 3217 struct Lisp_Symbol *let_bound_symbol = XSYMBOL (specpdl_symbol (p));
3218 eassert (let_bound_symbol->redirect != SYMBOL_VARALIAS); 3218 eassert (let_bound_symbol->u.s.redirect != SYMBOL_VARALIAS);
3219 if (symbol == let_bound_symbol 3219 if (symbol == let_bound_symbol
3220 && EQ (specpdl_where (p), buf)) 3220 && EQ (specpdl_where (p), buf))
3221 return 1; 3221 return 1;
@@ -3228,10 +3228,10 @@ static void
3228do_specbind (struct Lisp_Symbol *sym, union specbinding *bind, 3228do_specbind (struct Lisp_Symbol *sym, union specbinding *bind,
3229 Lisp_Object value, enum Set_Internal_Bind bindflag) 3229 Lisp_Object value, enum Set_Internal_Bind bindflag)
3230{ 3230{
3231 switch (sym->redirect) 3231 switch (sym->u.s.redirect)
3232 { 3232 {
3233 case SYMBOL_PLAINVAL: 3233 case SYMBOL_PLAINVAL:
3234 if (!sym->trapped_write) 3234 if (!sym->u.s.trapped_write)
3235 SET_SYMBOL_VAL (sym, value); 3235 SET_SYMBOL_VAL (sym, value);
3236 else 3236 else
3237 set_internal (specpdl_symbol (bind), value, Qnil, bindflag); 3237 set_internal (specpdl_symbol (bind), value, Qnil, bindflag);
@@ -3275,7 +3275,7 @@ specbind (Lisp_Object symbol, Lisp_Object value)
3275 sym = XSYMBOL (symbol); 3275 sym = XSYMBOL (symbol);
3276 3276
3277 start: 3277 start:
3278 switch (sym->redirect) 3278 switch (sym->u.s.redirect)
3279 { 3279 {
3280 case SYMBOL_VARALIAS: 3280 case SYMBOL_VARALIAS:
3281 sym = indirect_variable (sym); XSETSYMBOL (symbol, sym); goto start; 3281 sym = indirect_variable (sym); XSETSYMBOL (symbol, sym); goto start;
@@ -3299,10 +3299,10 @@ specbind (Lisp_Object symbol, Lisp_Object value)
3299 specpdl_ptr->let.where = Fcurrent_buffer (); 3299 specpdl_ptr->let.where = Fcurrent_buffer ();
3300 specpdl_ptr->let.saved_value = Qnil; 3300 specpdl_ptr->let.saved_value = Qnil;
3301 3301
3302 eassert (sym->redirect != SYMBOL_LOCALIZED 3302 eassert (sym->u.s.redirect != SYMBOL_LOCALIZED
3303 || (EQ (SYMBOL_BLV (sym)->where, Fcurrent_buffer ()))); 3303 || (EQ (SYMBOL_BLV (sym)->where, Fcurrent_buffer ())));
3304 3304
3305 if (sym->redirect == SYMBOL_LOCALIZED) 3305 if (sym->u.s.redirect == SYMBOL_LOCALIZED)
3306 { 3306 {
3307 if (!blv_found (SYMBOL_BLV (sym))) 3307 if (!blv_found (SYMBOL_BLV (sym)))
3308 specpdl_ptr->let.kind = SPECPDL_LET_DEFAULT; 3308 specpdl_ptr->let.kind = SPECPDL_LET_DEFAULT;
@@ -3413,9 +3413,9 @@ do_one_unbind (union specbinding *this_binding, bool unwinding,
3413 { /* If variable has a trivial value (no forwarding), and isn't 3413 { /* If variable has a trivial value (no forwarding), and isn't
3414 trapped, we can just set it. */ 3414 trapped, we can just set it. */
3415 Lisp_Object sym = specpdl_symbol (this_binding); 3415 Lisp_Object sym = specpdl_symbol (this_binding);
3416 if (SYMBOLP (sym) && XSYMBOL (sym)->redirect == SYMBOL_PLAINVAL) 3416 if (SYMBOLP (sym) && XSYMBOL (sym)->u.s.redirect == SYMBOL_PLAINVAL)
3417 { 3417 {
3418 if (XSYMBOL (sym)->trapped_write == SYMBOL_UNTRAPPED_WRITE) 3418 if (XSYMBOL (sym)->u.s.trapped_write == SYMBOL_UNTRAPPED_WRITE)
3419 SET_SYMBOL_VAL (XSYMBOL (sym), specpdl_old_value (this_binding)); 3419 SET_SYMBOL_VAL (XSYMBOL (sym), specpdl_old_value (this_binding));
3420 else 3420 else
3421 set_internal (sym, specpdl_old_value (this_binding), 3421 set_internal (sym, specpdl_old_value (this_binding),
@@ -3547,7 +3547,7 @@ context where binding is lexical by default. */)
3547 (Lisp_Object symbol) 3547 (Lisp_Object symbol)
3548{ 3548{
3549 CHECK_SYMBOL (symbol); 3549 CHECK_SYMBOL (symbol);
3550 return XSYMBOL (symbol)->declared_special ? Qt : Qnil; 3550 return XSYMBOL (symbol)->u.s.declared_special ? Qt : Qnil;
3551} 3551}
3552 3552
3553 3553
@@ -3703,7 +3703,8 @@ backtrace_eval_unrewind (int distance)
3703 just set it. No need to check for constant symbols here, 3703 just set it. No need to check for constant symbols here,
3704 since that was already done by specbind. */ 3704 since that was already done by specbind. */
3705 Lisp_Object sym = specpdl_symbol (tmp); 3705 Lisp_Object sym = specpdl_symbol (tmp);
3706 if (SYMBOLP (sym) && XSYMBOL (sym)->redirect == SYMBOL_PLAINVAL) 3706 if (SYMBOLP (sym)
3707 && XSYMBOL (sym)->u.s.redirect == SYMBOL_PLAINVAL)
3707 { 3708 {
3708 Lisp_Object old_value = specpdl_old_value (tmp); 3709 Lisp_Object old_value = specpdl_old_value (tmp);
3709 set_specpdl_old_value (tmp, SYMBOL_VAL (XSYMBOL (sym))); 3710 set_specpdl_old_value (tmp, SYMBOL_VAL (XSYMBOL (sym)));
diff --git a/src/fileio.c b/src/fileio.c
index fb66118905f..8808ad1d7ad 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3050,7 +3050,8 @@ support. */)
3050 acl = acl_from_text (SSDATA (acl_string)); 3050 acl = acl_from_text (SSDATA (acl_string));
3051 if (acl == NULL) 3051 if (acl == NULL)
3052 { 3052 {
3053 report_file_error ("Converting ACL", absname); 3053 if (acl_errno_valid (errno))
3054 report_file_error ("Converting ACL", absname);
3054 return Qnil; 3055 return Qnil;
3055 } 3056 }
3056 3057
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/font.h b/src/font.h
index 8f2e27f0edd..43d6f67e3e9 100644
--- a/src/font.h
+++ b/src/font.h
@@ -244,7 +244,7 @@ enum font_property_index
244 244
245struct font_spec 245struct font_spec
246{ 246{
247 struct vectorlike_header header; 247 union vectorlike_header header;
248 Lisp_Object props[FONT_SPEC_MAX]; 248 Lisp_Object props[FONT_SPEC_MAX];
249}; 249};
250 250
@@ -252,7 +252,7 @@ struct font_spec
252 252
253struct font_entity 253struct font_entity
254{ 254{
255 struct vectorlike_header header; 255 union vectorlike_header header;
256 Lisp_Object props[FONT_ENTITY_MAX]; 256 Lisp_Object props[FONT_ENTITY_MAX];
257}; 257};
258 258
@@ -265,7 +265,7 @@ struct font_entity
265 265
266struct font 266struct font
267{ 267{
268 struct vectorlike_header header; 268 union vectorlike_header header;
269 269
270 /* All Lisp_Object components must come first. 270 /* All Lisp_Object components must come first.
271 That ensures they are all aligned normally. */ 271 That ensures they are all aligned normally. */
diff --git a/src/frame.h b/src/frame.h
index e610fc768d3..a3b77636435 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -79,7 +79,7 @@ enum ns_appearance_type
79 79
80struct frame 80struct frame
81{ 81{
82 struct vectorlike_header header; 82 union vectorlike_header header;
83 83
84 /* All Lisp_Object components must come first. 84 /* All Lisp_Object components must come first.
85 That ensures they are all aligned normally. */ 85 That ensures they are all aligned normally. */
diff --git a/src/keyboard.c b/src/keyboard.c
index 2c29a643011..399149ae978 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -7904,7 +7904,7 @@ parse_menu_item (Lisp_Object item, int inmenubar)
7904 (such as lmenu.el set it up), check if the 7904 (such as lmenu.el set it up), check if the
7905 original command matches the cached command. */ 7905 original command matches the cached command. */
7906 && !(SYMBOLP (def) 7906 && !(SYMBOLP (def)
7907 && EQ (tem, XSYMBOL (def)->function)))) 7907 && EQ (tem, XSYMBOL (def)->u.s.function))))
7908 keys = Qnil; 7908 keys = Qnil;
7909 } 7909 }
7910 7910
@@ -8764,9 +8764,9 @@ access_keymap_keyremap (Lisp_Object map, Lisp_Object key, Lisp_Object prompt,
8764 /* Handle a symbol whose function definition is a keymap 8764 /* Handle a symbol whose function definition is a keymap
8765 or an array. */ 8765 or an array. */
8766 if (SYMBOLP (next) && !NILP (Ffboundp (next)) 8766 if (SYMBOLP (next) && !NILP (Ffboundp (next))
8767 && (ARRAYP (XSYMBOL (next)->function) 8767 && (ARRAYP (XSYMBOL (next)->u.s.function)
8768 || KEYMAPP (XSYMBOL (next)->function))) 8768 || KEYMAPP (XSYMBOL (next)->u.s.function)))
8769 next = Fautoload_do_load (XSYMBOL (next)->function, next, Qnil); 8769 next = Fautoload_do_load (XSYMBOL (next)->u.s.function, next, Qnil);
8770 8770
8771 /* If the keymap gives a function, not an 8771 /* If the keymap gives a function, not an
8772 array, then call the function with one arg and use 8772 array, then call the function with one arg and use
@@ -11513,7 +11513,7 @@ for that character after that prefix key. */);
11513 doc: /* Form to evaluate when Emacs starts up. 11513 doc: /* Form to evaluate when Emacs starts up.
11514Useful to set before you dump a modified Emacs. */); 11514Useful to set before you dump a modified Emacs. */);
11515 Vtop_level = Qnil; 11515 Vtop_level = Qnil;
11516 XSYMBOL (Qtop_level)->declared_special = false; 11516 XSYMBOL (Qtop_level)->u.s.declared_special = false;
11517 11517
11518 DEFVAR_KBOARD ("keyboard-translate-table", Vkeyboard_translate_table, 11518 DEFVAR_KBOARD ("keyboard-translate-table", Vkeyboard_translate_table,
11519 doc: /* Translate table for local keyboard input, or nil. 11519 doc: /* Translate table for local keyboard input, or nil.
diff --git a/src/lisp.h b/src/lisp.h
index e3262ad40f3..a25a673a9aa 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)
@@ -676,52 +664,60 @@ enum symbol_trapped_write
676 664
677struct Lisp_Symbol 665struct Lisp_Symbol
678{ 666{
679 bool_bf gcmarkbit : 1; 667 union
680 668 {
681 /* Indicates where the value can be found: 669 struct
682 0 : it's a plain var, the value is in the `value' field. 670 {
683 1 : it's a varalias, the value is really in the `alias' symbol. 671 bool_bf gcmarkbit : 1;
684 2 : it's a localized var, the value is in the `blv' object. 672
685 3 : it's a forwarding variable, the value is in `forward'. */ 673 /* Indicates where the value can be found:
686 ENUM_BF (symbol_redirect) redirect : 3; 674 0 : it's a plain var, the value is in the `value' field.
687 675 1 : it's a varalias, the value is really in the `alias' symbol.
688 /* 0 : normal case, just set the value 676 2 : it's a localized var, the value is in the `blv' object.
689 1 : constant, cannot set, e.g. nil, t, :keywords. 677 3 : it's a forwarding variable, the value is in `forward'. */
690 2 : trap the write, call watcher functions. */ 678 ENUM_BF (symbol_redirect) redirect : 3;
691 ENUM_BF (symbol_trapped_write) trapped_write : 2; 679
692 680 /* 0 : normal case, just set the value
693 /* Interned state of the symbol. This is an enumerator from 681 1 : constant, cannot set, e.g. nil, t, :keywords.
694 enum symbol_interned. */ 682 2 : trap the write, call watcher functions. */
695 unsigned interned : 2; 683 ENUM_BF (symbol_trapped_write) trapped_write : 2;
696 684
697 /* True means that this variable has been explicitly declared 685 /* Interned state of the symbol. This is an enumerator from
698 special (with `defvar' etc), and shouldn't be lexically bound. */ 686 enum symbol_interned. */
699 bool_bf declared_special : 1; 687 unsigned interned : 2;
700 688
701 /* True if pointed to from purespace and hence can't be GC'd. */ 689 /* True means that this variable has been explicitly declared
702 bool_bf pinned : 1; 690 special (with `defvar' etc), and shouldn't be lexically bound. */
703 691 bool_bf declared_special : 1;
704 /* The symbol's name, as a Lisp string. */ 692
705 Lisp_Object name; 693 /* True if pointed to from purespace and hence can't be GC'd. */
706 694 bool_bf pinned : 1;
707 /* Value of the symbol or Qunbound if unbound. Which alternative of the 695
708 union is used depends on the `redirect' field above. */ 696 /* The symbol's name, as a Lisp string. */
709 union { 697 Lisp_Object name;
710 Lisp_Object value; 698
711 struct Lisp_Symbol *alias; 699 /* Value of the symbol or Qunbound if unbound. Which alternative of the
712 struct Lisp_Buffer_Local_Value *blv; 700 union is used depends on the `redirect' field above. */
713 union Lisp_Fwd *fwd; 701 union {
714 } val; 702 Lisp_Object value;
715 703 struct Lisp_Symbol *alias;
716 /* Function value of the symbol or Qnil if not fboundp. */ 704 struct Lisp_Buffer_Local_Value *blv;
717 Lisp_Object function; 705 union Lisp_Fwd *fwd;
706 } val;
707
708 /* Function value of the symbol or Qnil if not fboundp. */
709 Lisp_Object function;
718 710
719 /* The symbol's property list. */ 711 /* The symbol's property list. */
720 Lisp_Object plist; 712 Lisp_Object plist;
721 713
722 /* Next symbol in obarray bucket, if the symbol is interned. */ 714 /* Next symbol in obarray bucket, if the symbol is interned. */
723 struct Lisp_Symbol *next; 715 struct Lisp_Symbol *next;
716 } s;
717 char alignas (GCALIGNMENT) gcaligned;
718 } u;
724}; 719};
720verify (alignof (struct Lisp_Symbol) % GCALIGNMENT == 0);
725 721
726/* Declare a Lisp-callable function. The MAXARGS parameter has the same 722/* Declare a Lisp-callable function. The MAXARGS parameter has the same
727 meaning as in the DEFUN macro, and is used to construct a prototype. */ 723 meaning as in the DEFUN macro, and is used to construct a prototype. */
@@ -795,13 +791,13 @@ struct Lisp_Symbol
795/* Header of vector-like objects. This documents the layout constraints on 791/* Header of vector-like objects. This documents the layout constraints on
796 vectors and pseudovectors (objects of PVEC_xxx subtype). It also prevents 792 vectors and pseudovectors (objects of PVEC_xxx subtype). It also prevents
797 compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR 793 compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR
798 and PSEUDOVECTORP cast their pointers to struct vectorlike_header *, 794 and PSEUDOVECTORP cast their pointers to union vectorlike_header *,
799 because when two such pointers potentially alias, a compiler won't 795 because when two such pointers potentially alias, a compiler won't
800 incorrectly reorder loads and stores to their size fields. See 796 incorrectly reorder loads and stores to their size fields. See
801 Bug#8546. */ 797 Bug#8546. */
802struct vectorlike_header 798union vectorlike_header
803 { 799 {
804 /* The only field contains various pieces of information: 800 /* The main member contains various pieces of information:
805 - The MSB (ARRAY_MARK_FLAG) holds the gcmarkbit. 801 - The MSB (ARRAY_MARK_FLAG) holds the gcmarkbit.
806 - The next bit (PSEUDOVECTOR_FLAG) indicates whether this is a plain 802 - The next bit (PSEUDOVECTOR_FLAG) indicates whether this is a plain
807 vector (0) or a pseudovector (1). 803 vector (0) or a pseudovector (1).
@@ -821,7 +817,9 @@ struct vectorlike_header
821 Current layout limits the pseudovectors to 63 PVEC_xxx subtypes, 817 Current layout limits the pseudovectors to 63 PVEC_xxx subtypes,
822 4095 Lisp_Objects in GC-ed area and 4095 word-sized other slots. */ 818 4095 Lisp_Objects in GC-ed area and 4095 word-sized other slots. */
823 ptrdiff_t size; 819 ptrdiff_t size;
820 char alignas (GCALIGNMENT) gcaligned;
824 }; 821 };
822verify (alignof (union vectorlike_header) % GCALIGNMENT == 0);
825 823
826INLINE bool 824INLINE bool
827(SYMBOLP) (Lisp_Object x) 825(SYMBOLP) (Lisp_Object x)
@@ -853,7 +851,7 @@ make_lisp_symbol (struct Lisp_Symbol *sym)
853INLINE Lisp_Object 851INLINE Lisp_Object
854builtin_lisp_symbol (int index) 852builtin_lisp_symbol (int index)
855{ 853{
856 return make_lisp_symbol (&lispsym[index].s); 854 return make_lisp_symbol (&lispsym[index]);
857} 855}
858 856
859INLINE void 857INLINE void
@@ -1093,10 +1091,10 @@ INLINE bool
1093 | ((restsize) << PSEUDOVECTOR_SIZE_BITS) \ 1091 | ((restsize) << PSEUDOVECTOR_SIZE_BITS) \
1094 | (lispsize))) 1092 | (lispsize)))
1095 1093
1096/* The cast to struct vectorlike_header * avoids aliasing issues. */ 1094/* The cast to union vectorlike_header * avoids aliasing issues. */
1097#define XSETPSEUDOVECTOR(a, b, code) \ 1095#define XSETPSEUDOVECTOR(a, b, code) \
1098 XSETTYPED_PSEUDOVECTOR (a, b, \ 1096 XSETTYPED_PSEUDOVECTOR (a, b, \
1099 (((struct vectorlike_header *) \ 1097 (((union vectorlike_header *) \
1100 XUNTAG (a, Lisp_Vectorlike)) \ 1098 XUNTAG (a, Lisp_Vectorlike)) \
1101 ->size), \ 1099 ->size), \
1102 code) 1100 code)
@@ -1143,20 +1141,28 @@ make_pointer_integer (void *p)
1143 1141
1144typedef struct interval *INTERVAL; 1142typedef struct interval *INTERVAL;
1145 1143
1146struct GCALIGNED Lisp_Cons 1144struct Lisp_Cons
1145{
1146 union
1147 { 1147 {
1148 /* Car of this cons cell. */ 1148 struct
1149 Lisp_Object car;
1150
1151 union
1152 { 1149 {
1153 /* Cdr of this cons cell. */ 1150 /* Car of this cons cell. */
1154 Lisp_Object cdr; 1151 Lisp_Object car;
1155 1152
1156 /* Used to chain conses on a free list. */ 1153 union
1157 struct Lisp_Cons *chain; 1154 {
1158 } u; 1155 /* Cdr of this cons cell. */
1159 }; 1156 Lisp_Object cdr;
1157
1158 /* Used to chain conses on a free list. */
1159 struct Lisp_Cons *chain;
1160 } u;
1161 } s;
1162 char alignas (GCALIGNMENT) gcaligned;
1163 } u;
1164};
1165verify (alignof (struct Lisp_Cons) % GCALIGNMENT == 0);
1160 1166
1161INLINE bool 1167INLINE bool
1162(NILP) (Lisp_Object x) 1168(NILP) (Lisp_Object x)
@@ -1192,12 +1198,12 @@ INLINE struct Lisp_Cons *
1192INLINE Lisp_Object * 1198INLINE Lisp_Object *
1193xcar_addr (Lisp_Object c) 1199xcar_addr (Lisp_Object c)
1194{ 1200{
1195 return &XCONS (c)->car; 1201 return &XCONS (c)->u.s.car;
1196} 1202}
1197INLINE Lisp_Object * 1203INLINE Lisp_Object *
1198xcdr_addr (Lisp_Object c) 1204xcdr_addr (Lisp_Object c)
1199{ 1205{
1200 return &XCONS (c)->u.cdr; 1206 return &XCONS (c)->u.s.u.cdr;
1201} 1207}
1202 1208
1203/* Use these from normal code. */ 1209/* Use these from normal code. */
@@ -1261,15 +1267,24 @@ CDR_SAFE (Lisp_Object c)
1261 return CONSP (c) ? XCDR (c) : Qnil; 1267 return CONSP (c) ? XCDR (c) : Qnil;
1262} 1268}
1263 1269
1264/* In a string or vector, the sign bit of the `size' is the gc mark bit. */ 1270/* In a string or vector, the sign bit of u.s.size is the gc mark bit. */
1265 1271
1266struct GCALIGNED Lisp_String 1272struct Lisp_String
1273{
1274 union
1267 { 1275 {
1268 ptrdiff_t size; 1276 struct
1269 ptrdiff_t size_byte; 1277 {
1270 INTERVAL intervals; /* Text properties in this string. */ 1278 ptrdiff_t size;
1271 unsigned char *data; 1279 ptrdiff_t size_byte;
1272 }; 1280 INTERVAL intervals; /* Text properties in this string. */
1281 unsigned char *data;
1282 } s;
1283 struct Lisp_String *next;
1284 char alignas (GCALIGNMENT) gcaligned;
1285 } u;
1286};
1287verify (alignof (struct Lisp_String) % GCALIGNMENT == 0);
1273 1288
1274INLINE bool 1289INLINE bool
1275STRINGP (Lisp_Object x) 1290STRINGP (Lisp_Object x)
@@ -1294,7 +1309,7 @@ XSTRING (Lisp_Object a)
1294INLINE bool 1309INLINE bool
1295STRING_MULTIBYTE (Lisp_Object str) 1310STRING_MULTIBYTE (Lisp_Object str)
1296{ 1311{
1297 return 0 <= XSTRING (str)->size_byte; 1312 return 0 <= XSTRING (str)->u.s.size_byte;
1298} 1313}
1299 1314
1300/* An upper bound on the number of bytes in a Lisp string, not 1315/* An upper bound on the number of bytes in a Lisp string, not
@@ -1316,20 +1331,20 @@ STRING_MULTIBYTE (Lisp_Object str)
1316/* Mark STR as a unibyte string. */ 1331/* Mark STR as a unibyte string. */
1317#define STRING_SET_UNIBYTE(STR) \ 1332#define STRING_SET_UNIBYTE(STR) \
1318 do { \ 1333 do { \
1319 if (XSTRING (STR)->size == 0) \ 1334 if (XSTRING (STR)->u.s.size == 0) \
1320 (STR) = empty_unibyte_string; \ 1335 (STR) = empty_unibyte_string; \
1321 else \ 1336 else \
1322 XSTRING (STR)->size_byte = -1; \ 1337 XSTRING (STR)->u.s.size_byte = -1; \
1323 } while (false) 1338 } while (false)
1324 1339
1325/* Mark STR as a multibyte string. Assure that STR contains only 1340/* Mark STR as a multibyte string. Assure that STR contains only
1326 ASCII characters in advance. */ 1341 ASCII characters in advance. */
1327#define STRING_SET_MULTIBYTE(STR) \ 1342#define STRING_SET_MULTIBYTE(STR) \
1328 do { \ 1343 do { \
1329 if (XSTRING (STR)->size == 0) \ 1344 if (XSTRING (STR)->u.s.size == 0) \
1330 (STR) = empty_multibyte_string; \ 1345 (STR) = empty_multibyte_string; \
1331 else \ 1346 else \
1332 XSTRING (STR)->size_byte = XSTRING (STR)->size; \ 1347 XSTRING (STR)->u.s.size_byte = XSTRING (STR)->u.s.size; \
1333 } while (false) 1348 } while (false)
1334 1349
1335/* Convenience functions for dealing with Lisp strings. */ 1350/* Convenience functions for dealing with Lisp strings. */
@@ -1337,7 +1352,7 @@ STRING_MULTIBYTE (Lisp_Object str)
1337INLINE unsigned char * 1352INLINE unsigned char *
1338SDATA (Lisp_Object string) 1353SDATA (Lisp_Object string)
1339{ 1354{
1340 return XSTRING (string)->data; 1355 return XSTRING (string)->u.s.data;
1341} 1356}
1342INLINE char * 1357INLINE char *
1343SSDATA (Lisp_Object string) 1358SSDATA (Lisp_Object string)
@@ -1358,7 +1373,7 @@ SSET (Lisp_Object string, ptrdiff_t index, unsigned char new)
1358INLINE ptrdiff_t 1373INLINE ptrdiff_t
1359SCHARS (Lisp_Object string) 1374SCHARS (Lisp_Object string)
1360{ 1375{
1361 ptrdiff_t nchars = XSTRING (string)->size; 1376 ptrdiff_t nchars = XSTRING (string)->u.s.size;
1362 eassume (0 <= nchars); 1377 eassume (0 <= nchars);
1363 return nchars; 1378 return nchars;
1364} 1379}
@@ -1372,7 +1387,7 @@ STRING_BYTES (struct Lisp_String *s)
1372#ifdef GC_CHECK_STRING_BYTES 1387#ifdef GC_CHECK_STRING_BYTES
1373 ptrdiff_t nbytes = string_bytes (s); 1388 ptrdiff_t nbytes = string_bytes (s);
1374#else 1389#else
1375 ptrdiff_t nbytes = s->size_byte < 0 ? s->size : s->size_byte; 1390 ptrdiff_t nbytes = s->u.s.size_byte < 0 ? s->u.s.size : s->u.s.size_byte;
1376#endif 1391#endif
1377 eassume (0 <= nbytes); 1392 eassume (0 <= nbytes);
1378 return nbytes; 1393 return nbytes;
@@ -1391,14 +1406,14 @@ STRING_SET_CHARS (Lisp_Object string, ptrdiff_t newsize)
1391 eassert (STRING_MULTIBYTE (string) 1406 eassert (STRING_MULTIBYTE (string)
1392 ? 0 <= newsize && newsize <= SBYTES (string) 1407 ? 0 <= newsize && newsize <= SBYTES (string)
1393 : newsize == SCHARS (string)); 1408 : newsize == SCHARS (string));
1394 XSTRING (string)->size = newsize; 1409 XSTRING (string)->u.s.size = newsize;
1395} 1410}
1396 1411
1397/* A regular vector is just a header plus an array of Lisp_Objects. */ 1412/* A regular vector is just a header plus an array of Lisp_Objects. */
1398 1413
1399struct Lisp_Vector 1414struct Lisp_Vector
1400 { 1415 {
1401 struct vectorlike_header header; 1416 union vectorlike_header header;
1402 Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER]; 1417 Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER];
1403 }; 1418 };
1404 1419
@@ -1455,7 +1470,7 @@ PSEUDOVECTOR_TYPE (struct Lisp_Vector *v)
1455 1470
1456/* Can't be used with PVEC_NORMAL_VECTOR. */ 1471/* Can't be used with PVEC_NORMAL_VECTOR. */
1457INLINE bool 1472INLINE bool
1458PSEUDOVECTOR_TYPEP (struct vectorlike_header *a, enum pvec_type code) 1473PSEUDOVECTOR_TYPEP (union vectorlike_header *a, enum pvec_type code)
1459{ 1474{
1460 /* We don't use PSEUDOVECTOR_TYPE here so as to avoid a shift 1475 /* We don't use PSEUDOVECTOR_TYPE here so as to avoid a shift
1461 * operation when `code' is known. */ 1476 * operation when `code' is known. */
@@ -1471,8 +1486,8 @@ PSEUDOVECTORP (Lisp_Object a, int code)
1471 return false; 1486 return false;
1472 else 1487 else
1473 { 1488 {
1474 /* Converting to struct vectorlike_header * avoids aliasing issues. */ 1489 /* Converting to union vectorlike_header * avoids aliasing issues. */
1475 struct vectorlike_header *h = XUNTAG (a, Lisp_Vectorlike); 1490 union vectorlike_header *h = XUNTAG (a, Lisp_Vectorlike);
1476 return PSEUDOVECTOR_TYPEP (h, code); 1491 return PSEUDOVECTOR_TYPEP (h, code);
1477 } 1492 }
1478} 1493}
@@ -1483,7 +1498,7 @@ struct Lisp_Bool_Vector
1483 { 1498 {
1484 /* HEADER.SIZE is the vector's size field. It doesn't have the real size, 1499 /* HEADER.SIZE is the vector's size field. It doesn't have the real size,
1485 just the subtype information. */ 1500 just the subtype information. */
1486 struct vectorlike_header header; 1501 union vectorlike_header header;
1487 /* This is the size in bits. */ 1502 /* This is the size in bits. */
1488 EMACS_INT size; 1503 EMACS_INT size;
1489 /* The actual bits, packed into bytes. 1504 /* The actual bits, packed into bytes.
@@ -1696,7 +1711,7 @@ struct Lisp_Char_Table
1696 pseudovector type information. It holds the size, too. 1711 pseudovector type information. It holds the size, too.
1697 The size counts the defalt, parent, purpose, ascii, 1712 The size counts the defalt, parent, purpose, ascii,
1698 contents, and extras slots. */ 1713 contents, and extras slots. */
1699 struct vectorlike_header header; 1714 union vectorlike_header header;
1700 1715
1701 /* This holds a default value, 1716 /* This holds a default value,
1702 which is used whenever the value for a specific character is nil. */ 1717 which is used whenever the value for a specific character is nil. */
@@ -1738,7 +1753,7 @@ struct Lisp_Sub_Char_Table
1738 { 1753 {
1739 /* HEADER.SIZE is the vector's size field, which also holds the 1754 /* HEADER.SIZE is the vector's size field, which also holds the
1740 pseudovector type information. It holds the size, too. */ 1755 pseudovector type information. It holds the size, too. */
1741 struct vectorlike_header header; 1756 union vectorlike_header header;
1742 1757
1743 /* Depth of this sub char-table. It should be 1, 2, or 3. A sub 1758 /* Depth of this sub char-table. It should be 1, 2, or 3. A sub
1744 char-table of depth 1 contains 16 elements, and each element 1759 char-table of depth 1 contains 16 elements, and each element
@@ -1813,7 +1828,7 @@ CHAR_TABLE_SET (Lisp_Object ct, int idx, Lisp_Object val)
1813 1828
1814struct Lisp_Subr 1829struct Lisp_Subr
1815 { 1830 {
1816 struct vectorlike_header header; 1831 union vectorlike_header header;
1817 union { 1832 union {
1818 Lisp_Object (*a0) (void); 1833 Lisp_Object (*a0) (void);
1819 Lisp_Object (*a1) (Lisp_Object); 1834 Lisp_Object (*a1) (Lisp_Object);
@@ -1909,20 +1924,20 @@ INLINE Lisp_Object
1909INLINE struct Lisp_Symbol * 1924INLINE struct Lisp_Symbol *
1910SYMBOL_ALIAS (struct Lisp_Symbol *sym) 1925SYMBOL_ALIAS (struct Lisp_Symbol *sym)
1911{ 1926{
1912 eassume (sym->redirect == SYMBOL_VARALIAS && sym->val.alias); 1927 eassume (sym->u.s.redirect == SYMBOL_VARALIAS && sym->u.s.val.alias);
1913 return sym->val.alias; 1928 return sym->u.s.val.alias;
1914} 1929}
1915INLINE struct Lisp_Buffer_Local_Value * 1930INLINE struct Lisp_Buffer_Local_Value *
1916SYMBOL_BLV (struct Lisp_Symbol *sym) 1931SYMBOL_BLV (struct Lisp_Symbol *sym)
1917{ 1932{
1918 eassume (sym->redirect == SYMBOL_LOCALIZED && sym->val.blv); 1933 eassume (sym->u.s.redirect == SYMBOL_LOCALIZED && sym->u.s.val.blv);
1919 return sym->val.blv; 1934 return sym->u.s.val.blv;
1920} 1935}
1921INLINE union Lisp_Fwd * 1936INLINE union Lisp_Fwd *
1922SYMBOL_FWD (struct Lisp_Symbol *sym) 1937SYMBOL_FWD (struct Lisp_Symbol *sym)
1923{ 1938{
1924 eassume (sym->redirect == SYMBOL_FORWARDED && sym->val.fwd); 1939 eassume (sym->u.s.redirect == SYMBOL_FORWARDED && sym->u.s.val.fwd);
1925 return sym->val.fwd; 1940 return sym->u.s.val.fwd;
1926} 1941}
1927 1942
1928INLINE void 1943INLINE void
@@ -1934,26 +1949,26 @@ INLINE void
1934INLINE void 1949INLINE void
1935SET_SYMBOL_ALIAS (struct Lisp_Symbol *sym, struct Lisp_Symbol *v) 1950SET_SYMBOL_ALIAS (struct Lisp_Symbol *sym, struct Lisp_Symbol *v)
1936{ 1951{
1937 eassume (sym->redirect == SYMBOL_VARALIAS && v); 1952 eassume (sym->u.s.redirect == SYMBOL_VARALIAS && v);
1938 sym->val.alias = v; 1953 sym->u.s.val.alias = v;
1939} 1954}
1940INLINE void 1955INLINE void
1941SET_SYMBOL_BLV (struct Lisp_Symbol *sym, struct Lisp_Buffer_Local_Value *v) 1956SET_SYMBOL_BLV (struct Lisp_Symbol *sym, struct Lisp_Buffer_Local_Value *v)
1942{ 1957{
1943 eassume (sym->redirect == SYMBOL_LOCALIZED && v); 1958 eassume (sym->u.s.redirect == SYMBOL_LOCALIZED && v);
1944 sym->val.blv = v; 1959 sym->u.s.val.blv = v;
1945} 1960}
1946INLINE void 1961INLINE void
1947SET_SYMBOL_FWD (struct Lisp_Symbol *sym, union Lisp_Fwd *v) 1962SET_SYMBOL_FWD (struct Lisp_Symbol *sym, union Lisp_Fwd *v)
1948{ 1963{
1949 eassume (sym->redirect == SYMBOL_FORWARDED && v); 1964 eassume (sym->u.s.redirect == SYMBOL_FORWARDED && v);
1950 sym->val.fwd = v; 1965 sym->u.s.val.fwd = v;
1951} 1966}
1952 1967
1953INLINE Lisp_Object 1968INLINE Lisp_Object
1954SYMBOL_NAME (Lisp_Object sym) 1969SYMBOL_NAME (Lisp_Object sym)
1955{ 1970{
1956 return XSYMBOL (sym)->name; 1971 return XSYMBOL (sym)->u.s.name;
1957} 1972}
1958 1973
1959/* Value is true if SYM is an interned symbol. */ 1974/* Value is true if SYM is an interned symbol. */
@@ -1961,7 +1976,7 @@ SYMBOL_NAME (Lisp_Object sym)
1961INLINE bool 1976INLINE bool
1962SYMBOL_INTERNED_P (Lisp_Object sym) 1977SYMBOL_INTERNED_P (Lisp_Object sym)
1963{ 1978{
1964 return XSYMBOL (sym)->interned != SYMBOL_UNINTERNED; 1979 return XSYMBOL (sym)->u.s.interned != SYMBOL_UNINTERNED;
1965} 1980}
1966 1981
1967/* Value is true if SYM is interned in initial_obarray. */ 1982/* Value is true if SYM is interned in initial_obarray. */
@@ -1969,7 +1984,7 @@ SYMBOL_INTERNED_P (Lisp_Object sym)
1969INLINE bool 1984INLINE bool
1970SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (Lisp_Object sym) 1985SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (Lisp_Object sym)
1971{ 1986{
1972 return XSYMBOL (sym)->interned == SYMBOL_INTERNED_IN_INITIAL_OBARRAY; 1987 return XSYMBOL (sym)->u.s.interned == SYMBOL_INTERNED_IN_INITIAL_OBARRAY;
1973} 1988}
1974 1989
1975/* Value is non-zero if symbol cannot be changed through a simple set, 1990/* Value is non-zero if symbol cannot be changed through a simple set,
@@ -2025,7 +2040,7 @@ struct hash_table_test
2025struct Lisp_Hash_Table 2040struct Lisp_Hash_Table
2026{ 2041{
2027 /* This is for Lisp; the hash table code does not refer to it. */ 2042 /* This is for Lisp; the hash table code does not refer to it. */
2028 struct vectorlike_header header; 2043 union vectorlike_header header;
2029 2044
2030 /* Nil if table is non-weak. Otherwise a symbol describing the 2045 /* Nil if table is non-weak. Otherwise a symbol describing the
2031 weakness of the table. */ 2046 weakness of the table. */
@@ -2945,7 +2960,7 @@ CHECK_NUMBER_CDR (Lisp_Object x)
2945/* This version of DEFUN declares a function prototype with the right 2960/* This version of DEFUN declares a function prototype with the right
2946 arguments, so we can catch errors with maxargs at compile-time. */ 2961 arguments, so we can catch errors with maxargs at compile-time. */
2947#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ 2962#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \
2948 static struct GCALIGNED Lisp_Subr sname = \ 2963 static struct Lisp_Subr sname = \
2949 { { PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, \ 2964 { { PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, \
2950 { .a ## maxargs = fnname }, \ 2965 { .a ## maxargs = fnname }, \
2951 minargs, maxargs, lname, intspec, 0}; \ 2966 minargs, maxargs, lname, intspec, 0}; \
@@ -3212,25 +3227,25 @@ set_hash_value_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val)
3212INLINE void 3227INLINE void
3213set_symbol_function (Lisp_Object sym, Lisp_Object function) 3228set_symbol_function (Lisp_Object sym, Lisp_Object function)
3214{ 3229{
3215 XSYMBOL (sym)->function = function; 3230 XSYMBOL (sym)->u.s.function = function;
3216} 3231}
3217 3232
3218INLINE void 3233INLINE void
3219set_symbol_plist (Lisp_Object sym, Lisp_Object plist) 3234set_symbol_plist (Lisp_Object sym, Lisp_Object plist)
3220{ 3235{
3221 XSYMBOL (sym)->plist = plist; 3236 XSYMBOL (sym)->u.s.plist = plist;
3222} 3237}
3223 3238
3224INLINE void 3239INLINE void
3225set_symbol_next (Lisp_Object sym, struct Lisp_Symbol *next) 3240set_symbol_next (Lisp_Object sym, struct Lisp_Symbol *next)
3226{ 3241{
3227 XSYMBOL (sym)->next = next; 3242 XSYMBOL (sym)->u.s.next = next;
3228} 3243}
3229 3244
3230INLINE void 3245INLINE void
3231make_symbol_constant (Lisp_Object sym) 3246make_symbol_constant (Lisp_Object sym)
3232{ 3247{
3233 XSYMBOL (sym)->trapped_write = SYMBOL_NOWRITE; 3248 XSYMBOL (sym)->u.s.trapped_write = SYMBOL_NOWRITE;
3234} 3249}
3235 3250
3236/* Buffer-local variable access functions. */ 3251/* Buffer-local variable access functions. */
@@ -3255,7 +3270,7 @@ set_overlay_plist (Lisp_Object overlay, Lisp_Object plist)
3255INLINE INTERVAL 3270INLINE INTERVAL
3256string_intervals (Lisp_Object s) 3271string_intervals (Lisp_Object s)
3257{ 3272{
3258 return XSTRING (s)->intervals; 3273 return XSTRING (s)->u.s.intervals;
3259} 3274}
3260 3275
3261/* Set text properties of S to I. */ 3276/* Set text properties of S to I. */
@@ -3263,7 +3278,7 @@ string_intervals (Lisp_Object s)
3263INLINE void 3278INLINE void
3264set_string_intervals (Lisp_Object s, INTERVAL i) 3279set_string_intervals (Lisp_Object s, INTERVAL i)
3265{ 3280{
3266 XSTRING (s)->intervals = i; 3281 XSTRING (s)->u.s.intervals = i;
3267} 3282}
3268 3283
3269/* Set a Lisp slot in TABLE to VAL. Most code should use this instead 3284/* Set a Lisp slot in TABLE to VAL. Most code should use this instead
@@ -3917,7 +3932,7 @@ typedef emacs_value (*emacs_subr) (emacs_env *, ptrdiff_t,
3917 3932
3918struct Lisp_Module_Function 3933struct Lisp_Module_Function
3919{ 3934{
3920 struct vectorlike_header header; 3935 union vectorlike_header header;
3921 3936
3922 /* Fields traced by GC; these must come first. */ 3937 /* Fields traced by GC; these must come first. */
3923 Lisp_Object documentation; 3938 Lisp_Object documentation;
@@ -4588,20 +4603,6 @@ enum { defined_GC_CHECK_STRING_BYTES = true };
4588enum { defined_GC_CHECK_STRING_BYTES = false }; 4603enum { defined_GC_CHECK_STRING_BYTES = false };
4589#endif 4604#endif
4590 4605
4591/* Struct inside unions that are typically no larger and aligned enough. */
4592
4593union Aligned_Cons
4594{
4595 struct Lisp_Cons s;
4596 double d; intmax_t i; void *p;
4597};
4598
4599union Aligned_String
4600{
4601 struct Lisp_String s;
4602 double d; intmax_t i; void *p;
4603};
4604
4605/* True for stack-based cons and string implementations, respectively. 4606/* True for stack-based cons and string implementations, respectively.
4606 Use stack-based strings only if stack-based cons also works. 4607 Use stack-based strings only if stack-based cons also works.
4607 Otherwise, STACK_CONS would create heap-based cons cells that 4608 Otherwise, STACK_CONS would create heap-based cons cells that
@@ -4609,18 +4610,16 @@ union Aligned_String
4609 4610
4610enum 4611enum
4611 { 4612 {
4612 USE_STACK_CONS = (USE_STACK_LISP_OBJECTS 4613 USE_STACK_CONS = USE_STACK_LISP_OBJECTS,
4613 && alignof (union Aligned_Cons) % GCALIGNMENT == 0),
4614 USE_STACK_STRING = (USE_STACK_CONS 4614 USE_STACK_STRING = (USE_STACK_CONS
4615 && !defined_GC_CHECK_STRING_BYTES 4615 && !defined_GC_CHECK_STRING_BYTES)
4616 && alignof (union Aligned_String) % GCALIGNMENT == 0)
4617 }; 4616 };
4618 4617
4619/* Auxiliary macros used for auto allocation of Lisp objects. Please 4618/* Auxiliary macros used for auto allocation of Lisp objects. Please
4620 use these only in macros like AUTO_CONS that declare a local 4619 use these only in macros like AUTO_CONS that declare a local
4621 variable whose lifetime will be clear to the programmer. */ 4620 variable whose lifetime will be clear to the programmer. */
4622#define STACK_CONS(a, b) \ 4621#define STACK_CONS(a, b) \
4623 make_lisp_ptr (&((union Aligned_Cons) { { a, { b } } }).s, Lisp_Cons) 4622 make_lisp_ptr (&((struct Lisp_Cons) {{{a, {b}}}}), Lisp_Cons)
4624#define AUTO_CONS_EXPR(a, b) \ 4623#define AUTO_CONS_EXPR(a, b) \
4625 (USE_STACK_CONS ? STACK_CONS (a, b) : Fcons (a, b)) 4624 (USE_STACK_CONS ? STACK_CONS (a, b) : Fcons (a, b))
4626 4625
@@ -4666,7 +4665,7 @@ enum
4666 Lisp_Object name = \ 4665 Lisp_Object name = \
4667 (USE_STACK_STRING \ 4666 (USE_STACK_STRING \
4668 ? (make_lisp_ptr \ 4667 ? (make_lisp_ptr \
4669 ((&((union Aligned_String) {{len, -1, 0, (unsigned char *) (str)}}).s), \ 4668 ((&(struct Lisp_String) {{{len, -1, 0, (unsigned char *) (str)}}}), \
4670 Lisp_String)) \ 4669 Lisp_String)) \
4671 : make_unibyte_string (str, len)) 4670 : make_unibyte_string (str, len))
4672 4671
diff --git a/src/lread.c b/src/lread.c
index 19ed07220cd..17463f4ef4e 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/process.h b/src/process.h
index 5a044f669f2..5670f447365 100644
--- a/src/process.h
+++ b/src/process.h
@@ -41,7 +41,7 @@ enum { PROCESS_OPEN_FDS = 6 };
41 41
42struct Lisp_Process 42struct Lisp_Process
43 { 43 {
44 struct vectorlike_header header; 44 union vectorlike_header header;
45 45
46 /* Name of subprocess terminal. */ 46 /* Name of subprocess terminal. */
47 Lisp_Object tty_name; 47 Lisp_Object tty_name;
diff --git a/src/termhooks.h b/src/termhooks.h
index dd6044aabd5..fe4e993c968 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -373,7 +373,7 @@ extern struct tty_display_info *gpm_tty;
373struct terminal 373struct terminal
374{ 374{
375 /* This is for Lisp; the terminal code does not refer to it. */ 375 /* This is for Lisp; the terminal code does not refer to it. */
376 struct vectorlike_header header; 376 union vectorlike_header header;
377 377
378 /* Parameter alist of this terminal. */ 378 /* Parameter alist of this terminal. */
379 Lisp_Object param_alist; 379 Lisp_Object param_alist;
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/thread.h b/src/thread.h
index 19baafbf8a1..1845974bc28 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -35,7 +35,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
35 35
36struct thread_state 36struct thread_state
37{ 37{
38 struct vectorlike_header header; 38 union vectorlike_header header;
39 39
40 /* The buffer in which the last search was performed, or 40 /* The buffer in which the last search was performed, or
41 Qt if the last search was done in a string; 41 Qt if the last search was done in a string;
@@ -230,7 +230,7 @@ typedef struct
230/* A mutex as a lisp object. */ 230/* A mutex as a lisp object. */
231struct Lisp_Mutex 231struct Lisp_Mutex
232{ 232{
233 struct vectorlike_header header; 233 union vectorlike_header header;
234 234
235 /* The name of the mutex, or nil. */ 235 /* The name of the mutex, or nil. */
236 Lisp_Object name; 236 Lisp_Object name;
@@ -261,7 +261,7 @@ XMUTEX (Lisp_Object a)
261/* A condition variable as a lisp object. */ 261/* A condition variable as a lisp object. */
262struct Lisp_CondVar 262struct Lisp_CondVar
263{ 263{
264 struct vectorlike_header header; 264 union vectorlike_header header;
265 265
266 /* The associated mutex. */ 266 /* The associated mutex. */
267 Lisp_Object mutex; 267 Lisp_Object mutex;
diff --git a/src/w32term.h b/src/w32term.h
index 8d08ca0a2bf..de234cb57db 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -431,7 +431,7 @@ extern struct w32_output w32term_display;
431struct scroll_bar { 431struct scroll_bar {
432 432
433 /* This field is shared by all vectors. */ 433 /* This field is shared by all vectors. */
434 struct vectorlike_header header; 434 union vectorlike_header header;
435 435
436 /* The window we're a scroll bar for. */ 436 /* The window we're a scroll bar for. */
437 Lisp_Object window; 437 Lisp_Object window;
diff --git a/src/window.c b/src/window.c
index cc1d2a7b36e..7f472523b49 100644
--- a/src/window.c
+++ b/src/window.c
@@ -3733,8 +3733,8 @@ make_parent_window (Lisp_Object window, bool horflag)
3733 3733
3734 o = XWINDOW (window); 3734 o = XWINDOW (window);
3735 p = allocate_window (); 3735 p = allocate_window ();
3736 memcpy ((char *) p + sizeof (struct vectorlike_header), 3736 memcpy ((char *) p + sizeof (union vectorlike_header),
3737 (char *) o + sizeof (struct vectorlike_header), 3737 (char *) o + sizeof (union vectorlike_header),
3738 word_size * VECSIZE (struct window)); 3738 word_size * VECSIZE (struct window));
3739 /* P's buffer slot may change from nil to a buffer... */ 3739 /* P's buffer slot may change from nil to a buffer... */
3740 adjust_window_count (p, 1); 3740 adjust_window_count (p, 1);
@@ -6232,7 +6232,7 @@ from the top of the window. */)
6232 6232
6233struct save_window_data 6233struct save_window_data
6234 { 6234 {
6235 struct vectorlike_header header; 6235 union vectorlike_header header;
6236 Lisp_Object selected_frame; 6236 Lisp_Object selected_frame;
6237 Lisp_Object current_window; 6237 Lisp_Object current_window;
6238 Lisp_Object f_current_buffer; 6238 Lisp_Object f_current_buffer;
@@ -6260,7 +6260,7 @@ struct save_window_data
6260/* This is saved as a Lisp_Vector. */ 6260/* This is saved as a Lisp_Vector. */
6261struct saved_window 6261struct saved_window
6262{ 6262{
6263 struct vectorlike_header header; 6263 union vectorlike_header header;
6264 6264
6265 Lisp_Object window, buffer, start, pointm, old_pointm; 6265 Lisp_Object window, buffer, start, pointm, old_pointm;
6266 Lisp_Object pixel_left, pixel_top, pixel_height, pixel_width; 6266 Lisp_Object pixel_left, pixel_top, pixel_height, pixel_width;
diff --git a/src/window.h b/src/window.h
index df7c23f824b..25c9686a9f0 100644
--- a/src/window.h
+++ b/src/window.h
@@ -88,7 +88,7 @@ struct cursor_pos
88struct window 88struct window
89 { 89 {
90 /* This is for Lisp; the terminal code does not refer to it. */ 90 /* This is for Lisp; the terminal code does not refer to it. */
91 struct vectorlike_header header; 91 union vectorlike_header header;
92 92
93 /* The frame this window is on. */ 93 /* The frame this window is on. */
94 Lisp_Object frame; 94 Lisp_Object frame;
diff --git a/src/xterm.c b/src/xterm.c
index e11cde771ab..28abfaecde9 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -231,7 +231,7 @@ static void x_sync_with_move (struct frame *, int, int, bool);
231static int handle_one_xevent (struct x_display_info *, 231static int handle_one_xevent (struct x_display_info *,
232 const XEvent *, int *, 232 const XEvent *, int *,
233 struct input_event *); 233 struct input_event *);
234#if ! (defined USE_X_TOOLKIT || defined USE_MOTIF) 234#if ! (defined USE_X_TOOLKIT || defined USE_MOTIF) && defined USE_GTK
235static int x_dispatch_event (XEvent *, Display *); 235static int x_dispatch_event (XEvent *, Display *);
236#endif 236#endif
237static void x_wm_set_window_state (struct frame *, int); 237static void x_wm_set_window_state (struct frame *, int);
@@ -9047,6 +9047,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
9047 return count; 9047 return count;
9048} 9048}
9049 9049
9050#if defined USE_X_TOOLKIT || defined USE_MOTIF || defined USE_GTK
9051
9050/* Handles the XEvent EVENT on display DISPLAY. 9052/* Handles the XEvent EVENT on display DISPLAY.
9051 This is used for event loops outside the normal event handling, 9053 This is used for event loops outside the normal event handling,
9052 i.e. looping while a popup menu or a dialog is posted. 9054 i.e. looping while a popup menu or a dialog is posted.
@@ -9065,6 +9067,7 @@ x_dispatch_event (XEvent *event, Display *display)
9065 9067
9066 return finish; 9068 return finish;
9067} 9069}
9070#endif
9068 9071
9069/* Read events coming from the X server. 9072/* Read events coming from the X server.
9070 Return as soon as there are no more events to be read. 9073 Return as soon as there are no more events to be read.
@@ -12512,7 +12515,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
12512 { 12515 {
12513 terminal->kboard = allocate_kboard (Qx); 12516 terminal->kboard = allocate_kboard (Qx);
12514 12517
12515 if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->function, Qunbound)) 12518 if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->u.s.function, Qunbound))
12516 { 12519 {
12517 char *vendor = ServerVendor (dpy); 12520 char *vendor = ServerVendor (dpy);
12518 12521
diff --git a/src/xterm.h b/src/xterm.h
index 6274630706f..7ab20ba06c6 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -887,7 +887,7 @@ extern void x_mark_frame_dirty (struct frame *f);
887struct scroll_bar 887struct scroll_bar
888{ 888{
889 /* These fields are shared by all vectors. */ 889 /* These fields are shared by all vectors. */
890 struct vectorlike_header header; 890 union vectorlike_header header;
891 891
892 /* The window we're a scroll bar for. */ 892 /* The window we're a scroll bar for. */
893 Lisp_Object window; 893 Lisp_Object window;
diff --git a/src/xwidget.h b/src/xwidget.h
index 22a8eb3a557..02a0453dabb 100644
--- a/src/xwidget.h
+++ b/src/xwidget.h
@@ -33,7 +33,7 @@ struct window;
33 33
34struct xwidget 34struct xwidget
35{ 35{
36 struct vectorlike_header header; 36 union vectorlike_header header;
37 37
38 /* Auxiliary data. */ 38 /* Auxiliary data. */
39 Lisp_Object plist; 39 Lisp_Object plist;
@@ -62,7 +62,7 @@ struct xwidget
62 62
63struct xwidget_view 63struct xwidget_view
64{ 64{
65 struct vectorlike_header header; 65 union vectorlike_header header;
66 Lisp_Object model; 66 Lisp_Object model;
67 Lisp_Object w; 67 Lisp_Object w;
68 68