* enhancement: CONS can now stack-allocate on x86 and
x86-64. (Earlier LIST and LIST* supported stack-allocation, but
CONS did not:)
+ * enhancement: nested lists can now be stack allocated on
+ platforms providing stack allocation support.
* enhancement: DEFINE-MODIFY-MACRO lambda-list information is
now more readable in environments like Slime which display it.
(thanks to Tobias C. Rittweiler)
Result of MAKE is not stack allocated, which means that
stack-allocation of structures is impossible.
--------------------------------------------------------------------------------
-#21
-(defun-with-dx foo ()
- (let ((dx (list (list 1 2) (list 3 4))))
- (declare (dynamic-extent dx))
- ...))
-
-External list in DX is allocated on stack, but internal are not.
---------------------------------------------------------------------------------
#22
IR2 does not perform unused code flushing.
--------------------------------------------------------------------------------
(setf (car args) nil)))
(values))
+
+(defun handle-nested-dynamic-extent-lvars (arg)
+ (let ((use (lvar-uses arg)))
+ ;; Stack analysis wants DX value generators to end their
+ ;; blocks. Uses of mupltiple used LVARs already end their blocks,
+ ;; so we just need to process used-once LVARs.
+ (when (node-p use)
+ (node-ends-block use))
+ ;; If the function result is DX, so are its arguments... This
+ ;; assumes that all our DX functions do not store their arguments
+ ;; anywhere -- just use, and maybe return.
+ (if (basic-combination-p use)
+ (cons arg (funcall (lambda (lists)
+ (reduce #'append lists))
+ (mapcar #'handle-nested-dynamic-extent-lvars (basic-combination-args use))))
+ (list arg))))
+
(defun recognize-dynamic-extent-lvars (call fun)
(declare (type combination call) (type clambda fun))
(loop for arg in (basic-combination-args call)
and var in (lambda-vars fun)
- when (and arg
- (lambda-var-dynamic-extent var)
+ when (and arg (lambda-var-dynamic-extent var)
(not (lvar-dynamic-extent arg)))
- collect arg into dx-lvars
- and do (let ((use (lvar-uses arg)))
- ;; Stack analysis wants DX value generators to end
- ;; their blocks. Uses of mupltiple used LVARs already
- ;; end their blocks, so we just need to process
- ;; used-once LVARs.
- (when (node-p use)
- (node-ends-block use)))
+ append (handle-nested-dynamic-extent-lvars arg) into dx-lvars
finally (when dx-lvars
(binding* ((before-ctran (node-prev call))
(nil (ensure-block-start before-ctran))
(true cons)
nil))
+;;; Nested DX
+
+(defun-with-dx nested-dx-lists ()
+ (let ((dx (list (list 1 2) (list 3 4))))
+ (declare (dynamic-extent dx))
+ (true dx)
+ nil))
+
+(defun-with-dx nested-dx-conses ()
+ (let ((dx (cons 1 (cons 2 (cons 3 (cons (cons t t) nil))))))
+ (declare (dynamic-extent dx))
+ (true dx)
+ nil))
+
;;; with-spinlock should use DX and not cons
(defvar *slock* (sb-thread::make-spinlock :name "slocklock"))
(assert-no-consing (test-lvar-subst 11))
(assert-no-consing (dx-value-cell 13))
(assert-no-consing (cons-on-stack 42))
+ (assert-no-consing (nested-dx-conses))
+ (assert-no-consing (nested-dx-lists))
;; Not strictly DX..
(assert-no-consing (test-hash-table))
#+sb-thread
;;; 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.10.5"
+"1.0.10.6"