emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 49e80e7: Tweak recent hash-table fix


From: Paul Eggert
Subject: [Emacs-diffs] master 49e80e7: Tweak recent hash-table fix
Date: Sun, 21 Jul 2019 02:21:46 -0400 (EDT)

branch: master
commit 49e80e765b693736a8bb97ae5bfa341d25bf4f02
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    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.
---
 src/fns.c | 27 ++++++++++++---------------
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/src/fns.c b/src/fns.c
index 5f1ed07..d7e1231 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -4176,19 +4176,23 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
        }
       if (new_size <= old_size)
        new_size = old_size + 1;
-      double threshold = h->rehash_threshold;
-      double index_float = new_size / threshold;
-      EMACS_INT index_size = (index_float < INDEX_SIZE_BOUND + 1
-                             ? next_almost_prime (index_float)
-                             : INDEX_SIZE_BOUND + 1);
-      if (INDEX_SIZE_BOUND < max (index_size, 2 * new_size))
-       error ("Hash table too large to resize");
 
       /* Allocate all the new vectors before updating *H, to
         avoid problems if memory is exhausted.  larger_vecalloc
         finishes computing the size of the replacement vectors.  */
-      Lisp_Object next = larger_vecalloc (h->next, new_size - old_size, -1);
+      Lisp_Object next = larger_vecalloc (h->next, new_size - old_size,
+                                         INDEX_SIZE_BOUND / 2);
       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));
+      double threshold = h->rehash_threshold;
+      double index_float = next_size / threshold;
+      EMACS_INT index_size = (index_float < INDEX_SIZE_BOUND + 1
+                             ? next_almost_prime (index_float)
+                             : INDEX_SIZE_BOUND + 1);
+      if (INDEX_SIZE_BOUND < index_size)
+       error ("Hash table too large to resize");
       Lisp_Object key_and_value
        = larger_vector (h->key_and_value, 2 * (next_size - old_size),
                         2 * next_size);
@@ -4198,13 +4202,6 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
       h->key_and_value = key_and_value;
       h->hash = hash;
       h->next = next;
-
-      /* Update the free list.  Do it so that new entries are added at
-         the end of the free list.  This makes some operations like
-         maphash faster.  */
-      for (ptrdiff_t i = old_size; i < next_size - 1; i++)
-       set_hash_next_slot (h, i, i + 1);
-      set_hash_next_slot (h, next_size - 1, -1);
       h->next_free = old_size;
 
       /* Rehash.  */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]