[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: Prevent userdata from being marked for garbage collection?
- From: Roberto Ierusalimschy <roberto@...>
- Date: Fri, 6 Jul 2012 10:26:00 -0300
> In the Lua 5.1 code, after
> myobject = nil
> the myobject and the sentinel are referring to each other (sentinel
> is a value of myobject, and myobject is an upvalue of the sentinel's
> __gc metamethod), but the garbage collectors next "mark phase" would
> see them as an unreachable island and thus leave them both "white".
> (Or does that sentinel's upvalue reference cause one last time the
> myobject to become black?)
> In the "cleaning phase", the sentinel with its __gc metamethod is
> put into the tmudata list. (If myobject had a __gc (in 5.2), it
> would be, too -- and gone for good.)
> According to PiL2, chapter 31.2, the sentinel is also marked as alive / "black".
> (I guess this is done to exclude it from the subsequent "sweep phase"?)
> Is here the magic? Does the last step propagate from the userdata
> and thus also cause the referred myobject to become alive again?
Yes. Everything once in the tmudata list is ressurected, and it
propagates. (Otherwise, even the __gc function itself could be
collected!) All objects reachable from a finalizing object are kept
alive together with the object itself. (Their finalizers, however,
will run too if they are reachable *only* through other finalizers.)
Actually, the moving to the tmudata list is done in the atomic phase,
before sweeping starts, exactly because before propagation Lua cannot
know what is really garbage.
Weak tables also enter in this mix. Let us call all objects reachable
only through finalizers "zombies". (That includes finalizing objects
too.) If a zombie is a value in a weak table, that entry is removed.
But a zombie as a key in a weak table keeps the entry. This allows
the finalizer to use the weak table to access data related to the
object being finalized.