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