1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/PoolAllocator.h Tue Jul 24 23:53:34 2012 -0700
1.3 @@ -0,0 +1,136 @@
1.4 +/*
1.5 + * Copyright (C) 2012 David Anderson
1.6 + *
1.7 + * This file is part of JITCraft.
1.8 + *
1.9 + * JITCraft is free software: you can redistribute it and/or modify it under
1.10 + * the terms of the GNU General Public License as published by the Free
1.11 + * Software Foundation, either version 3 of the License, or (at your option)
1.12 + * any later version.
1.13 + *
1.14 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
1.15 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
1.17 + *
1.18 + * You should have received a copy of the GNU General Public License along with
1.19 + * JITCraft. If not, see http://www.gnu.org/licenses/.
1.20 + */
1.21 +#ifndef _include_jitcraft_pool_allocator_h_
1.22 +#define _include_jitcraft_pool_allocator_h_
1.23 +
1.24 +#include <new>
1.25 +#include <stddef.h>
1.26 +#include <limits.h>
1.27 +#include "Utility.h"
1.28 +#include "Vector.h"
1.29 +
1.30 +namespace ke {
1.31 +
1.32 +// Allocates memory in chunks that are not freed until the entire allocator
1.33 +// is freed. This is intended for use with large, temporary data structures.
1.34 +class PoolAllocator
1.35 +{
1.36 + friend class PoolAllocationScope;
1.37 +
1.38 + struct Pool {
1.39 + char *base;
1.40 + char *ptr;
1.41 + char *end;
1.42 + Pool *prev;
1.43 +
1.44 + size_t size() const {
1.45 + return size_t(end - base);
1.46 + }
1.47 + };
1.48 +
1.49 + static const size_t kDefaultPoolSize = 8 * 1024;
1.50 + static const size_t kMaxReserveSize = 64 * 1024;
1.51 +
1.52 + private:
1.53 + Pool *reserved_;
1.54 + Pool *last_;
1.55 +
1.56 + private:
1.57 + void unwind(char *pos);
1.58 + void *slowAllocate(size_t actualBytes);
1.59 +
1.60 + public:
1.61 + PoolAllocator();
1.62 + ~PoolAllocator();
1.63 +
1.64 + void *allocate(size_t bytes) {
1.65 + // Guarantee malloc alignment.
1.66 + size_t actualBytes = Align(bytes, kMallocAlignment);
1.67 + if (!last_ || (size_t(last_->end - last_->ptr) < actualBytes))
1.68 + return slowAllocate(actualBytes);
1.69 + char *ptr = last_->ptr;
1.70 + last_->ptr += actualBytes;
1.71 + return ptr;
1.72 + }
1.73 +
1.74 + char *enter();
1.75 + void leave(char *position);
1.76 +};
1.77 +
1.78 +class PoolScope
1.79 +{
1.80 + PoolAllocator &pool_;
1.81 + char *position_;
1.82 +
1.83 + public:
1.84 + PoolScope(PoolAllocator &allocator)
1.85 + : pool_(allocator),
1.86 + position_(allocator.enter())
1.87 + {
1.88 + }
1.89 + ~PoolScope()
1.90 + {
1.91 + pool_.leave(position_);
1.92 + }
1.93 +};
1.94 +
1.95 +class PoolObject
1.96 +{
1.97 + public:
1.98 + void *operator new(size_t size, PoolAllocator &pool) {
1.99 + return pool.allocate(size);
1.100 + }
1.101 + void *operator new [](size_t size, PoolAllocator &pool) {
1.102 + return pool.allocate(size);
1.103 + }
1.104 +
1.105 + // Using delete on pool-allocated objects is illegal.
1.106 + void operator delete(void *ptr, PoolAllocator &pool) {
1.107 + assert(false);
1.108 + }
1.109 + void operator delete [](void *ptr, PoolAllocator &pool) {
1.110 + assert(false);
1.111 + }
1.112 +};
1.113 +
1.114 +class PoolAllocationPolicy
1.115 +{
1.116 + protected:
1.117 + void reportAllocationOverflow();
1.118 + void reportOutOfMemory();
1.119 +
1.120 + public:
1.121 + void *malloc(size_t bytes);
1.122 + void free(void *ptr);
1.123 +};
1.124 +
1.125 +template <typename T>
1.126 +class PoolList
1.127 + : public Vector<T, PoolAllocationPolicy>,
1.128 + public PoolObject
1.129 +{
1.130 + public:
1.131 + PoolList()
1.132 + : Vector(PoolAllocationPolicy())
1.133 + {
1.134 + }
1.135 +};
1.136 +
1.137 +}
1.138 +
1.139 +#endif // _include_jitcraft_pool_allocator_h_