patterncppMinor
Pool allocator for a scripting language parser
Viewed 0 times
scriptingparserlanguageforpoolallocator
Problem
At the moment I'm writing a parser and interpreter for a custom scripting language, to learn more about the basic concepts involved and to get more familiar with tools like
The parsing process requires the allocation of a lot of small data structures to store intermediate language symbols and syntax tree nodes. The allocation pattern consists, in general, of a lot of sequential allocations with very few deallocations, and then everything gets freed at the end of the parsing, when the source code is done processing.
This seems like the perfect case for a pool allocator that can be drained with a single call at the end, to free all memory in one action. A reference on pool allocators.
My current implementation follows. I have tried to keep things as simple as possible. The pool maintains a linked list of small arrays. Objects reside inside these small arrays, so new allocations won't require copying data over to a new portion. There is still some fragmentation, but it is much lower if compared with raw
Any comments are appreciated.
``
// before deallocating the b
bison and flex.The parsing process requires the allocation of a lot of small data structures to store intermediate language symbols and syntax tree nodes. The allocation pattern consists, in general, of a lot of sequential allocations with very few deallocations, and then everything gets freed at the end of the parsing, when the source code is done processing.
This seems like the perfect case for a pool allocator that can be drained with a single call at the end, to free all memory in one action. A reference on pool allocators.
My current implementation follows. I have tried to keep things as simple as possible. The pool maintains a linked list of small arrays. Objects reside inside these small arrays, so new allocations won't require copying data over to a new portion. There is still some fragmentation, but it is much lower if compared with raw
new. Fragmentation can be further mitigated by choosing the best Granularity size for the small arrays to match the use case.Any comments are appreciated.
``
#ifndef OBJECT_POOL_HPP
#define OBJECT_POOL_HPP
#include
#include
#include
#include
#include
#include
// ========================================================
// class ObjectPool:
// ========================================================
//
// Pool of fixed-size memory blocks (similar to a list of arrays).
//
// This pool allocator operates as a linked list of small arrays.
// Each array is a pool of blocks with the size of 'T' template parameter.
// Template parameter Granularity defines the size in objects of type 'T'
// of such arrays.
//
// allocate() will return an uninitialized memory block.
// The user is responsible for calling construct() on it to run class
// constructors if necessary, and destroy()` to call class destructor// before deallocating the b
Solution
You may want to change
by
If the PoolBlock is aligned for PoolObj/T you will not have the 4/8 bytes of 'next' disturbing the harmony. At the back there will be no such issue.
Besides, it's easier to fit if your next step is using (lazily) mapped memory from the page pool to store a PoolBlock.
If you target high performance and the statistics are not really needed, you may want to get rid of them (i.e.: in a release build) as their relative cost is not negligible.
struct PoolBlock
{
PoolBlock * next;
PoolObj objects[Granularity];
};by
struct PoolBlock
{
PoolObj objects[Granularity];
PoolBlock * next;
};If the PoolBlock is aligned for PoolObj/T you will not have the 4/8 bytes of 'next' disturbing the harmony. At the back there will be no such issue.
Besides, it's easier to fit if your next step is using (lazily) mapped memory from the page pool to store a PoolBlock.
If you target high performance and the statistics are not really needed, you may want to get rid of them (i.e.: in a release build) as their relative cost is not negligible.
Code Snippets
struct PoolBlock
{
PoolBlock * next;
PoolObj objects[Granularity];
};struct PoolBlock
{
PoolObj objects[Granularity];
PoolBlock * next;
};Context
StackExchange Code Review Q#93772, answer score: 2
Revisions (0)
No revisions yet.