lua-users home
lua-l archive

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

Red Artist:

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


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.
> 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.