aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMattias EngdegÄrd2023-10-28 12:07:42 +0200
committerMattias EngdegÄrd2024-01-12 18:02:15 +0100
commit43127e5ec110debadef5e823ee8adbfc561bb708 (patch)
treec6171f089722f215ddc0b31d8ce24775ea902b6e /src
parent462b3e6ae4eefeb65a2dc7b144db3e1af9a7720d (diff)
downloademacs-43127e5ec110debadef5e823ee8adbfc561bb708.tar.gz
emacs-43127e5ec110debadef5e823ee8adbfc561bb708.zip
Refactor hash table vector reallocation
* src/fns.c (larger_vecalloc): Remove. (larger_vector): Simplify. (alloc_larger_vector): New. (maybe_resize_hash_table): Use alloc_larger_vector as a simpler and faster replacement for larger_vecalloc.
Diffstat (limited to 'src')
-rw-r--r--src/fns.c60
1 files changed, 29 insertions, 31 deletions
diff --git a/src/fns.c b/src/fns.c
index 207094909f4..56b4e9a18c0 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -4339,11 +4339,10 @@ get_key_arg (Lisp_Object key, ptrdiff_t nargs, Lisp_Object *args, char *used)
4339/* Return a Lisp vector which has the same contents as VEC but has 4339/* Return a Lisp vector which has the same contents as VEC but has
4340 at least INCR_MIN more entries, where INCR_MIN is positive. 4340 at least INCR_MIN more entries, where INCR_MIN is positive.
4341 If NITEMS_MAX is not -1, do not grow the vector to be any larger 4341 If NITEMS_MAX is not -1, do not grow the vector to be any larger
4342 than NITEMS_MAX. New entries in the resulting vector are 4342 than NITEMS_MAX. New entries in the resulting vector are nil. */
4343 uninitialized. */
4344 4343
4345static Lisp_Object 4344Lisp_Object
4346larger_vecalloc (Lisp_Object vec, ptrdiff_t incr_min, ptrdiff_t nitems_max) 4345larger_vector (Lisp_Object vec, ptrdiff_t incr_min, ptrdiff_t nitems_max)
4347{ 4346{
4348 struct Lisp_Vector *v; 4347 struct Lisp_Vector *v;
4349 ptrdiff_t incr, incr_max, old_size, new_size; 4348 ptrdiff_t incr, incr_max, old_size, new_size;
@@ -4360,23 +4359,11 @@ larger_vecalloc (Lisp_Object vec, ptrdiff_t incr_min, ptrdiff_t nitems_max)
4360 new_size = old_size + incr; 4359 new_size = old_size + incr;
4361 v = allocate_vector (new_size); 4360 v = allocate_vector (new_size);
4362 memcpy (v->contents, XVECTOR (vec)->contents, old_size * sizeof *v->contents); 4361 memcpy (v->contents, XVECTOR (vec)->contents, old_size * sizeof *v->contents);
4362 memclear (v->contents + old_size, (new_size - old_size) * word_size);
4363 XSETVECTOR (vec, v); 4363 XSETVECTOR (vec, v);
4364 return vec; 4364 return vec;
4365} 4365}
4366 4366
4367/* Likewise, except set new entries in the resulting vector to nil. */
4368
4369Lisp_Object
4370larger_vector (Lisp_Object vec, ptrdiff_t incr_min, ptrdiff_t nitems_max)
4371{
4372 ptrdiff_t old_size = ASIZE (vec);
4373 Lisp_Object v = larger_vecalloc (vec, incr_min, nitems_max);
4374 ptrdiff_t new_size = ASIZE (v);
4375 memclear (XVECTOR (v)->contents + old_size,
4376 (new_size - old_size) * word_size);
4377 return v;
4378}
4379
4380 4367
4381/*********************************************************************** 4368/***********************************************************************
4382 Low-level Functions 4369 Low-level Functions
@@ -4631,6 +4618,20 @@ copy_hash_table (struct Lisp_Hash_Table *h1)
4631} 4618}
4632 4619
4633 4620
4621/* Allocate a Lisp vector of NEW_SIZE elements.
4622 Copy elements from VEC and leave the rest undefined. */
4623static Lisp_Object
4624alloc_larger_vector (Lisp_Object vec, ptrdiff_t new_size)
4625{
4626 eassert (VECTORP (vec));
4627 ptrdiff_t old_size = ASIZE (vec);
4628 eassert (new_size >= old_size);
4629 struct Lisp_Vector *v = allocate_vector (new_size);
4630 memcpy (v->contents, XVECTOR (vec)->contents, old_size * sizeof *v->contents);
4631 XSETVECTOR (vec, v);
4632 return vec;
4633}
4634
4634/* Compute index into the index vector from a hash value. */ 4635/* Compute index into the index vector from a hash value. */
4635static inline ptrdiff_t 4636static inline ptrdiff_t
4636hash_index_index (struct Lisp_Hash_Table *h, Lisp_Object hash_code) 4637hash_index_index (struct Lisp_Hash_Table *h, Lisp_Object hash_code)
@@ -4666,26 +4667,23 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
4666 new_size = old_size + 1; 4667 new_size = old_size + 1;
4667 4668
4668 /* Allocate all the new vectors before updating *H, to 4669 /* Allocate all the new vectors before updating *H, to
4669 avoid problems if memory is exhausted. larger_vecalloc 4670 avoid problems if memory is exhausted. */
4670 finishes computing the size of the replacement vectors. */ 4671 Lisp_Object next = alloc_larger_vector (h->next, new_size);
4671 Lisp_Object next = larger_vecalloc (h->next, new_size - old_size, 4672 for (ptrdiff_t i = old_size; i < new_size - 1; i++)
4672 new_size);
4673 ptrdiff_t next_size = ASIZE (next);
4674 for (ptrdiff_t i = old_size; i < next_size - 1; i++)
4675 ASET (next, i, make_fixnum (i + 1)); 4673 ASET (next, i, make_fixnum (i + 1));
4676 ASET (next, next_size - 1, make_fixnum (-1)); 4674 ASET (next, new_size - 1, make_fixnum (-1));
4677 4675
4678 /* Build the new&larger key_and_value vector, making sure the new 4676 /* Build the new&larger key_and_value vector, making sure the new
4679 fields are initialized to `unbound`. */ 4677 fields are initialized to `unbound`. */
4680 Lisp_Object key_and_value 4678 Lisp_Object key_and_value
4681 = larger_vecalloc (h->key_and_value, 2 * (next_size - old_size), 4679 = alloc_larger_vector (h->key_and_value, 2 * new_size);
4682 2 * next_size); 4680 for (ptrdiff_t i = 2 * old_size; i < 2 * new_size; i++)
4683 for (ptrdiff_t i = 2 * old_size; i < 2 * next_size; i++)
4684 ASET (key_and_value, i, Qunbound); 4681 ASET (key_and_value, i, Qunbound);
4685 4682
4686 Lisp_Object hash = larger_vector (h->hash, next_size - old_size, 4683 Lisp_Object hash = alloc_larger_vector (h->hash, new_size);
4687 next_size); 4684 memclear (XVECTOR (hash)->contents + old_size,
4688 ptrdiff_t index_size = hash_index_size (h, next_size); 4685 (new_size - old_size) * word_size);
4686 ptrdiff_t index_size = hash_index_size (h, new_size);
4689 h->index = make_vector (index_size, make_fixnum (-1)); 4687 h->index = make_vector (index_size, make_fixnum (-1));
4690 h->key_and_value = key_and_value; 4688 h->key_and_value = key_and_value;
4691 h->hash = hash; 4689 h->hash = hash;
@@ -4704,7 +4702,7 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
4704 4702
4705#ifdef ENABLE_CHECKING 4703#ifdef ENABLE_CHECKING
4706 if (HASH_TABLE_P (Vpurify_flag) && XHASH_TABLE (Vpurify_flag) == h) 4704 if (HASH_TABLE_P (Vpurify_flag) && XHASH_TABLE (Vpurify_flag) == h)
4707 message ("Growing hash table to: %"pD"d", next_size); 4705 message ("Growing hash table to: %"pD"d", new_size);
4708#endif 4706#endif
4709 } 4707 }
4710} 4708}