xo-alloc2: ++ documentation + threshold size for THP feature

This commit is contained in:
Roland Conybeare 2025-12-23 21:06:38 -05:00
commit 289751d3fd
18 changed files with 642 additions and 192 deletions

View file

@ -3,8 +3,15 @@
AAllocator Reference
====================
Abstract interface facet for arena allocator.
Provides simple arena allocation.
Abstract interface facet for an allocator.
Base class for runtime polymorphism over allocator implementations,
using faceted object model.
* runtime size consists of vtable pointer only.
* per FOMO prinicples, runtime state is stored separately.
Classes that inherit ``AAllocator`` will not add state
Context
-------
@ -12,40 +19,24 @@ Context
.. ditaa::
:--scale: 0.99
+-------------------------------+--------------------------------------+
| | IAllocator_DX1Collector |
| | IAllocIterator_DX1CollectorIterator |
| IAllocator_DArena | |
| IAllocIterator_DArenaIterator +--------------------------------------+
| | DX1Collector |
| | DX1CollectorIterator |
| | |
+-------------------------------+---------+----------------------------+
| DArena | |
| DArenaIterator | |
+-----------------------------------------+ CollectorConfig |
| ArenaConfig | |
+-----------------------------------------+----------------------------+
+----------------------------------+-----------------------------------+
| RAllocator | RAllocIterator |
+----------------------------------+-----------------------------------+
| IAllocator_DX1Collector | IAllocIterator_DX1Collector |
| IAllocator_DArena | IAllocIterator_DArena |
+----------------------------------+-----------------------------------+
| IAllocator_Xfer | IAllocIterator_Xfer |
| IAllocator_Any | IAllocIterator_Any |
+----------------------------------+-----------------------------------+
| AAllocator | AAllocIterator |
+----------------------------------+-----------------------------------+
+---------------+------------------+----------------------+------------+
| | | AllocInfo | |
| generation | +----------------------+ |
| object_age | AllocError | AllocHeaderConfig | cmpresult |
| role | +----------------------+ |
| | | AllocHeader | |
+---------------+------------------+----------------------+------------+
+----------------------+-------------------------+-----------------------------------+
| RAllocator | RAllocIterator | IAllocator_DArena |
| | | IAllocIterator_DArenaIterator |
+----------------------+-------------------------+-----------------------------------+
| IAllocator_Xfer | IAllocIterator_Xfer | DArena |
| IAllocator_Any | IAllocIterator_Any | DArenaIterator |
| IAllocator_Impltype | IAllocIterator_Impltype | |
| | | |
+----------------------+-------------------------+-----------------------------------+
|cBLU AAllocator | AAllocIterator | ArenaConfig |
+----------------------+-------------------------+-----------------------------------+
+-----------------+----------------------------------------------+-------------------+
| | AllocInfo | |
| +----------------------------------------------+ |
| AllocError | AllocHeaderConfig | cmpresult |
| +----------------------------------------------+ |
| | AllocHeader | |
+-----------------+----------------------------------------------+-------------------+
.. code-block:: cpp

View file

@ -0,0 +1,61 @@
.. _AllocInfo-reference:
AllocInfo Reference
===================
Information, including alloc metadata, pertaining to a particular allocation.
Context
-------
.. ditaa::
:--scale: 0.99
+----------------------+-------------------------+-----------------------------------+
| RAllocator | RAllocIterator | IAllocator_DArena |
| | | IAllocIterator_DArenaIterator |
+----------------------+-------------------------+-----------------------------------+
| IAllocator_Xfer | IAllocIterator_Xfer | DArena |
| IAllocator_Any | IAllocIterator_Any | DArenaIterator |
| IAllocator_Impltype | IAllocIterator_Impltype | |
| | | |
+----------------------+-------------------------+-----------------------------------+
| AAllocator | AAllocIterator | ArenaConfig cBLU |
+----------------------+-------------------------+-----------------------------------+
+-----------------+----------------------------------------------+-------------------+
| | AllocInfo | |
| +----------------------------------------------+ |
| AllocError | AllocHeaderConfig | cmpresult |
| +----------------------------------------------+ |
| | AllocHeader | |
+-----------------+----------------------------------------------+-------------------+
.. code-block:: cpp
#include <xo/alloc2/DArena.hpp>
Class
-----
.. doxygenclass:: xo::mm::AllocInfo
Member Variables
----------------
.. doxygengroup:: mm-allocinfo-instance-vars
Type Traits
-----------
.. doxygengroup:: mm-allocinfo-traits
Constructors
------------
.. doxygengroup:: mm-allocinfo-ctors
Methods
-------
.. doxygengroup:: mm-allocinfo-methods

View file

@ -5,10 +5,12 @@ xo_docdir_doxygen_config()
xo_docdir_sphinx_config(
index.rst
glossary.rst
examples.rst
implementation.rst
AAllocator-reference.rst
ArenaConfig-reference.rst
DArena-reference.rst
AllocInfo-reference.rst
#install.rst
#introduction.rst
#implementation.rst

View file

@ -11,17 +11,24 @@ Context
.. ditaa::
:--scale: 0.99
+--------------------------------+
| IAllocator_DArena |
+--------------------------------+
| IAllocator_Xfer |
+--------------------------------+
| IAllocator_ImplType |
+--------------+-----------------+
| | DArena cBLU|
| AAllocator +-----------------+
| | ArenaConfig |
+--------------+-----------------+
+----------------------+-------------------------+-----------------------------------+
| RAllocator | RAllocIterator | IAllocator_DArena |
| | | IAllocIterator_DArenaIterator |
+----------------------+-------------------------+-----------------------------------+
| IAllocator_Xfer | IAllocIterator_Xfer | DArena cBLU |
| IAllocator_Any | IAllocIterator_Any +-----------------------------------+
| IAllocator_Impltype | IAllocIterator_Impltype | DArenaIterator |
| | | |
+----------------------+-------------------------+-----------------------------------+
| AAllocator | AAllocIterator | ArenaConfig |
+----------------------+-------------------------+-----------------------------------+
+-----------------+----------------------------------------------+-------------------+
| | AllocInfo | |
| +----------------------------------------------+ |
| AllocError | AllocHeaderConfig | cmpresult |
| +----------------------------------------------+ |
| | AllocHeader | |
+-----------------+----------------------------------------------+-------------------+
.. code-block:: cpp
@ -29,11 +36,13 @@ Context
Arena memory layout
~~~~~~~~~~~~~~~~~~~
.. code-block:: text
<----------------------------size-------------------------->
<------------------------reserved-------------------------->
<------------committed-----------><-------uncommitted------>
<--allocated-->
<--allocated--><----available---->
XXXXXXXXXXXXXXX___________________..........................
^ ^ ^ ^
@ -44,7 +53,9 @@ Arena memory layout
[.] uncommitted: mapped in virtual memory, not backed by memory
Allocation layout
Representation for a single allocation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: text
free_(pre)
@ -60,8 +71,8 @@ Allocation layout
^ |
last_header_ free_(post)
[+] guard after each allocation, for simple sanitize checks
[0] unused header bits (avail to application)
[+] guard surrounding each allocation, for simple sanitize checks
[0] unused header bits (available for application metadata)
[z] record allocation size
[@] new allocated memory
[p] padding (to uintptr_t alignment)
@ -85,3 +96,8 @@ Constructors
------------
.. doxygengroup:: mm-arena-ctors
Methods
-------
.. doxygengroup:: mm-arena-methods

View file

@ -32,9 +32,81 @@ Size here is a hard maximum. It cannot be changed for this arena instance.
.. code-block:: cpp
arena.reserved(); // 64k
arena.reserved(); // 64k
arena.committed(); // 0k
arena.allocated(); // ok
arena.available(); // 0k
Although we know the address range for arena, it doesn't own any physical
memory yet.
memory yet. Two ways to commit memory:
1. Attempt allocation:
.. code-block:: cpp
std::byte * mem = arena.alloc(5*1024);
if (!mem)
throw std::runtime_error("alloc failed");
arena.reserved(); // 64k
arena.committed(); // 8k - 2 pages
arena.allocateed(); // 5k
arena.available(); // 3k
2. Expand committed memory explicitly:
.. code-block:: cpp
bool ok = arena.expand(5*1024);
assert(ok);
arena.reserved(); // 64k
arena.committed(); // 8k - 2 pages
arena.allocated(); // 0k
arena.available(); // 8k
Examining alloc metadata
------------------------
Given a successful allocation:
.. code-block:: cpp
std::size_t req_z = 5*1024;
std::byte * mem = arena.alloc(req_z);
if (!mem)
throw std::runtime_error("alloc failed");
AllocInfo info = arena.alloc_info(mem);
info.payload(); // [mem, mem + req_z (+ up to 7 bytes padding)]
info.is_valid(); // true
info.guard_lo(); // guard bytes preceding alloc
info.guard_hi(); // guard bytes following alloc
Recycling memory
----------------
.. code-block:: cpp
// arena in non-empty state
arena.reserved(); // 64k
arena.committed(); // 8k - 2 pages
arena.allocateed(); // 5k
arena.available(); // 3k
arena.clear();
arena.reserved() // 64k
arena.committed(); // 8k - 2 pages
arena.allocated(); // 0k
arena.available(); // 8k
Memory released by @ref Darena::clear is still committed.
It's in use as far as operating system is concerned.
To release memory to the operating system, destroy arena:
.. code-block:: cpp
arena.~DArena(); // or just let arena go out of scope

View file

@ -1,7 +1,7 @@
.. _implementation:
Components
==========
Implementation
==============
Library dependency tower for *xo-alloc2*
@ -15,36 +15,147 @@ Library dependency tower for *xo-alloc2*
| xo_cmake |
+-----------------+
Abstraction tower for *xo-alloc2* components
Abstraction tower for *xo-alloc2* components (simplified)
.. ditaa::
:--scale: 0.99
+--------------------------------+
| IAllocator_DArena |
+--------------------------------+
| IAllocator_Xfer |
| IAllocator_Any |
+--------------+-----------------+
| | DArena |
| AAllocator +-----------------+
| | ArenaConfig |
+--------------+-----------------+
+----------------+-----------------+-------------------+
| | | DArena |
| Allocator | AllocIterator | DArenaIterator |
| | +-------------------+
| | | ArenaConfig |
+----------------+-----------------+-------------------+
| auxiliary types |
+------------------------------------------------------+
.. list-table:: Descriptions
Abstraction tower for *xo-alloc2* components (detailed)
.. ditaa::
:--scale: 0.99
+----------------------+-------------------------+-----------------------------------+
| RAllocator | RAllocIterator | IAllocator_DArena |
| | | IAllocIterator_DArenaIterator |
+----------------------+-------------------------+-----------------------------------+
| IAllocator_Xfer | IAllocIterator_Xfer | DArena |
| IAllocator_Any | IAllocIterator_Any | DArenaIterator |
| IAllocator_Impltype | IAllocIterator_Impltype | |
| | | |
+----------------------+-------------------------+-----------------------------------+
| AAllocator | AAllocIterator | ArenaConfig |
+----------------------+-------------------------+-----------------------------------+
+-----------------+----------------------------------------------+-------------------+
| | AllocInfo | |
| +----------------------------------------------+ |
| AllocError | AllocHeaderConfig | cmpresult |
| +----------------------------------------------+ |
| | AllocHeader | |
+-----------------+----------------------------------------------+-------------------+
.. list-table:: Polymorphic Allocator
:header-rows: 1
:widths: 20 90
* - Component
* - Class
- Description
* - ``AAllocator``
- allocator facet (abstract interface)
* - ``DArena``
- arena representation
* - ``IAllocator_ImplType<D>``
- lookup implementation for allocator A
with representation D.
- Abstract allocator interface for runtime polymorphism
* - ``IAllocator_Any``
- Stub allocator interface for uninitialized variant
* - ``IAllocator_Xfer<D>``
- transfer interface. downcast to native state.
* - ``IAllocator_DArena``
- allocator implementation for ``DArena``
- Allocator interface template for representation ``D``
* - ``IAllocator_Impltype<D>``
- Lookup allocator interface for representation ``D``
* - ``RAllocator<O>``
- Provide allocator methods for FOMO object ``O``
.. list-table:: Polymorphich Alloc Iterator
:header-rows: 1
:widths: 20 90
* - Class
- Description
* - ``AAllocIterator``
- Abstract interface for iteration over allocs
* - ``IAllocIterator_Any``
- Stub alloc-iterator interface for uninitialized variant
* - ``IAllocIterator_Xfer<D>``
- Alloc-iterator interface template for representation ``D``
* - ``IAllocIterator_Impltype<D>``
- Lookup alloc-iterator interface for representation ``D``
* - ``RAllocIterator<D>``
- Provide alloc-iterator methods for FOMO object ``O``.
.. list-table:: Native Arena Allocator
:header-rows: 1
:widths: 20 90
* - Class
- Description
* - ``ArenaConfig``
- Configuration for a ``DArena`` instance
* - ``DArena``
- VM-aware arena allocator
* - ``DArenaIterator``
- Iterator over ``DArena`` allocations
* - ``IAlllocator_DArena``
- Adapt a ``DArena`` to facet ``AAllocator``
* - ``IAllocIterator_DArenaAllocator``
- Adapt a ``DArenaIterator`` to facet ``AAllocIterator``
.. list-table:: Auxiliary/Support Types
:header-rows: 1
:widths: 20 90
* - Class
- Description
* - ``AllocError``
- Return type for an alloc request, with error details.
* - ``AllocInfo``
- An opaque allocation. Value of an alloc-iterator.
* - ``AllocHeaderConfig``
- Per-allocator configuration of alloc headers
* - ``AllocHeader``
- Per-allocation header (8 bytes)
* - ``cmpresult``
- Result of alloc-iterator comparison
Example Object Diagram
.. uml::
:caption: representation for an arena allocator
:scale: 99%
:align: center
object rarena1<<RAllocator>>
rarena1 : iface = vtable1
rarena1 : data = darena1
object vtable1<<IAllocator_DArena_vtable>>
vtable1 : alloc()
object darena1<<DArena>>
darena1 : config
darena1 : lo
darena1 : hi
darena1 : free
darena1 : limit
darena1 : last_error
rarena1 o-- vtable1
rarena1 o-- darena1
Remarks:
* When we know the allocator representation at compile time (``DArena`` here),
then we also know the interface (``IAllocator_DArena``).
Devirtualization is easy since interface methods are all final.
* Size of a FOMO object is two pointers; it's natural to create such objects
on the fly and pass them by value.
When storing an allocator in another data structure, we only need to use
the RAllocator stack if we want runtime polymorphism for the stored allocator.
Otherwise can store a ``DArena`` instance.

View file

@ -26,6 +26,7 @@ Implemented using FOMO (faceted rust-like object model) from xo-facet
AAllocator-reference
ArenaConfig-reference
DArena-reference
AllocInfo-reference
glossary
genindex
search