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; size_t getMaxSize() const;
std::byte* getAddress() const; std::byte* getAddress() const;
// Helper functions for allocators
bool maybeGrow(size_t minSize);
void maybeShrink(size_t targetSize);
private: private:
std::byte* m_data; std::byte* m_data;
size_t m_committedSize; size_t m_committedSize;

View File

@@ -77,17 +77,9 @@ size_t Arena::getMaxSize() const
std::byte* Arena::alloc(size_t size) std::byte* Arena::alloc(size_t size)
{ {
size_t neededSize = m_usedSize + size; size_t neededSize = m_usedSize + size;
if (neededSize > m_region.getSize()) if (!m_region.maybeGrow(std::max(neededSize, m_minSize))) {
{
// 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)) {
return nullptr; return nullptr;
} }
}
std::byte* ret = m_region.getAddress() + m_usedSize; std::byte* ret = m_region.getAddress() + m_usedSize;
m_usedSize = neededSize; m_usedSize = neededSize;
@@ -128,13 +120,7 @@ void Arena::reset()
m_watermark[kWatermarkLen - 1] = m_usedSize; m_watermark[kWatermarkLen - 1] = m_usedSize;
size_t targetSize = std::bit_ceil(highWatermark) << 1; size_t targetSize = std::bit_ceil(highWatermark) << 1;
if (targetSize < m_minSize) { m_region.maybeShrink(std::max(m_minSize, targetSize));
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_usedSize = 0; m_usedSize = 0;
} }

View File

@@ -154,4 +154,32 @@ std::byte* Region::getAddress() const
return m_data; 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