Re: freeze for sbcl-2.6.3
Andreas Franke via Sbcl-devel <[email protected]> Thu, 26 Mar 2026 22:04:04 +0000
| Newsgroups | gmane.lisp.steel-bank.devel |
|---|---|
| Message-ID | <trinity-43dbe699-79a3-40a7-bb14-be269cd97656-1774562644750@trinity-msg-rest-gmx-gmx-live-6779b97d68-9ptrx> |
Ok, rejecting bad host lisps makes sense. Maybe something like attached patch 0000 would do? And then there are some more patches, mostly for later, developed and tested using QEMU system-mode emulation: 0001 a fix for non-elfinated platforms 0002 small cleanup (?) 0003 ppc64 no-soft-card-marks unbreak for benchmarking I feel we shouldn't support a host Lisp that fails basic math. Plenty of non-buggy hosts exist to choose from. Instead we can detect the situation in src/cold/shared, and stop with an error message that the host Lisp is too buggy to compile SBCL. Other projects have similar pre-checks. Otherwise how do we know when it is or isn't OK to write a particular arithmetic expression? _______________________________________________ Sbcl-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/sbcl-devel
0000-Detect-bad-host-compiler-arithmetic-early-in-the-bui.patch
(text/x-patch, 1.3 KB)
From 084201f35e3fc0248885e0e97ffd5974fbc88585 Mon Sep 17 00:00:00 2001 From: Andreas Franke <[email protected]> Date: Thu, 26 Mar 2026 21:33:42 +0000 Subject: [PATCH] Detect bad host compiler arithmetic early in the build --- src/cold/shared.lisp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/cold/shared.lisp b/src/cold/shared.lisp index e0393a4cc..e800a464d 100644 --- a/src/cold/shared.lisp +++ b/src/cold/shared.lisp @@ -101,6 +101,18 @@ (values pid code) (values pid (- code)))))) +;;; Catch host compilers that silently miscompile integer arithmetic +;;; (e.g. ECL 21.2.1 wraps the first one to 0 when compiled). +(dolist (form '((lambda () (1+ #xFFFFFFFF)) + (lambda () (1+ #xFFFFFFFFFFFFFFFF)))) + (let* ((fun (compile nil form)) + (expected (funcall (coerce form 'function))) + (got (funcall fun))) + (unless (eql got expected) + (error "Host Lisp miscompiled ~S:~% Interpreted: ~D~% Compiled: ~D~%~ + This host Lisp cannot be used to build SBCL." + form expected got)))) + ;;; If TRUE, then COMPILE-FILE is being invoked only to process ;;; :COMPILE-TOPLEVEL forms, not to produce an output file. ;;; This is part of the implementation of parallelized make-host-2. -- 2.43.0
0001-Fix-warm-core-crash-on-non-elfinated-platforms.patch
(text/x-patch, 4.3 KB)
From c79bd2502ec430f8bcc7ff15307b9d2cdc73b8ee Mon Sep 17 00:00:00 2001 From: Andreas Franke <[email protected]> Date: Fri, 13 Mar 2026 19:01:59 +0000 Subject: [PATCH] Fix warm core crash on non-elfinated platforms os_link_runtime's dlsym branch used 'count' from the core header as the loop bound for initializing alien linkage table entries. This count reflects cold init and is never updated when the warm build adds foreign symbols, so entries beyond it are left uninitialized. On platforms that dispatch foreign calls through the alien linkage table (everything except x86-64), this crashes during early init when a warm-added symbol is called before foreign-reinit runs. Use the hash-table's high-water mark (data[0]) as the loop bound, consistent with the prelinked branch. Preserve 'count' as n_prelinked so that update-alien-linkage-table still re-resolves symbols from user-loaded shared objects not yet reopened at startup. Suppress warnings for those user symbols (index >= count) since they will be re-resolved after reopen-shared-objects. --- src/runtime/os-common.c | 12 +++++++++--- tests/foreign.test.sh | 27 +++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/runtime/os-common.c b/src/runtime/os-common.c index 0204189a9..1fa4640e1 100644 --- a/src/runtime/os-common.c +++ b/src/runtime/os-common.c @@ -200,8 +200,12 @@ void os_link_runtime(lispobj vector, lispobj count) gc_assert(simple_base_string_p(is_data ? CONS(name)->car : name)); arch_write_linkage_table_entry(linkage_index, (void*)*table, is_data); } - } else { // Process only 'count' entries by looking them up - int n = alien_linkage_table_n_prelinked = count; + } else { // Look up all entries via dlsym. + // Use data[0] (the hash-table's high-water mark) as loop bound, + // not 'count' which may be stale if the warm build added symbols. + int n = fixnum_value(name_table->data[0]); + // Preserve 'count' for update-alien-linkage-table's re-resolution threshold. + alien_linkage_table_n_prelinked = count; for ( ; n-- ; linkage_index++, name_index += 2 ) { lispobj item = name_table->data[name_index]; bool is_data = listp(item); @@ -210,7 +214,9 @@ void os_link_runtime(lispobj vector, lispobj count) void* result = os_dlsym_default(namechars); if (result) { arch_write_linkage_table_entry(linkage_index, result, is_data); - } else { // startup might or might not work. ymmv + } else if (linkage_index < count) { + // Symbols beyond 'count' are from user-loaded shared objects, + // re-resolved later by foreign-reinit. fprintf(stderr, "Missing required foreign symbol '%s'\n", namechars); } } diff --git a/tests/foreign.test.sh b/tests/foreign.test.sh index d8d7f4d0c..043950f4b 100755 --- a/tests/foreign.test.sh +++ b/tests/foreign.test.sh @@ -357,6 +357,33 @@ else echo "skipping missing-so test (no core file, possibly due to linkage table above)" fi +# Save/restore with a user-loaded shared object. +# Exercises the dlsym branch of os_link_runtime: symbols from .so files +# closed at save time should not produce spurious warnings on restart. +echo "Testing save/restore with user-loaded shared object" +run_sbcl <<EOF + (load-shared-object (truename "$TEST_FILESTEM-c.so")) + (define-alien-routine late-bar int) + (assert (= 14 (late-bar))) + (save-lisp-and-die "$TEST_FILESTEM.user-so.core") +EOF +if [ $? = 0 ]; then + run_sbcl_with_core $TEST_FILESTEM.user-so.core $options --noprint \ + --eval "(setf sb-ext:*evaluator-mode* :${TEST_SBCL_EVALUATOR_MODE:-compile})" \ + <<EOF 2>$TEST_FILESTEM.user-so.stderr + (assert (= 14 (late-bar))) + (exit :code $EXIT_LISP_WIN) +EOF + check_status_maybe_lose "start with user-loaded so" $? + if grep -q "Missing required foreign symbol" $TEST_FILESTEM.user-so.stderr; then + echo "FAIL: spurious foreign symbol warnings on restart" + cat $TEST_FILESTEM.user-so.stderr + exit $EXIT_LOSE + fi +else + echo "skipping user-so restart test (save failed)" +fi + # ADDR of a heap-allocated object cat > $TEST_FILESTEM.addr.heap.c <<EOF struct foo -- 2.43.0
0002-Remove-dead-exit-22-fallthrough-in-foreign-test.patch
(text/x-patch, 1.4 KB)
From 0e00363f45ccd0d3e81676f314828e7d92c5e080 Mon Sep 17 00:00:00 2001 From: Andreas Franke <[email protected]> Date: Thu, 26 Mar 2026 20:23:06 +0000 Subject: [PATCH] Remove dead exit-22 fallthrough in foreign test Unreachable since bc6b79521 removed #+linkage-table guards. --- tests/foreign.test.sh | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/foreign.test.sh b/tests/foreign.test.sh index 043950f4b..bc4495860 100755 --- a/tests/foreign.test.sh +++ b/tests/foreign.test.sh @@ -290,10 +290,8 @@ test_save() { (eval-when (:compile-toplevel :load-toplevel :execute) (setq *features* (union *features* sb-impl:+internal-features+))) (save-lisp-and-die "$TEST_FILESTEM.$x.core") -(sb-ext:exit :code 22) ; catch this EOF - check_status_maybe_lose "save $1" $? \ - 0 "(successful save)" 22 "(linkage table not available)" + check_status_maybe_lose "save $1" $? 0 "(successful save)" } test_save small @@ -332,10 +330,8 @@ if [ -f $TEST_FILESTEM.fast.core ] ; then (print :fell-through) (invoke-debugger condition))) (save-lisp-and-die "$TEST_FILESTEM.missing.core") - (sb-ext:exit :code 22) ; catch this EOF - check_status_maybe_lose "saving-missing-so-core" $? \ - 0 "(successful save)" 22 "(linkage table not available)" + check_status_maybe_lose "saving-missing-so-core" $? 0 "(successful save)" fi rm $TEST_FILESTEM-b.so $TEST_FILESTEM-b2.so -- 2.43.0
0003-ppc64-conditionalize-write-barriers-for-no-SCM.patch
(text/x-patch, 4.5 KB)
From 5cb4a1248471f7b0f25e3678eba47738c3549dec Mon Sep 17 00:00:00 2001 From: Andreas Franke <[email protected]> Date: Sun, 15 Mar 2026 02:14:02 +0000 Subject: [PATCH 3/3] ppc64: conditionalize write barriers for no-SCM Allow building PPC64 without :soft-card-marks so that the mprotect-based write barrier can be benchmarked against SCM. Three files need conditionalization: - memory.lisp: guard emit-gengc-barrier body with #+soft-card-marks (non-SCM relies on mprotect, not explicit card marking) - parms.lisp: guard cards-per-page with #+soft-card-marks (generic/parms.lisp provides the #-soft-card-marks fallback) - cell.lisp: code-header-set VOP must write the correct card-marked value. With SCM the value is 0 (thread-base-tn's low byte); without SCM it is 1 (the constant card-marked). Note: the reg_CARDTABLE load in ppc64-assem.S is intentionally NOT guarded. On PPC64, r17 doubles as the linkage-space base used by every named function call (call.lisp, arith.lisp), so it must always be initialized. --- src/compiler/ppc64/cell.lisp | 5 +++++ src/compiler/ppc64/memory.lisp | 19 +++++++++++-------- src/compiler/ppc64/parms.lisp | 1 + src/runtime/ppc64-assem.S | 2 +- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/compiler/ppc64/cell.lisp b/src/compiler/ppc64/cell.lisp index 835e82558..ccdcbe434 100644 --- a/src/compiler/ppc64/cell.lisp +++ b/src/compiler/ppc64/cell.lisp @@ -534,7 +534,12 @@ ;; Compute card mark index (inst rldicl card object (- 64 gencgc-card-shift) (make-fixup nil :card-table-index-mask)) ;; Touch the card mark byte. + #+soft-card-marks (inst stbx thread-base-tn card-table-base-tn card) ; THREAD-TN's low byte is 0 + #-soft-card-marks + (progn + (inst li temp card-marked) + (inst stbx temp card-table-base-tn card)) ;; set 'written' flag in the code header ;; If two threads get here at the same time, they'll write the same byte. (let ((byte (- #+big-endian 4 #+little-endian 3 other-pointer-lowtag))) diff --git a/src/compiler/ppc64/memory.lisp b/src/compiler/ppc64/memory.lisp index c4565d1b6..b4acd6efc 100644 --- a/src/compiler/ppc64/memory.lisp +++ b/src/compiler/ppc64/memory.lisp @@ -13,14 +13,17 @@ (in-package "SB-VM") (defun emit-gengc-barrier (object cell-address temps &optional value-tn-ref allocator) - (aver (neq (car temps) cell-address)) ; LD would clobber the cell-address - (when (require-gengc-barrier-p object value-tn-ref allocator) - ;; (inst ld (car temps) thread-base-tn (ash thread-card-table-slot word-shift)) - ;; RLIDCL dest, source, (64-rightshift), (64-indexbits) - (inst rldicl (car temps) (or cell-address object) (- 64 gencgc-card-shift) - (make-fixup nil :card-table-index-mask)) - ;; THREAD-TN's low byte is 0. - (inst stbx thread-base-tn card-table-base-tn (car temps)))) + #-soft-card-marks (declare (ignore object cell-address temps value-tn-ref allocator)) + #+soft-card-marks + (progn + (aver (neq (car temps) cell-address)) ; LD would clobber the cell-address + (when (require-gengc-barrier-p object value-tn-ref allocator) + ;; (inst ld (car temps) thread-base-tn (ash thread-card-table-slot word-shift)) + ;; RLIDCL dest, source, (64-rightshift), (64-indexbits) + (inst rldicl (car temps) (or cell-address object) (- 64 gencgc-card-shift) + (make-fixup nil :card-table-index-mask)) + ;; THREAD-TN's low byte is 0. + (inst stbx thread-base-tn card-table-base-tn (car temps))))) ;;; Cell-Ref and Cell-Set are used to define VOPs like CAR, where the offset to diff --git a/src/compiler/ppc64/parms.lisp b/src/compiler/ppc64/parms.lisp index aa5ed948d..bd9da8a21 100644 --- a/src/compiler/ppc64/parms.lisp +++ b/src/compiler/ppc64/parms.lisp @@ -26,6 +26,7 @@ ;;; threads claim memory from the global heap. (defconstant gencgc-page-bytes +backend-page-bytes+) ;;; Granularity at which writes to old generations are logged. +#+soft-card-marks (defconstant cards-per-page 32) ;;; The minimum size of new allocation regions. While it doesn't ;;; currently make a lot of sense to have a card size lower than diff --git a/src/runtime/ppc64-assem.S b/src/runtime/ppc64-assem.S index 00d481356..46ddeef0e 100644 --- a/src/runtime/ppc64-assem.S +++ b/src/runtime/ppc64-assem.S @@ -166,7 +166,7 @@ Low Address ld reg_A2,16(reg_CFP) ld reg_A3,24(reg_CFP) - /* load gc_card_mark */ + /* load gc_card_mark (also used as linkage space base) */ ld reg_CARDTABLE, (-LIST_POINTER_LOWTAG-16)(reg_NULL) /* Function is an indirect closure */ -- 2.43.0