Re: [Sbcl-bugs] [BUG] PCL slot-makunb ound dfun missing RETURN-FROM ACCESS — allocates ~607 bytes per call

Stas Boukarev <[email protected]> Wed, 11 Mar 2026 18:56:48 +0300
Newsgroups gmane.lisp.steel-bank.devel
Message-ID <CAF63=11VtdX-fE_5ekyeAMcqjtCroOj5mnTUd9bB9eN85E2y5A@mail.gmail.com>
Applied. Thanks.

On Wed, Mar 11, 2026 at 6:41 PM John Mallery <[email protected]> wrote:
>
> SBCL version: 2.6.1 (also affects current git HEAD)
> Platform: Darwin arm64 (Apple Silicon), likely all platforms
>
> DESCRIPTION
>
> The one-class and two-class discriminating function generators for
> slot-accessor makunbound generic functions are missing RETURN-FROM
> ACCESS in the fast-path success case.  Every other accessor type
> (:reader, :writer, :boundp) wraps its result in (RETURN-FROM ACCESS
> ...) to skip the fallthrough to the miss function.  The :makunbound
> case omits this, causing every slot-makunbound call to fall through
> to the cache miss function even when the class matches.
>
> This results in ~607 bytes of allocation per slot-makunbound call
> (miss function rebuilds the cache, allocates wrapper lists, etc.).
> In CL-HTTP under load, slot-makunbound is called once per header per
> request during header-set cleanup, causing 24.3% of total allocation
> (8.8% direct + 15.5% cache miss overhead).
>
> HOW TO REPRODUCE
>
>  (defclass foo () ((x :initform 42)))
>  (defmethod slot-makunbound-using-class
>      ((class standard-class) (obj foo)
>       (slotd standard-effective-slot-definition))
>    (call-next-method))
>
>  (let ((obj (make-instance 'foo)))
>    ;; Warm the dispatch cache
>    (dotimes (i 20) (slot-makunbound obj 'x) (setf (slot-value obj 'x) 42))
>    ;; Measure
>    (let ((before (sb-ext:get-bytes-consed)))
>      (dotimes (i 10000)
>        (slot-makunbound obj 'x)
>        (setf (slot-value obj 'x) 42))
>      (format t "~,1F bytes/makunbound~%"
>              (/ (float (- (sb-ext:get-bytes-consed) before)) 10000.0))))
>
>  ;; Prints ~607 bytes/makunbound (should be ~0)
>
> FIX
>
> 3-line change in src/pcl/dlisp.lisp.  Add RETURN-FROM ACCESS around
> the :makunbound case, matching :reader, :writer, and :boundp:
>
> --- a/src/pcl/dlisp.lisp
> +++ b/src/pcl/dlisp.lisp
> @@ -246,8 +246,9 @@
>                  `((let ((value ,read-form))
>                      (return-from access (not (unbound-marker-p value))))))
>                 (:makunbound
> -                 `((progn (setf ,read-form +slot-unbound+)
> -                          ,instance)))
> +                 `((return-from access
> +                     (progn (setf ,read-form +slot-unbound+)
> +                            ,instance))))
>                 (:writer
>                  `((return-from access (setf ,read-form ,(car arglist)))))))
>           (funcall miss-fn ,@arglist))))))
>
> IMPACT
>
> Any application that calls slot-makunbound frequently (CLOS-heavy web
> servers, object pools, etc.) pays ~607 bytes per call.  The PCL cache
> miss from the fallthrough also causes quadratic behavior as the cache
> grows and rehashes repeatedly for entries that should have been hits.
>
>
> _______________________________________________
> Sbcl-bugs mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/sbcl-bugs


_______________________________________________
Sbcl-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sbcl-devel