I made a few changes to the GC and broader memory handling:
The GC now automatically collects when the heap runs out of space from which to allocate. If it's not happy enough with how much memory is left after a collection, the subsequent collection will double the heap size.
Con4m no longer replaces the default allocator for hatrack internal calls. That is, hatrack allocation now all uses the system malloc for all its internal records.
I added finalizer support. Object instantiations that have a finalizer in their vtable automatically get registered; the finalizer gets called if and only if the object gets collected.
I added finalizers for all of the hatrack data structures (and for the stream type), which is necessary to avoid hatrack leaks after change #2.
To support set operations properly, I changed the hatrack interface for unions, intersections, disjunctions and difference operations to take an extra parameter with a fully pre-allocated result object (that should not be in use until the function returns). This way, the top-level set objects can all be allocated by the con4m GC, even though all the internal stores will now use the system malloc. This isn't ideal, but I spent a lot of time looking at how to properly parameterize the different kinds of hatrack allocation, and every non-hacky option I'd like better is a massive amount of additional work I'm not willing to do.
For future work, there should probably be some awareness of the overall system memory situation, to adjust heap size if appropriate, and collect when the system is getting very low.
I made a few changes to the GC and broader memory handling:
For future work, there should probably be some awareness of the overall system memory situation, to adjust heap size if appropriate, and collect when the system is getting very low.
Stacked on top #31.