@@ -64,19 +64,19 @@ class CNodePool : public core::IReferenceCounted
6464 inline CDebugInfo (const void * data, const uint32_t size) : m_size(size)
6565 {
6666 if (data)
67- memcpy (this +1 ,data,m_size);
67+ memcpy (std::launder ( this +1 ) ,data,m_size);
6868 }
6969 inline CDebugInfo (const std::string_view& view) : CDebugInfo(nullptr ,view.length()+1)
7070 {
71- auto * out = reinterpret_cast <char *>(this +1 );
71+ auto * out = std::launder ( reinterpret_cast <char *>(this +1 ) );
7272 if (m_size>1 )
7373 memcpy (out,view.data (),m_size);
7474 out[m_size-1 ] = 0 ;
7575 }
7676
7777 inline const std::span<const uint8_t > data () const
7878 {
79- return {reinterpret_cast <const uint8_t *>(this +1 ),m_size};
79+ return {std::launder ( reinterpret_cast <const uint8_t *>(this +1 ) ),m_size};
8080 }
8181
8282 protected:
@@ -174,6 +174,7 @@ class CNodePool : public core::IReferenceCounted
174174 const uint32_t size = ptr->getSize ();
175175 static_cast <INode*>(ptr)->~INode (); // can't use `std::destroy_at<T>(ptr);` because of destructor being non-public
176176 // wipe v-table to mark as dead (so `~CNodePool` doesn't run destructor twice)
177+ // NOTE: This won't work if we start reusing memory, even zeroing out the whole node won't work! Then need an accurate record of live nodes!
177178 const void * nullVTable = nullptr ;
178179 assert (memcmp (ptr,&nullVTable,sizeof (nullVTable))!=0 ); // double free
179180 memset (static_cast <INode*>(ptr),0 ,sizeof (nullVTable));
@@ -196,6 +197,7 @@ class CNodePool : public core::IReferenceCounted
196197 for (auto handleOff=chunk.getAllocator ().get_total_size (); handleOff<chunkSize; handleOff+=sizeof (Handle))
197198 {
198199 const auto pHandle = reinterpret_cast <const Handle*>(chunk.m_data +handleOff);
200+ // NOTE: This won't work if we start reusing memory, even zeroing out the whole node won't work! Then need an accurate record of live nodes!
199201 if (auto * node=deref<INode>(*pHandle); node)
200202 node->~INode (); // can't use `std::destroy_at<T>(ptr);` because of destructor being non-public
201203 }
@@ -207,7 +209,7 @@ class CNodePool : public core::IReferenceCounted
207209 struct Chunk
208210 {
209211 // for now using KISS, we can use geeneralpupose allocator later
210- // Generalpurpose woudl require us to store the allocated handle list in a different way, so that handles can be quickly removed from it.
212+ // Generalpurpose would require us to store the allocated handle list in a different way, so that handles can be quickly removed from it.
211213 // Maybe a doubly linked list around the original allocation?
212214 using allocator_t = core::LinearAddressAllocatorST<Handle::value_t >;
213215
@@ -232,8 +234,9 @@ class CNodePool : public core::IReferenceCounted
232234 return invalid_address;
233235 }
234236 // clear vtable to mark as not initialized yet
237+ // TODO: this won't work with reusable memory / not bump allocator
235238 memset (m_data+retval,0 ,sizeof (INode));
236- *reinterpret_cast <Handle::value_t *>(m_data+newSize) = retval;
239+ *std::launder ( reinterpret_cast <Handle::value_t *>(m_data+newSize) ) = retval;
237240 // shrink allocator
238241 getAllocator () = allocator_t (newSize, std::move (getAllocator ()), nullptr );
239242 }
@@ -264,9 +267,9 @@ class CNodePool : public core::IReferenceCounted
264267 return ptr;
265268 else
266269 {
267- if (*reinterpret_cast <const void * const *>(ptr)) // vtable not wiped
270+ if (*std::launder ( reinterpret_cast <const void * const *>(ptr) )) // vtable not wiped
268271 {
269- auto * base = reinterpret_cast <INode*>(ptr);
272+ auto * base = std::launder ( reinterpret_cast <INode*>(ptr) );
270273 return dynamic_cast <T*>(base);
271274 }
272275 }
0 commit comments