Support pin-changing on ByteArray#s
I'm mostly posting this here as a chance for discussion for this feature, as I've wanted it a few times before and because Roman Leshchinskiy mentioned it on reddit and reminded me.
IIRC, the basic idea was to have an operation like:
pin# :: ByteArray# -> ByteArray#
Then you could say:
let y = pin# x
and y would have the same contents as x but be pinned. Whether it is the same memory block as x would be implementation-dependent but with GHC, it would be. When GHC would garbage collect y, it would unpin x (if x is still alive). You would also have unpin# so if you said:
let z = unpin# y
then z will become unpinned when y is garbage collected.
I mostly care because it's unfortunate to have to decide up front whether you want to suffer from memory fragmentation or to support foreign bindings. This could for example let us break the distinction between Data.Vector.Unboxed and Data.Vector.Storable. From a higher level, you might have a
withPinned function that would temporarily pin (without copying) an array while you make foreign calls with it (even across multiple foreign calls), and then would unpin it when you're done.
I'm not sure what this would entail on the actual GC/runtime side of things, but I figured it'd be worth discussing.