Machine Code Generation for C++
Zone memory allocator and containers.
AsmJit uses zone memory allocation (also known as Arena allocation) to allocate most of the data it uses. It's a fast allocator that allows AsmJit to allocate a lot of small data structures fast and without
malloc() overhead. Since code generators and all related classes are usually short-lived this approach decreases memory usage and fragmentation as arena-based allocators always allocate larger blocks of memory, which are then split into smaller chunks.
Another advantage of zone memory allocation is that since the whole library uses this strategy it's very easy to deallocate everything that a particular instance is holding by simply releasing the memory the allocator holds. This improves destruction time of such objects as there is no destruction at all. Long-lived objects just reset its data in destructor or in their reset() member function for a future reuse. For this purpose all containers in AsmJit are also zone allocated.
The most common data structure exposed by AsmJit is ZoneVector. It's very similar to
std::vector, but the implementation doesn't use exceptions and uses the mentioned ZoneAllocator for performance reasons. You don't have to worry about allocations as you should not need to add items to AsmJit's data structures directly as there should be API for all required operations.
The following APIs in CodeHolder returns ZoneVector reference:
ZoneVector has overloaded array access operator to make it possible to access its elements through operator. Some standard functions like ZoneVector::empty(), ZoneVector::size(), and ZoneVector::data() are provided as well. Vectors are also iterable through a range-based for loop:
Zone-allocated containers do not store the allocator within the container. This decision was made to reduce the footprint of such containers as AsmJit tooling, especially Compiler's register allocation, may use many instances of such containers to perform code analysis and register allocation.
For example to append an item into a ZoneVector it's required to pass the allocator as the first argument, so it can be used in case that the vector needs a reallocation. Such function also returns an error, which must be propagated to the caller.
Containers like ZoneVector also provide a functionality to reserve a certain number of items before any items are added to it. This approach is used internally in most places as it allows to prepare space for data that will be added to some container before the data itself was created.