]> git.eshelyaron.com Git - emacs.git/commitdiff
(struct charset): Remove dependency on hash-table internals
authorStefan Monnier <monnier@iro.umontreal.ca>
Wed, 24 Jan 2024 03:30:13 +0000 (22:30 -0500)
committerEshel Yaron <me@eshelyaron.com>
Wed, 24 Jan 2024 18:31:53 +0000 (19:31 +0100)
`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.

(cherry picked from commit 33b8d5b6c5a22bab069cdac4bddda932b3d18b13)

src/charset.c
src/charset.h
src/pdumper.c

index f562af90cb2cafa7f0e4fa4917cc00d655a778e8..9633ccaaef900f173b73d634cefbe3be22ec556e 100644 (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);
+}
+*/
+
 \f
 void
 init_charset (void)
index ba83cd5ccb2e3e7db87add57e2e70cf02af5d056..1edb4a248ac8714d33a15233291619479aadc11b 100644 (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)
index bff11ada02ca85d7a2e92220b14c12a34b25d991..9c9a1ff382cc842d71c84c26cf400048f59d4b83 100644 (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;