lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


thanks for the detailed reply.
that helped a lot

On Wed, 28 Dec 2022 at 15:52, Xmilia Hermit <xmilia.hermit@gmail.com> wrote:
Red Artist:

> So, I understand that you mark an object for finalization by setting a
> metatable with __gc method.

Yes

> Does this mean there exists an order for finalizers? In particular,
> the order seems to be the reverse of the order in which we set the
> metatable.
Yes
> > that is, the first finalizer to be called is the one associated with
> the object marked last in the program.
>
> This line in particular makes it seem that younger garbage is
> finalized first and older garbage last.
You can have older objects marked for finalization later than young
objects. Take:
a={} -- Old
b={} -- Young
setmetatable(b,{__gc=fin}) -- called second by gc
setmetatable(a,{__gc=fin}) -- called first by gc
> My first question is whether this order is actually required to be
> followed by Lua implementations?
My personal opinion is that a conformant Lua implementation needs to
implement everything the way the manual specifies.
So, in this case, the exact ordering is required. This is important for
C libraries as the order ensures that the objects created from the
library are finalized before the library is unloaded.
> If there *is* an order, then I need to assign an unique incremental id
> to each userdata/table object.
> Then, at the end of garbage collection, first collect all those ids ->
> **sort them in decreasing order** -> then call finalizers.
I would implement it by using one bit in every object to tell if the
object is already marked for finalization. If it is marked for
finalization the bit is checked and in case the object is not marked set
and the pointer to the object is added to an array of finalization objects.
Then in the GC phase, after all objects are marked, travers the array in
reverse order and add all objects not marked by the GC to a new array,
and compact the old array. Mark all objects in the new array and do a
full remark, and then call the finalizers.
The only hard thing here is to follow the lua_setmetatable spec since it
is not allowed to throw memory errors when the array is full and cannot
be extended.
> As a follow up question, does Lua actually guarantee that if an
> younger object without references becomes garbage, then any older
> object without references MUST BE garbage too?
I don't think this is specified in the manual, so in my opinion not.

Regards,
Xmilia