On 14/08/12 15:47, Matthew Fluet wrote:
On Mon, Aug 13, 2012 at 5:47 PM, Phil Clayton <[email protected]> wrote:
This can be worked around easily, for example by creating a variant of
PolyML.export that adds a final PolyML.fullGC to the exported function (for
both normal and exception paths). However, there is the question of
whether, on termination, a full GC is needed or does a call to each
finalizer suffice. If it is the latter, the work-around with an explicit GC
does more work than required.
I would think that you would want a full GC. I wouldn't expect a
finalizer to run unless the value it is finalizing has been garbage
collected, and it is possible that some code might depend upon that
invariant. If there is code that should run at the end of the
program, whether or not a value has been garbage collected, then
OS.Process.atExit seems to be the better choice.
With Poly/ML, a finalizer is a C function attached to a vol that, when
called, is passed (the pointer at offset 0 in) the C data that the vol
wraps. So, I suppose a vol's finalizer could callback to SML and cause
another vol to become unreachable, invoking another finalizer and so on.
I was trying to contrive such an example where the finalizers needed
to occur in such an order but was having difficulty. I'm starting to
form the opinion that this finalization mechanism, that works on vols
rather than ML objects generally like in MLton, has very limited support
for expressing order relationships between finalizers. After all, there
is no way for the garbage collector to track dependencies via C. May be
it is simplest to make no claims about the order of finalizers? (I've
not found the current support to be an issue.)
I'm glad you mentioned OS.Process.exit - the work-around would also need
to cover that exit path by (OS.Process.atExit PolyML.fullGC).
By comparison, for stand-alone executables created with MLton, any remaining
finalizers (added with MLton.Finalizable.addFinalizer) are called prior to
termination - possibly due to a final GC, I don't know.
Actually, it is due to multiple final GCs. The implementation is at:
http://mlton.svn.sourceforge.net/viewvc/mlton/mlton/trunk/basis-library/mlton/finalizable.sml
The loop is to handle the situation where a full GC reveals that some
finalizers should be run and, after running the finalizers and
discarding those closures, another full GC reveals that yet more
finalizers should be run.
Thanks - I hadn't appreciated that one call to MLton.GC.collect doesn't
attempt a further GC after any finalizers that it triggers are run. It
would be useful to know whether PolyML.fullGC is the same. (If so, my
work-around above won't work generally.)
Phil
_______________________________________________
polyml mailing list
[email protected]
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml