diff --git a/include/utils/LinearAllocator.h b/include/utils/LinearAllocator.h deleted file mode 100644 index 4772bc8f7..000000000 --- a/include/utils/LinearAllocator.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2012, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ANDROID_LINEARALLOCATOR_H -#define ANDROID_LINEARALLOCATOR_H - -#include - -namespace android { - -/** - * A memory manager that internally allocates multi-kbyte buffers for placing objects in. It avoids - * the overhead of malloc when many objects are allocated. It is most useful when creating many - * small objects with a similar lifetime, and doesn't add significant overhead for large - * allocations. - */ -class LinearAllocator { -public: - LinearAllocator(); - ~LinearAllocator(); - - /** - * Reserves and returns a region of memory of at least size 'size', aligning as needed. - * Typically this is used in an object's overridden new() method or as a replacement for malloc. - * - * The lifetime of the returned buffers is tied to that of the LinearAllocator. If calling - * delete() on an object stored in a buffer is needed, it should be overridden to use - * rewindIfLastAlloc() - */ - void* alloc(size_t size); - - /** - * Attempt to deallocate the given buffer, with the LinearAllocator attempting to rewind its - * state if possible. No destructors are called. - */ - void rewindIfLastAlloc(void* ptr, size_t allocSize); - - /** - * Dump memory usage statistics to the log (allocated and wasted space) - */ - void dumpMemoryStats(const char* prefix = ""); - - /** - * The number of bytes used for buffers allocated in the LinearAllocator (does not count space - * wasted) - */ - size_t usedSize() const { return mTotalAllocated - mWastedSpace; } - -private: - LinearAllocator(const LinearAllocator& other); - - class Page; - - Page* newPage(size_t pageSize); - bool fitsInCurrentPage(size_t size); - void ensureNext(size_t size); - void* start(Page *p); - void* end(Page* p); - - size_t mPageSize; - size_t mMaxAllocSize; - void* mNext; - Page* mCurrentPage; - Page* mPages; - - // Memory usage tracking - size_t mTotalAllocated; - size_t mWastedSpace; - size_t mPageCount; - size_t mDedicatedPageCount; -}; - -}; // namespace android - -#endif // ANDROID_LINEARALLOCATOR_H diff --git a/libutils/Android.mk b/libutils/Android.mk index e9c5f8996..f675a94e8 100644 --- a/libutils/Android.mk +++ b/libutils/Android.mk @@ -20,7 +20,6 @@ commonSources:= \ CallStack.cpp \ FileMap.cpp \ JenkinsHash.cpp \ - LinearAllocator.cpp \ LinearTransform.cpp \ Log.cpp \ NativeHandle.cpp \ diff --git a/libutils/LinearAllocator.cpp b/libutils/LinearAllocator.cpp deleted file mode 100644 index 8b90696ff..000000000 --- a/libutils/LinearAllocator.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright 2012, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define LOG_TAG "LinearAllocator" -#define LOG_NDEBUG 1 - -#include -#include -#include - - -// The ideal size of a page allocation (these need to be multiples of 8) -#define INITIAL_PAGE_SIZE ((size_t)4096) // 4kb -#define MAX_PAGE_SIZE ((size_t)131072) // 128kb - -// The maximum amount of wasted space we can have per page -// Allocations exceeding this will have their own dedicated page -// If this is too low, we will malloc too much -// Too high, and we may waste too much space -// Must be smaller than INITIAL_PAGE_SIZE -#define MAX_WASTE_SIZE ((size_t)1024) - -#if ALIGN_DOUBLE -#define ALIGN_SZ (sizeof(double)) -#else -#define ALIGN_SZ (sizeof(int)) -#endif - -#define ALIGN(x) ((x + ALIGN_SZ - 1 ) & ~(ALIGN_SZ - 1)) -#define ALIGN_PTR(p) ((void*)(ALIGN((size_t)p))) - -#if LOG_NDEBUG -#define ADD_ALLOCATION(size) -#define RM_ALLOCATION(size) -#else -#include -#include -static size_t s_totalAllocations = 0; -static nsecs_t s_nextLog = 0; -static android::Mutex s_mutex; - -static void _logUsageLocked() { - nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); - if (now > s_nextLog) { - s_nextLog = now + milliseconds_to_nanoseconds(10); - ALOGV("Total memory usage: %zu kb", s_totalAllocations / 1024); - } -} - -static void _addAllocation(size_t size) { - android::AutoMutex lock(s_mutex); - s_totalAllocations += size; - _logUsageLocked(); -} - -#define ADD_ALLOCATION(size) _addAllocation(size); -#define RM_ALLOCATION(size) _addAllocation(-size); -#endif - -#define min(x,y) (((x) < (y)) ? (x) : (y)) - -namespace android { - -class LinearAllocator::Page { -public: - Page* next() { return mNextPage; } - void setNext(Page* next) { mNextPage = next; } - - Page() - : mNextPage(0) - {} - - void* operator new(size_t /*size*/, void* buf) { return buf; } - - void* start() { - return (void*) (((size_t)this) + sizeof(Page)); - } - - void* end(int pageSize) { - return (void*) (((size_t)start()) + pageSize); - } - -private: - Page(const Page& /*other*/) {} - Page* mNextPage; -}; - -LinearAllocator::LinearAllocator() - : mPageSize(INITIAL_PAGE_SIZE) - , mMaxAllocSize(MAX_WASTE_SIZE) - , mNext(0) - , mCurrentPage(0) - , mPages(0) - , mTotalAllocated(0) - , mWastedSpace(0) - , mPageCount(0) - , mDedicatedPageCount(0) {} - -LinearAllocator::~LinearAllocator(void) { - Page* p = mPages; - while (p) { - Page* next = p->next(); - p->~Page(); - free(p); - RM_ALLOCATION(mPageSize); - p = next; - } -} - -void* LinearAllocator::start(Page* p) { - return ALIGN_PTR(((size_t*)p) + sizeof(Page)); -} - -void* LinearAllocator::end(Page* p) { - return ((char*)p) + mPageSize; -} - -bool LinearAllocator::fitsInCurrentPage(size_t size) { - return mNext && ((char*)mNext + size) <= end(mCurrentPage); -} - -void LinearAllocator::ensureNext(size_t size) { - if (fitsInCurrentPage(size)) return; - - if (mCurrentPage && mPageSize < MAX_PAGE_SIZE) { - mPageSize = min(MAX_PAGE_SIZE, mPageSize * 2); - mPageSize = ALIGN(mPageSize); - } - mWastedSpace += mPageSize; - Page* p = newPage(mPageSize); - if (mCurrentPage) { - mCurrentPage->setNext(p); - } - mCurrentPage = p; - if (!mPages) { - mPages = mCurrentPage; - } - mNext = start(mCurrentPage); -} - -void* LinearAllocator::alloc(size_t size) { - size = ALIGN(size); - if (size > mMaxAllocSize && !fitsInCurrentPage(size)) { - ALOGV("Exceeded max size %zu > %zu", size, mMaxAllocSize); - // Allocation is too large, create a dedicated page for the allocation - Page* page = newPage(size); - mDedicatedPageCount++; - page->setNext(mPages); - mPages = page; - if (!mCurrentPage) - mCurrentPage = mPages; - return start(page); - } - ensureNext(size); - void* ptr = mNext; - mNext = ((char*)mNext) + size; - mWastedSpace -= size; - return ptr; -} - -void LinearAllocator::rewindIfLastAlloc(void* ptr, size_t allocSize) { - // Don't bother rewinding across pages - allocSize = ALIGN(allocSize); - if (ptr >= start(mCurrentPage) && ptr < end(mCurrentPage) - && ptr == ((char*)mNext - allocSize)) { - mTotalAllocated -= allocSize; - mWastedSpace += allocSize; - mNext = ptr; - } -} - -LinearAllocator::Page* LinearAllocator::newPage(size_t pageSize) { - pageSize = ALIGN(pageSize + sizeof(LinearAllocator::Page)); - ADD_ALLOCATION(pageSize); - mTotalAllocated += pageSize; - mPageCount++; - void* buf = malloc(pageSize); - return new (buf) Page(); -} - -static const char* toSize(size_t value, float& result) { - if (value < 2000) { - result = value; - return "B"; - } - if (value < 2000000) { - result = value / 1024.0f; - return "KB"; - } - result = value / 1048576.0f; - return "MB"; -} - -void LinearAllocator::dumpMemoryStats(const char* prefix) { - float prettySize; - const char* prettySuffix; - prettySuffix = toSize(mTotalAllocated, prettySize); - ALOGD("%sTotal allocated: %.2f%s", prefix, prettySize, prettySuffix); - prettySuffix = toSize(mWastedSpace, prettySize); - ALOGD("%sWasted space: %.2f%s (%.1f%%)", prefix, prettySize, prettySuffix, - (float) mWastedSpace / (float) mTotalAllocated * 100.0f); - ALOGD("%sPages %zu (dedicated %zu)", prefix, mPageCount, mDedicatedPageCount); -} - -}; // namespace android