Next: , Previous: Slot access, Up: Efficiency


6.2 Dynamic-extent allocation

SBCL has limited support for performing allocation on the stack when a variable is declared dynamic-extent. The dynamic-extent declarations are not verified, but are simply trusted as long as sb-ext:*stack-allocate-dynamic-extent* is true.

If dynamic extent constraints specified in the Common Lisp standard are violated, the best that can happen is for the program to have garbage in variables and return values; more commonly, the system will crash.

— Variable: sb-ext:*stack-allocate-dynamic-extent*

If true (the default), the compiler respects dynamic-extent declarations and stack allocates otherwise inaccessible parts of the object whenever possible. Potentially long (over one page in size) vectors are, however, not stack allocated except in zero safety code, as such a vector could overflow the stack without triggering overflow protection.

There are many cases when dynamic-extent declarations could be useful. At present, SBCL implements stack allocation for

Examples:

     ;;; Declaiming a structure constructor inline before definition makes
     ;;; stack allocation possible.
     (declaim (inline make-thing))
     (defstruct thing obj next)
     
     ;;; Stack allocation of various objects bound to DYNAMIC-EXTENT
     ;;; variables.
     (let* ((list (list 1 2 3))
            (nested (cons (list 1 2) (list* 3 4 (list 5))))
            (vector (make-array 3 :element-type 'single-float))
            (thing (make-thing :obj list
                               :next (make-thing :obj (make-array 3)))))
       (declare (dynamic-extent list nested vector thing))
       ...)
     
     ;;; Stack allocation of arguments to a local function is equivalent
     ;;; to stack allocation of local variable values.
     (flet ((f (x)
              (declare (dynamic-extent x))
              ...))
       ...
       (f (list 1 2 3))
       (f (cons (cons 1 2) (cons 3 4)))
       ...)
     
     ;;; Stack allocation of &REST lists
     (defun foo (&rest args)
       (declare (dynamic-extent args))
       ...)

Future plans include