aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerb Derby <herb@google.com>2017-04-27 15:22:02 -0400
committerSkia Commit-Bot <skia-commit-bot@chromium.org>2017-04-27 19:47:21 +0000
commit4b32ab1b7cac09f42b0867f6c63cd8656dd9918d (patch)
tree29b4aeaba4053726c99908ea183fce50d1f5d323
parent308e62416e9c8191932c6bde1711f336bafda373 (diff)
downloadplatform_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.cpp79
-rw-r--r--src/core/SkArenaAlloc.h24
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};