SkArenaAlloc aligned under-allocation

We cannot rely on natural allocation alignment (8) after footer
installation.  Always compute and apply explicit alignment.

Bug: chromium:1124776
Change-Id: I5ff880409df83284b1f9668a771c2a750f72c148
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/315646
Commit-Queue: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Herb Derby <herb@google.com>
This commit is contained in:
Florin Malita 2020-09-08 14:59:16 -04:00 committed by Skia Commit-Bot
parent bbbc28e0ba
commit 26c24eda3e
3 changed files with 16 additions and 10 deletions

View File

@ -74,19 +74,14 @@ char* SkArenaAlloc::NextBlock(char* footerEnd) {
void SkArenaAlloc::ensureSpace(uint32_t size, uint32_t alignment) {
constexpr uint32_t headerSize = sizeof(Footer) + sizeof(ptrdiff_t);
// The chrome c++ library we use does not define std::max_align_t.
// This must be conservative to add the right amount of extra memory to handle the alignment
// padding.
constexpr uint32_t alignof_max_align_t = 8;
constexpr uint32_t maxSize = std::numeric_limits<uint32_t>::max();
constexpr uint32_t overhead = headerSize + sizeof(Footer);
AssertRelease(size <= maxSize - overhead);
uint32_t objSizeAndOverhead = size + overhead;
if (alignment > alignof_max_align_t) {
uint32_t alignmentOverhead = alignment - 1;
AssertRelease(objSizeAndOverhead <= maxSize - alignmentOverhead);
objSizeAndOverhead += alignmentOverhead;
}
const uint32_t alignmentOverhead = alignment - 1;
AssertRelease(objSizeAndOverhead <= maxSize - alignmentOverhead);
objSizeAndOverhead += alignmentOverhead;
uint32_t minAllocationSize = fNextHeapAlloc;

View File

@ -8,6 +8,7 @@
#ifndef SkArenaAlloc_DEFINED
#define SkArenaAlloc_DEFINED
#include "include/core/SkTypes.h"
#include "include/private/SkTFitsIn.h"
#include <array>
@ -170,7 +171,13 @@ private:
this->ensureSpace(size, alignment);
alignedOffset = (~reinterpret_cast<uintptr_t>(fCursor) + 1) & mask;
}
return fCursor + alignedOffset;
char* object = fCursor + alignedOffset;
SkASSERT((reinterpret_cast<uintptr_t>(object) & (alignment - 1)) == 0);
SkASSERT(object + size <= fEnd);
return object;
}
char* allocObjectWithFooter(uint32_t sizeIncludingFooter, uint32_t alignment);

View File

@ -180,4 +180,8 @@ DEF_TEST(ArenaAlloc, r) {
REPORTER_ASSERT(r, created == 128);
REPORTER_ASSERT(r, destroyed == 128);
{
SkArenaAlloc arena(4096);
arena.makeBytesAlignedTo(4081, 8);
}
}