]> git.eshelyaron.com Git - emacs.git/commitdiff
Don't dump the `hash` vector if it will need to be recomputed anyway
authorStefan Monnier <monnier@iro.umontreal.ca>
Fri, 26 Jul 2019 18:59:15 +0000 (14:59 -0400)
committerStefan Monnier <monnier@iro.umontreal.ca>
Fri, 26 Jul 2019 19:03:03 +0000 (15:03 -0400)
* 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
src/lisp.h
src/pdumper.c

index 3c85dbeae532efd26eaf16e0ec6f9fb5bd3d7502..acc6d46db858bddcba70b33aa1e125f109ec08b9 100644 (file)
--- 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);
 }
 
index 680798621cac79468820557c8c0928cf2f6c5941..f437609fe1ff5d83b2fa0a0dc201eadedc9552b9 100644 (file)
@@ -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
index 4ba819b41037689cec3b6ef40ce493b842508939..1a5d1f32ba5f2db9ccec9dcbfd91eca01ccb9948 100644 (file)
@@ -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);