Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SubRunAllocator.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2021 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
12
13#include <cstddef>
14#include <memory>
15#include <new>
16
17namespace sktext::gpu {
18
19// -- BagOfBytes ---------------------------------------------------------------------------------
20BagOfBytes::BagOfBytes(char* bytes, size_t size, size_t firstHeapAllocation)
21 : fFibProgression(size, firstHeapAllocation) {
22 SkASSERT_RELEASE(size < kMaxByteSize);
23 SkASSERT_RELEASE(firstHeapAllocation < kMaxByteSize);
24
25 std::size_t space = size;
26 void* ptr = bytes;
27 if (bytes && std::align(kMaxAlignment, sizeof(Block), ptr, space)) {
28 this->setupBytesAndCapacity(bytes, size);
29 new (fEndByte) Block(nullptr, nullptr);
30 }
31}
32
33BagOfBytes::BagOfBytes(size_t firstHeapAllocation)
34 : BagOfBytes(nullptr, 0, firstHeapAllocation) {}
35
37 Block* cursor = reinterpret_cast<Block*>(fEndByte);
38 while (cursor != nullptr) {
39 char* toDelete = cursor->fBlockStart;
40 cursor = cursor->fPrevious;
41 delete [] toDelete;
42 }
43}
44
45BagOfBytes::Block::Block(char* previous, char* startOfBlock)
46 : fBlockStart{startOfBlock}
47 , fPrevious{reinterpret_cast<Block*>(previous)} {}
48
49void* BagOfBytes::alignedBytes(int size, int alignment) {
50 SkASSERT_RELEASE(0 < size && size < kMaxByteSize);
51 SkASSERT_RELEASE(0 < alignment && alignment <= kMaxAlignment);
52 SkASSERT_RELEASE(SkIsPow2(alignment));
53
54 return this->allocateBytes(size, alignment);
55}
56
57void BagOfBytes::setupBytesAndCapacity(char* bytes, int size) {
58 // endByte must be aligned to the maximum alignment to allow tracking alignment using capacity;
59 // capacity and endByte are both aligned to max alignment.
60 intptr_t endByte = reinterpret_cast<intptr_t>(bytes + size - sizeof(Block)) & -kMaxAlignment;
61 fEndByte = reinterpret_cast<char*>(endByte);
62 fCapacity = fEndByte - bytes;
63}
64
65void BagOfBytes::needMoreBytes(int requestedSize, int alignment) {
66 int nextBlockSize = fFibProgression.nextBlockSize();
68 std::max(requestedSize, nextBlockSize), kAllocationAlignment);
69 char* const bytes = new char[size];
70 // fEndByte is changed by setupBytesAndCapacity. Remember it to link back to.
71 char* const previousBlock = fEndByte;
72 this->setupBytesAndCapacity(bytes, size);
73
74 // Make a block to delete these bytes, and points to the previous block.
75 new (fEndByte) Block{previousBlock, bytes};
76
77 // Make fCapacity the alignment for the requested object.
78 fCapacity = fCapacity & -alignment;
79 SkASSERT(fCapacity >= requestedSize);
80}
81
82// -- SubRunAllocator ----------------------------------------------------------------------------
83SubRunAllocator::SubRunAllocator(char* bytes, int size, int firstHeapAllocation)
84 : fAlloc{bytes, SkTo<size_t>(size), SkTo<size_t>(firstHeapAllocation)} {
85 SkASSERT_RELEASE(SkTFitsIn<size_t>(size));
86 SkASSERT_RELEASE(SkTFitsIn<size_t>(firstHeapAllocation));
87}
88
89SubRunAllocator::SubRunAllocator(int firstHeapAllocation)
90 : SubRunAllocator(nullptr, 0, firstHeapAllocation) { }
91
92void* SubRunAllocator::alignedBytes(int unsafeSize, int unsafeAlignment) {
93 return fAlloc.alignedBytes(unsafeSize, unsafeAlignment);
94}
95
96} // namespace sktext::gpu
#define SkASSERT_RELEASE(cond)
Definition SkAssert.h:100
#define SkASSERT(cond)
Definition SkAssert.h:116
SkBlockAllocator::Block Block
constexpr bool SkIsPow2(T value)
Definition SkMath.h:51
constexpr D SkTo(S s)
Definition SkTo.h:16
uint32_t nextBlockSize()
void * alignedBytes(int unsafeSize, int unsafeAlignment)
BagOfBytes(char *block, size_t blockSize, size_t firstHeapAllocation)
static constexpr int PlatformMinimumSizeWithOverhead(int requestedSize, int assumedAlignment)
void * alignedBytes(int size, int alignment)
SubRunAllocator(char *block, int blockSize, int firstHeapAllocation)