Source
(defmethod sweep-some-heap-blocks ((heap mark-and-sweep-heap)
(amount integer))
(let* ((object-table (object-table heap))
(block (+ (heap-start heap) (nr-heap-bytes-sweeped heap)))
(work-done 0))
;; Sweep across the heap, looking for dead blocks.
(loop
while (and (< work-done amount)
(< block (heap-end heap)))
do (multiple-value-bind (block-header block-start)
(read-block-start heap block)
;; For non-free blocks, the block start contains a previous-pointer,
;; which can be either nil or a positive integer.
;; A negative block-start means the block already belongs to
;; a free list. In that case, the block size is the abs of
;; the block start.
;; A non-negative (or nil) block-start means the block is occupied.
;; In that case, the block size is in the header.
(let* ((free-p (and (integerp block-start) (minusp block-start)))
(block-size (if free-p (- block-start) block-header)))
;; Reclaim dead blocks.
(when (not free-p) ; only non-free blocks
(let* ((heap-stream (heap-stream heap))
(object-id (progn
(deserialize heap-stream)
(deserialize heap-stream))))
(when (not (block-alive-p object-table object-id block))
;; The block is dead (either because the object is dead
;; or because the block contains an old version): return
;; the block to its free list.
(deallocate-block block heap))))
;;
(incf work-done block-size)
;; Move to next block (if there is one).
(incf block block-size))))
;;
(incf (nr-heap-bytes-sweeped heap) work-done)
(when (>= block (heap-end heap))
;; We've finished sweeping the heap: move to the next state.
(setf (state heap) :sweeping-object-table))
;; Return the amount of work done.
work-done))
Source Context