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

MemoryPoolAllocator, Stack: lazily allocate Allocators
This commit is contained in:
Milo Yip 2014-10-31 09:34:27 +08:00
commit d6c1c57159
2 changed files with 13 additions and 14 deletions

View File

@ -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;

View File

@ -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_;