This is all fine, except that implementing finalizer ordering slows down ForeignPtrs quite a bit, in particular mallocForeignPtr takes a 20% hit just allocating the IORef needed to store the list of finalizers. Ideas for a better implementation are welcome.
Having obviously optimized the hell out of mallocForeignPtr, it sounds like it's time to optimize the hell out of IORef. :-)
Or, on the assumption that the slowdown comes from splitting what was a single object into 2 or even three separate objects, do what it takes to turn it back into a single object - i.e., put a mutable field directly in the MFP object.
Best of all, do as CAML has done and add the machinery (and semantics changes) necessary so that whenever you have a tuple with a mutable field in it, GHC will implement it without adding an indirection through a separate IORef object. Highly worthwhile and might possibly help with your MFP problem :-)
I already optimised away one level of indirection by using a strict field and -funbox-strict-fields (standard practice when putting an IORef in a constructor :-), but there is still a separate object for the primitive mutable variable. Folding this into the constructor is an interesting idea - I'll muse on it.
Anyway, this message is really about what names we should use for the old Haskell-finalizer versions of newForeignPtr and addForeignPtrFinalizer (and as such it doesn't have any bearing on the FFI spec 1.0).
I'm rather taken by 'oldNewForeignPtr'.
That implies the functionality is deprecated, rather than just non-portable, which is not the case at all.
I'm assuming that we want to keep these functions in some form in GHC - where to put them is one issue; Foreign.ForeignPtr is a possibility (but not ForeignPtr), or GHC.ForeignPtr.
I'd put them in GHC.ForeignPtr and make no other change in their name.
One vote for GHC.ForeignPtr then. Any others?
Easy for people to transition, easy for people to see non-portable code, probably little risk of collision with the ffi-mandated FunPtr versions.
On the subject of non-portability: the hierarchy is scattered with non-portable libraries, because the decision was taken a while back not to use the hierarchy to indicate portability, but to use it to guide programmers towards *functionality*. There are exceptions - eg. for extensions which are likely to remain compiler-specific. I don't think Haskell finalizers are necessarily GHC-specific, so putting them under GHC doesn't seem right in the long term. Cheers, Simon