src/PoolAllocator.cpp
author Asher Baker <asherkin@gmail.com>
Mon Jun 10 01:04:43 2013 +0100 (2013-06-10)
changeset 263 ba85a47ee414
parent 195 c1ba166f3fc4
permissions -rw-r--r--
Normalise line endings.
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
#include <assert.h>
asherkin@263
    19
#include <stdlib.h>
asherkin@263
    20
#include <new>
asherkin@263
    21
#include "PoolAllocator.h"
asherkin@263
    22
#include "Zone.h"
asherkin@263
    23
#include "Spaces-inl.h"
asherkin@263
    24
#include "Heap-inl.h"
asherkin@263
    25
asherkin@263
    26
using namespace ke;
asherkin@263
    27
asherkin@263
    28
PoolAllocator::PoolAllocator()
asherkin@263
    29
  : reserved_(NULL),
asherkin@263
    30
    last_(NULL)
asherkin@263
    31
{
asherkin@263
    32
}
asherkin@263
    33
asherkin@263
    34
PoolAllocator::~PoolAllocator()
asherkin@263
    35
{
asherkin@263
    36
    unwind(NULL);
asherkin@263
    37
    if (reserved_)
asherkin@263
    38
        free(reserved_);
asherkin@263
    39
}
asherkin@263
    40
asherkin@263
    41
char *
asherkin@263
    42
PoolAllocator::enter()
asherkin@263
    43
{
asherkin@263
    44
    if (!last_)
asherkin@263
    45
        return NULL;
asherkin@263
    46
    return last_->ptr;
asherkin@263
    47
}
asherkin@263
    48
asherkin@263
    49
void
asherkin@263
    50
PoolAllocator::leave(char *pos)
asherkin@263
    51
{
asherkin@263
    52
    unwind(pos);
asherkin@263
    53
}
asherkin@263
    54
asherkin@263
    55
void
asherkin@263
    56
PoolAllocator::unwind(char *pos)
asherkin@263
    57
{
asherkin@263
    58
    while (last_) {
asherkin@263
    59
        if (pos && pos >= last_->base && pos < last_->end)
asherkin@263
    60
            break;
asherkin@263
    61
        Pool *prev = last_->prev;
asherkin@263
    62
        {
asherkin@263
    63
            if (last_->size() <= kMaxReserveSize &&
asherkin@263
    64
                (!reserved_ || reserved_->size() < last_->size()))
asherkin@263
    65
            {
asherkin@263
    66
                if (reserved_)
asherkin@263
    67
                    free(reserved_);
asherkin@263
    68
                reserved_ = last_;
asherkin@263
    69
            } else {
asherkin@263
    70
                free(last_);
asherkin@263
    71
            }
asherkin@263
    72
        }
asherkin@263
    73
        last_ = prev;
asherkin@263
    74
    }
asherkin@263
    75
asherkin@263
    76
    if (!last_) {
asherkin@263
    77
        assert(!pos);
asherkin@263
    78
        return;
asherkin@263
    79
    }
asherkin@263
    80
asherkin@263
    81
    last_->ptr = pos;
asherkin@263
    82
}
asherkin@263
    83
asherkin@263
    84
void *
asherkin@263
    85
PoolAllocator::slowAllocate(size_t actualBytes)
asherkin@263
    86
{
asherkin@263
    87
    size_t bytesNeeded = actualBytes + sizeof(Pool);
asherkin@263
    88
    if (bytesNeeded < kDefaultPoolSize)
asherkin@263
    89
        bytesNeeded = kDefaultPoolSize;
asherkin@263
    90
asherkin@263
    91
    Pool *pool;
asherkin@263
    92
    if (reserved_ && reserved_->size() >= bytesNeeded) {
asherkin@263
    93
        pool = reserved_;
asherkin@263
    94
        reserved_ = NULL;
asherkin@263
    95
    } else {
asherkin@263
    96
        pool = (Pool *)malloc(bytesNeeded);
asherkin@263
    97
        if (!pool) {
asherkin@263
    98
            ZONE()->reportOutOfMemory();
asherkin@263
    99
            return NULL;
asherkin@263
   100
        }
asherkin@263
   101
        pool->base = (char *)(pool + 1);
asherkin@263
   102
        pool->end = (char *)pool + bytesNeeded;
asherkin@263
   103
    }
asherkin@263
   104
    pool->ptr = pool->base + actualBytes;
asherkin@263
   105
    pool->prev = last_;
asherkin@263
   106
    last_ = pool;
asherkin@263
   107
    return pool->base;
asherkin@263
   108
}
asherkin@263
   109
asherkin@263
   110
void
asherkin@263
   111
PoolAllocationPolicy::reportOutOfMemory()
asherkin@263
   112
{
asherkin@263
   113
    ZONE()->reportOutOfMemory();
asherkin@263
   114
}
asherkin@263
   115
asherkin@263
   116
void
asherkin@263
   117
PoolAllocationPolicy::reportAllocationOverflow()
asherkin@263
   118
{
asherkin@263
   119
    ZONE()->reportError(Message_AllocationOverflow);
asherkin@263
   120
}
asherkin@263
   121
asherkin@263
   122
void *
asherkin@263
   123
PoolAllocationPolicy::malloc(size_t bytes)
asherkin@263
   124
{
asherkin@263
   125
    return ZONE()->pool().rawAllocate(bytes);
asherkin@263
   126
}
asherkin@263
   127
asherkin@263
   128
void
asherkin@263
   129
PoolAllocationPolicy::free(void *ptr)
asherkin@263
   130
{
asherkin@263
   131
}