diff --git a/Source/System/Entity.cpp b/Source/System/Entity.cpp index e3fb49bb6..3aa2579c6 100644 --- a/Source/System/Entity.cpp +++ b/Source/System/Entity.cpp @@ -237,6 +237,11 @@ namespace RTE { } void Entity::ClassInfo::FillPool(int fillAmount) { +#ifdef __SANITIZE_ADDRESS__ + // If we have ASan, make this a no-op. + (void)(fillAmount); // Silence warning about unused variable. +#else + // Default to the set block allocation size if fillAmount is 0 if (fillAmount <= 0) { fillAmount = m_PoolAllocBlockCount; @@ -248,6 +253,7 @@ namespace RTE { m_AllocatedPool.push_back(m_Allocate()); } } +#endif } bool Entity::ClassInfo::IsClassOrChildClassOf(const ClassInfo* classInfoToCheck) const { @@ -260,6 +266,13 @@ namespace RTE { } void* Entity::ClassInfo::GetPoolMemory() { +#ifdef __SANITIZE_ADDRESS__ + // If compiled with ASan, sidestep pooling and just use the allocator normally. + + void* foundMemory = m_Allocate(); + RTEAssert(foundMemory, "m_Allocate failed! to make memory!"); +#else + std::lock_guard guard(m_Mutex); RTEAssert(IsConcrete(), "Trying to get pool memory of an abstract Entity class!"); @@ -274,6 +287,7 @@ namespace RTE { m_AllocatedPool.pop_back(); RTEAssert(foundMemory, "Could not find an available instance in the pool, even after increasing its size!"); +#endif // Keep track of the number of instances passed out m_InstancesInUse++; @@ -285,8 +299,14 @@ namespace RTE { if (!returnedMemory) { return 0; } + +#ifdef __SANITIZE_ADDRESS__ + // If compiled with ASan, sidestep pooling and just use the allocator normally. + m_Deallocate(returnedMemory); +#else std::lock_guard guard(m_Mutex); m_AllocatedPool.push_back(returnedMemory); +#endif // Keep track of the number of instances passed in m_InstancesInUse--; diff --git a/Source/System/Entity.h b/Source/System/Entity.h index 8caa3ccae..0bd377360 100644 --- a/Source/System/Entity.h +++ b/Source/System/Entity.h @@ -7,6 +7,14 @@ #include #include +// Concoction based on: +// https://stackoverflow.com/questions/34813412/how-to-detect-if-building-with-address-sanitizer-when-building-with-gcc-4-8#78444624 +#if defined(__has_feature) // MSVC doesn't have this +# if __has_feature(address_sanitizer) // for Clang +# define __SANITIZE_ADDRESS__ // GCC and MSVC already set this +# endif +#endif + namespace RTE { typedef std::function MemoryAllocate; //!< Convenient name definition for the memory allocation callback function. @@ -173,7 +181,9 @@ namespace RTE { int m_PoolAllocBlockCount; //!< The number of instances to fill up the pool of this type with each time it runs dry. int m_InstancesInUse; //!< The number of allocated instances passed out from the pool. +#ifndef __ADDRESS_SANITIZER__ // Unused when ASan is enabled. std::mutex m_Mutex; //!< Mutex to ensure multiple things aren't grabbing/deallocating memory at the same time +#endif // Forbidding copying ClassInfo(const ClassInfo& reference) = delete;