MemoryPool: store usage and capacity as integers instead of using pointers

This commit is contained in:
Benoit Blanchon
2023-06-14 21:05:42 +02:00
parent 437307a955
commit 2a663db3c7

View File

@ -34,11 +34,12 @@ class MemoryPool {
deallocAllStrings(); deallocAllStrings();
deallocPool(); deallocPool();
allocator_ = src.allocator_; allocator_ = src.allocator_;
begin_ = src.begin_; pool_ = src.pool_;
end_ = src.end_; poolCapacity_ = src.poolCapacity_;
right_ = src.right_; poolUsage_ = src.poolUsage_;
overflowed_ = src.overflowed_; overflowed_ = src.overflowed_;
src.begin_ = src.end_ = src.right_ = nullptr; src.pool_ = nullptr;
src.poolCapacity_ = src.poolUsage_ = 0;
strings_ = src.strings_; strings_ = src.strings_;
src.strings_ = nullptr; src.strings_ = nullptr;
return *this; return *this;
@ -52,17 +53,17 @@ class MemoryPool {
size_t capa = addPadding(requiredSize); size_t capa = addPadding(requiredSize);
if (capa == capacity()) if (capa == capacity())
return; return;
allocator_->deallocate(begin_); allocator_->deallocate(pool_);
allocPool(requiredSize); allocPool(requiredSize);
} }
// Gets the capacity of the memoryPool in bytes // Gets the capacity of the memoryPool in bytes
size_t capacity() const { size_t capacity() const {
return size_t(end_ - begin_); return poolCapacity_;
} }
size_t size() const { size_t size() const {
size_t total = size_t(right_ - begin_); size_t total = poolUsage_;
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 +78,8 @@ class MemoryPool {
overflowed_ = true; overflowed_ = true;
return 0; return 0;
} }
auto p = right_; auto p = pool_ + poolUsage_;
right_ += bytes; poolUsage_ += bytes;
return p; return p;
} }
@ -167,13 +168,13 @@ class MemoryPool {
} }
void clear() { void clear() {
right_ = begin_; poolUsage_ = 0;
overflowed_ = false; overflowed_ = false;
deallocAllStrings(); deallocAllStrings();
} }
bool canAlloc(size_t bytes) const { bool canAlloc(size_t bytes) const {
return right_ + bytes <= end_; return poolUsage_ + bytes <= poolCapacity_;
} }
// Workaround for missing placement new // Workaround for missing placement new
@ -182,14 +183,10 @@ class MemoryPool {
} }
ptrdiff_t shrinkToFit() { ptrdiff_t shrinkToFit() {
auto oldBegin = begin_; auto originalPoolAddress = pool_;
auto newCapacity = size_t(right_ - begin_); pool_ = reinterpret_cast<char*>(allocator_->reallocate(pool_, poolUsage_));
poolCapacity_ = poolUsage_;
begin_ = return pool_ - originalPoolAddress;
reinterpret_cast<char*>(allocator_->reallocate(begin_, newCapacity));
end_ = right_ = begin_ + newCapacity;
return begin_ - oldBegin;
} }
private: private:
@ -202,21 +199,20 @@ class MemoryPool {
} }
void allocPool(size_t capa) { void allocPool(size_t capa) {
auto buf = capa ? reinterpret_cast<char*>(allocator_->allocate(capa)) : 0; pool_ = capa ? reinterpret_cast<char*>(allocator_->allocate(capa)) : 0;
begin_ = right_ = buf; poolUsage_ = 0;
end_ = buf ? buf + capa : 0; poolCapacity_ = pool_ ? capa : 0;
ARDUINOJSON_ASSERT(isAligned(begin_)); ARDUINOJSON_ASSERT(isAligned(pool_));
ARDUINOJSON_ASSERT(isAligned(right_));
ARDUINOJSON_ASSERT(isAligned(end_));
} }
void deallocPool() { void deallocPool() {
if (begin_) if (pool_)
allocator_->deallocate(begin_); allocator_->deallocate(pool_);
} }
Allocator* allocator_; Allocator* allocator_;
char *begin_, *right_, *end_; char* pool_;
size_t poolUsage_, poolCapacity_;
bool overflowed_; bool overflowed_;
StringNode* strings_ = nullptr; StringNode* strings_ = nullptr;
}; };