You beat me to my response. malloc/free are great for long running processes where memory can't just infinitely increase, but there's a ton of stuff in a compiler -- types, expressions, symbols -- that survives until the process exits. There's benefit in both space (because you don't have to add headers to the blocks as malloc() does, so free() can work) and time to doing it this way.

On Mon, Aug 17, 2020 at 2:03 PM Paul Winalski <paul.winalski@gmail.com> wrote:
On 8/16/20, Noel Chiappa <jnc@mercury.lcs.mit.edu> wrote:
>
> The V7 compiler seems to use sbrk() (the system call to manage the location of
> the end of a process' data space), and manage the additional data space
> 'manually'; it does not seem to use a true generic heap. See gblock() in
> c01.c:

This is very common in compilers.  Both the DEC/Compaq and Intel
compilers manage heap memory this way. Each particular phase or pass
of a compiler tends to build its on set of data structures in heap,
and then free the whole mess when the phase/pass is done.  malloc/free
doesn't fit the model very well because you have to free each
structure individually, and for more persistent structures you don't
get very good locality of reference.  What works better is to use a
multitude of mini-heaps that can be freed up all in one go.

-Paul W.