September 09, 2008
This may be a stupid question, but it may also be kind of interesting.  To make GC faster in D, would it be possible to handle the simple cases, where an object has a lifetime that is well defined at compile time, statically, and only use traditional GC for the not-so-trivial cases?  For example, let's say you have the following relatively simple case:

pure int foo() {
    auto myHugeArray = new uint[10_000_000];
    //Do only stuff that's legal for pure functions.
}

Since foo() is a pure function, it can't modify global state, i.e. no side
effects.  Since no side effects are allowed and the return type of foo() is
not even a reference type, it can be statically proven that myHugeArray can be
freed as soon as foo() goes out of scope, potentially saving a GC run.
Furthermore, if the compiler can prove that neither myHugeArray nor any alias
or slice of it is used after a certain point in foo(), it can be freed even
before foo() goes out of scope.

Of course, a sufficiently smart compiler could handle less trivial cases than a pure function call and could do so conservatively since it's backed up by a regular GC anyhow. This would allow GC to be used when it's faster (i.e. when an object's lifecycle is not trivial, and managing memory statically would either generate lots of code bloat or simply be impossible, leading to ad-hoc ref counting or some other bad solution).  At the same time, the equivalent of manual memory management would used when it's faster (when the lifecycle of an object is trivial, such as when it can be proven by the compiler to be bound to a scope), except that it would be safe.