diff -r 000000000000 -r c455ebb9a5dc jitcraft/PoolAllocator.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jitcraft/PoolAllocator.cpp Mon Jun 25 02:57:28 2012 -0700 @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2012 David Anderson + * + * This file is part of JITCraft. + * + * JITCraft is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * JITCraft. If not, see http://www.gnu.org/licenses/. + */ +#include +#include +#include +#include "PoolAllocator.h" + +using namespace jc; + +PoolAllocator::PoolAllocator() + : reserved_(NULL), + last_(NULL) +{ +} + +PoolAllocator::~PoolAllocator() +{ + unwind(NULL); + if (reserved_) + free(reserved_); +} + +char * +PoolAllocator::enter() +{ + if (!last_) + return NULL; + return last_->ptr; +} + +void +PoolAllocator::leave(char *pos) +{ + unwind(pos); +} + +void +PoolAllocator::unwind(char *pos) +{ + while (last_) { + if (pos && pos >= last_->base && pos < last_->end) + break; + Pool *prev = last_->prev; + { + if (last_->size() <= kMaxReserveSize && + (!reserved_ || reserved_->size() < last_->size())) + { + if (reserved_) + free(reserved_); + reserved_ = last_; + } else { + free(last_); + } + } + last_ = prev; + } + + if (!last_) { + assert(!pos); + return; + } + + last_->ptr = pos; +} + +void * +PoolAllocator::slowAllocate(size_t actualBytes) +{ + size_t bytesNeeded = actualBytes + sizeof(Pool); + if (bytesNeeded < kDefaultPoolSize) + bytesNeeded = kDefaultPoolSize; + + Pool *pool; + if (reserved_ && reserved_->size() >= bytesNeeded) { + pool = reserved_; + reserved_ = NULL; + } else { + pool = (Pool *)malloc(bytesNeeded); + if (!pool) + throw std::bad_alloc(); + pool->base = (char *)(pool + 1); + pool->end = (char *)pool + bytesNeeded; + } + pool->ptr = pool->base + actualBytes; + pool->prev = last_; + last_ = pool; + return pool->base; +}