src/PoolAllocator.h
author David Anderson <dvander@alliedmods.net>
Sat Dec 22 18:22:14 2012 -0800 (2012-12-22)
changeset 230 fb3cd08bc7fb
parent 195 c1ba166f3fc4
child 263 ba85a47ee414
permissions -rw-r--r--
Re-add LIFO stack optimizations.
     1 /*
     2  * Copyright (C) 2012 David Anderson
     3  *
     4  * This file is part of JITCraft.
     5  *
     6  * JITCraft is free software: you can redistribute it and/or modify it under
     7  * the terms of the GNU General Public License as published by the Free
     8  * Software Foundation, either version 3 of the License, or (at your option)
     9  * any later version.
    10  * 
    11  * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    14  *
    15  * You should have received a copy of the GNU General Public License along with
    16  * JITCraft. If not, see http://www.gnu.org/licenses/.
    17  */
    18 #ifndef _include_jitcraft_pool_allocator_h_
    19 #define _include_jitcraft_pool_allocator_h_
    20 
    21 #include <new>
    22 #include <stddef.h>
    23 #include <limits.h>
    24 #include "Utility.h"
    25 #include "Vector.h"
    26 
    27 namespace ke {
    28 
    29 // Allocates memory in chunks that are not freed until the entire allocator
    30 // is freed. This is intended for use with large, temporary data structures.
    31 class PoolAllocator
    32 {
    33     friend class PoolAllocationScope;
    34 
    35     struct Pool {
    36         char *base;
    37         char *ptr;
    38         char *end;
    39         Pool *prev;
    40 
    41         size_t size() const {
    42             return size_t(end - base);
    43         }
    44     };
    45 
    46     static const size_t kDefaultPoolSize = 8 * 1024;
    47     static const size_t kMaxReserveSize = 64 * 1024;
    48 
    49   private:
    50     Pool *reserved_;
    51     Pool *last_;
    52 
    53   private:
    54     void unwind(char *pos);
    55     void *slowAllocate(size_t actualBytes);
    56 
    57   public:
    58     PoolAllocator();
    59     ~PoolAllocator();
    60 
    61     void *rawAllocate(size_t bytes) {
    62         // Guarantee malloc alignment.
    63         size_t actualBytes = Align(bytes, kMallocAlignment);
    64         if (!last_ || (size_t(last_->end - last_->ptr) < actualBytes))
    65             return slowAllocate(actualBytes);
    66         char *ptr = last_->ptr;
    67         last_->ptr += actualBytes;
    68         return ptr;
    69     }
    70 
    71     template <typename T>
    72     T *alloc(size_t count = 1) {
    73         void *ptr = rawAllocate(count * sizeof(T));
    74         if (!ptr)
    75             return NULL;
    76 
    77         return reinterpret_cast<T *>(ptr);
    78     }
    79 
    80     char *enter();
    81     void leave(char *position);
    82 };
    83 
    84 class PoolScope
    85 {
    86     PoolAllocator &pool_;
    87     char *position_;
    88 
    89   public:
    90     PoolScope(PoolAllocator &allocator)
    91       : pool_(allocator),
    92         position_(allocator.enter())
    93     {
    94     }
    95     ~PoolScope()
    96     {
    97         pool_.leave(position_);
    98     }
    99 };
   100 
   101 class PoolObject
   102 {
   103   public:
   104     void *operator new(size_t size, PoolAllocator &pool) {
   105         return pool.rawAllocate(size);
   106     }
   107     void *operator new [](size_t size, PoolAllocator &pool) {
   108         return pool.rawAllocate(size);
   109     }
   110     
   111     // Using delete on pool-allocated objects is illegal.
   112     void operator delete(void *ptr, PoolAllocator &pool) {
   113         assert(false);
   114     }
   115     void operator delete [](void *ptr, PoolAllocator &pool) {
   116         assert(false);
   117     }
   118 };
   119 
   120 class PoolAllocationPolicy
   121 {
   122   protected:
   123     void reportAllocationOverflow();
   124     void reportOutOfMemory();
   125 
   126   public:
   127     void *malloc(size_t bytes);
   128     void free(void *ptr);
   129 };
   130 
   131 template <typename T>
   132 class PoolList
   133   : public Vector<T, PoolAllocationPolicy>,
   134     public PoolObject
   135 {
   136   public:
   137     PoolList()
   138       : Vector<T, PoolAllocationPolicy>(PoolAllocationPolicy())
   139     {
   140     }
   141 };
   142 
   143 }
   144 
   145 #endif // _include_jitcraft_pool_allocator_h_