[rucksack-devel] GC problems

Arthur Lemmens alemmens at xs4all.nl
Tue Aug 8 14:47:44 UTC 2006


Edi Weitz wrote:

>   (defun check-gc (n)
>     (with-rucksack (rucksack *test-suite* :if-exists :supersede)
>       (with-transaction ()
>         ;; after this, INNER can be reached directly from the root
>         (let* ((inner (p-cons "Waldorf" "Statler"))
>                (root (p-cons 42 inner)))
>           (add-rucksack-root root rucksack)))
>       (with-transaction ()
>         (let* ((root (first (rucksack-roots rucksack)))
>                (inner (p-cdr root))
>                (array (p-make-array n)))
>           ;; after this, INNER can't be reached from the root anymore
>           (setf (p-cdr root) 43)
>           ;; now let the GC do some work
>           (dotimes (i n)
>             (let ((string (format nil "~R" i)))
>               (setf (p-aref array i) (p-cons string string))))
>           ;; hook INNER back to the root again before we finish the
>           ;; transaction
>           (setf (p-car root) array
>                 (p-cdr root) (p-cons 'bar (p-cons 'foo inner))))) ; [***]
>       (with-transaction ()
>         (let* ((root (first (rucksack-roots rucksack)))
>                (inner (p-cdr (p-cdr (p-cdr root)))))
>           ;; we expect the list ("Waldorf" "Statler") here
>           (list (p-car inner) (p-cdr inner))))))

Thanks, that's a nice test case.  (It's already committed to CVS from
one of your other patches.)

> What happens is similar to what I described on July 20, but not the
> same: In the second transaction, the GC has to do a lot of work if N
> is large enough, one pass won't suffice.  But then on the first pass
> already, INNER can't be reached from the one and only root anymore
> because it can only be reached through the P-CONS objects created in
> the [***] line, and these are at the end of the dirty queue and
> haven't been written to disc when the GC scans the heap for the first
> time.
>
> So, the GC marks INNER dead and frees its space.  INNER's block will
> then be re-allocated for some other object from the dirty queue.
> Bang...
>
> The important difference between the July 20 case and this one is that
> INNER was not written in the current transaction - it's an "old"
> object.  Still, the GC is wrong when it frees its space.

Yes.  Would you agree that this problem can also be solved by writing
dirty objects to disk when the scanner sees them?  Or am I missing
something?

> I /think/ there were discussion about similar cases on this mailing
> list two months ago or so, but IIRC they were about more "esoteric"
> scenarios where you hold references to persistent objects while you're
> not within a transaction or somesuch.  IMHO, the example above is a
> completely legitimate usage of Rucksack, though.

Yes, I agree.

Arthur




More information about the rucksack-devel mailing list