I'm trying to figure out if it's possible to put a MutableArray# in
a compact region. Doing this is explicitly discouraged by ghc devs
and by the documentation
because it allows users to point to something outside of the Compact.
That aside, I'm still interested in trying to do this, with the understanding
that I would be responsible for ensuring that the array only point to things
inside the same Compact.
My line of thinking was to add an Array# to a compact region and then
attempt to thaw it using unsafeThawArray#:
unsafeThawArray# :: Array# a -> State# s -> (#State# s, MutableArray# s a#)
I should then be able to use writeArray#, provided that (a) everything I
write into the MutableArray# is in the same compact region and (b) I
evaluate everything to WHNF with seq before writing it to the array. I think this would be safe. I do have one concern based on the
stg_unsafeThawArrayzh commentary:
A MUT_ARR_PTRS lives on the mutable list, but a MUT_ARR_PTRS_FROZEN normally doesn't...
I don't understand the internals of GHC well, but here is my understanding of the comment:
There is something called the mutable list, which has a bunch of mutable arrays and
is occassionally scan by the GC. For my purposes, this is problematic, since it means
that unsafeThawArray# will cause the GC to start scanning things in a compact region.
That's not good. But, maybe my understanding is wrong, which would be great.
If unsafeThawArray# cannot do what I need, I was thinking that unsafeCoerce# would
do it, but I again I'd like to hear from someone knowledgeable on this subject. Thanks and let me know if I can clarify anything.
EDIT: Just a comment for future readers. After thinking about this more, I realized that using SmallArray# instead of Array# would be better. It should make writes faster. Compare the code for writing to MutableArray# with the code for writing to SmallMutableArray#. The card table that MutableArray# keeps updated is worthless when everything is on the compact heap since it's never going to get scanned anyway.