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