simplify next allocation size

Since the fibonacci sequence is always multiplied by
fFirstHeapAllocationSize, change the names ofr fFib0 and
fFib1 to fNextHeapAlloc, and fYetNextHeapAlloc, and assign
both to be fFirstHeapAllocationSize. This will create the
same sequence of heap allocation sizes. Now
fFirstHeapAllocationSize is only used in reset(). This will
simplify CL/307348 which move reset to a different class.

Change-Id: I54da1980239645acd36992476915137dd68ab9da
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/307349
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
Herb Derby 2020-08-01 17:12:48 -04:00 committed by Skia Commit-Bot
parent 10f019c506
commit bfcf8c4832
2 changed files with 30 additions and 16 deletions

View File

@ -17,12 +17,14 @@ 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))}
: fDtorCursor{block}
, fCursor{block}
, fEnd{block + ToU32(size)}
, fFirstBlock{block}
, fFirstSize{ToU32(size)}
, fFirstHeapAllocationSize{first_allocated_block(ToU32(size), ToU32(firstHeapAllocation))}
, fNextHeapAlloc{fFirstHeapAllocationSize}
, fYetNextHeapAlloc{fNextHeapAlloc}
{
if (size < sizeof(Footer)) {
fEnd = fCursor = fDtorCursor = nullptr;
@ -110,13 +112,14 @@ void SkArenaAlloc::ensureSpace(uint32_t size, uint32_t alignment) {
objSizeAndOverhead += alignmentOverhead;
}
uint32_t minAllocationSize;
if (fFirstHeapAllocationSize <= maxSize / fFib0) {
minAllocationSize = fFirstHeapAllocationSize * fFib0;
fFib0 += fFib1;
std::swap(fFib0, fFib1);
uint32_t minAllocationSize = fNextHeapAlloc;
// Calculate the next heap alloc that won't overflow.
if (fYetNextHeapAlloc <= maxSize - fNextHeapAlloc) {
fNextHeapAlloc += fYetNextHeapAlloc;
std::swap(fNextHeapAlloc, fYetNextHeapAlloc);
} else {
minAllocationSize = maxSize;
fNextHeapAlloc = maxSize;
}
uint32_t allocationSize = std::max(objSizeAndOverhead, minAllocationSize);

View File

@ -223,10 +223,21 @@ private:
const uint32_t fFirstSize;
const uint32_t fFirstHeapAllocationSize;
// Use the Fibonacci sequence as the growth factor for block size. The size of the block
// allocated is fFib0 * fFirstHeapAllocationSize. Using 2 ^ n * fFirstHeapAllocationSize
// had too much slop for Android.
uint32_t fFib0 {1}, fFib1 {1};
// 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
// progression that's simple to implement and grows with roughly a 1.6 exponent:
//
// To start,
// fNextHeapAlloc = fYetNextHeapAlloc = 1*fFirstHeapAllocationSize;
//
// And then when we do allocate, follow a Fibonacci f(n+2) = f(n+1) + f(n) rule:
// void* block = malloc(fNextHeapAlloc);
// std::swap(fNextHeapAlloc, fYetNextHeapAlloc)
// fYetNextHeapAlloc += fNextHeapAlloc;
//
// 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?
};
// Helper for defining allocators with inline/reserved storage.