aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2019-07-20 23:21:14 -0700
committerPaul Eggert2019-07-20 23:21:41 -0700
commit49e80e765b693736a8bb97ae5bfa341d25bf4f02 (patch)
tree500758c693dc3b53b8fad751157af270414025a8
parent515afc9c15870cd7bd6b96e2d8b89938116923ac (diff)
downloademacs-49e80e765b693736a8bb97ae5bfa341d25bf4f02.tar.gz
emacs-49e80e765b693736a8bb97ae5bfa341d25bf4f02.zip
Tweak recent hash-table fix
* src/fns.c (maybe_resize_hash_table): Completely initialize the new ‘next’ vector before allocating more vectors, as this preserves locality a bit better and it’s safer not to leave an uninitialized Lisp object around. Use next_size instead of new_size to compute new index size.
-rw-r--r--src/fns.c27
1 files changed, 12 insertions, 15 deletions
diff --git a/src/fns.c b/src/fns.c
index 5f1ed07a120..d7e123122d6 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -4176,19 +4176,23 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
4176 } 4176 }
4177 if (new_size <= old_size) 4177 if (new_size <= old_size)
4178 new_size = old_size + 1; 4178 new_size = old_size + 1;
4179 double threshold = h->rehash_threshold;
4180 double index_float = new_size / threshold;
4181 EMACS_INT index_size = (index_float < INDEX_SIZE_BOUND + 1
4182 ? next_almost_prime (index_float)
4183 : INDEX_SIZE_BOUND + 1);
4184 if (INDEX_SIZE_BOUND < max (index_size, 2 * new_size))
4185 error ("Hash table too large to resize");
4186 4179
4187 /* Allocate all the new vectors before updating *H, to 4180 /* Allocate all the new vectors before updating *H, to
4188 avoid problems if memory is exhausted. larger_vecalloc 4181 avoid problems if memory is exhausted. larger_vecalloc
4189 finishes computing the size of the replacement vectors. */ 4182 finishes computing the size of the replacement vectors. */
4190 Lisp_Object next = larger_vecalloc (h->next, new_size - old_size, -1); 4183 Lisp_Object next = larger_vecalloc (h->next, new_size - old_size,
4184 INDEX_SIZE_BOUND / 2);
4191 ptrdiff_t next_size = ASIZE (next); 4185 ptrdiff_t next_size = ASIZE (next);
4186 for (ptrdiff_t i = old_size; i < next_size - 1; i++)
4187 gc_aset (next, i, make_fixnum (i + 1));
4188 gc_aset (next, next_size - 1, make_fixnum (-1));
4189 double threshold = h->rehash_threshold;
4190 double index_float = next_size / threshold;
4191 EMACS_INT index_size = (index_float < INDEX_SIZE_BOUND + 1
4192 ? next_almost_prime (index_float)
4193 : INDEX_SIZE_BOUND + 1);
4194 if (INDEX_SIZE_BOUND < index_size)
4195 error ("Hash table too large to resize");
4192 Lisp_Object key_and_value 4196 Lisp_Object key_and_value
4193 = larger_vector (h->key_and_value, 2 * (next_size - old_size), 4197 = larger_vector (h->key_and_value, 2 * (next_size - old_size),
4194 2 * next_size); 4198 2 * next_size);
@@ -4198,13 +4202,6 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
4198 h->key_and_value = key_and_value; 4202 h->key_and_value = key_and_value;
4199 h->hash = hash; 4203 h->hash = hash;
4200 h->next = next; 4204 h->next = next;
4201
4202 /* Update the free list. Do it so that new entries are added at
4203 the end of the free list. This makes some operations like
4204 maphash faster. */
4205 for (ptrdiff_t i = old_size; i < next_size - 1; i++)
4206 set_hash_next_slot (h, i, i + 1);
4207 set_hash_next_slot (h, next_size - 1, -1);
4208 h->next_free = old_size; 4205 h->next_free = old_size;
4209 4206
4210 /* Rehash. */ 4207 /* Rehash. */