+data ForeignPtr a = ForeignPtr Addr# ForeignPtrContents
+ -- we cache the Addr# in the ForeignPtr object, but attach
+ -- the finalizer to the IORef (or the MutableByteArray# in
+ -- the case of a MallocPtr). The aim of the representation
+ -- is to make withForeignPtr efficient; in fact, withForeignPtr
+ -- should be just as efficient as unpacking a Ptr, and multiple
+ -- withForeignPtrs can share an unpacked ForeignPtr. Note
+ -- that touchForeignPtr only has to touch the ForeignPtrContents
+ -- object, because that ensures that whatever the finalizer is
+ -- attached to is kept alive.
+
+data ForeignPtrContents
+ = PlainNoFinalizer
+ | PlainWithFinalizer !(IORef [IO ()])
+ | MallocPtrNoFinalizer (MutableByteArray# RealWorld)
+ | MallocPtrWithFinalizer (MutableByteArray# RealWorld) !(IORef [IO ()])
+ -- we optimise the no-finalizer case, which is especially common
+ -- with a MallocPtr. mallocForeignPtr doesn't have to create an
+ -- IORef, or set up a weak pointer.