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:
parent
10f019c506
commit
bfcf8c4832
@ -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);
|
||||
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user