Commit d6c1c571 authored by Milo Yip's avatar Milo Yip

Merge pull request #188 from pah/feature/lazy-alloc-allocators

MemoryPoolAllocator, Stack: lazily allocate Allocators 
parents 96f979a0 e8f5d9f8
......@@ -104,9 +104,6 @@ public:
MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 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.
......@@ -216,6 +213,8 @@ private:
/*! \param capacity Capacity of the chunk in bytes.
*/
void AddChunk(size_t capacity) {
if (!baseAllocator_)
ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator());
ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(sizeof(ChunkHeader) + capacity));
chunk->capacity = capacity;
chunk->size = 0;
......
......@@ -35,23 +35,21 @@ class Stack {
public:
// Optimization note: Do not allocate memory for stack_ in constructor.
// 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);
if (!allocator_)
ownAllocator = allocator_ = RAPIDJSON_NEW(Allocator());
}
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
Stack(Stack&& rhs)
: allocator_(rhs.allocator_),
ownAllocator(rhs.ownAllocator),
ownAllocator_(rhs.ownAllocator_),
stack_(rhs.stack_),
stackTop_(rhs.stackTop_),
stackEnd_(rhs.stackEnd_),
initialCapacity_(rhs.initialCapacity_)
{
rhs.allocator_ = 0;
rhs.ownAllocator = 0;
rhs.ownAllocator_ = 0;
rhs.stack_ = 0;
rhs.stackTop_ = 0;
rhs.stackEnd_ = 0;
......@@ -70,14 +68,14 @@ public:
Destroy();
allocator_ = rhs.allocator_;
ownAllocator = rhs.ownAllocator;
ownAllocator_ = rhs.ownAllocator_;
stack_ = rhs.stack_;
stackTop_ = rhs.stackTop_;
stackEnd_ = rhs.stackEnd_;
initialCapacity_ = rhs.initialCapacity_;
rhs.allocator_ = 0;
rhs.ownAllocator = 0;
rhs.ownAllocator_ = 0;
rhs.stack_ = 0;
rhs.stackTop_ = 0;
rhs.stackEnd_ = 0;
......@@ -140,9 +138,11 @@ private:
void Expand(size_t count) {
// Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity.
size_t newCapacity;
if (stack_ == 0)
if (stack_ == 0) {
if (!allocator_)
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
newCapacity = initialCapacity_;
else {
} else {
newCapacity = GetCapacity();
newCapacity += (newCapacity + 1) / 2;
}
......@@ -162,7 +162,7 @@ private:
void Destroy() {
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.
......@@ -170,7 +170,7 @@ private:
Stack& operator=(const Stack&);
Allocator* allocator_;
Allocator* ownAllocator;
Allocator* ownAllocator_;
char *stack_;
char *stackTop_;
char *stackEnd_;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment