# Arena allocator

Scratchpads [mem/scratch] are fine for temporary data, but for semi-temporary
data, not so much. Sometimes, we need to hold onto temporary data for longer and
the size of that data can vary wildly, making it difficult to find a reasonable
size for our buffer.

If we have a clear point where we can say "from this moment, I don't need any of
this class of data", then the arena allocator [mem/alloc] is ideally suited for
the task.

One such example are line buffers in text/ed. We don't know beforehand how many
characters we'll have to deal with, it depends on the size of the input file.
Also, we don't know if the user is going to edit the file a little bit or a lot.
Allocating a static buffer either wastes memory or makes the app too
constrained.

The arena allocator is a linked list of fixed size buffers (4 kilobytes) that
grow whenever we need more memory by adding a buffer to the linked list. When we
clear the arena, it rewinds itself to its first buffer and reuse those
previously allocated buffers for subsequent allocations, growing the list again
if it reaches its previous limit.

## Locked arenas

Sometimes, the role of an arena is to keep us from writing to HERE. It is the
case, for example, of arenas used in compilers such as [comp/c] or
[comp/oberon].

In those cases, we actually never want to allocate a new buffer during regular
operations, only during "ensurenext".

To make sure that unexpected arena growing doesn't corrupt HERE memory, you can
create what we call a "locked arena" instead of a regular arena. A locked arena
aborts with error on NEWHERE.

## API

newarena ( -- alloc )
  Create a new empty arena

newlockedarena ( -- alloc )
  Create a new locked arena.

ensurenext ( -- )
  With CURALLOC being an arena, ensures that the current arena buffer has a
  "next" buffer. Create one if it hasn't. This gives you leeway for some
  allocations guaranteeing you you won't tap into system memory.

reset ( -- )
  With CURALLOC being an arena, reset it to its first buffer, HERE pointing to
  the first byte of that buffer.

withinarena? ( a -- f ) *A*
  With CURALLOC being an arena, yield whether the specified address is within
  the bounds of one of the buffers of the arena.
