MemoryPool: store slots at the beginning of the pool

This commit is contained in:
Benoit Blanchon
2023-06-14 11:41:03 +02:00
parent 56b3b4d5a9
commit 437307a955

View File

@ -62,7 +62,7 @@ class MemoryPool {
} }
size_t size() const { size_t size() const {
size_t total = size_t(end_ - right_); size_t total = size_t(right_ - begin_);
for (auto node = strings_; node; node = node->next) for (auto node = strings_; node; node = node->next)
total += sizeofString(node->length); total += sizeofString(node->length);
return total; return total;
@ -77,8 +77,9 @@ class MemoryPool {
overflowed_ = true; overflowed_ = true;
return 0; return 0;
} }
right_ -= bytes; auto p = right_;
return right_; right_ += bytes;
return p;
} }
template <typename TAdaptedString> template <typename TAdaptedString>
@ -166,13 +167,13 @@ class MemoryPool {
} }
void clear() { void clear() {
right_ = end_; right_ = begin_;
overflowed_ = false; overflowed_ = false;
deallocAllStrings(); deallocAllStrings();
} }
bool canAlloc(size_t bytes) const { bool canAlloc(size_t bytes) const {
return begin_ + bytes <= right_; return right_ + bytes <= end_;
} }
// Workaround for missing placement new // Workaround for missing placement new
@ -181,43 +182,17 @@ class MemoryPool {
} }
ptrdiff_t shrinkToFit() { ptrdiff_t shrinkToFit() {
ptrdiff_t bytes_reclaimed = squash(); auto oldBegin = begin_;
if (bytes_reclaimed == 0) auto newCapacity = size_t(right_ - begin_);
return 0;
void* old_ptr = begin_; begin_ =
void* new_ptr = allocator_->reallocate(old_ptr, capacity()); reinterpret_cast<char*>(allocator_->reallocate(begin_, newCapacity));
end_ = right_ = begin_ + newCapacity;
ptrdiff_t ptr_offset = return begin_ - oldBegin;
static_cast<char*>(new_ptr) - static_cast<char*>(old_ptr);
movePointers(ptr_offset);
return ptr_offset - bytes_reclaimed;
} }
private: private:
ptrdiff_t squash() {
char* new_right = addPadding(begin_);
if (new_right >= right_)
return 0;
size_t right_size = static_cast<size_t>(end_ - right_);
memmove(new_right, right_, right_size);
ptrdiff_t bytes_reclaimed = right_ - new_right;
right_ = new_right;
end_ = new_right + right_size;
return bytes_reclaimed;
}
// Move all pointers together
// This funcion is called after a realloc.
void movePointers(ptrdiff_t offset) {
begin_ += offset;
right_ += offset;
end_ += offset;
}
void deallocAllStrings() { void deallocAllStrings() {
while (strings_) { while (strings_) {
auto node = strings_; auto node = strings_;
@ -228,8 +203,8 @@ class MemoryPool {
void allocPool(size_t capa) { void allocPool(size_t capa) {
auto buf = capa ? reinterpret_cast<char*>(allocator_->allocate(capa)) : 0; auto buf = capa ? reinterpret_cast<char*>(allocator_->allocate(capa)) : 0;
begin_ = buf; begin_ = right_ = buf;
end_ = right_ = buf ? buf + capa : 0; end_ = buf ? buf + capa : 0;
ARDUINOJSON_ASSERT(isAligned(begin_)); ARDUINOJSON_ASSERT(isAligned(begin_));
ARDUINOJSON_ASSERT(isAligned(right_)); ARDUINOJSON_ASSERT(isAligned(right_));
ARDUINOJSON_ASSERT(isAligned(end_)); ARDUINOJSON_ASSERT(isAligned(end_));