1414#include < type_traits>
1515#include < utility>
1616
17+ #include < util/check.h>
18+
1719/* *
1820 * A memory resource similar to std::pmr::unsynchronized_pool_resource, but
1921 * optimized for node-based containers. It has the following properties:
@@ -155,12 +157,15 @@ class PoolResource final
155157 // if there is still any available memory left, put it into the freelist.
156158 size_t remaining_available_bytes = std::distance (m_available_memory_it, m_available_memory_end);
157159 if (0 != remaining_available_bytes) {
160+ ASAN_UNPOISON_MEMORY_REGION (m_available_memory_it, sizeof (ListNode));
158161 PlacementAddToList (m_available_memory_it, m_free_lists[remaining_available_bytes / ELEM_ALIGN_BYTES]);
162+ ASAN_POISON_MEMORY_REGION (m_available_memory_it, sizeof (ListNode));
159163 }
160164
161165 void * storage = ::operator new (m_chunk_size_bytes, std::align_val_t {ELEM_ALIGN_BYTES});
162166 m_available_memory_it = new (storage) std::byte[m_chunk_size_bytes];
163167 m_available_memory_end = m_available_memory_it + m_chunk_size_bytes;
168+ ASAN_POISON_MEMORY_REGION (m_available_memory_it, m_chunk_size_bytes);
164169 m_allocated_chunks.emplace_back (m_available_memory_it);
165170 }
166171
@@ -202,6 +207,7 @@ class PoolResource final
202207 for (std::byte* chunk : m_allocated_chunks) {
203208 std::destroy (chunk, chunk + m_chunk_size_bytes);
204209 ::operator delete ((void *)chunk, std::align_val_t {ELEM_ALIGN_BYTES});
210+ ASAN_UNPOISON_MEMORY_REGION (chunk, m_chunk_size_bytes);
205211 }
206212 }
207213
@@ -217,7 +223,11 @@ class PoolResource final
217223 // we've already got data in the pool's freelist, unlink one element and return the pointer
218224 // to the unlinked memory. Since FreeList is trivially destructible we can just treat it as
219225 // uninitialized memory.
220- return std::exchange (m_free_lists[num_alignments], m_free_lists[num_alignments]->m_next );
226+ ASAN_UNPOISON_MEMORY_REGION (m_free_lists[num_alignments], sizeof (ListNode));
227+ auto * next{m_free_lists[num_alignments]->m_next };
228+ ASAN_POISON_MEMORY_REGION (m_free_lists[num_alignments], sizeof (ListNode));
229+ ASAN_UNPOISON_MEMORY_REGION (m_free_lists[num_alignments], bytes);
230+ return std::exchange (m_free_lists[num_alignments], next);
221231 }
222232
223233 // freelist is empty: get one allocation from allocated chunk memory.
@@ -228,6 +238,7 @@ class PoolResource final
228238 }
229239
230240 // Make sure we use the right amount of bytes for that freelist (might be rounded up),
241+ ASAN_UNPOISON_MEMORY_REGION (m_available_memory_it, round_bytes);
231242 return std::exchange (m_available_memory_it, m_available_memory_it + round_bytes);
232243 }
233244
@@ -244,7 +255,9 @@ class PoolResource final
244255 const std::size_t num_alignments = NumElemAlignBytes (bytes);
245256 // put the memory block into the linked list. We can placement construct the FreeList
246257 // into the memory since we can be sure the alignment is correct.
258+ ASAN_UNPOISON_MEMORY_REGION (p, sizeof (ListNode));
247259 PlacementAddToList (p, m_free_lists[num_alignments]);
260+ ASAN_POISON_MEMORY_REGION (p, std::max (bytes, sizeof (ListNode)));
248261 } else {
249262 // Can't use the pool => forward deallocation to ::operator delete().
250263 ::operator delete (p, std::align_val_t {alignment});
0 commit comments