move SkArenaAlloc reset to its own class

SkArenaAlloc has three fields that are used only for reset. Make a
subclass called SkArenaAllocWithReset which has the three
fields, and has the reset functionality.

An example of a reset() that is used instead of using a better scope
is PathOpsAngleAfter in PathOpsAngleTest.cpp.

Change-Id: Ie1965d128dfb7df9e022f4d18460d3f75f33e1a6
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/307348
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
Herb Derby 2020-08-01 16:26:04 -04:00 committed by Skia Commit-Bot
parent 51f2c15276
commit 6e2c56fefc
13 changed files with 64 additions and 39 deletions

View File

@ -101,7 +101,7 @@ private:
sk_sp<GrDirectContext> fMockContext;
SkPoint fStaticVertexData[(kNumCubicsInChalkboard + 2) * 8];
GrDrawIndexedIndirectCommand fStaticDrawIndexedIndirectData[32];
SkSTArenaAlloc<1024 * 1024> fAllocator;
SkSTArenaAllocWithReset<1024 * 1024> fAllocator;
};
// This serves as a base class for benchmarking individual methods on GrPathTessellateOp.

View File

@ -175,7 +175,7 @@ void SkShaper_CoreText::shape(const char* utf8, size_t utf8Bytes,
SkUniqueCFRef<CTTypesetterRef> typesetter(
CTTypesetterCreateWithAttributedString(attrString.get()));
SkSTArenaAlloc<4096> arena;
SkSTArenaAllocWithReset<4096> arena;
// We have to compute RunInfos in a loop, and then reuse them in a 2nd loop,
// so we store them in an array (we reuse the array's storage for each line).

View File

@ -17,13 +17,10 @@ static uint32_t first_allocated_block(uint32_t blockSize, uint32_t firstHeapAllo
}
SkArenaAlloc::SkArenaAlloc(char* block, size_t size, size_t firstHeapAllocation)
: fDtorCursor{block}
, fCursor{block}
, fEnd{block + ToU32(size)}
, fFirstBlock{block}
, fFirstSize{ToU32(size)}
, fFirstHeapAllocationSize{first_allocated_block(ToU32(size), ToU32(firstHeapAllocation))}
, fNextHeapAlloc{fFirstHeapAllocationSize}
: fDtorCursor {block}
, fCursor {block}
, fEnd {block + ToU32(size)}
, fNextHeapAlloc{first_allocated_block(ToU32(size), ToU32(firstHeapAllocation))}
, fYetNextHeapAlloc{fNextHeapAlloc}
{
if (size < sizeof(Footer)) {
@ -39,11 +36,6 @@ SkArenaAlloc::~SkArenaAlloc() {
RunDtorsOnBlock(fDtorCursor);
}
void SkArenaAlloc::reset() {
this->~SkArenaAlloc();
new (this) SkArenaAlloc{fFirstBlock, fFirstSize, fFirstHeapAllocationSize};
}
void SkArenaAlloc::installFooter(FooterAction* action, uint32_t padding) {
assert(padding < 64);
int64_t actionInt = (int64_t)(intptr_t)action;
@ -175,3 +167,21 @@ restart:
return objStart;
}
static uint32_t to_uint32_t(size_t v) {
assert(SkTFitsIn<uint32_t>(v));
return (uint32_t)v;
}
SkArenaAllocWithReset::SkArenaAllocWithReset(char* block,
size_t size,
size_t firstHeapAllocation)
: SkArenaAlloc(block, size, firstHeapAllocation)
, fFirstBlock{block}
, fFirstSize{to_uint32_t(size)}
, fFirstHeapAllocationSize{to_uint32_t(firstHeapAllocation)} {}
void SkArenaAllocWithReset::reset() {
this->~SkArenaAllocWithReset();
new (this) SkArenaAllocWithReset{fFirstBlock, fFirstSize, fFirstHeapAllocationSize};
}

View File

@ -67,8 +67,7 @@ public:
SkArenaAlloc(char* block, size_t blockSize, size_t firstHeapAllocation);
explicit SkArenaAlloc(size_t firstHeapAllocation)
: SkArenaAlloc(nullptr, 0, firstHeapAllocation)
{}
: SkArenaAlloc(nullptr, 0, firstHeapAllocation) {}
~SkArenaAlloc();
@ -136,9 +135,6 @@ public:
return objStart;
}
// Destroy all allocated objects, free any heap allocations.
void reset();
private:
static void AssertRelease(bool cond) { if (!cond) { ::abort(); } }
static uint32_t ToU32(size_t v) {
@ -219,9 +215,6 @@ private:
char* fDtorCursor;
char* fCursor;
char* fEnd;
char* const fFirstBlock;
const uint32_t fFirstSize;
const uint32_t fFirstHeapAllocationSize;
// We found allocating strictly doubling amounts of memory from the heap left too
// much unused slop, particularly on Android. Instead we'll follow a Fibonacci-like
@ -237,7 +230,23 @@ private:
//
// That makes the nth allocation fib(n) * fFirstHeapAllocationSize bytes.
uint32_t fNextHeapAlloc, // How many bytes minimum will we allocate next from the heap?
fYetNextHeapAlloc; // And then how many the next allocation after that?
fYetNextHeapAlloc; // And then how many the next allocation after that?
};
class SkArenaAllocWithReset : public SkArenaAlloc {
public:
SkArenaAllocWithReset(char* block, size_t blockSize, size_t firstHeapAllocation);
explicit SkArenaAllocWithReset(size_t firstHeapAllocation)
: SkArenaAllocWithReset(nullptr, 0, firstHeapAllocation) {}
// Destroy all allocated objects, free any heap allocations.
void reset();
private:
char* const fFirstBlock;
const uint32_t fFirstSize;
const uint32_t fFirstHeapAllocationSize;
};
// Helper for defining allocators with inline/reserved storage.
@ -252,4 +261,12 @@ public:
: SkArenaAlloc{this->data(), this->size(), firstHeapAllocation} {}
};
template <size_t InlineStorageSize>
class SkSTArenaAllocWithReset
: private std::array<char, InlineStorageSize>, public SkArenaAllocWithReset {
public:
explicit SkSTArenaAllocWithReset(size_t firstHeapAllocation = InlineStorageSize)
: SkArenaAllocWithReset{this->data(), this->size(), firstHeapAllocation} {}
};
#endif // SkArenaAlloc_DEFINED

View File

@ -341,7 +341,7 @@ private:
std::vector<SkGlyph> fPathsToSend;
// Alloc for storing bits and pieces of paths, Cleared after diffs are serialized.
SkArenaAlloc fPathAlloc{256};
SkArenaAllocWithReset fPathAlloc{256};
};
SkStrikeServer::RemoteStrike::RemoteStrike(

View File

@ -89,7 +89,7 @@ private:
int fHeight;
SkISize fDrawBounds;
SkSTArenaAlloc<512> fNodeAllocator;
SkSTArenaAllocWithReset<512> fNodeAllocator;
Node* fTopNode = nullptr;
sk_sp<GrTextureProxy> fTextureProxy;

View File

@ -261,7 +261,7 @@ private:
};
// Storage for ops' pipelines, draws, and inline uploads.
SkArenaAlloc fArena{sizeof(GrPipeline) * 100};
SkArenaAllocWithReset fArena{sizeof(GrPipeline) * 100};
// Store vertex and index data on behalf of ops that are flushed.
GrVertexBufferAllocPool fVertexPool;

View File

@ -326,7 +326,7 @@ private:
// MDB TODO: 4096 for the first allocation of the clip space will be huge overkill.
// Gather statistics to determine the correct size.
SkArenaAlloc fClipAllocator{4096};
SkArenaAllocWithReset fClipAllocator{4096};
SkDEBUGCODE(int fNumClips;)
// TODO: We could look into this being a set if we find we're adding a lot of duplicates that is

View File

@ -51,7 +51,7 @@ private:
SkPDFTagNode* node,
SkPDFDocument* doc);
SkArenaAlloc fArena;
SkArenaAllocWithReset fArena;
SkTHashMap<int, SkPDFTagNode*> fNodeMap;
SkPDFTagNode* fRoot = nullptr;
SkTArray<SkTArray<SkPDFTagNode*>> fMarksPerPage;

View File

@ -189,7 +189,7 @@ static char* dupstr(SkArenaAlloc* chunk, const char src[]) {
class SkDOMParser : public SkXMLParser {
public:
SkDOMParser(SkArenaAlloc* chunk) : SkXMLParser(&fParserError), fAlloc(chunk) {
SkDOMParser(SkArenaAllocWithReset* chunk) : SkXMLParser(&fParserError), fAlloc(chunk) {
fAlloc->reset();
fRoot = nullptr;
fLevel = 0;
@ -283,7 +283,7 @@ private:
}
SkTDArray<SkDOM::Node*> fParentStack;
SkArenaAlloc* fAlloc;
SkArenaAllocWithReset* fAlloc;
SkDOM::Node* fRoot;
bool fNeedToFlush;

View File

@ -85,7 +85,7 @@ public:
};
private:
SkArenaAlloc fAlloc;
SkArenaAllocWithReset fAlloc;
Node* fRoot;
std::unique_ptr<SkDOMParser> fParser;

View File

@ -149,7 +149,7 @@ DEF_TEST(ArenaAlloc, r) {
REPORTER_ASSERT(r, destroyed == 11);
{
SkSTArenaAlloc<64> arena;
SkSTArenaAllocWithReset<64> arena;
arena.makeArrayDefault<char>(256);
arena.reset();
arena.reset();

View File

@ -430,19 +430,17 @@ struct FourPoints {
};
DEF_TEST(PathOpsAngleAfter, reporter) {
SkSTArenaAlloc<4096> allocator;
SkOpContourHead contour;
SkOpGlobalState state(&contour, &allocator SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr));
contour.init(&state, false, false);
for (int index = intersectDataSetsSize - 1; index >= 0; --index) {
IntersectData* dataArray = intersectDataSets[index];
const int dataSize = intersectDataSetSizes[index];
for (int index2 = 0; index2 < dataSize - 2; ++index2) {
allocator.reset();
contour.reset();
SkSTArenaAlloc<4096> alloc;
SkOpContourHead contour;
SkOpGlobalState state(&contour, &alloc SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr));
contour.init(&state, false, false);
for (int index3 = 0; index3 < 3; ++index3) {
IntersectData& data = dataArray[index2 + index3];
SkPoint* temp = (SkPoint*) allocator.make<FourPoints>();
SkPoint* temp = (SkPoint*) alloc.make<FourPoints>();
for (int idx2 = 0; idx2 < data.fPtCount; ++idx2) {
temp[idx2] = data.fPts.fPts[idx2].asSkPoint();
}