Currently, Sapling will never free up space in the arena even if history is rewritten and some trees will never be reached. This is essentially a memory leak, and will cause Sapling to just accumulate memory over time.
Some kind of garbage collection has to happen, because Sapling's arena allocator only produces immutable references to the nodes. However, because of the tree structure of the AST, we can rely on AST nodes having no reference cycles and so standard reference counting should suffice to prevent memory leaks. However, some custom drop code will be required (because we can't simply deallocate small parts of memory owned by the Arena
- we need to notify the arena that this cell isn't being used).
So I think the solution is going to have to involve some kind of smart pointer that does reference counting but, instead of deallocating the memory it points to, instead notifies the Arena
whenever the reference count hits 0
. Also, AST nodes in the arena currently sit inside Item
structures (which in its own right probably should be called Cell
), which allows us to add extra fields for things like RC and memoisation of expensive functions (string conversions, etc.).
My proposed solution would be something like having a Ref<'arena, Node>
smart pointer, which contains an RCed reference to an arena::Item<Node>
, which can then be deref-ed into just a plain &'arena Node
.
Node memory management is definitely not something that I want to screw up, and I've never had to deal with smart pointers or RCing before so if someone who knows more is happy to implement this then feel free :)
.