diff options
| author | Paul Eggert | 2017-11-13 10:54:20 -0800 |
|---|---|---|
| committer | Paul Eggert | 2017-11-13 10:54:20 -0800 |
| commit | 99ceefa8ec4f9993663492cfcce6bb82a94569c1 (patch) | |
| tree | 507f76715b3086f34672b7c984dc09befaa57fc6 /src/alloc.c | |
| parent | a7b7b85567f766ff510a5eaaaf32dbbbec15efd0 (diff) | |
| parent | 79108894dbcd642121466bb6af6c98c6a56e9233 (diff) | |
| download | emacs-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/alloc.c')
| -rw-r--r-- | src/alloc.c | 234 |
1 files changed, 111 insertions, 123 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 | |||
| 1818 | string_bytes (struct Lisp_String *s) | 1818 | string_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 | ||
| 1973 | void | 1974 | void |
| 1974 | allocate_string_data (struct Lisp_String *s, | 1975 | allocate_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; | |||
| 2731 | void | 2732 | void |
| 2732 | free_cons (struct Lisp_Cons *ptr) | 2733 | free_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 | ||
| 2926 | enum | 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 | 2933 | enum {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 | 2936 | enum { 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. */ |
| 2941 | verify (VECTOR_BLOCK_SIZE % roundup_size == 0); | 2939 | verify (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 | |||
| 3551 | union 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 | ||
| 3565 | struct symbol_block | 3553 | struct 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; | |||
| 3589 | static void | 3577 | static void |
| 3590 | set_symbol_name (Lisp_Object sym, Lisp_Object name) | 3578 | set_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 | ||
| 3595 | void | 3583 | void |
| @@ -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 | ||
| 3612 | DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0, | 3600 | DEFUN ("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); |