Say we want to test that an object is not referenced anywhere else,
and use a weak list for that.
(defun tester ()
(let ((wl (make-weak-list))
;; Turn off GC.
(gc-cons-threshold most-positive-fixnum))
;; (cons 'foo 'bar) is a fresh object
(set-weak-list-list wl (list (cons 'foo 'bar)))
(assert (eq (length (weak-list-list wl)) 1))
(garbage-collect)
(assert (eq (length (weak-list-list wl)) 0))))
Calling (tester) works as expected. However, after byte-compiling it
with (byte-compile 'tester), the second assertion will fail. It seems
that a pointer to the created object is left somewhere on the bytecode
interpreter stack. If you add (setq x wl) somewhere in the function
and garbage-collect after the function exits,
(length (weak-list-list x)) will evaluate to 0.
Inspecting bytecode.c proves this to be true -- all the stack is
GCPRO'd all the time, so even discarded data is a "root of
accessibility".
I wonder if this can be construed as a bug. If yes, it could be fixed
by having DISCARD either reset the discarded stuff to Qnil, or
adjusting gcpro.nvars (I think the latter should be faster). On the
other hand, I wouldn't want to affect the bytecode interpreter only to
satisfy a very esoteric requirement.
What do the others think?
Show replies by date