Lightweight arenas ================== Standard arenas --------------- A standard arena in SLUL consists of one or more 4 KiB blocks, where the start of each block contains: - a pointer to the first block (null in the first block) - a pointer to the next block (null in the last block) - a bump pointer The next pointer and bump pointer can be stored as one pointer; the next pointer in the high order bits, and the bump pointer in the low order bits). The first block additionally contains a pointer to additional data for the arena, such as pointers to overridable system functions. Lightweight arenas ------------------ Goal: - Avoid requiring a full 4 KiB allocation. Cases: 1. Stack-like usage. Sub-arena is allocated, and then no allocations are done in the base arena until the sub-arena has been freed. 2. One-shot-allocated objects. A sub-arena is allocated for the object, which is "initialized" in some way. Initialization only allocates inside the sub-arena. After the initialization, no allocations are done in the sub-arena. 3. Per-object allocation with mostly reasonably small objects. The object needs unconstrained arena allocation, with a separate arena, but using a full 4 KiB arena would be wasteful. Solutions to case 1 - Stack like usage -------------------------------------- Can simply use the same arena, and just save and restore the bump pointer. Special handling is required for any newly allocated blocks, which need to be either freed or marked as unused/available. Solutions to case 2 - One-shot-allocated objects ------------------------------------------------ Problems: - Allocation can be done with any ref inside the arena - Base and sub-arena(s) can become interleaving - How should deallocation be done? - Does the "arena_free()" function always get the initial sub-arena pointer, or could it get a pointer to a subsequently allocated "sub-"object? Could use a separate block/set of blocks per "physical" arena for case 2 and 3. These blocks could have some flag that indicates that it they are special blocks. For case 2, a flag would be needed to indicate that special care needs to be taken when freeing "the" arena (which is actually multiple arenas). It is also necessary with some kind of partitioning of the arena. Perhaps a linked list? Performance? Maybe allocations can be done as usual, with only two additional pointers added, one at the start of the one-shot arena and one at the end (both part of the linked list), plus an update of the pointer at the start (that indicates the the arena has "one-shot sub-arenas" inside) Overall arena layout: - base ptr / first sub-arena - next ptr / bump ptr ... - sub-arena 1: end pointer ... sub-arena 1 data ... - sub-arena 1: next pointer ... How should nested sub-arenas work? TODO Solutions to case 3 - Unconstrained per-object allocation --------------------------------------------------------- TODO