]> git.eshelyaron.com Git - emacs.git/commitdiff
Use key Qunbound instead of hash value hash_unused for free entries
authorMattias Engdegård <mattiase@acm.org>
Tue, 21 Nov 2023 21:12:08 +0000 (22:12 +0100)
committerMattias Engdegård <mattiase@acm.org>
Sat, 13 Jan 2024 19:50:39 +0000 (20:50 +0100)
Previously, free hash table entries were indicated by both hash value
hash_unused and key Qunbound; we now rely on the latter only.
This allows us to change the hash representation to one that does not
have an unused value.

* src/lisp.h (hash_unused): Remove.
All uses adapted to calling hash_unused_entry_key_p on the key instead.
The hash values for unused hash table entries are now undefined; all
initialisation and assignment to hash_unused has been removed.

src/fns.c
src/lisp.h
src/macfont.m
src/pdumper.c

index b68fb393703fde0088122c8ede19fb8047fd9821..ed7b7bb2024a9664050fbe65ce1b3e89e5827749 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -4577,8 +4577,6 @@ make_hash_table (const struct hash_table_test *test, EMACS_INT size,
        h->key_and_value[i] = HASH_UNUSED_ENTRY_KEY;
 
       h->hash = hash_table_alloc_bytes (size * sizeof *h->hash);
-      for (ptrdiff_t i = 0; i < size; i++)
-       h->hash[i] = hash_unused;
 
       h->next = hash_table_alloc_bytes (size * sizeof *h->next);
       for (ptrdiff_t i = 0; i < size - 1; i++)
@@ -4682,8 +4680,6 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
 
       hash_hash_t *hash = hash_table_alloc_bytes (new_size * sizeof *hash);
       memcpy (hash, h->hash, old_size * sizeof *hash);
-      for (ptrdiff_t i = old_size; i < new_size; i++)
-       hash[i] = hash_unused;
 
       ptrdiff_t old_index_size = h->index_size;
       ptrdiff_t index_size = hash_index_size (new_size);
@@ -4755,8 +4751,6 @@ hash_table_thaw (Lisp_Object hash_table)
   h->next_free = -1;
 
   h->hash = hash_table_alloc_bytes (size * sizeof *h->hash);
-  for (ptrdiff_t i = 0; i < size; i++)
-    h->hash[i] = hash_unused;
 
   h->next = hash_table_alloc_bytes (size * sizeof *h->next);
   for (ptrdiff_t i = 0; i < size; i++)
@@ -4831,14 +4825,13 @@ ptrdiff_t
 hash_put (struct Lisp_Hash_Table *h, Lisp_Object key, Lisp_Object value,
          hash_hash_t hash)
 {
-  eassert (!BASE_EQ (key, Qunbound));
+  eassert (!hash_unused_entry_key_p (key));
   /* Increment count after resizing because resizing may fail.  */
   maybe_resize_hash_table (h);
   h->count++;
 
   /* Store key/value in the key_and_value vector.  */
   ptrdiff_t i = h->next_free;
-  eassert (HASH_HASH (h, i) == hash_unused);
   eassert (hash_unused_entry_key_p (HASH_KEY (h, i)));
   h->next_free = HASH_NEXT (h, i);
   set_hash_key_slot (h, i, key);
@@ -4883,7 +4876,6 @@ hash_remove_from_table (struct Lisp_Hash_Table *h, Lisp_Object key)
             the free list.  */
          set_hash_key_slot (h, i, HASH_UNUSED_ENTRY_KEY);
          set_hash_value_slot (h, i, Qnil);
-         set_hash_hash_slot (h, i, hash_unused);
          set_hash_next_slot (h, i, h->next_free);
          h->next_free = i;
          h->count--;
@@ -4906,7 +4898,6 @@ hash_clear (struct Lisp_Hash_Table *h)
       ptrdiff_t size = HASH_TABLE_SIZE (h);
       for (ptrdiff_t i = 0; i < size; i++)
        {
-         set_hash_hash_slot (h, i, hash_unused);
          set_hash_next_slot (h, i, i < size - 1 ? i + 1 : -1);
          set_hash_key_slot (h, i, HASH_UNUSED_ENTRY_KEY);
          set_hash_value_slot (h, i, Qnil);
@@ -4986,10 +4977,9 @@ sweep_weak_table (struct Lisp_Hash_Table *h, bool remove_entries_p)
                  set_hash_next_slot (h, i, h->next_free);
                  h->next_free = i;
 
-                 /* Clear key, value, and hash.  */
+                 /* Clear key and value.  */
                  set_hash_key_slot (h, i, HASH_UNUSED_ENTRY_KEY);
                  set_hash_value_slot (h, i, Qnil);
-                 set_hash_hash_slot (h, i, hash_unused);
 
                   eassert (h->count != 0);
                   h->count--;
index f27f506b58ffe3a9f5064fe5b6ad705421f2e3e6..0701028c14cd0691d250825354ffa0df0af85831 100644 (file)
@@ -2425,11 +2425,6 @@ typedef enum {
                            both key and value remain.  */
 } hash_table_weakness_t;
 
-/* An value that marks an unused hash entry.
-   Any hash_hash_t value that is not a valid fixnum will do here.  */
-enum { hash_unused = (hash_hash_t)MOST_POSITIVE_FIXNUM + 1 };
-verify (FIXNUM_OVERFLOW_P (hash_unused));
-
 /* The type of a hash table index, both for table indices and index
    (hash) indices.  It's signed and a subtype of ptrdiff_t.  */
 typedef int32_t hash_idx_t;
@@ -2475,7 +2470,7 @@ struct Lisp_Hash_Table
      Otherwise it is heap-allocated.  */
   hash_idx_t *index;
 
-  /* Vector of hash codes.  The value hash_unused marks an unused table entry.
+  /* Vector of hash codes.  Unused entries have undefined values.
      This vector is table_size entries long.  */
   hash_hash_t *hash;
 
index 48502c2ec00a627b062d763849349fdf365a3ab1..6f192b00f1b1be63c49d4c342dac7d2c0fa2dfb6 100644 (file)
@@ -980,7 +980,7 @@ macfont_invalidate_family_cache (void)
       ptrdiff_t i, size = HASH_TABLE_SIZE (h);
 
       for (i = 0; i < size; ++i)
-       if (HASH_HASH (h, i) != hash_unused)
+       if (!hash_unused_entry_key_p (HASH_KEY (h, i)))
          {
            Lisp_Object value = HASH_VALUE (h, i);
 
index 38682816f0a26e28774b4ab0bc84c7b2bdfb36ea..54f0f2bca1331dc1087f49bd027dd9eb8abbd568 100644 (file)
@@ -2676,11 +2676,14 @@ hash_table_contents (struct Lisp_Hash_Table *h)
      relies on it by expecting hash table indices to stay constant
      across the dump.  */
   for (ptrdiff_t i = 0; i < old_size; i++)
-    if (HASH_HASH (h, i) != hash_unused)
-      {
-       key_and_value[n++] = HASH_KEY (h, i);
-       key_and_value[n++] = HASH_VALUE (h, i);
-      }
+    {
+      Lisp_Object key = HASH_KEY (h, i);
+      if (!hash_unused_entry_key_p (key))
+       {
+         key_and_value[n++] = key;
+         key_and_value[n++] = HASH_VALUE (h, i);
+       }
+    }
 
   return key_and_value;
 }