Added Region::maybeGrow and Region::maybeShrink helper functions to be shared by multiple Allocators

This commit is contained in:
2026-09-28 00:13:14 -07:00
parent 9fe6784da1
commit 713fa239f5
3 changed files with 36 additions and 18 deletions

View File

@@ -49,6 +49,10 @@ public:
size_t getMaxSize() const;
std::byte* getAddress() const;
// Helper functions for allocators
bool maybeGrow(size_t minSize);
void maybeShrink(size_t targetSize);
private:
std::byte* m_data;
size_t m_committedSize;

View File

@@ -77,17 +77,9 @@ size_t Arena::getMaxSize() const
std::byte* Arena::alloc(size_t size)
{
size_t neededSize = m_usedSize + size;
if (neededSize > m_region.getSize())
{
// Increase the size exponentially when we run out
size_t newSize = std::bit_ceil(neededSize) << 1;
if (newSize < m_minSize) {
newSize = m_minSize;
}
if (!m_region.resize(newSize)) {
if (!m_region.maybeGrow(std::max(neededSize, m_minSize))) {
return nullptr;
}
}
std::byte* ret = m_region.getAddress() + m_usedSize;
m_usedSize = neededSize;
@@ -128,13 +120,7 @@ void Arena::reset()
m_watermark[kWatermarkLen - 1] = m_usedSize;
size_t targetSize = std::bit_ceil(highWatermark) << 1;
if (targetSize < m_minSize) {
targetSize = m_minSize;
}
size_t thresholdSize = targetSize << 1; // The threshold for shrinking is greater than the target to implement hysteresis
if (m_region.getSize() > thresholdSize) {
m_region.resize(targetSize);
}
m_region.maybeShrink(std::max(m_minSize, targetSize));
m_usedSize = 0;
}

View File

@@ -154,4 +154,32 @@ std::byte* Region::getAddress() const
return m_data;
}
};
bool Region::maybeGrow(size_t minSize)
{
if (minSize < m_committedSize) {
// Already big enough
return true;
}
if (minSize > m_maxSize) {
// We can't grow this big
return false;
}
// We need to grow.
// Increase the size exponentially, capped to m_maxSize
size_t newSize = std::bit_ceil(minSize) << 1;
newSize = std::min(m_maxSize, newSize);
return resize(newSize);
}
void Region::maybeShrink(size_t targetSize)
{
size_t thresholdSize = targetSize << 1; // The threshold for shrinking is greater than the target to implement hysteresis
if (getSize() > thresholdSize) {
resize(targetSize);
}
}
} // namespace mimir