Merge pull request #188 from pah/feature/lazy-alloc-allocators
MemoryPoolAllocator, Stack: lazily allocate Allocators
This commit is contained in:
commit
d6c1c57159
@ -104,9 +104,6 @@ public:
|
|||||||
MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
|
MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
|
||||||
chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
|
chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
|
||||||
{
|
{
|
||||||
if (!baseAllocator_)
|
|
||||||
ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator());
|
|
||||||
AddChunk(chunk_capacity_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Constructor with user-supplied buffer.
|
//! Constructor with user-supplied buffer.
|
||||||
@ -216,6 +213,8 @@ private:
|
|||||||
/*! \param capacity Capacity of the chunk in bytes.
|
/*! \param capacity Capacity of the chunk in bytes.
|
||||||
*/
|
*/
|
||||||
void AddChunk(size_t capacity) {
|
void AddChunk(size_t capacity) {
|
||||||
|
if (!baseAllocator_)
|
||||||
|
ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator());
|
||||||
ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(sizeof(ChunkHeader) + capacity));
|
ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(sizeof(ChunkHeader) + capacity));
|
||||||
chunk->capacity = capacity;
|
chunk->capacity = capacity;
|
||||||
chunk->size = 0;
|
chunk->size = 0;
|
||||||
|
@ -35,23 +35,21 @@ class Stack {
|
|||||||
public:
|
public:
|
||||||
// Optimization note: Do not allocate memory for stack_ in constructor.
|
// Optimization note: Do not allocate memory for stack_ in constructor.
|
||||||
// Do it lazily when first Push() -> Expand() -> Resize().
|
// Do it lazily when first Push() -> Expand() -> Resize().
|
||||||
Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) {
|
Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) {
|
||||||
RAPIDJSON_ASSERT(stackCapacity > 0);
|
RAPIDJSON_ASSERT(stackCapacity > 0);
|
||||||
if (!allocator_)
|
|
||||||
ownAllocator = allocator_ = RAPIDJSON_NEW(Allocator());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
Stack(Stack&& rhs)
|
Stack(Stack&& rhs)
|
||||||
: allocator_(rhs.allocator_),
|
: allocator_(rhs.allocator_),
|
||||||
ownAllocator(rhs.ownAllocator),
|
ownAllocator_(rhs.ownAllocator_),
|
||||||
stack_(rhs.stack_),
|
stack_(rhs.stack_),
|
||||||
stackTop_(rhs.stackTop_),
|
stackTop_(rhs.stackTop_),
|
||||||
stackEnd_(rhs.stackEnd_),
|
stackEnd_(rhs.stackEnd_),
|
||||||
initialCapacity_(rhs.initialCapacity_)
|
initialCapacity_(rhs.initialCapacity_)
|
||||||
{
|
{
|
||||||
rhs.allocator_ = 0;
|
rhs.allocator_ = 0;
|
||||||
rhs.ownAllocator = 0;
|
rhs.ownAllocator_ = 0;
|
||||||
rhs.stack_ = 0;
|
rhs.stack_ = 0;
|
||||||
rhs.stackTop_ = 0;
|
rhs.stackTop_ = 0;
|
||||||
rhs.stackEnd_ = 0;
|
rhs.stackEnd_ = 0;
|
||||||
@ -70,14 +68,14 @@ public:
|
|||||||
Destroy();
|
Destroy();
|
||||||
|
|
||||||
allocator_ = rhs.allocator_;
|
allocator_ = rhs.allocator_;
|
||||||
ownAllocator = rhs.ownAllocator;
|
ownAllocator_ = rhs.ownAllocator_;
|
||||||
stack_ = rhs.stack_;
|
stack_ = rhs.stack_;
|
||||||
stackTop_ = rhs.stackTop_;
|
stackTop_ = rhs.stackTop_;
|
||||||
stackEnd_ = rhs.stackEnd_;
|
stackEnd_ = rhs.stackEnd_;
|
||||||
initialCapacity_ = rhs.initialCapacity_;
|
initialCapacity_ = rhs.initialCapacity_;
|
||||||
|
|
||||||
rhs.allocator_ = 0;
|
rhs.allocator_ = 0;
|
||||||
rhs.ownAllocator = 0;
|
rhs.ownAllocator_ = 0;
|
||||||
rhs.stack_ = 0;
|
rhs.stack_ = 0;
|
||||||
rhs.stackTop_ = 0;
|
rhs.stackTop_ = 0;
|
||||||
rhs.stackEnd_ = 0;
|
rhs.stackEnd_ = 0;
|
||||||
@ -140,9 +138,11 @@ private:
|
|||||||
void Expand(size_t count) {
|
void Expand(size_t count) {
|
||||||
// Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity.
|
// Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity.
|
||||||
size_t newCapacity;
|
size_t newCapacity;
|
||||||
if (stack_ == 0)
|
if (stack_ == 0) {
|
||||||
|
if (!allocator_)
|
||||||
|
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
|
||||||
newCapacity = initialCapacity_;
|
newCapacity = initialCapacity_;
|
||||||
else {
|
} else {
|
||||||
newCapacity = GetCapacity();
|
newCapacity = GetCapacity();
|
||||||
newCapacity += (newCapacity + 1) / 2;
|
newCapacity += (newCapacity + 1) / 2;
|
||||||
}
|
}
|
||||||
@ -162,7 +162,7 @@ private:
|
|||||||
|
|
||||||
void Destroy() {
|
void Destroy() {
|
||||||
Allocator::Free(stack_);
|
Allocator::Free(stack_);
|
||||||
RAPIDJSON_DELETE(ownAllocator); // Only delete if it is owned by the stack
|
RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prohibit copy constructor & assignment operator.
|
// Prohibit copy constructor & assignment operator.
|
||||||
@ -170,7 +170,7 @@ private:
|
|||||||
Stack& operator=(const Stack&);
|
Stack& operator=(const Stack&);
|
||||||
|
|
||||||
Allocator* allocator_;
|
Allocator* allocator_;
|
||||||
Allocator* ownAllocator;
|
Allocator* ownAllocator_;
|
||||||
char *stack_;
|
char *stack_;
|
||||||
char *stackTop_;
|
char *stackTop_;
|
||||||
char *stackEnd_;
|
char *stackEnd_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user