[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);