ML is interesting because it emphasis immutability. For performance reasons, a part of it is in effect mutable and thread local. Some ML implementations are very interesting for us.
But let's get back to D. To make the example simpler, let's get rid of shared (in effect, the same thing can be achieve with write barrier on shared and do not fundamentally affect the way it works). So we have a TL GC that run on a regular basis.When doing so, it also collect the pointers to the immutable heap and give the to the immutable GC as roots. Now the immutable GC works from these roots, but will consider everything allocated after it get its root as alive. This is working because the new root to the immutable heap that can appear in the TL heap can come from: - new allocations. - from read in immutable heap. - other thread (and it will be a root from their scan). Let's get rid of #3 by making std.concurency aware of the GC system. An exchange from a non scanned thread to a scanned one will register a root. We get rid of #1 by choosing that all allocation done after getting the roots are considered alive. We get rid of #2 by recurrence. Reading from the immutable heap require a reference to the immutable heap. Ultimately, you end up with a root in #1 or #2 scenario, that will be considered alive. As the chain of reference is immutable, the one you read will ultimately be scanned. The idea is based on Doligez-Leroy's GC, but using TL heap as the small object and immutable heap as the shared. Note that this GC is done for ML, where most things are immutable and this is why it works well (only require write barriers). This strategy would be a disaster in java for instance, or for us to use the small object strategy for TL. http://gallium.inria.fr/~xleroy/publi/concurrent-gc.pdf http://www.cs.tau.ac.il/~msagiv/courses/mm/doligez.ppt