LinearAllocator.cpp revision b5bc454870c8b7df88a633b18c4c6499361c3a08
11ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck/* 21ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * Copyright 2012, The Android Open Source Project 31ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * 41ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * Redistribution and use in source and binary forms, with or without 51ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * modification, are permitted provided that the following conditions 61ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * are met: 71ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * * Redistributions of source code must retain the above copyright 81ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * notice, this list of conditions and the following disclaimer. 91ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * * Redistributions in binary form must reproduce the above copyright 101ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * notice, this list of conditions and the following disclaimer in the 111ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * documentation and/or other materials provided with the distribution. 121ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * 131ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 141ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 151ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 161ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 171ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 181ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 191ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 201ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 211ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 221ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 231ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 241ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck */ 251ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 261ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#define LOG_NDEBUG 1 271ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 281ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#include "utils/LinearAllocator.h" 291ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 301ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#include <stdlib.h> 311ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#include <utils/Log.h> 321ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 331ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 341ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck// The ideal size of a page allocation (these need to be multiples of 8) 351ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#define INITIAL_PAGE_SIZE ((size_t)4096) // 4kb 361ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#define MAX_PAGE_SIZE ((size_t)131072) // 128kb 371ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 381ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck// The maximum amount of wasted space we can have per page 391ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck// Allocations exceeding this will have their own dedicated page 401ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck// If this is too low, we will malloc too much 411ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck// Too high, and we may waste too much space 421ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck// Must be smaller than INITIAL_PAGE_SIZE 431ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#define MAX_WASTE_SIZE ((size_t)1024) 441ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 451ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#if ALIGN_DOUBLE 461ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#define ALIGN_SZ (sizeof(double)) 471ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#else 481ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#define ALIGN_SZ (sizeof(int)) 491ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#endif 501ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 511ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#define ALIGN(x) ((x + ALIGN_SZ - 1 ) & ~(ALIGN_SZ - 1)) 521ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#define ALIGN_PTR(p) ((void*)(ALIGN((size_t)p))) 531ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 541ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#if LOG_NDEBUG 551ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#define ADD_ALLOCATION(size) 561ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#define RM_ALLOCATION(size) 571ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#else 581ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#include <utils/Thread.h> 591ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#include <utils/Timers.h> 601ed723723d9e42a064d54799cc24bdc24891e44dJohn Reckstatic size_t s_totalAllocations = 0; 611ed723723d9e42a064d54799cc24bdc24891e44dJohn Reckstatic nsecs_t s_nextLog = 0; 621ed723723d9e42a064d54799cc24bdc24891e44dJohn Reckstatic android::Mutex s_mutex; 631ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 641ed723723d9e42a064d54799cc24bdc24891e44dJohn Reckstatic void _logUsageLocked() { 651ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 661ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck if (now > s_nextLog) { 671ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck s_nextLog = now + milliseconds_to_nanoseconds(10); 681ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck ALOGV("Total memory usage: %zu kb", s_totalAllocations / 1024); 691ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck } 701ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck} 711ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 721ed723723d9e42a064d54799cc24bdc24891e44dJohn Reckstatic void _addAllocation(size_t size) { 731ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck android::AutoMutex lock(s_mutex); 741ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck s_totalAllocations += size; 751ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck _logUsageLocked(); 761ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck} 771ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 781ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#define ADD_ALLOCATION(size) _addAllocation(size); 791ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#define RM_ALLOCATION(size) _addAllocation(-size); 801ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#endif 811ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 821ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck#define min(x,y) (((x) < (y)) ? (x) : (y)) 831ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 84b5bc454870c8b7df88a633b18c4c6499361c3a08John Reckvoid* operator new(std::size_t size, android::uirenderer::LinearAllocator& la) { 85b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck return la.alloc(size); 86b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck} 87b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck 881ed723723d9e42a064d54799cc24bdc24891e44dJohn Recknamespace android { 891ed723723d9e42a064d54799cc24bdc24891e44dJohn Recknamespace uirenderer { 901ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 911ed723723d9e42a064d54799cc24bdc24891e44dJohn Reckclass LinearAllocator::Page { 921ed723723d9e42a064d54799cc24bdc24891e44dJohn Reckpublic: 931ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck Page* next() { return mNextPage; } 941ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck void setNext(Page* next) { mNextPage = next; } 951ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 961ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck Page() 971ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck : mNextPage(0) 981ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck {} 991ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 1001ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck void* operator new(size_t /*size*/, void* buf) { return buf; } 1011ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 1021ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck void* start() { 1031ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck return (void*) (((size_t)this) + sizeof(Page)); 1041ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck } 1051ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 1061ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck void* end(int pageSize) { 1071ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck return (void*) (((size_t)start()) + pageSize); 1081ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck } 1091ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 1101ed723723d9e42a064d54799cc24bdc24891e44dJohn Reckprivate: 1111ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck Page(const Page& /*other*/) {} 1121ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck Page* mNextPage; 1131ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck}; 1141ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 1151ed723723d9e42a064d54799cc24bdc24891e44dJohn ReckLinearAllocator::LinearAllocator() 1161ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck : mPageSize(INITIAL_PAGE_SIZE) 1171ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck , mMaxAllocSize(MAX_WASTE_SIZE) 1181ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck , mNext(0) 1191ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck , mCurrentPage(0) 1201ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck , mPages(0) 1211ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck , mTotalAllocated(0) 1221ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck , mWastedSpace(0) 1231ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck , mPageCount(0) 1241ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck , mDedicatedPageCount(0) {} 1251ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 1261ed723723d9e42a064d54799cc24bdc24891e44dJohn ReckLinearAllocator::~LinearAllocator(void) { 127b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck while (mDtorList) { 128b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck auto node = mDtorList; 129b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck mDtorList = node->next; 130b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck node->dtor(node->addr); 131b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck } 1321ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck Page* p = mPages; 1331ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck while (p) { 1341ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck Page* next = p->next(); 1351ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck p->~Page(); 1361ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck free(p); 1371ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck RM_ALLOCATION(mPageSize); 1381ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck p = next; 1391ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck } 1401ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck} 1411ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 1421ed723723d9e42a064d54799cc24bdc24891e44dJohn Reckvoid* LinearAllocator::start(Page* p) { 1431ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck return ALIGN_PTR(((size_t*)p) + sizeof(Page)); 1441ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck} 1451ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 1461ed723723d9e42a064d54799cc24bdc24891e44dJohn Reckvoid* LinearAllocator::end(Page* p) { 1471ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck return ((char*)p) + mPageSize; 1481ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck} 1491ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 1501ed723723d9e42a064d54799cc24bdc24891e44dJohn Reckbool LinearAllocator::fitsInCurrentPage(size_t size) { 1511ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck return mNext && ((char*)mNext + size) <= end(mCurrentPage); 1521ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck} 1531ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 1541ed723723d9e42a064d54799cc24bdc24891e44dJohn Reckvoid LinearAllocator::ensureNext(size_t size) { 1551ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck if (fitsInCurrentPage(size)) return; 1561ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 1571ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck if (mCurrentPage && mPageSize < MAX_PAGE_SIZE) { 1581ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck mPageSize = min(MAX_PAGE_SIZE, mPageSize * 2); 1591ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck mPageSize = ALIGN(mPageSize); 1601ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck } 1611ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck mWastedSpace += mPageSize; 1621ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck Page* p = newPage(mPageSize); 1631ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck if (mCurrentPage) { 1641ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck mCurrentPage->setNext(p); 1651ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck } 1661ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck mCurrentPage = p; 1671ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck if (!mPages) { 1681ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck mPages = mCurrentPage; 1691ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck } 1701ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck mNext = start(mCurrentPage); 1711ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck} 1721ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 1731ed723723d9e42a064d54799cc24bdc24891e44dJohn Reckvoid* LinearAllocator::alloc(size_t size) { 1741ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck size = ALIGN(size); 1751ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck if (size > mMaxAllocSize && !fitsInCurrentPage(size)) { 1761ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck ALOGV("Exceeded max size %zu > %zu", size, mMaxAllocSize); 1771ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck // Allocation is too large, create a dedicated page for the allocation 1781ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck Page* page = newPage(size); 1791ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck mDedicatedPageCount++; 1801ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck page->setNext(mPages); 1811ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck mPages = page; 1821ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck if (!mCurrentPage) 1831ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck mCurrentPage = mPages; 1841ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck return start(page); 1851ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck } 1861ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck ensureNext(size); 1871ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck void* ptr = mNext; 1881ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck mNext = ((char*)mNext) + size; 1891ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck mWastedSpace -= size; 1901ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck return ptr; 1911ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck} 1921ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 193b5bc454870c8b7df88a633b18c4c6499361c3a08John Reckvoid LinearAllocator::addToDestructionList(Destructor dtor, void* addr) { 194b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck static_assert(std::is_standard_layout<DestructorNode>::value, 195b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck "DestructorNode must have standard layout"); 196b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck static_assert(std::is_trivially_destructible<DestructorNode>::value, 197b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck "DestructorNode must be trivially destructable"); 198b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck auto node = new (*this) DestructorNode(); 199b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck node->dtor = dtor; 200b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck node->addr = addr; 201b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck node->next = mDtorList; 202b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck mDtorList = node; 203b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck} 204b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck 205b5bc454870c8b7df88a633b18c4c6499361c3a08John Reckvoid LinearAllocator::runDestructorFor(void* addr) { 206b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck auto node = mDtorList; 207b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck DestructorNode* previous = nullptr; 208b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck while (node) { 209b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck if (node->addr == addr) { 210b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck if (previous) { 211b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck previous->next = node->next; 212b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck } else { 213b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck mDtorList = node->next; 214b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck } 215b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck node->dtor(node->addr); 216b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck rewindIfLastAlloc(node, sizeof(DestructorNode)); 217b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck break; 218b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck } 219b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck previous = node; 220b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck node = node->next; 221b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck } 222b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck} 223b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck 2241ed723723d9e42a064d54799cc24bdc24891e44dJohn Reckvoid LinearAllocator::rewindIfLastAlloc(void* ptr, size_t allocSize) { 225b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck // First run the destructor as running the destructor will 226b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck // also rewind for the DestructorNode allocation which will 227b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck // have been allocated after this void* if it has a destructor 228b5bc454870c8b7df88a633b18c4c6499361c3a08John Reck runDestructorFor(ptr); 2291ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck // Don't bother rewinding across pages 2301ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck allocSize = ALIGN(allocSize); 2311ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck if (ptr >= start(mCurrentPage) && ptr < end(mCurrentPage) 2321ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck && ptr == ((char*)mNext - allocSize)) { 2331ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck mWastedSpace += allocSize; 2341ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck mNext = ptr; 2351ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck } 2361ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck} 2371ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 2381ed723723d9e42a064d54799cc24bdc24891e44dJohn ReckLinearAllocator::Page* LinearAllocator::newPage(size_t pageSize) { 2391ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck pageSize = ALIGN(pageSize + sizeof(LinearAllocator::Page)); 2401ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck ADD_ALLOCATION(pageSize); 2411ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck mTotalAllocated += pageSize; 2421ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck mPageCount++; 2431ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck void* buf = malloc(pageSize); 2441ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck return new (buf) Page(); 2451ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck} 2461ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 2471ed723723d9e42a064d54799cc24bdc24891e44dJohn Reckstatic const char* toSize(size_t value, float& result) { 2481ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck if (value < 2000) { 2491ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck result = value; 2501ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck return "B"; 2511ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck } 2521ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck if (value < 2000000) { 2531ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck result = value / 1024.0f; 2541ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck return "KB"; 2551ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck } 2561ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck result = value / 1048576.0f; 2571ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck return "MB"; 2581ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck} 2591ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 2601ed723723d9e42a064d54799cc24bdc24891e44dJohn Reckvoid LinearAllocator::dumpMemoryStats(const char* prefix) { 2611ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck float prettySize; 2621ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck const char* prettySuffix; 2631ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck prettySuffix = toSize(mTotalAllocated, prettySize); 2641ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck ALOGD("%sTotal allocated: %.2f%s", prefix, prettySize, prettySuffix); 2651ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck prettySuffix = toSize(mWastedSpace, prettySize); 2661ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck ALOGD("%sWasted space: %.2f%s (%.1f%%)", prefix, prettySize, prettySuffix, 2671ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck (float) mWastedSpace / (float) mTotalAllocated * 100.0f); 2681ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck ALOGD("%sPages %zu (dedicated %zu)", prefix, mPageCount, mDedicatedPageCount); 2691ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck} 2701ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck 2711ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck}; // namespace uirenderer 2721ed723723d9e42a064d54799cc24bdc24891e44dJohn Reck}; // namespace android 273