diff options
| author | Mattias EngdegÄrd | 2023-10-28 12:07:42 +0200 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2024-01-12 18:02:15 +0100 |
| commit | 43127e5ec110debadef5e823ee8adbfc561bb708 (patch) | |
| tree | c6171f089722f215ddc0b31d8ce24775ea902b6e /src | |
| parent | 462b3e6ae4eefeb65a2dc7b144db3e1af9a7720d (diff) | |
| download | emacs-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.c | 60 |
1 files changed, 29 insertions, 31 deletions
| @@ -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 | ||
| 4345 | static Lisp_Object | 4344 | Lisp_Object |
| 4346 | larger_vecalloc (Lisp_Object vec, ptrdiff_t incr_min, ptrdiff_t nitems_max) | 4345 | larger_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 | |||
| 4369 | Lisp_Object | ||
| 4370 | larger_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. */ | ||
| 4623 | static Lisp_Object | ||
| 4624 | alloc_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. */ |
| 4635 | static inline ptrdiff_t | 4636 | static inline ptrdiff_t |
| 4636 | hash_index_index (struct Lisp_Hash_Table *h, Lisp_Object hash_code) | 4637 | hash_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 | } |