From a572ab7de4266dec958d50612a8376df6bb45226 Mon Sep 17 00:00:00 2001 From: Nikodemus Siivola Date: Mon, 12 May 2008 14:12:42 +0000 Subject: [PATCH] 1.0.16.29: workaround for bug 419 * Require an explicit SB-C::STACK-ALLOCATE-VALUE-CELLS optimize declaration before stack allocating value cells to prevent returning garbage values from hairy user code. --- BUGS | 11 +++++++++-- NEWS | 4 ++++ make-host-2.lisp | 4 +++- src/compiler/ir2tran.lisp | 5 ++++- src/compiler/policies.lisp | 7 +++++++ tests/dynamic-extent.impure.lisp | 16 ++++++++++++++++ version.lisp-expr | 2 +- 7 files changed, 44 insertions(+), 5 deletions(-) diff --git a/BUGS b/BUGS index 75a62e018..d503d80e2 100644 --- a/BUGS +++ b/BUGS @@ -1810,7 +1810,8 @@ WORKAROUND: 419: stack-allocated indirect closure variables are not popped - (locally (declare (optimize speed (safety 0))) + (locally (declare (optimize sb-c::stack-allocate-dynamic-extent + sb-c::stack-allocate-value-cells)) (defun bug419 (x) (multiple-value-call #'list (eval '(values 1 2 3)) @@ -1823,7 +1824,13 @@ WORKAROUND: (declare (dynamic-extent #'mget #'mset)) ((lambda (f g) (eval `(progn ,f ,g (values 4 5 6)))) #'mget #'mset)))))) - (ASSERT (EQUAL (BUG419) '(1 2 3 4 5 6))) => failure + (ASSERT (EQUAL (BUG419 42) '(1 2 3 4 5 6))) => failure + + Note: as of SBCL 1.0.26.29 this bug no longer affects user code, as + SB-C::STACK-ALLOCATE-VALUE-CELLS needs to be explicitly turned on for + that to happen. Proper fix for this bug requires (Nikodemus thinks) + storing the relevant LAMBDA-VARs in a :DYNAMIC-EXTENT cleanup, and + teaching stack analysis how to deal with them. 420: The MISC.556 test from gcl/ansi-tests/misc.lsp fails hard. diff --git a/NEWS b/NEWS index 808956ea0..3990725e1 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,9 @@ ;;;; -*- coding: utf-8; -*- changes in sbcl-1.0.17 relative to 1.0.16: + * temporary regression: user code can no longer allocate closure + variable storage on stack, due to bug 419 without explicitly + requesting it. Please consult sbcl-devel for advice if you need to + use this feature in the meanwhile. * optimization: ADJOIN and PUSHNEW are upto ~70% faster in normal SPEED policies. * optimization: APPEND is upto ~10% faster in normal SPEED policies. diff --git a/make-host-2.lisp b/make-host-2.lisp index 8bc96bf36..7e66112ef 100644 --- a/make-host-2.lisp +++ b/make-host-2.lisp @@ -29,7 +29,9 @@ ;; never insert stepper conditions (sb!c:insert-step-conditions 0) ;; always stack-allocate if requested - (sb!c::stack-allocate-dynamic-extent 3))))) + (sb!c::stack-allocate-dynamic-extent 3) + ;; ...even value cells! + (sb!c::stack-allocate-value-cells 3))))) (compile 'proclaim-target-optimization) (defun in-target-cross-compilation-mode (fun) diff --git a/src/compiler/ir2tran.lisp b/src/compiler/ir2tran.lisp index 3e1385d0e..f2c53818f 100644 --- a/src/compiler/ir2tran.lisp +++ b/src/compiler/ir2tran.lisp @@ -57,7 +57,10 @@ (defun emit-make-value-cell (node block value res) (event make-value-cell-event node) (let ((leaf (tn-leaf res))) - (vop make-value-cell node block value (and leaf (leaf-dynamic-extent leaf)) + (vop make-value-cell node block value + (and leaf (leaf-dynamic-extent leaf) + ;; FIXME: See bug 419 + (policy node (> stack-allocate-value-cells 1))) res))) ;;;; leaf reference diff --git a/src/compiler/policies.lisp b/src/compiler/policies.lisp index 9164e6b0c..0ab60a1cc 100644 --- a/src/compiler/policies.lisp +++ b/src/compiler/policies.lisp @@ -100,6 +100,13 @@ and will refer to the new function, bound to FOO.") "Control whether allocate objects, declared DYNAMIC-EXTENT, on stack.") +(define-optimization-quality stack-allocate-value-cells + ;; FIXME, see bug 419 + 0 + ("no" "maybe" "yes" "yes") + "Control whether allocate closure variable storage, declared +DYNAMIC-EXTENT, on stack.") + (define-optimization-quality stack-allocate-vector (cond ((= stack-allocate-dynamic-extent 0) 0) ((= safety 0) 3) diff --git a/tests/dynamic-extent.impure.lisp b/tests/dynamic-extent.impure.lisp index a6034c7ce..e27f5aeb2 100644 --- a/tests/dynamic-extent.impure.lisp +++ b/tests/dynamic-extent.impure.lisp @@ -129,6 +129,7 @@ ;;; value-cells (defun-with-dx dx-value-cell (x) + (declare (optimize sb-c::stack-allocate-value-cells)) ;; Not implemented everywhere, yet. #+(or x86 x86-64 mips) (let ((cell x)) @@ -310,4 +311,19 @@ (multiple-value-bind (i j) (let-converted-vars-dx-allocated-bug 1 2 3) (assert (and (equal i j) (equal i (list 1 2 3))))) + +;;; workaround for bug 419 -- real issue remains, but check that the +;;; bandaid holds. +(defun-with-dx bug419 (x) + (multiple-value-call #'list + (eval '(values 1 2 3)) + (let ((x x)) + (declare (dynamic-extent x)) + (flet ((mget (y) + (+ x y)) + (mset (z) + (incf x z))) + (declare (dynamic-extent #'mget #'mset)) + ((lambda (f g) (eval `(progn ,f ,g (values 4 5 6)))) #'mget #'mset))))) +(assert (equal (bug419 42) '(1 2 3 4 5 6))) diff --git a/version.lisp-expr b/version.lisp-expr index aca0b2184..93fb676e8 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"1.0.16.28" +"1.0.16.29" -- 2.11.4.GIT