
On 12/7/11 5:03 AM, Simon Marlow wrote:
It would be possible, but it's not quite as straightforward as you might think. Suppose you have a program like this:
xs = [1..100000] evens = filter ((==0) . (`mod` 2)) xs
and you fully evaluate "evens". Now, GHC will garbage collect "xs", because it isn't required any more. However, if you revert "evens" to a CAF, now we require "xs" again, so we have to either revert that to a CAF or arrange to retain it in the first place on the grounds that we might need it again if some other CAF is reverted.
Reverting xs to a CAF is not hard - we could have the GC revert CAFs as soon as they become unreachable. Arranging to retain it is harder.
Right. I know it isn't easy to do in the general case, which is why I was looking for an API hook rather than a Haskell function. Luckily my case is like xs. The only free variables are common functions ---functions used by list comprehension notation, methods of Num Int, Enum Int, Ord Int, (||), and (&&)--- which are almost surely inlined away and would never be reverted anyways.
GHCi gets around this by reverting *all* CAFs at the same time when you say :load.
There's one other thing: GHC doesn't support reverting CAFs in interpreted code at the moment, you have to reload the module.
So you need the following things:
- modify the GC to revert CAFs when they become garbage
- add a primop to revert a single CAF
not too hard, I would think...
Good to know. I'll take a look at it over the break and see if I can come up with something. -- Live well, ~wren