diff --git a/src/alloc.c b/src/alloc.c index c0c24c65737..5da38cadb5d 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -5866,7 +5866,6 @@ garbage_collect (void) mark_terminals (); mark_kboards (); mark_threads (); - mark_charset (); mark_composite (); mark_profiler (); #ifdef HAVE_PGTK diff --git a/src/charset.c b/src/charset.c index 42dc6a60367..11d181d4032 100644 --- a/src/charset.c +++ b/src/charset.c @@ -65,6 +65,12 @@ struct charset *charset_table; int charset_table_size; int charset_table_used; +/* Table of attribute vectors. charset_attributes_table[id] contains + the attribute vector for the charset at charset_table[id]. + + This is a separate vector to simplify GC. */ +Lisp_Object charset_attributes_table; + /* Special charsets corresponding to symbols. */ int charset_ascii; int charset_eight_bit; @@ -1131,13 +1137,19 @@ usage: (define-charset-internal ...) */) coding_system.charbuf[i] entries, which are 'int'. */ int old_size = charset_table_size; ptrdiff_t new_size = old_size; - struct charset *new_table = - xpalloc (0, &new_size, 1, - min (INT_MAX, MOST_POSITIVE_FIXNUM), - sizeof *charset_table); - memcpy (new_table, charset_table, old_size * sizeof *new_table); - charset_table = new_table; + struct charset *new_table + = xpalloc (0, &new_size, 1, + min (INT_MAX, MOST_POSITIVE_FIXNUM), + sizeof *charset_table); + memcpy (new_table, charset_table, + old_size * sizeof *new_table); + charset_table = new_table; charset_table_size = new_size; + Lisp_Object new_attr_table = make_vector (new_size, Qnil); + for (size_t i = 0; i < old_size; i++) + ASET (new_attr_table, i, + AREF (charset_attributes_table, i)); + charset_attributes_table = new_attr_table; /* FIXME: This leaks memory, as the old charset_table becomes unreachable. If the old charset table is charset_table_init then this leak is intentional; otherwise, it's unclear. @@ -1152,8 +1164,9 @@ usage: (define-charset-internal ...) */) ASET (attrs, charset_id, make_fixnum (id)); charset.id = id; - charset.attributes = attrs; charset_table[id] = charset; + ASET (charset_attributes_table, id, attrs); + eassert (ASIZE (charset_attributes_table) == charset_table_size); if (charset.method == CHARSET_METHOD_MAP) { @@ -2272,15 +2285,6 @@ See also `charset-priority-list' and `set-charset-priority'. */) return charsets; } -/* Not strictly necessary, because all charset attributes are also - reachable from `Vcharset_hash_table`. */ -void -mark_charset (void) -{ - for (int i = 0; i < charset_table_used; i++) - mark_object (charset_table[i].attributes); -} - void init_charset (void) @@ -2383,6 +2387,9 @@ syms_of_charset (void) charset_table_used = 0; PDUMPER_REMEMBER_SCALAR (charset_table_used); + charset_attributes_table = make_vector (charset_table_size, Qnil); + staticpro (&charset_attributes_table); + defsubr (&Scharsetp); defsubr (&Smap_charset_chars); defsubr (&Sdefine_charset_internal); diff --git a/src/charset.h b/src/charset.h index 56ed62b4473..0738217dc0c 100644 --- a/src/charset.h +++ b/src/charset.h @@ -150,8 +150,6 @@ struct charset /* Index to charset_table. */ int id; - Lisp_Object attributes; - /* Dimension of the charset: 1, 2, 3, or 4. */ int dimension; @@ -250,6 +248,8 @@ extern struct charset *charset_table; extern int charset_table_size; extern int charset_table_used; +extern Lisp_Object charset_attributes_table; + #define CHARSET_FROM_ID(id) (charset_table + (id)) extern Lisp_Object Vcharset_ordered_list; @@ -287,8 +287,14 @@ extern int emacs_mule_charset[256]; #define CHARSET_SYMBOL_HASH_INDEX(symbol) \ hash_find (XHASH_TABLE (Vcharset_hash_table), symbol) +INLINE Lisp_Object +charset_attributes_getter (struct charset *charset) +{ + return AREF (charset_attributes_table, charset->id); +} + /* Return the attribute vector of CHARSET. */ -#define CHARSET_ATTRIBUTES(charset) (charset)->attributes +#define CHARSET_ATTRIBUTES(charset) (charset_attributes_getter (charset)) #define CHARSET_ID(charset) ((charset)->id) #define CHARSET_DIMENSION(charset) ((charset)->dimension) diff --git a/src/lisp.h b/src/lisp.h index 37c34dfbe84..cbd61126a74 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4226,7 +4226,6 @@ extern ptrdiff_t multibyte_chars_in_text (const unsigned char *, ptrdiff_t); extern void syms_of_character (void); /* Defined in charset.c. */ -extern void mark_charset (void); extern void init_charset (void); extern void init_charset_once (void); extern void syms_of_charset (void); diff --git a/src/pdumper.c b/src/pdumper.c index c21af24d9f1..3f338db33c6 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -3208,7 +3208,7 @@ dump_object_for_offset (struct dump_context *ctx, Lisp_Object object) static dump_off dump_charset (struct dump_context *ctx, int cs_i) { -#if CHECK_STRUCTS && !defined (HASH_charset_E31F4B5D96) +#if CHECK_STRUCTS && !defined (HASH_charset_C9F4DCA7A7) # error "charset changed. See CHECK_STRUCTS comment in config.h." #endif /* We can't change the alignment here, because ctx->offset is what @@ -3220,7 +3220,6 @@ dump_charset (struct dump_context *ctx, int cs_i) if (cs_i < charset_table_used) /* Don't look at uninitialized data. */ { DUMP_FIELD_COPY (&out, cs, id); - dump_field_lv (ctx, &out, cs, &cs->attributes, WEIGHT_NORMAL); DUMP_FIELD_COPY (&out, cs, dimension); memcpy (out.code_space, &cs->code_space, sizeof (cs->code_space)); if (cs->code_space_mask)