diff options
author | Herb Derby <herb@google.com> | 2017-04-27 15:22:02 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-04-27 19:47:21 +0000 |
commit | 4b32ab1b7cac09f42b0867f6c63cd8656dd9918d (patch) | |
tree | 29b4aeaba4053726c99908ea183fce50d1f5d323 | |
parent | 308e62416e9c8191932c6bde1711f336bafda373 (diff) | |
download | platform_external_skqp-4b32ab1b7cac09f42b0867f6c63cd8656dd9918d.tar.gz platform_external_skqp-4b32ab1b7cac09f42b0867f6c63cd8656dd9918d.tar.bz2 platform_external_skqp-4b32ab1b7cac09f42b0867f6c63cd8656dd9918d.zip |
Add instrumentation into SkArenaAlloc.
Add a parameter to the constructor that will have the dtor print out
stats for setting the initial parameters.
Clean up: Move some function so they are in the same order as .h
Change-Id: I19d87dcc9c3b8dcc3e1d4f2ff078b78bbc490d92
Reviewed-on: https://skia-review.googlesource.com/14600
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Herb Derby <herb@google.com>
-rw-r--r-- | src/core/SkArenaAlloc.cpp | 79 | ||||
-rw-r--r-- | src/core/SkArenaAlloc.h | 24 |
2 files changed, 68 insertions, 35 deletions
diff --git a/src/core/SkArenaAlloc.cpp b/src/core/SkArenaAlloc.cpp index eca3aa97d7..bfe3ff4a65 100644 --- a/src/core/SkArenaAlloc.cpp +++ b/src/core/SkArenaAlloc.cpp @@ -11,35 +11,7 @@ static char* end_chain(char*) { return nullptr; } -char* SkArenaAlloc::SkipPod(char* footerEnd) { - char* objEnd = footerEnd - (sizeof(Footer) + sizeof(int32_t)); - int32_t skip; - memmove(&skip, objEnd, sizeof(int32_t)); - return objEnd - skip; -} - -void SkArenaAlloc::RunDtorsOnBlock(char* footerEnd) { - while (footerEnd != nullptr) { - Footer footer; - memcpy(&footer, footerEnd - sizeof(Footer), sizeof(Footer)); - - FooterAction* action = (FooterAction*)(footer >> 6); - ptrdiff_t padding = footer & 63; - - footerEnd = action(footerEnd) - padding; - } -} - -char* SkArenaAlloc::NextBlock(char* footerEnd) { - char* objEnd = footerEnd - (sizeof(Footer) + sizeof(char*)); - char* next; - memmove(&next, objEnd, sizeof(char*)); - RunDtorsOnBlock(next); - delete [] objEnd; - return nullptr; -} - -SkArenaAlloc::SkArenaAlloc(char* block, size_t size, size_t extraSize) +SkArenaAlloc::SkArenaAlloc(char* block, size_t size, size_t extraSize, Tracking tracking) : fDtorCursor {block} , fCursor {block} , fEnd {block + SkTo<uint32_t>(size)} @@ -51,18 +23,32 @@ SkArenaAlloc::SkArenaAlloc(char* block, size_t size, size_t extraSize) fEnd = fCursor = fDtorCursor = nullptr; } + if (tracking == kTrack) { + fTotalSlop = 0; + } + if (fCursor != nullptr) { this->installFooter(end_chain, 0); + if (fTotalSlop >= 0) { + fTotalAlloc += fFirstSize; + } } } SkArenaAlloc::~SkArenaAlloc() { + if (fTotalSlop >= 0) { + int32_t lastSlop = fEnd - fCursor; + fTotalSlop += lastSlop; + SkDebugf("SkArenaAlloc initial: %p %u %u total alloc: %u total slop: %d last slop: %d\n", + fFirstBlock, fFirstSize, fExtraSize, fTotalAlloc, fTotalSlop, lastSlop); + } RunDtorsOnBlock(fDtorCursor); } void SkArenaAlloc::reset() { this->~SkArenaAlloc(); - new (this) SkArenaAlloc{fFirstBlock, fFirstSize, fExtraSize}; + new (this) SkArenaAlloc{fFirstBlock, fFirstSize, fExtraSize, + fTotalSlop < 0 ? kDontTrack : kTrack}; } void SkArenaAlloc::installFooter(FooterAction* action, uint32_t padding) { @@ -83,6 +69,34 @@ void SkArenaAlloc::installPtrFooter(FooterAction* action, char* ptr, uint32_t pa this->installFooter(action, padding); } +char* SkArenaAlloc::SkipPod(char* footerEnd) { + char* objEnd = footerEnd - (sizeof(Footer) + sizeof(int32_t)); + int32_t skip; + memmove(&skip, objEnd, sizeof(int32_t)); + return objEnd - skip; +} + +void SkArenaAlloc::RunDtorsOnBlock(char* footerEnd) { + while (footerEnd != nullptr) { + Footer footer; + memcpy(&footer, footerEnd - sizeof(Footer), sizeof(Footer)); + + FooterAction* action = (FooterAction*)(footer >> 6); + ptrdiff_t padding = footer & 63; + + footerEnd = action(footerEnd) - padding; + } +} + +char* SkArenaAlloc::NextBlock(char* footerEnd) { + char* objEnd = footerEnd - (sizeof(Footer) + sizeof(char*)); + char* next; + memmove(&next, objEnd, sizeof(char*)); + RunDtorsOnBlock(next); + delete [] objEnd; + return nullptr; +} + void SkArenaAlloc::installUint32Footer(FooterAction* action, uint32_t value, uint32_t padding) { memmove(fCursor, &value, sizeof(uint32_t)); fCursor += sizeof(uint32_t); @@ -113,6 +127,11 @@ void SkArenaAlloc::ensureSpace(uint32_t size, uint32_t alignment) { char* newBlock = new char[allocationSize]; + if (fTotalSlop >= 0) { + fTotalAlloc += allocationSize; + fTotalSlop += fEnd - fCursor; + } + auto previousDtor = fDtorCursor; fCursor = newBlock; fDtorCursor = newBlock; diff --git a/src/core/SkArenaAlloc.h b/src/core/SkArenaAlloc.h index 488adfc681..e838579062 100644 --- a/src/core/SkArenaAlloc.h +++ b/src/core/SkArenaAlloc.h @@ -53,21 +53,30 @@ // For arrays of non-POD objects there is a per array overhead of typically 8 bytes. There is an // addition overhead when switching from POD data to non-POD data of typically 8 bytes. // +// You can track memory use by adding SkArenaAlloc::kTrack as the last parameter to any constructor. +// +// char storage[someNumber]; +// SkArenaAlloc alloc{storage, SkArenaAlloc::kTrack}; +// +// This will print out a line for every destructor or reset call that has the total memory +// allocated, the total slop (the unused portion of a block), and the slop of the last block. +// // If additional blocks are needed they are increased exponentially. This strategy bounds the // recursion of the RunDtorsOnBlock to be limited to O(log size-of-memory). Block size grow using // the Fibonacci sequence which means that for 2^32 memory there are 48 allocations, and for 2^48 // there are 71 allocations. class SkArenaAlloc { public: - SkArenaAlloc(char* block, size_t size, size_t extraSize); + enum Tracking {kDontTrack, kTrack}; + SkArenaAlloc(char* block, size_t size, size_t, Tracking tracking = kDontTrack); template <size_t kSize> - SkArenaAlloc(char (&block)[kSize], size_t extraSize = kSize) - : SkArenaAlloc(block, kSize, extraSize) + SkArenaAlloc(char (&block)[kSize], size_t extraSize = kSize, Tracking tracking = kDontTrack) + : SkArenaAlloc(block, kSize, extraSize, tracking) {} - SkArenaAlloc(size_t extraSize) - : SkArenaAlloc(nullptr, 0, extraSize) + SkArenaAlloc(size_t extraSize, Tracking tracking = kDontTrack) + : SkArenaAlloc(nullptr, 0, extraSize, tracking) {} ~SkArenaAlloc(); @@ -197,6 +206,11 @@ private: char* const fFirstBlock; const uint32_t fFirstSize; const uint32_t fExtraSize; + + // Track some useful stats. Track stats if fTotalSlop is >= 0; + uint32_t fTotalAlloc { 0}; + int32_t fTotalSlop {-1}; + // Use the Fibonacci sequence as the growth factor for block size. The size of the block // allocated is fFib0 * fExtraSize. Using 2 ^ n * fExtraSize had too much slop for Android. uint32_t fFib0 {1}, fFib1 {1}; |