emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 0dc5a85 3/3: Don't dump the `hash` vector if it wil


From: Stefan Monnier
Subject: [Emacs-diffs] master 0dc5a85 3/3: Don't dump the `hash` vector if it will need to be recomputed anyway
Date: Fri, 26 Jul 2019 15:03:08 -0400 (EDT)

branch: master
commit 0dc5a85a1c3772a6e78f077719d82f437f626b1e
Author: Stefan Monnier <address@hidden>
Commit: Stefan Monnier <address@hidden>

    Don't dump the `hash` vector if it will need to be recomputed anyway
    
    * src/fns.c (hash_table_rehash): Only set `hash` field at the end.
    (sweep_weak_table): Only set slot of `hash` vector when that vector exists.
    (Fhash_table_count): No need to hash_rehash_if_needed any more.
    
    * src/lisp.h (hash_rehash_needed_p): Test the presence of `hash` instead.
    
    * src/pdumper.c (check_hash_table_rehash, dump_hash_table):
    Set `hash` to nil to indicate that the table needs to be rehashed.
---
 src/fns.c     | 15 ++++++++-------
 src/lisp.h    |  2 +-
 src/pdumper.c | 10 ++++++++--
 3 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/src/fns.c b/src/fns.c
index 3c85dbe..acc6d46 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -4246,9 +4246,9 @@ hash_table_rehash (struct Lisp_Hash_Table *h)
 
   /* These structures may have been purecopied and shared
      (bug#36447).  */
+  Lisp_Object hash = make_nil_vector (size);
   h->next = Fcopy_sequence (h->next);
   h->index = Fcopy_sequence (h->index);
-  h->hash = make_nil_vector (size);
 
   /* Recompute the actual hash codes for each entry in the table.
      Order is still invalid.  */
@@ -4256,7 +4256,7 @@ hash_table_rehash (struct Lisp_Hash_Table *h)
     {
       Lisp_Object key = HASH_KEY (h, i);
       if (!EQ (key, Qunbound))
-       set_hash_hash_slot (h, i, h->test.hashfn (key, h));
+        ASET (hash, i, h->test.hashfn (key, h));
     }
 
   /* Reset the index so that any slot we don't fill below is marked
@@ -4265,9 +4265,9 @@ hash_table_rehash (struct Lisp_Hash_Table *h)
 
   /* Rebuild the collision chains.  */
   for (ptrdiff_t i = 0; i < size; ++i)
-    if (!NILP (HASH_HASH (h, i)))
+    if (!NILP (AREF (hash, i)))
       {
-        EMACS_UINT hash_code = XUFIXNUM (HASH_HASH (h, i));
+        EMACS_UINT hash_code = XUFIXNUM (AREF (hash, i));
         ptrdiff_t start_of_bucket = hash_code % ASIZE (h->index);
         set_hash_next_slot (h, i, HASH_INDEX (h, start_of_bucket));
         set_hash_index_slot (h, start_of_bucket, i);
@@ -4278,7 +4278,7 @@ hash_table_rehash (struct Lisp_Hash_Table *h)
      Do this last so that if we're interrupted, we retry on next
      access. */
   eassert (hash_rehash_needed_p (h));
-  h->count = -h->count;
+  h->hash = hash;
   eassert (!hash_rehash_needed_p (h));
 }
 
@@ -4483,7 +4483,8 @@ sweep_weak_table (struct Lisp_Hash_Table *h, bool 
remove_entries_p)
                  /* Clear key, value, and hash.  */
                  set_hash_key_slot (h, i, Qunbound);
                  set_hash_value_slot (h, i, Qnil);
-                  set_hash_hash_slot (h, i, Qnil);
+                  if (!NILP (h->hash))
+                    set_hash_hash_slot (h, i, Qnil);
 
                   eassert (h->count != 0);
                   h->count += h->count > 0 ? -1 : 1;
@@ -4889,7 +4890,7 @@ DEFUN ("hash-table-count", Fhash_table_count, 
Shash_table_count, 1, 1, 0,
   (Lisp_Object table)
 {
   struct Lisp_Hash_Table *h = check_hash_table (table);
-  hash_rehash_if_needed (h);
+  eassert (h->count >= 0);
   return make_fixnum (h->count);
 }
 
diff --git a/src/lisp.h b/src/lisp.h
index 6807986..f437609 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2388,7 +2388,7 @@ void hash_table_rehash (struct Lisp_Hash_Table *h);
 INLINE bool
 hash_rehash_needed_p (const struct Lisp_Hash_Table *h)
 {
-  return h->count < 0;
+  return NILP (h->hash);
 }
 
 INLINE void
diff --git a/src/pdumper.c b/src/pdumper.c
index 4ba819b..1a5d1f3 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -2666,7 +2666,7 @@ check_hash_table_rehash (Lisp_Object table_orig)
   hash_rehash_if_needed (XHASH_TABLE (table_orig));
   Lisp_Object table_rehashed = Fcopy_hash_table (table_orig);
   eassert (!hash_rehash_needed_p (XHASH_TABLE (table_rehashed)));
-  XHASH_TABLE (table_rehashed)->count *= -1;
+  XHASH_TABLE (table_rehashed)->hash = Qnil;
   eassert (count == 0 || hash_rehash_needed_p (XHASH_TABLE (table_rehashed)));
   hash_rehash_if_needed (XHASH_TABLE (table_rehashed));
   eassert (!hash_rehash_needed_p (XHASH_TABLE (table_rehashed)));
@@ -2733,7 +2733,13 @@ dump_hash_table (struct dump_context *ctx,
      the need to rehash-on-access if we can load the dump where we
      want.  */
   if (hash->count > 0 && !is_stable)
-    hash->count = -hash->count;
+    /* Hash codes will have to be recomputed anyway, so let's not dump them.
+       Also set `hash` to nil for hash_rehash_needed_p.
+       We could also refrain from dumping the `next' and `index' vectors,
+       except that `next' is currently used for HASH_TABLE_SIZE and
+       we'd have to rebuild the next_free list as well as adjust
+       sweep_weak_hash_table for the case where there's no `index'.  */
+    hash->hash = Qnil;
 
   START_DUMP_PVEC (ctx, &hash->header, struct Lisp_Hash_Table, out);
   dump_pseudovector_lisp_fields (ctx, &out->header, &hash->header);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]