master: Ensure that hash-table-index-vector stays with the table
snuglas via Sbcl-commits <[email protected]>
| Newsgroups | gmane.lisp.steel-bank.cvs |
|---|---|
| Message-ID | <[email protected]> |
The branch "master" has been updated in SBCL:
via f9075a0c2a84fa62f135a175c3b15fc0a6dc7915 (commit)
from f7d9205bfd9fefeeafbc683cadb3f86130dc22a9 (commit)
- Log -----------------------------------------------------------------
commit f9075a0c2a84fa62f135a175c3b15fc0a6dc7915
Author: Douglas Katzman <[email protected]>
Date: Wed Aug 12 18:31:36 2026 -0400
Ensure that hash-table-index-vector stays with the table
This accidental omission of ALLOCATING-FOR-HASH-TABLE had catastrophic
consequences if any system table was involved. I discovered the problem
in particular on SB-DI::*COMPILED-DEBUG-FUNS* which meant that you were
crashing while crashing, because you couldn't extract cached debug funs.
Test case by Gemini
---
src/code/target-hash-table.lisp | 4 +++-
tests/ht-affinity.impure.lisp | 21 +++++++++++++++++++++
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/src/code/target-hash-table.lisp b/src/code/target-hash-table.lisp
index 18a60869e..9a1dfc538 100644
--- a/src/code/target-hash-table.lisp
+++ b/src/code/target-hash-table.lisp
@@ -1976,7 +1976,9 @@ multiple threads accessing the same hash-table without locking."
;; have been cleared already in another thread.
(when (or (/= (kv-vector-rehash-stamp old-kv-vector) initial-stamp)
(not (zerop (kv-vector-rehash-stamp new-kv-vector))))
- (setq new-index-vector (make-index-vector new-n-buckets))))
+ (setq new-index-vector
+ (allocating-for-hash-table (table)
+ (make-index-vector new-n-buckets)))))
;; Preserve only the 'hashing' bit on the OLD-KV-VECTOR so that
;; its high-water-mark can meaningfully be reduced to 0 when done.
diff --git a/tests/ht-affinity.impure.lisp b/tests/ht-affinity.impure.lisp
new file mode 100644
index 000000000..3deef6591
--- /dev/null
+++ b/tests/ht-affinity.impure.lisp
@@ -0,0 +1,21 @@
+#+(or gc-stress ;; c-find-heap->arena is not gc-safe
+ (not system-tlabs) interpreter) (invoke-restart 'run-tests::skip-file)
+
+(test-util:with-test (:name :puthash-heap-table-addr-hash-realloc)
+ (let ((a (sb-vm:new-arena 1048576))
+ (old-threshold (sb-ext:bytes-consed-between-gcs)))
+ (unwind-protect
+ (progn
+ ;; Low GC threshold ensures GC occurs during realloc inside grow-hash-table
+ (setf (sb-ext:bytes-consed-between-gcs) 4096)
+ (let ((table (make-hash-table :test 'eq :size 128 :rehash-size 2)))
+ (assert (not (sb-impl::flat-hash-table-p table)))
+ (sb-vm:with-arena (a)
+ (dotimes (i 1000)
+ (let ((k (sb-vm:without-arena (cons i i))))
+ (setf (gethash k table) i))
+ (assert (sb-ext:heap-allocated-p
+ (sb-impl::hash-table-index-vector table))))))
+ (assert (null (sb-vm:c-find-heap->arena a))))
+ (setf (sb-ext:bytes-consed-between-gcs) old-threshold)
+ (sb-vm:destroy-arena a))))
-----------------------------------------------------------------------
hooks/post-receive
--
SBCL