aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2019-07-26 14:59:15 -0400
committerStefan Monnier2019-07-26 15:03:03 -0400
commit0dc5a85a1c3772a6e78f077719d82f437f626b1e (patch)
treeabe77c1082f55453027d08937302a3e122069be7 /src
parentc74da403aa95ec67598c41aa4f1b97975391135b (diff)
downloademacs-0dc5a85a1c3772a6e78f077719d82f437f626b1e.tar.gz
emacs-0dc5a85a1c3772a6e78f077719d82f437f626b1e.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/fns.c15
-rw-r--r--src/lisp.h2
-rw-r--r--src/pdumper.c10
3 files changed, 17 insertions, 10 deletions
diff --git a/src/fns.c b/src/fns.c
index 3c85dbeae53..acc6d46db85 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -4246,9 +4246,9 @@ hash_table_rehash (struct Lisp_Hash_Table *h)
4246 4246
4247 /* These structures may have been purecopied and shared 4247 /* These structures may have been purecopied and shared
4248 (bug#36447). */ 4248 (bug#36447). */
4249 Lisp_Object hash = make_nil_vector (size);
4249 h->next = Fcopy_sequence (h->next); 4250 h->next = Fcopy_sequence (h->next);
4250 h->index = Fcopy_sequence (h->index); 4251 h->index = Fcopy_sequence (h->index);
4251 h->hash = make_nil_vector (size);
4252 4252
4253 /* Recompute the actual hash codes for each entry in the table. 4253 /* Recompute the actual hash codes for each entry in the table.
4254 Order is still invalid. */ 4254 Order is still invalid. */
@@ -4256,7 +4256,7 @@ hash_table_rehash (struct Lisp_Hash_Table *h)
4256 { 4256 {
4257 Lisp_Object key = HASH_KEY (h, i); 4257 Lisp_Object key = HASH_KEY (h, i);
4258 if (!EQ (key, Qunbound)) 4258 if (!EQ (key, Qunbound))
4259 set_hash_hash_slot (h, i, h->test.hashfn (key, h)); 4259 ASET (hash, i, h->test.hashfn (key, h));
4260 } 4260 }
4261 4261
4262 /* Reset the index so that any slot we don't fill below is marked 4262 /* 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)
4265 4265
4266 /* Rebuild the collision chains. */ 4266 /* Rebuild the collision chains. */
4267 for (ptrdiff_t i = 0; i < size; ++i) 4267 for (ptrdiff_t i = 0; i < size; ++i)
4268 if (!NILP (HASH_HASH (h, i))) 4268 if (!NILP (AREF (hash, i)))
4269 { 4269 {
4270 EMACS_UINT hash_code = XUFIXNUM (HASH_HASH (h, i)); 4270 EMACS_UINT hash_code = XUFIXNUM (AREF (hash, i));
4271 ptrdiff_t start_of_bucket = hash_code % ASIZE (h->index); 4271 ptrdiff_t start_of_bucket = hash_code % ASIZE (h->index);
4272 set_hash_next_slot (h, i, HASH_INDEX (h, start_of_bucket)); 4272 set_hash_next_slot (h, i, HASH_INDEX (h, start_of_bucket));
4273 set_hash_index_slot (h, start_of_bucket, i); 4273 set_hash_index_slot (h, start_of_bucket, i);
@@ -4278,7 +4278,7 @@ hash_table_rehash (struct Lisp_Hash_Table *h)
4278 Do this last so that if we're interrupted, we retry on next 4278 Do this last so that if we're interrupted, we retry on next
4279 access. */ 4279 access. */
4280 eassert (hash_rehash_needed_p (h)); 4280 eassert (hash_rehash_needed_p (h));
4281 h->count = -h->count; 4281 h->hash = hash;
4282 eassert (!hash_rehash_needed_p (h)); 4282 eassert (!hash_rehash_needed_p (h));
4283} 4283}
4284 4284
@@ -4483,7 +4483,8 @@ sweep_weak_table (struct Lisp_Hash_Table *h, bool remove_entries_p)
4483 /* Clear key, value, and hash. */ 4483 /* Clear key, value, and hash. */
4484 set_hash_key_slot (h, i, Qunbound); 4484 set_hash_key_slot (h, i, Qunbound);
4485 set_hash_value_slot (h, i, Qnil); 4485 set_hash_value_slot (h, i, Qnil);
4486 set_hash_hash_slot (h, i, Qnil); 4486 if (!NILP (h->hash))
4487 set_hash_hash_slot (h, i, Qnil);
4487 4488
4488 eassert (h->count != 0); 4489 eassert (h->count != 0);
4489 h->count += h->count > 0 ? -1 : 1; 4490 h->count += h->count > 0 ? -1 : 1;
@@ -4889,7 +4890,7 @@ DEFUN ("hash-table-count", Fhash_table_count, Shash_table_count, 1, 1, 0,
4889 (Lisp_Object table) 4890 (Lisp_Object table)
4890{ 4891{
4891 struct Lisp_Hash_Table *h = check_hash_table (table); 4892 struct Lisp_Hash_Table *h = check_hash_table (table);
4892 hash_rehash_if_needed (h); 4893 eassert (h->count >= 0);
4893 return make_fixnum (h->count); 4894 return make_fixnum (h->count);
4894} 4895}
4895 4896
diff --git a/src/lisp.h b/src/lisp.h
index 680798621ca..f437609fe1f 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2388,7 +2388,7 @@ void hash_table_rehash (struct Lisp_Hash_Table *h);
2388INLINE bool 2388INLINE bool
2389hash_rehash_needed_p (const struct Lisp_Hash_Table *h) 2389hash_rehash_needed_p (const struct Lisp_Hash_Table *h)
2390{ 2390{
2391 return h->count < 0; 2391 return NILP (h->hash);
2392} 2392}
2393 2393
2394INLINE void 2394INLINE void
diff --git a/src/pdumper.c b/src/pdumper.c
index 4ba819b4103..1a5d1f32ba5 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -2666,7 +2666,7 @@ check_hash_table_rehash (Lisp_Object table_orig)
2666 hash_rehash_if_needed (XHASH_TABLE (table_orig)); 2666 hash_rehash_if_needed (XHASH_TABLE (table_orig));
2667 Lisp_Object table_rehashed = Fcopy_hash_table (table_orig); 2667 Lisp_Object table_rehashed = Fcopy_hash_table (table_orig);
2668 eassert (!hash_rehash_needed_p (XHASH_TABLE (table_rehashed))); 2668 eassert (!hash_rehash_needed_p (XHASH_TABLE (table_rehashed)));
2669 XHASH_TABLE (table_rehashed)->count *= -1; 2669 XHASH_TABLE (table_rehashed)->hash = Qnil;
2670 eassert (count == 0 || hash_rehash_needed_p (XHASH_TABLE (table_rehashed))); 2670 eassert (count == 0 || hash_rehash_needed_p (XHASH_TABLE (table_rehashed)));
2671 hash_rehash_if_needed (XHASH_TABLE (table_rehashed)); 2671 hash_rehash_if_needed (XHASH_TABLE (table_rehashed));
2672 eassert (!hash_rehash_needed_p (XHASH_TABLE (table_rehashed))); 2672 eassert (!hash_rehash_needed_p (XHASH_TABLE (table_rehashed)));
@@ -2733,7 +2733,13 @@ dump_hash_table (struct dump_context *ctx,
2733 the need to rehash-on-access if we can load the dump where we 2733 the need to rehash-on-access if we can load the dump where we
2734 want. */ 2734 want. */
2735 if (hash->count > 0 && !is_stable) 2735 if (hash->count > 0 && !is_stable)
2736 hash->count = -hash->count; 2736 /* Hash codes will have to be recomputed anyway, so let's not dump them.
2737 Also set `hash` to nil for hash_rehash_needed_p.
2738 We could also refrain from dumping the `next' and `index' vectors,
2739 except that `next' is currently used for HASH_TABLE_SIZE and
2740 we'd have to rebuild the next_free list as well as adjust
2741 sweep_weak_hash_table for the case where there's no `index'. */
2742 hash->hash = Qnil;
2737 2743
2738 START_DUMP_PVEC (ctx, &hash->header, struct Lisp_Hash_Table, out); 2744 START_DUMP_PVEC (ctx, &hash->header, struct Lisp_Hash_Table, out);
2739 dump_pseudovector_lisp_fields (ctx, &out->header, &hash->header); 2745 dump_pseudovector_lisp_fields (ctx, &out->header, &hash->header);