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;
|
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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user