diff options
author | John Reck <jreck@google.com> | 2015-04-23 15:51:55 -0700 |
---|---|---|
committer | John Reck <jreck@google.com> | 2015-04-23 16:04:50 -0700 |
commit | b5bc454870c8b7df88a633b18c4c6499361c3a08 (patch) | |
tree | 47dabcf133dec831d33966f0cf53dce5e0a40ffc /libs/hwui/utils/LinearAllocator.cpp | |
parent | 1ed723723d9e42a064d54799cc24bdc24891e44d (diff) | |
download | frameworks_base-b5bc454870c8b7df88a633b18c4c6499361c3a08.zip frameworks_base-b5bc454870c8b7df88a633b18c4c6499361c3a08.tar.gz frameworks_base-b5bc454870c8b7df88a633b18c4c6499361c3a08.tar.bz2 |
Teach LA how to destroy
Change-Id: I57ab30b6d56370dade6987f442136ea5e5546c9b
Diffstat (limited to 'libs/hwui/utils/LinearAllocator.cpp')
-rw-r--r-- | libs/hwui/utils/LinearAllocator.cpp | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/libs/hwui/utils/LinearAllocator.cpp b/libs/hwui/utils/LinearAllocator.cpp index 31e439f..59b12cf 100644 --- a/libs/hwui/utils/LinearAllocator.cpp +++ b/libs/hwui/utils/LinearAllocator.cpp @@ -81,6 +81,10 @@ static void _addAllocation(size_t size) { #define min(x,y) (((x) < (y)) ? (x) : (y)) +void* operator new(std::size_t size, android::uirenderer::LinearAllocator& la) { + return la.alloc(size); +} + namespace android { namespace uirenderer { @@ -120,6 +124,11 @@ LinearAllocator::LinearAllocator() , mDedicatedPageCount(0) {} LinearAllocator::~LinearAllocator(void) { + while (mDtorList) { + auto node = mDtorList; + mDtorList = node->next; + node->dtor(node->addr); + } Page* p = mPages; while (p) { Page* next = p->next(); @@ -181,12 +190,46 @@ void* LinearAllocator::alloc(size_t size) { return ptr; } +void LinearAllocator::addToDestructionList(Destructor dtor, void* addr) { + static_assert(std::is_standard_layout<DestructorNode>::value, + "DestructorNode must have standard layout"); + static_assert(std::is_trivially_destructible<DestructorNode>::value, + "DestructorNode must be trivially destructable"); + auto node = new (*this) DestructorNode(); + node->dtor = dtor; + node->addr = addr; + node->next = mDtorList; + mDtorList = node; +} + +void LinearAllocator::runDestructorFor(void* addr) { + auto node = mDtorList; + DestructorNode* previous = nullptr; + while (node) { + if (node->addr == addr) { + if (previous) { + previous->next = node->next; + } else { + mDtorList = node->next; + } + node->dtor(node->addr); + rewindIfLastAlloc(node, sizeof(DestructorNode)); + break; + } + previous = node; + node = node->next; + } +} + void LinearAllocator::rewindIfLastAlloc(void* ptr, size_t allocSize) { + // First run the destructor as running the destructor will + // also rewind for the DestructorNode allocation which will + // have been allocated after this void* if it has a destructor + runDestructorFor(ptr); // 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; } |