(struct charset): Remove dependency on hash-table internals

`struct charset` kept an index into the internal `key_and_value` array
of hash tables, which only worked because of details of how
hash-tables are handled.  Replace it with a reference to the
value stored at that location in the hash-table, which saves us an
indirection while at it.

* src/charset.h (struct charset): Replace `hash_index` field with
`attributes` field.
(CHARSET_ATTRIBUTES): Simplify accordingly.
(CHARSET_HASH_INDEX): Delete unused macro.
* src/charset.c (Fdefine_charset_internal):
* src/pdumper.c (dump_charset): Adjust accordingly.
(dump_charset_table): Set the referrer since that's needed while
dumping Lisp_Object fields.
This commit is contained in:
Stefan Monnier 2024-01-23 22:30:13 -05:00
parent 13c7249105
commit 33b8d5b6c5
3 changed files with 29 additions and 16 deletions

View file

@ -1108,18 +1108,18 @@ usage: (define-charset-internal ...) */)
ASET (attrs, charset_plist, args[charset_arg_plist]);
hash_hash_t hash_code;
charset.hash_index = hash_lookup_get_hash (hash_table, args[charset_arg_name],
&hash_code);
if (charset.hash_index >= 0)
ptrdiff_t hash_index
= hash_lookup_get_hash (hash_table, args[charset_arg_name],
&hash_code);
if (hash_index >= 0)
{
new_definition_p = 0;
new_definition_p = false;
id = XFIXNAT (CHARSET_SYMBOL_ID (args[charset_arg_name]));
set_hash_value_slot (hash_table, charset.hash_index, attrs);
set_hash_value_slot (hash_table, hash_index, attrs);
}
else
{
charset.hash_index = hash_put (hash_table, args[charset_arg_name], attrs,
hash_code);
hash_put (hash_table, args[charset_arg_name], attrs, hash_code);
if (charset_table_used == charset_table_size)
{
/* Ensure that charset IDs fit into 'int' as well as into the
@ -1150,6 +1150,7 @@ usage: (define-charset-internal ...) */)
ASET (attrs, charset_id, make_fixnum (id));
charset.id = id;
charset.attributes = attrs;
charset_table[id] = charset;
if (charset.method == CHARSET_METHOD_MAP)
@ -2269,6 +2270,16 @@ 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)

View file

@ -150,8 +150,7 @@ struct charset
/* Index to charset_table. */
int id;
/* Index to Vcharset_hash_table. */
ptrdiff_t hash_index;
Lisp_Object attributes;
/* Dimension of the charset: 1, 2, 3, or 4. */
int dimension;
@ -289,11 +288,9 @@ extern int emacs_mule_charset[256];
hash_lookup (XHASH_TABLE (Vcharset_hash_table), symbol)
/* Return the attribute vector of CHARSET. */
#define CHARSET_ATTRIBUTES(charset) \
HASH_VALUE (XHASH_TABLE (Vcharset_hash_table), (charset)->hash_index)
#define CHARSET_ATTRIBUTES(charset) (charset)->attributes
#define CHARSET_ID(charset) ((charset)->id)
#define CHARSET_HASH_INDEX(charset) ((charset)->hash_index)
#define CHARSET_DIMENSION(charset) ((charset)->dimension)
#define CHARSET_CODE_SPACE(charset) ((charset)->code_space)
#define CHARSET_CODE_LINEAR_P(charset) ((charset)->code_linear_p)

View file

@ -2650,9 +2650,11 @@ hash_table_contents (struct Lisp_Hash_Table *h)
* sizeof *key_and_value);
ptrdiff_t n = 0;
/* Make sure key_and_value ends up in the same order; charset.c
relies on it by expecting hash table indices to stay constant
across the dump. */
/* Make sure key_and_value ends up in the same order; the `hash_index`
field of `struct composition` relies on it by expecting hash table
indices to stay constant across the dump.
FIXME: Remove such dependency on hash table internals (there might
be another one in `composition_gstring_from_id`). */
DOHASH (h, i)
{
key_and_value[n++] = HASH_KEY (h, i);
@ -3224,7 +3226,7 @@ dump_charset (struct dump_context *ctx, int cs_i)
struct charset out;
dump_object_start (ctx, &out, sizeof (out));
DUMP_FIELD_COPY (&out, cs, id);
DUMP_FIELD_COPY (&out, cs, hash_index);
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_i < charset_table_used && cs->code_space_mask)
@ -3262,12 +3264,15 @@ dump_charset_table (struct dump_context *ctx)
ctx->flags.pack_objects = true;
dump_align_output (ctx, DUMP_ALIGNMENT);
dump_off offset = ctx->offset;
if (dump_set_referrer (ctx))
ctx->current_referrer = build_string ("charset_table");
/* We are dumping the entire table, not just the used slots, because
otherwise when we restore from the pdump file, the actual size of
the table will be smaller than charset_table_size, and we will
crash if/when a new charset is defined. */
for (int i = 0; i < charset_table_size; ++i)
dump_charset (ctx, i);
dump_clear_referrer (ctx);
dump_emacs_reloc_to_dump_ptr_raw (ctx, &charset_table, offset);
ctx->flags = old_flags;
return offset;