src/PoolAllocator.h
author David Anderson <dvander@alliedmods.net>
Sat Sep 15 13:32:01 2012 -0700 (2012-09-15)
changeset 183 05571208642f
parent 91 5f4402180204
child 195 c1ba166f3fc4
permissions -rw-r--r--
Fix bug in error reporting for array assignment dimension mismatches.
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@0
    61
    void *allocate(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@0
    71
    char *enter();
dvander@0
    72
    void leave(char *position);
dvander@0
    73
};
dvander@0
    74
dvander@0
    75
class PoolScope
dvander@0
    76
{
dvander@0
    77
    PoolAllocator &pool_;
dvander@0
    78
    char *position_;
dvander@0
    79
dvander@0
    80
  public:
dvander@0
    81
    PoolScope(PoolAllocator &allocator)
dvander@0
    82
      : pool_(allocator),
dvander@0
    83
        position_(allocator.enter())
dvander@0
    84
    {
dvander@0
    85
    }
dvander@0
    86
    ~PoolScope()
dvander@0
    87
    {
dvander@0
    88
        pool_.leave(position_);
dvander@0
    89
    }
dvander@0
    90
};
dvander@0
    91
dvander@0
    92
class PoolObject
dvander@0
    93
{
dvander@0
    94
  public:
dvander@0
    95
    void *operator new(size_t size, PoolAllocator &pool) {
dvander@0
    96
        return pool.allocate(size);
dvander@0
    97
    }
dvander@0
    98
    void *operator new [](size_t size, PoolAllocator &pool) {
dvander@0
    99
        return pool.allocate(size);
dvander@0
   100
    }
dvander@0
   101
    
dvander@0
   102
    // Using delete on pool-allocated objects is illegal.
dvander@0
   103
    void operator delete(void *ptr, PoolAllocator &pool) {
dvander@0
   104
        assert(false);
dvander@0
   105
    }
dvander@0
   106
    void operator delete [](void *ptr, PoolAllocator &pool) {
dvander@0
   107
        assert(false);
dvander@0
   108
    }
dvander@0
   109
};
dvander@0
   110
dvander@55
   111
class PoolAllocationPolicy
dvander@55
   112
{
dvander@55
   113
  protected:
dvander@55
   114
    void reportAllocationOverflow();
dvander@55
   115
    void reportOutOfMemory();
dvander@55
   116
dvander@55
   117
  public:
dvander@55
   118
    void *malloc(size_t bytes);
dvander@55
   119
    void free(void *ptr);
dvander@55
   120
};
dvander@55
   121
dvander@56
   122
template <typename T>
dvander@56
   123
class PoolList
dvander@56
   124
  : public Vector<T, PoolAllocationPolicy>,
dvander@56
   125
    public PoolObject
dvander@56
   126
{
dvander@56
   127
  public:
dvander@56
   128
    PoolList()
danderson@91
   129
      : Vector<T, PoolAllocationPolicy>(PoolAllocationPolicy())
dvander@56
   130
    {
dvander@56
   131
    }
dvander@56
   132
};
dvander@56
   133
dvander@0
   134
}
dvander@0
   135
dvander@0
   136
#endif // _include_jitcraft_pool_allocator_h_