emacs-diffs
[Top][All Lists]
Advanced

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

master ad004f10f36: * src/lisp.h (DOHASH): Handle rehashing (bug#68690)


From: Stefan Monnier
Subject: master ad004f10f36: * src/lisp.h (DOHASH): Handle rehashing (bug#68690)
Date: Wed, 24 Jan 2024 14:54:26 -0500 (EST)

branch: master
commit ad004f10f3668d464d32ed8da18639da9bcc01bb
Author: Stefan Monnier <monnier@iro.umontreal.ca>
Commit: Stefan Monnier <monnier@iro.umontreal.ca>

    * src/lisp.h (DOHASH): Handle rehashing (bug#68690)
    
    I gave too much credit to the comment, and didn't realize that macro
    was used in places that didn't obey the comment.
    This macro is getting pretty hideous!
---
 src/lisp.h | 38 ++++++++++++++++++++++++--------------
 1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/src/lisp.h b/src/lisp.h
index f822417ffb1..d07d9d14e2f 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2604,20 +2604,30 @@ hash_from_key (struct Lisp_Hash_Table *h, Lisp_Object 
key)
 }
 
 /* Iterate K and V as key and value of valid entries in hash table H.
-   The body may remove the current entry or alter its value slot, but not
-   mutate TABLE in any other way.  */
-#define DOHASH(h, k, v)                                                        
\
-  for (Lisp_Object *dohash_##k##_##v##_kv = (h)->key_and_value,                
\
-                   *dohash_##k##_##v##_end = dohash_##k##_##v##_kv     \
-                                             + 2 * HASH_TABLE_SIZE (h),        
\
-                   k, v;                                               \
-       dohash_##k##_##v##_kv < dohash_##k##_##v##_end                  \
-       && (k = dohash_##k##_##v##_kv[0],                               \
-           v = dohash_##k##_##v##_kv[1], /*maybe unsed*/ (void)v,       \
-           true);                                                      \
-        dohash_##k##_##v##_kv += 2)                                    \
-    if (hash_unused_entry_key_p (k))                                   \
-      ;                                                                        
\
+   The body may mutate the hash-table.  */
+#define DOHASH(h, k, v)                                                        
 \
+  for (Lisp_Object *dohash_##k##_##v##_base = (h)->key_and_value,       \
+                   *dohash_##k##_##v##_kv   = dohash_##k##_##v##_base,  \
+                   *dohash_##k##_##v##_end  = dohash_##k##_##v##_base   \
+                                              + 2 * HASH_TABLE_SIZE (h), \
+                   k, v;                                                \
+       dohash_##k##_##v##_kv < dohash_##k##_##v##_end                   \
+       && (dohash_##k##_##v##_base == (h)->key_and_value                 \
+           /* The `key_and_value` table has been reallocated!  */        \
+           || (dohash_##k##_##v##_kv                                     \
+                  = (dohash_##k##_##v##_kv - dohash_##k##_##v##_base)   \
+                    + (h)->key_and_value,                                \
+               dohash_##k##_##v##_base = (h)->key_and_value,             \
+               dohash_##k##_##v##_end  = dohash_##k##_##v##_base        \
+                                         + 2 * HASH_TABLE_SIZE (h),      \
+               /* Check again, in case the table has shrunk.  */         \
+               dohash_##k##_##v##_kv < dohash_##k##_##v##_end))          \
+       && (k = dohash_##k##_##v##_kv[0],                                 \
+           v = dohash_##k##_##v##_kv[1], /*maybe unused*/ (void)v,       \
+           true);                                                       \
+        dohash_##k##_##v##_kv += 2)                                     \
+    if (hash_unused_entry_key_p (k))                                    \
+      ;                                                                        
 \
     else
 
 



reply via email to

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