[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master ceebf3e: Fix clrhash bug when hash table needs reha
From: |
Paul Eggert |
Subject: |
[Emacs-diffs] master ceebf3e: Fix clrhash bug when hash table needs rehashing |
Date: |
Wed, 21 Aug 2019 22:01:54 -0400 (EDT) |
branch: master
commit ceebf3efbea7faffc01558d88c91250539c737e0
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>
Fix clrhash bug when hash table needs rehashing
Problem reported by Pip Cet in:
https://lists.gnu.org/r/emacs-devel/2019-08/msg00316.html
* src/fns.c (maybe_resize_hash_table): Prefer ASET to gc_aset
where either will do. Simplify appending of Qunbound values.
Put index_size calculation closer to where it’s needed.
(hash_clear): If hash_rehash_needed_p (h), don’t clear the
nonexistent hash vector. Use memclear to speed up clearing.
* src/lisp.h (HASH_TABLE_SIZE): Check that the size is positive,
and tell that to the compiler.
---
src/fns.c | 28 ++++++++++++----------------
src/lisp.h | 9 +++++----
2 files changed, 17 insertions(+), 20 deletions(-)
diff --git a/src/fns.c b/src/fns.c
index b606d62..8ca0953 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -4198,21 +4198,20 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
new_size);
ptrdiff_t next_size = ASIZE (next);
for (ptrdiff_t i = old_size; i < next_size - 1; i++)
- gc_aset (next, i, make_fixnum (i + 1));
- gc_aset (next, next_size - 1, make_fixnum (-1));
- ptrdiff_t index_size = hash_index_size (h, next_size);
+ ASET (next, i, make_fixnum (i + 1));
+ ASET (next, next_size - 1, make_fixnum (-1));
/* Build the new&larger key_and_value vector, making sure the new
fields are initialized to `unbound`. */
Lisp_Object key_and_value
= larger_vecalloc (h->key_and_value, 2 * (next_size - old_size),
2 * next_size);
- for (ptrdiff_t i = ASIZE (h->key_and_value);
- i < ASIZE (key_and_value); i++)
+ for (ptrdiff_t i = 2 * old_size; i < 2 * next_size; i++)
ASET (key_and_value, i, Qunbound);
Lisp_Object hash = larger_vector (h->hash, next_size - old_size,
next_size);
+ ptrdiff_t index_size = hash_index_size (h, next_size);
h->index = make_vector (index_size, make_fixnum (-1));
h->key_and_value = key_and_value;
h->hash = hash;
@@ -4404,17 +4403,14 @@ hash_clear (struct Lisp_Hash_Table *h)
{
if (h->count > 0)
{
- ptrdiff_t i, size = HASH_TABLE_SIZE (h);
-
- for (i = 0; i < size; ++i)
- {
- set_hash_next_slot (h, i, i < size - 1 ? i + 1 : -1);
- set_hash_key_slot (h, i, Qunbound);
- set_hash_value_slot (h, i, Qnil);
- set_hash_hash_slot (h, i, Qnil);
- }
-
- for (i = 0; i < ASIZE (h->index); ++i)
+ ptrdiff_t size = HASH_TABLE_SIZE (h);
+ if (!hash_rehash_needed_p (h))
+ memclear (XVECTOR (h->hash)->contents, size * word_size);
+ memclear (XVECTOR (h->key_and_value)->contents, size * 2 * word_size);
+ for (ptrdiff_t i = 0; i < size; i++)
+ set_hash_next_slot (h, i, i < size - 1 ? i + 1 : -1);
+
+ for (ptrdiff_t i = 0; i < ASIZE (h->index); i++)
ASET (h->index, i, make_fixnum (-1));
h->next_free = 0;
diff --git a/src/lisp.h b/src/lisp.h
index 56ad99b..ae5a81e 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2307,7 +2307,7 @@ struct Lisp_Hash_Table
weakness of the table. */
Lisp_Object weak;
- /* Vector of hash codes.
+ /* Vector of hash codes, or nil if the table needs rehashing.
If the I-th entry is unused, then hash[I] should be nil. */
Lisp_Object hash;
@@ -2327,8 +2327,7 @@ struct Lisp_Hash_Table
'index' are special and are either ignored by the GC or traced in
a special way (e.g. because of weakness). */
- /* Number of key/value entries in the table. This number is
- negated if the table needs rehashing. */
+ /* Number of key/value entries in the table. */
ptrdiff_t count;
/* Index of first free entry in free list, or -1 if none. */
@@ -2413,7 +2412,9 @@ HASH_HASH (const struct Lisp_Hash_Table *h, ptrdiff_t idx)
INLINE ptrdiff_t
HASH_TABLE_SIZE (const struct Lisp_Hash_Table *h)
{
- return ASIZE (h->next);
+ ptrdiff_t size = ASIZE (h->next);
+ eassume (0 < size);
+ return size;
}
void hash_table_rehash (struct Lisp_Hash_Table *h);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] master ceebf3e: Fix clrhash bug when hash table needs rehashing,
Paul Eggert <=