Evaluate update thunks in the RTS?
The selector thunk optimization is well known to be beneficial.
In short for a thunk of the form:
let val = case x of
(y,_) -> y
it's very beneficial to have the RTS evaluate the thunk in case x
is already a tuple constructor.
Now I'm wondering about record updates. In particular if we have code like:
let myOptions = myOldOptions { some_field = newValue }
could we optimize this to an equivalent thunk that get's similarly evaluated by the runtime during GC? Matt recently fixed a space leak caused by code like this in !8807 (closed)
As it stands we end up with something like:
myOptions =
THUNK{fv: myOldOptions, newValue}
[ case myOldOptions of
Options f1 f2 f3 _ -> Options f1 f2 f3 newValue
]
where the reference to myOldOptions keeps the old value in some_field
alive until myOptions is forced.
Currently the only solution is to make myOptions strict. It would be nice if this sort of leak would "fix itself" the same way it does for selector thunks.
In general I imagine the pattern would be easy (but maybe not cheap?) to identify during code generation. Not 100% sure it's worth doing this. But might be worth looking into.