Added Region::maybeGrow and Region::maybeShrink helper functions to be shared by multiple Allocators
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user