summaryrefslogtreecommitdiffstats
path: root/vespamalloc
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2023-10-10 14:39:24 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2023-10-10 14:40:15 +0000
commita16beaa8463652fe5ca8fa5d4519447d8e6f15f6 (patch)
treeb99d4111608b8332c7fb231d17a36999504a435e /vespamalloc
parent16bdf92863957c505697e5badd8d965df8471035 (diff)
Add validation of internal malloc structures.
Diffstat (limited to 'vespamalloc')
-rw-r--r--vespamalloc/src/vespamalloc/malloc/globalpool.h5
-rw-r--r--vespamalloc/src/vespamalloc/malloc/globalpool.hpp11
2 files changed, 14 insertions, 2 deletions
diff --git a/vespamalloc/src/vespamalloc/malloc/globalpool.h b/vespamalloc/src/vespamalloc/malloc/globalpool.h
index fea8f8ffff8..97360e0d006 100644
--- a/vespamalloc/src/vespamalloc/malloc/globalpool.h
+++ b/vespamalloc/src/vespamalloc/malloc/globalpool.h
@@ -17,6 +17,8 @@ class AllocPoolT
public:
typedef AFList<MemBlockPtrT> ChunkSList;
AllocPoolT(DataSegment & ds);
+ AllocPoolT(const AllocPoolT & ap) = delete;
+ AllocPoolT & operator = (const AllocPoolT & ap) = delete;
~AllocPoolT();
ChunkSList *getFree(SizeClassT sc, size_t minBlocks);
@@ -40,8 +42,7 @@ private:
ChunkSList * malloc(const Guard & guard, SizeClassT sc) __attribute__((noinline));
ChunkSList * getChunks(const Guard & guard, size_t numChunks) __attribute__((noinline));
ChunkSList * allocChunkList(const Guard & guard) __attribute__((noinline));
- AllocPoolT(const AllocPoolT & ap);
- AllocPoolT & operator = (const AllocPoolT & ap);
+ void validate(const void * ptr) const noexcept;
class AllocFree
{
diff --git a/vespamalloc/src/vespamalloc/malloc/globalpool.hpp b/vespamalloc/src/vespamalloc/malloc/globalpool.hpp
index e68944f118d..2f7ff589492 100644
--- a/vespamalloc/src/vespamalloc/malloc/globalpool.hpp
+++ b/vespamalloc/src/vespamalloc/malloc/globalpool.hpp
@@ -87,6 +87,7 @@ typename AllocPoolT<MemBlockPtrT>::ChunkSList *
AllocPoolT<MemBlockPtrT>::getFree(SizeClassT sc, size_t UNUSED(minBlocks))
{
ChunkSList * csl = getFree(sc);
+ validate(csl);
USE_STAT2(_stat[sc]._getFree.fetch_add(1, std::memory_order_relaxed));
return csl;
}
@@ -97,8 +98,10 @@ AllocPoolT<MemBlockPtrT>::exchangeFree(SizeClassT sc, typename AllocPoolT<MemBlo
{
PARANOID_CHECK1( if (csl->empty() || (csl->count() > ChunkSList::NumBlocks)) { *(int*)0 = 0; } );
AllocFree & af = _scList[sc];
+ validate(af._full.load(std::memory_order_relaxed)._ptr);
ChunkSList::linkIn(af._full, csl, csl);
ChunkSList *ncsl = getFree(sc);
+ validate(ncsl);
USE_STAT2(_stat[sc]._exchangeFree.fetch_add(1, std::memory_order_relaxed));
return ncsl;
}
@@ -109,14 +112,22 @@ AllocPoolT<MemBlockPtrT>::exchangeAlloc(SizeClassT sc, typename AllocPoolT<MemBl
{
PARANOID_CHECK1( if ( ! csl->empty()) { *(int*)0 = 0; } );
AllocFree & af = _scList[sc];
+ validate(af._empty.load(std::memory_order_relaxed)._ptr);
ChunkSList::linkIn(af._empty, csl, csl);
ChunkSList * ncsl = getAlloc(sc);
+ validate(ncsl);
USE_STAT2(_stat[sc]._exchangeAlloc.fetch_add(1, std::memory_order_relaxed));
PARANOID_CHECK1( if (ncsl->empty() || (ncsl->count() > ChunkSList::NumBlocks)) { *(int*)0 = 0; } );
return ncsl;
}
template <typename MemBlockPtrT>
+void
+AllocPoolT<MemBlockPtrT>::validate(const void * ptr) const noexcept {
+ assert((ptr == nullptr) || _dataSegment.containsPtr(ptr));
+}
+
+template <typename MemBlockPtrT>
typename AllocPoolT<MemBlockPtrT>::ChunkSList *
AllocPoolT<MemBlockPtrT>::exactAlloc(size_t exactSize, SizeClassT sc,
typename AllocPoolT<MemBlockPtrT>::ChunkSList * csl)