dvander@0: /* dvander@0: * Copyright (C) 2012 David Anderson dvander@0: * dvander@0: * This file is part of JITCraft. dvander@0: * dvander@0: * JITCraft is free software: you can redistribute it and/or modify it under dvander@0: * the terms of the GNU General Public License as published by the Free dvander@0: * Software Foundation, either version 3 of the License, or (at your option) dvander@0: * any later version. dvander@0: * dvander@0: * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY dvander@0: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS dvander@0: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. dvander@0: * dvander@0: * You should have received a copy of the GNU General Public License along with dvander@0: * JITCraft. If not, see http://www.gnu.org/licenses/. dvander@0: */ dvander@0: #include dvander@0: #include dvander@0: #include dvander@0: #include "PoolAllocator.h" dvander@55: #include "Zone.h" danderson@92: #include "Spaces-inl.h" danderson@92: #include "Heap-inl.h" dvander@0: dvander@59: using namespace ke; dvander@0: dvander@0: PoolAllocator::PoolAllocator() dvander@0: : reserved_(NULL), dvander@0: last_(NULL) dvander@0: { dvander@0: } dvander@0: dvander@0: PoolAllocator::~PoolAllocator() dvander@0: { dvander@0: unwind(NULL); dvander@0: if (reserved_) dvander@0: free(reserved_); dvander@0: } dvander@0: dvander@0: char * dvander@0: PoolAllocator::enter() dvander@0: { dvander@0: if (!last_) dvander@0: return NULL; dvander@0: return last_->ptr; dvander@0: } dvander@0: dvander@0: void dvander@0: PoolAllocator::leave(char *pos) dvander@0: { dvander@0: unwind(pos); dvander@0: } dvander@0: dvander@0: void dvander@0: PoolAllocator::unwind(char *pos) dvander@0: { dvander@0: while (last_) { dvander@0: if (pos && pos >= last_->base && pos < last_->end) dvander@0: break; dvander@0: Pool *prev = last_->prev; dvander@0: { dvander@0: if (last_->size() <= kMaxReserveSize && dvander@0: (!reserved_ || reserved_->size() < last_->size())) dvander@0: { dvander@0: if (reserved_) dvander@0: free(reserved_); dvander@0: reserved_ = last_; dvander@0: } else { dvander@0: free(last_); dvander@0: } dvander@0: } dvander@0: last_ = prev; dvander@0: } dvander@0: dvander@0: if (!last_) { dvander@0: assert(!pos); dvander@0: return; dvander@0: } dvander@0: dvander@0: last_->ptr = pos; dvander@0: } dvander@0: dvander@0: void * dvander@0: PoolAllocator::slowAllocate(size_t actualBytes) dvander@0: { dvander@0: size_t bytesNeeded = actualBytes + sizeof(Pool); dvander@0: if (bytesNeeded < kDefaultPoolSize) dvander@0: bytesNeeded = kDefaultPoolSize; dvander@0: dvander@0: Pool *pool; dvander@0: if (reserved_ && reserved_->size() >= bytesNeeded) { dvander@0: pool = reserved_; dvander@0: reserved_ = NULL; dvander@0: } else { dvander@0: pool = (Pool *)malloc(bytesNeeded); dvander@69: if (!pool) { dvander@69: ZONE()->reportOutOfMemory(); dvander@69: return NULL; dvander@69: } dvander@0: pool->base = (char *)(pool + 1); dvander@0: pool->end = (char *)pool + bytesNeeded; dvander@0: } dvander@0: pool->ptr = pool->base + actualBytes; dvander@0: pool->prev = last_; dvander@0: last_ = pool; dvander@0: return pool->base; dvander@0: } dvander@55: dvander@55: void dvander@55: PoolAllocationPolicy::reportOutOfMemory() dvander@55: { dvander@69: ZONE()->reportOutOfMemory(); dvander@55: } dvander@55: dvander@55: void dvander@55: PoolAllocationPolicy::reportAllocationOverflow() dvander@55: { dvander@69: ZONE()->reportError(Message_AllocationOverflow); dvander@55: } dvander@55: dvander@55: void * dvander@55: PoolAllocationPolicy::malloc(size_t bytes) dvander@55: { dvander@195: return ZONE()->pool().rawAllocate(bytes); dvander@55: } dvander@55: dvander@55: void dvander@55: PoolAllocationPolicy::free(void *ptr) dvander@55: { dvander@55: }