Implement (most of) the dynamic-extent vops on x86-64.
... no support for vectors yet.
* optimization: structure instances with raw slots now use less
memory, and probably show better memory locality. (thanks to
David Lichteblau)
+ * optimization: DYNAMIC-EXTENT declarations for lists and closures
+ are treated as requests for stack allocation on the x86-64
+ platform.
* contrib improvement: it's harder to cause SOCKET-CLOSE to close()
the wrong file descriptor; implementation of SOCKET-OPEN-P.
(thanks to Tony Martinez)
(in-package "SB!VM")
\f
;;;; LIST and LIST*
+(defoptimizer (list stack-allocate-result) ((&rest args))
+ (not (null args)))
+(defoptimizer (list* stack-allocate-result) ((&rest args))
+ (not (null (rest args))))
(define-vop (list-or-list*)
(:args (things :more t))
(storew reg ,list ,slot list-pointer-lowtag))))
(let ((cons-cells (if star (1- num) num)))
(pseudo-atomic
- (allocation res (* (pad-data-block cons-size) cons-cells) node)
+ (allocation res (* (pad-data-block cons-size) cons-cells) node
+ (awhen (sb!c::node-lvar node)
+ (sb!c::lvar-dynamic-extent it)))
(inst lea res
(make-ea :byte :base res :disp list-pointer-lowtag))
(move ptr res)
(define-vop (make-closure)
(:args (function :to :save :scs (descriptor-reg)))
(:info length stack-allocate-p)
- (:ignore stack-allocate-p)
(:temporary (:sc any-reg) temp)
(:results (result :scs (descriptor-reg)))
(:node-var node)
(:generator 10
- (pseudo-atomic
+ (maybe-pseudo-atomic stack-allocate-p
(let ((size (+ length closure-info-offset)))
- (allocation result (pad-data-block size) node)
+ (allocation result (pad-data-block size) node stack-allocate-p)
(inst lea result
(make-ea :byte :base result :disp fun-pointer-lowtag))
(storew (logior (ash (1- size) n-widetag-bits) closure-header-widetag)
(inst mov value
(make-ea :qword :base object :disp (- (* index n-word-bytes))))))
-
;;; Turn more arg (context, count) into a list.
+(defoptimizer (%listify-rest-args stack-allocate-result) ((&rest args))
+ t)
+
(define-vop (listify-rest-args)
(:translate %listify-rest-args)
(:policy :safe)
(:generator 20
(let ((enter (gen-label))
(loop (gen-label))
- (done (gen-label)))
+ (done (gen-label))
+ (stack-allocate-p (node-stack-allocate-p node)))
(move src context)
(move rcx count)
;; Check to see whether there are no args, and just return NIL if so.
(inst mov result nil-value)
(inst jecxz done)
(inst lea dst (make-ea :qword :index rcx :scale 2))
- (pseudo-atomic
- (allocation dst dst node)
+ (maybe-pseudo-atomic stack-allocate-p
+ (allocation dst dst node stack-allocate-p)
(inst lea dst (make-ea :byte :base dst :disp list-pointer-lowtag))
;; Convert the count into a raw value, so that we can use the
;; LOOP instruction.
;;; node-var then it is used to make an appropriate speed vs size
;;; decision.
+(defun allocation-dynamic-extent (alloc-tn size)
+ (inst sub rsp-tn size)
+ ;; see comment in x86/macros.lisp implementation of this
+ (inst and rsp-tn #.(lognot lowtag-mask))
+ (aver (not (location= alloc-tn rsp-tn)))
+ (inst mov alloc-tn rsp-tn)
+ (values))
+
;;; This macro should only be used inside a pseudo-atomic section,
;;; which should also cover subsequent initialization of the
;;; object.
(inst pop alloc-tn)
(values))
-(defun allocation (alloc-tn size &optional ignored)
+(defun allocation (alloc-tn size &optional ignored dynamic-extent)
(declare (ignore ignored))
+ (when dynamic-extent
+ (allocation-dynamic-extent alloc-tn size)
+ (return-from allocation (values)))
(let ((NOT-INLINE (gen-label))
(DONE (gen-label))
;; Yuck.
;;; the ATOMIC bit is bit 0, the INTERRUPTED bit is bit 1, and you check
;;; the C flag after the shift to see whether you were interrupted.
+;;; FIXME: THIS NAME IS BACKWARDS!
+(defmacro maybe-pseudo-atomic (really-p &body body)
+ `(if ,really-p
+ (progn ,@body)
+ (pseudo-atomic ,@body)))
+
(defmacro pseudo-atomic (&rest forms)
(with-unique-names (label)
`(let ((,label (gen-label)))
(funcall thunk))
(assert (< (- (get-bytes-consed) before) times))))
-#+x86
+#+(or x86 x86-64)
(progn
(assert-no-consing (dxlength 1 2 3))
(assert-no-consing (dxlength t t t t t t))
;;; 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".)
-"0.9.1.47"
+"0.9.1.48"