From 412a86d014783be99a7a9a0fae407791b95806e8 Mon Sep 17 00:00:00 2001 From: Herb Derby Date: Wed, 18 Jan 2017 17:07:48 -0500 Subject: Fix reset and deleting behavior. * Reset the Arena state. * Call all the dtors before deleting the blocks. TBR=mtklein@google.com Change-Id: Iac320fec16e572cc9a6184c1f580089ab720f036 Reviewed-on: https://skia-review.googlesource.com/7221 Reviewed-by: Herb Derby Commit-Queue: Herb Derby --- src/core/SkArenaAlloc.cpp | 46 ++++++++++++++++++++++++++-------------------- src/core/SkArenaAlloc.h | 18 ++++++++++++------ 2 files changed, 38 insertions(+), 26 deletions(-) (limited to 'src/core') diff --git a/src/core/SkArenaAlloc.cpp b/src/core/SkArenaAlloc.cpp index d6c249b573..03ab9fad4f 100644 --- a/src/core/SkArenaAlloc.cpp +++ b/src/core/SkArenaAlloc.cpp @@ -12,15 +12,21 @@ struct Skipper { char* operator()(char* objEnd, ptrdiff_t size) { return objEnd + size; } }; -struct NextBlock { - char* operator()(char* objEnd, ptrdiff_t size) { delete [] objEnd; return objEnd + size; } +struct SkArenaAlloc::NextBlock { + char* operator()(char* objEnd, ptrdiff_t size) { + ResetBlock(objEnd + size); + delete [] objEnd; + return nullptr; + } }; SkArenaAlloc::SkArenaAlloc(char* block, size_t size, size_t extraSize) - : fDtorCursor{block} - , fCursor {block} - , fEnd {block + size} - , fExtraSize {extraSize} + : fDtorCursor {block} + , fCursor {block} + , fEnd {block + size} + , fFirstBlock {block} + , fFirstSize {size} + , fExtraSize {extraSize} { if (size < sizeof(Footer)) { fEnd = fCursor = fDtorCursor = nullptr; @@ -32,16 +38,12 @@ SkArenaAlloc::SkArenaAlloc(char* block, size_t size, size_t extraSize) } SkArenaAlloc::~SkArenaAlloc() { - this->reset(); + ResetBlock(fDtorCursor); } void SkArenaAlloc::reset() { - Footer f; - memmove(&f, fDtorCursor - sizeof(Footer), sizeof(Footer)); - char* releaser = fDtorCursor; - while (releaser != nullptr) { - releaser = this->callFooterAction(releaser); - } + this->~SkArenaAlloc(); + new (this) SkArenaAlloc{fFirstBlock, fFirstSize, fExtraSize}; } void SkArenaAlloc::installFooter(FooterAction* releaser, ptrdiff_t padding) { @@ -54,8 +56,6 @@ void SkArenaAlloc::installFooter(FooterAction* releaser, ptrdiff_t padding) { Footer footer = (Footer)(footerData); memmove(fCursor, &footer, sizeof(Footer)); - Footer check; - memmove(&check, fCursor, sizeof(Footer)); fCursor += sizeof(Footer); fDtorCursor = fCursor; } @@ -104,7 +104,7 @@ char* SkArenaAlloc::allocObject(size_t size, size_t alignment) { char* SkArenaAlloc::allocObjectWithFooter(size_t sizeIncludingFooter, size_t alignment) { size_t mask = alignment - 1; - restart: +restart: size_t skipOverhead = 0; bool needsSkipFooter = fCursor != fDtorCursor; if (needsSkipFooter) { @@ -132,14 +132,20 @@ char* SkArenaAlloc::allocObjectWithFooter(size_t sizeIncludingFooter, size_t ali return objStart; } -char* SkArenaAlloc::callFooterAction(char* end) { +void SkArenaAlloc::ResetBlock(char* footerEnd) { + while (footerEnd != nullptr) { + footerEnd = CallFooterAction(footerEnd); + } +} + +char* SkArenaAlloc::CallFooterAction(char* footerEnd) { Footer footer; - memcpy(&footer, end - sizeof(Footer), sizeof(Footer)); + memcpy(&footer, footerEnd - sizeof(Footer), sizeof(Footer)); - FooterAction* releaser = (FooterAction*)((char*)EndChain + (footer >> 5)); + FooterAction* action = (FooterAction*)((char*)EndChain + (footer >> 5)); ptrdiff_t padding = footer & 31; - char* r = releaser(end) - padding; + char* r = action(footerEnd) - padding; return r; } diff --git a/src/core/SkArenaAlloc.h b/src/core/SkArenaAlloc.h index 8152c94cbd..56006c30b2 100644 --- a/src/core/SkArenaAlloc.h +++ b/src/core/SkArenaAlloc.h @@ -56,7 +56,7 @@ public: SkArenaAlloc(char* block, size_t size, size_t extraSize = 0); template - SkArenaAlloc(char (&block)[kSize], size_t extraSize = 0) + SkArenaAlloc(char (&block)[kSize], size_t extraSize = kSize) : SkArenaAlloc(block, kSize, extraSize) {} @@ -116,6 +116,8 @@ private: using Footer = int32_t; using FooterAction = char* (char*); + struct NextBlock; + void installFooter(FooterAction* releaser, ptrdiff_t padding); // N.B. Action is different than FooterAction. FooterAction expects the end of the Footer, @@ -179,7 +181,9 @@ private: return objStart; } - char* callFooterAction(char* end); + static char* CallFooterAction(char* end); + + static void ResetBlock(char* footerEnd); static char* EndChain(char*); @@ -195,10 +199,12 @@ private: } }; - char* fDtorCursor; - char* fCursor; - char* fEnd; - size_t fExtraSize; + char* fDtorCursor; + char* fCursor; + char* fEnd; + char* const fFirstBlock; + const size_t fFirstSize; + const size_t fExtraSize; }; #endif//SkFixedAlloc_DEFINED -- cgit v1.2.3