aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias EngdegÄrd2024-01-18 18:45:16 +0100
committerMattias EngdegÄrd2024-01-18 18:56:26 +0100
commitef01250ef9c22aa1ac2ecff3136aabf79b2a677b (patch)
treeecbbbd985351cb27c10ad9b7414408eba44a5067
parent2c887f497c723c2397888e2f406faa4de3a8208a (diff)
downloademacs-ef01250ef9c22aa1ac2ecff3136aabf79b2a677b.tar.gz
emacs-ef01250ef9c22aa1ac2ecff3136aabf79b2a677b.zip
Only use a hash index size of 1 for tables with size 0 (bug#68244)
This invariant was intended but insufficiently enforced which could lead to an assertion failure. * src/fns.c (hash_index_size): Assume size>0, and return a value >1. (make_hash_table): Only use hash_index_size for size>0.
-rw-r--r--src/fns.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/src/fns.c b/src/fns.c
index 5bedf49ef36..15bbd270311 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -4525,9 +4525,14 @@ hash_index_size (ptrdiff_t size)
4525 ptrdiff_t upper_bound = min (MOST_POSITIVE_FIXNUM, 4525 ptrdiff_t upper_bound = min (MOST_POSITIVE_FIXNUM,
4526 min (TYPE_MAXIMUM (hash_idx_t), 4526 min (TYPE_MAXIMUM (hash_idx_t),
4527 PTRDIFF_MAX / sizeof (ptrdiff_t))); 4527 PTRDIFF_MAX / sizeof (ptrdiff_t)));
4528 ptrdiff_t index_size = size + (size >> 2); /* 1.25x larger */ 4528 /* Single-element index vectors are used iff size=0. */
4529 eassert (size > 0);
4530 ptrdiff_t lower_bound = 2;
4531 ptrdiff_t index_size = size + max (size >> 2, 1); /* 1.25x larger */
4529 if (index_size < upper_bound) 4532 if (index_size < upper_bound)
4530 index_size = next_almost_prime (index_size); 4533 index_size = (index_size < lower_bound
4534 ? lower_bound
4535 : next_almost_prime (index_size));
4531 if (index_size > upper_bound) 4536 if (index_size > upper_bound)
4532 error ("Hash table too large"); 4537 error ("Hash table too large");
4533 return index_size; 4538 return index_size;
@@ -4565,15 +4570,13 @@ make_hash_table (const struct hash_table_test *test, EMACS_INT size,
4565 h->weakness = weak; 4570 h->weakness = weak;
4566 h->count = 0; 4571 h->count = 0;
4567 h->table_size = size; 4572 h->table_size = size;
4568 int index_size = hash_index_size (size);
4569 h->index_size = index_size;
4570 4573
4571 if (size == 0) 4574 if (size == 0)
4572 { 4575 {
4573 h->key_and_value = NULL; 4576 h->key_and_value = NULL;
4574 h->hash = NULL; 4577 h->hash = NULL;
4575 h->next = NULL; 4578 h->next = NULL;
4576 eassert (index_size == 1); 4579 h->index_size = 1;
4577 h->index = (hash_idx_t *)empty_hash_index_vector; 4580 h->index = (hash_idx_t *)empty_hash_index_vector;
4578 h->next_free = -1; 4581 h->next_free = -1;
4579 } 4582 }
@@ -4591,6 +4594,8 @@ make_hash_table (const struct hash_table_test *test, EMACS_INT size,
4591 h->next[i] = i + 1; 4594 h->next[i] = i + 1;
4592 h->next[size - 1] = -1; 4595 h->next[size - 1] = -1;
4593 4596
4597 int index_size = hash_index_size (size);
4598 h->index_size = index_size;
4594 h->index = hash_table_alloc_bytes (index_size * sizeof *h->index); 4599 h->index = hash_table_alloc_bytes (index_size * sizeof *h->index);
4595 for (ptrdiff_t i = 0; i < index_size; i++) 4600 for (ptrdiff_t i = 0; i < index_size; i++)
4596 h->index[i] = -1; 4601 h->index[i] = -1;