[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Lua gc
- From: Mike Pall <mikelu-0412@...>
- Date: Tue, 28 Dec 2004 11:44:55 +0100
Hi,
skaller wrote:
> how does one mark an object as a root?
You put it in the so-called 'registry'. This is just a table anchored
at the root which never gets collected until you close the lua_State.
It is only accessible to C calls via the LUA_REGISTRYINDEX pseudo-index.
> This is necessary, so that even if an object is
> unreachable, it isn't collected. It is marked
> as a root, because someone *else* is using it.
Just put a reference to your object in the registry (or a table of your
own, referenced from the registry).
> For example: Lua interpreter #1 creates some object,
> and passes it to #2. #1 must mark the object as a root.
> It also uses sets the finalisation callback in #2,
> so when it is unreachable in #2, the #2 finaliser
> will 'unmark' the object as a root, so #1 can
> now collect it.
While this works in theory, it does not work in practice due to the way
the GC works. Passing a generic object to a different Lua universe will get
you into trouble. Even passing strings won't work properly because they need
to be anchored in the string table (lots of things depend on the property
s1 == s2 <=> ptr(s1) == ptr(s2) which is ensured by the single string table).
> If this is done with full user data, it generalises
> to arbitrary sharing, at the cost of one extra
> level of indirection every time the object crosses
> an interpreter boundary.
You may get this to work if you only use boxed pointers to a reference
counted object created outside of Lua. Every Lua universe needs its own
copy of this userdata.
> It isn't clear how to make this seamless (transparent),
> for any GC (not just Lua's or mine).
I think it only works when you use a reference-counting scheme on top of
a mark/sweep collector. Not the other way round. Marrying two mark/sweep
collectors is more or less hopeless.
> It also isn't clear what happens in Lua if you unravel
> the full user data one level, and get the other interpreters
> object out of it: which functions will work with this data
> without triggering faulty GC operations? to be clear --
> we'd be working with an object that is the correct structure
> for a Lua object, and may even have been created by a
> lua API call .. but is used with a 'different' lua_State*
> than it was created with.
It breaks on containers because you'd need to intercept storage of an
object in a container owned by the wrong universe. This gets arbitrarily
complicated. And without containers and strings (see above) there's
nothing left worth sharing ...
> The difficulty is that such an object, being a pointer,
> may be put on the Lua stack .. then there is a reference
> to it we don't know about .. OTOH Lua might know about it,
> examining the stack, and incorrectly do something to
> it .. such as try to do a mark or sweep on it ..
The stack is definitely examined during the GC. And it will definitely
break.
Bye,
Mike