asherkin@263: /* asherkin@263: * Copyright (C) 2012 David Anderson asherkin@263: * asherkin@263: * This file is part of JITCraft. asherkin@263: * asherkin@263: * JITCraft is free software: you can redistribute it and/or modify it under asherkin@263: * the terms of the GNU General Public License as published by the Free asherkin@263: * Software Foundation, either version 3 of the License, or (at your option) asherkin@263: * any later version. asherkin@263: * asherkin@263: * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY asherkin@263: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS asherkin@263: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. asherkin@263: * asherkin@263: * You should have received a copy of the GNU General Public License along with asherkin@263: * JITCraft. If not, see http://www.gnu.org/licenses/. asherkin@263: */ asherkin@263: #ifndef _include_jitcraft_pool_allocator_h_ asherkin@263: #define _include_jitcraft_pool_allocator_h_ asherkin@263: asherkin@263: #include asherkin@263: #include asherkin@263: #include asherkin@263: #include "Utility.h" asherkin@263: #include "Vector.h" asherkin@263: asherkin@263: namespace ke { asherkin@263: asherkin@263: // Allocates memory in chunks that are not freed until the entire allocator asherkin@263: // is freed. This is intended for use with large, temporary data structures. asherkin@263: class PoolAllocator asherkin@263: { asherkin@263: friend class PoolAllocationScope; asherkin@263: asherkin@263: struct Pool { asherkin@263: char *base; asherkin@263: char *ptr; asherkin@263: char *end; asherkin@263: Pool *prev; asherkin@263: asherkin@263: size_t size() const { asherkin@263: return size_t(end - base); asherkin@263: } asherkin@263: }; asherkin@263: asherkin@263: static const size_t kDefaultPoolSize = 8 * 1024; asherkin@263: static const size_t kMaxReserveSize = 64 * 1024; asherkin@263: asherkin@263: private: asherkin@263: Pool *reserved_; asherkin@263: Pool *last_; asherkin@263: asherkin@263: private: asherkin@263: void unwind(char *pos); asherkin@263: void *slowAllocate(size_t actualBytes); asherkin@263: asherkin@263: public: asherkin@263: PoolAllocator(); asherkin@263: ~PoolAllocator(); asherkin@263: asherkin@263: void *rawAllocate(size_t bytes) { asherkin@263: // Guarantee malloc alignment. asherkin@263: size_t actualBytes = Align(bytes, kMallocAlignment); asherkin@263: if (!last_ || (size_t(last_->end - last_->ptr) < actualBytes)) asherkin@263: return slowAllocate(actualBytes); asherkin@263: char *ptr = last_->ptr; asherkin@263: last_->ptr += actualBytes; asherkin@263: return ptr; asherkin@263: } asherkin@263: asherkin@263: template asherkin@263: T *alloc(size_t count = 1) { asherkin@263: void *ptr = rawAllocate(count * sizeof(T)); asherkin@263: if (!ptr) asherkin@263: return NULL; asherkin@263: asherkin@263: return reinterpret_cast(ptr); asherkin@263: } asherkin@263: asherkin@263: char *enter(); asherkin@263: void leave(char *position); asherkin@263: }; asherkin@263: asherkin@263: class PoolScope asherkin@263: { asherkin@263: PoolAllocator &pool_; asherkin@263: char *position_; asherkin@263: asherkin@263: public: asherkin@263: PoolScope(PoolAllocator &allocator) asherkin@263: : pool_(allocator), asherkin@263: position_(allocator.enter()) asherkin@263: { asherkin@263: } asherkin@263: ~PoolScope() asherkin@263: { asherkin@263: pool_.leave(position_); asherkin@263: } asherkin@263: }; asherkin@263: asherkin@263: class PoolObject asherkin@263: { asherkin@263: public: asherkin@263: void *operator new(size_t size, PoolAllocator &pool) { asherkin@263: return pool.rawAllocate(size); asherkin@263: } asherkin@263: void *operator new [](size_t size, PoolAllocator &pool) { asherkin@263: return pool.rawAllocate(size); asherkin@263: } asherkin@263: asherkin@263: // Using delete on pool-allocated objects is illegal. asherkin@263: void operator delete(void *ptr, PoolAllocator &pool) { asherkin@263: assert(false); asherkin@263: } asherkin@263: void operator delete [](void *ptr, PoolAllocator &pool) { asherkin@263: assert(false); asherkin@263: } asherkin@263: }; asherkin@263: asherkin@263: class PoolAllocationPolicy asherkin@263: { asherkin@263: protected: asherkin@263: void reportAllocationOverflow(); asherkin@263: void reportOutOfMemory(); asherkin@263: asherkin@263: public: asherkin@263: void *malloc(size_t bytes); asherkin@263: void free(void *ptr); asherkin@263: }; asherkin@263: asherkin@263: template asherkin@263: class PoolList asherkin@263: : public Vector, asherkin@263: public PoolObject asherkin@263: { asherkin@263: public: asherkin@263: PoolList() asherkin@263: : Vector(PoolAllocationPolicy()) asherkin@263: { asherkin@263: } asherkin@263: }; asherkin@263: asherkin@263: } asherkin@263: asherkin@263: #endif // _include_jitcraft_pool_allocator_h_