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