asmjit::JitAllocator Class Reference

A simple implementation of memory manager that uses asmjit::VirtMem functions to manage virtual memory for JIT compiled code.

Implementation notes:

  • Granularity of allocated blocks is different than granularity for a typical C malloc. In addition, the allocator can use several memory pools having a different granularity to minimize the maintenance overhead. Multiple pools feature requires kFlagUseMultiplePools flag to be set.
  • The allocator doesn't store any information in executable memory, instead, the implementation uses two bit-vectors to manage allocated memory of each allocator-block. The first bit-vector called 'used' is used to track used memory (where each bit represents memory size defined by granularity) and the second bit vector called 'stop' is used as a sentinel to mark where the allocated area ends.
  • Internally, the allocator also uses RB tree to keep track of all blocks across all pools. Each inserted block is added to the tree so it can be matched fast during release() and shrink().

Public Members


Member Functions

Construction & Destruction
Alloc & Release

Constructor & Destructor Documentation

JitAllocator::JitAllocator(const CreateParams* params = nullptr)explicitnoexcept

Creates a JitAllocator instance.


Destroys the JitAllocator instance and release all blocks held.

Member Function Documentation

void JitAllocator::reset(ResetPolicy resetPolicy = ResetPolicy::kSoft)noexcept

Free all allocated memory - makes all pointers returned by alloc() invalid.

This function is not thread-safe as it's designed to be used when nobody else is using allocator. The reason is that there is no point of calling reset() when the allocator is still in use.

JitAllocatorOptions JitAllocator::options() constnoexcept

Returns allocator options, see Flags.

bool JitAllocator::hasOption(JitAllocatorOptions option) constnoexcept

Tests whether the allocator has the given option set.

uint32_t JitAllocator::blockSize() constnoexcept

Returns a base block size (a minimum size of block that the allocator would allocate).

uint32_t JitAllocator::granularity() constnoexcept

Returns granularity of the allocator.

uint32_t JitAllocator::fillPattern() constnoexcept

Returns pattern that is used to fill unused memory if kFlagUseFillPattern is set.

Error JitAllocator::alloc(void** rxPtrOut, void** rwPtrOut, size_t size)noexcept

Allocates a new memory block of the requested size.

When the function is successful it stores two pointers in rxPtrOut and rwPtrOut. The pointers will be different only if kOptionUseDualMapping was used to setup the allocator (in that case the rxPtrOut would point to a Read+Execute region and rwPtrOut would point to a Read+Write region of the same memory-mapped block.

Error JitAllocator::release(void* rxPtr)noexcept

Releases a memory block returned by alloc().

This function is thread-safe.

Error JitAllocator::shrink(void* rxPtr, size_t newSize)noexcept

Frees extra memory allocated with rxPtr by shrinking it to the given newSize.

This function is thread-safe.

Error JitAllocator::query(void* rxPtr, void** rxPtrOut, void** rwPtrOut, size_t* sizeOut) constnoexcept

Queries information about an allocated memory block that contains the given rxPtr.

The function returns kErrorOk when rxPtr is matched and fills rxPtrOut, rwPtrOut, and sizeOut output arguments. The returned rxPtrOut and rwPtrOut pointers point to the beginning of the block, and sizeOut describes the total amount of bytes this allocation uses - sizeOut will always be aligned to the allocation granularity, so for example if an allocation was 1 byte and the size granularity is 64, the returned sizeOut will be 64 bytes, because that's what the allocator sees.

Statistics JitAllocator::statistics() constnoexcept

Returns JIT allocator statistics.

This function is thread-safe.

Member Data Documentation

Impl* JitAllocator::_impl

Allocator implementation (private).