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