Re: pinning objects in ffi.gc() finalizers

  • From: Mike Pall <mike-1407@xxxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Wed, 2 Jul 2014 17:02:17 +0200

Cosmin Apreutesei wrote:
> I noticed that pinning objects in ffi.gc finalizers() doesn't work, at
> least not when the program exits -- it's like the upvalues of the
> finalizer are weak references. Is this a bug or a feature?

'pinning' (in GC terminology) means preventing an object from
moving its address. That's not applicable here, since Lua and
LuaJIT have a non-moving GC.

You probably mean anchoring. But upvalues are strong anchors, so
this is not what happens here.

> When the program exits, sometimes heap's finalizer is called before
> mem's finalizer, even though mem's finalizer pins heap.

Don't confuse finalization and freeing of the underlying objects.
In this case it's the cdata pointers themselves which are most
certainly anchored and kept alive by the upvalues.

But that doesn't affect finalization order: cdata objects do not
have a defined finalization order right now (unlike userdata).
Actually, cdata finalizer handling is rather messy in the current
GC and fixing that would be tricky.

[
Note that you can create a similar problem with userdata where a
finalizer of an older object has an upvalue anchoring a younger
object: that doesn't prevent the younger object from being
finalized first -- but it does prevent the younger object from
being freed before the finalizer for the older object is invoked.

local o1 = newproxy(true)
local o2 = newproxy(true)
getmetatable(o2).__gc = function(x) print("finalize o2", x) end
getmetatable(o1).__gc = function(x) print("finalize o1", x, o2) end
-- This finalizes o2 first, even though o1's finalizer anchors o2.
]

--Mike

Other related posts: