From f6f030dbdc1b8cd636f1e340e506ae776b57999c Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Thu, 11 Apr 2019 09:15:58 -0700 Subject: Optimized memory layout of ObjectBase<> (reduced size by 40 bytes on msvc x64) --- Graphics/GraphicsEngine/include/DeviceObjectBase.h | 75 ++++++++++++---------- Graphics/GraphicsEngine/include/EngineMemory.h | 2 + Graphics/GraphicsEngine/src/EngineMemory.cpp | 5 ++ 3 files changed, 49 insertions(+), 33 deletions(-) (limited to 'Graphics/GraphicsEngine') diff --git a/Graphics/GraphicsEngine/include/DeviceObjectBase.h b/Graphics/GraphicsEngine/include/DeviceObjectBase.h index 2cec3625..0ecacb0c 100644 --- a/Graphics/GraphicsEngine/include/DeviceObjectBase.h +++ b/Graphics/GraphicsEngine/include/DeviceObjectBase.h @@ -26,11 +26,12 @@ /// \file /// Implementation of the Diligent::DeviceObjectBase template class -#include +#include +#include #include "RefCntAutoPtr.h" #include "ObjectBase.h" #include "UniqueIdentifier.h" - +#include "EngineMemory.h" namespace Diligent { @@ -52,13 +53,30 @@ public: const ObjectDescType& ObjDesc, bool bIsDeviceInternal = false) : TBase(pRefCounters), - // Do not keep strong reference to the device if the object is an internal device object - m_spDevice (bIsDeviceInternal ? nullptr : pDevice), - m_pDevice (pDevice), - m_ObjectNameCopy(ObjDesc.Name ? String{ObjDesc.Name} : ThisToString()), - m_Desc (ObjDesc) + m_pDevice (pDevice), + m_Desc (ObjDesc), + m_bIsDeviceInternal(bIsDeviceInternal) { - m_Desc.Name = m_ObjectNameCopy.c_str(); + // Do not keep strong reference to the device if the object is an internal device object + if (!m_bIsDeviceInternal) + { + m_pDevice->AddRef(); + } + + if (ObjDesc.Name != nullptr) + { + auto size = strlen(ObjDesc.Name) + 1; + auto* NameCopy = reinterpret_cast(ALLOCATE(GetStringAllocator(), "Object name copy", size)); + memcpy(NameCopy, ObjDesc.Name, size); + m_Desc.Name = NameCopy; + } + else + { + size_t size = 16 + 2 + 1; // 0x12345678 + auto* AddressStr = reinterpret_cast(ALLOCATE(GetStringAllocator(), "Object address string", size)); + snprintf(AddressStr, size, "0x%llX", static_cast(reinterpret_cast(this))); + m_Desc.Name = AddressStr; + } // !!!WARNING!!! // We cannot add resource to the hash table from here, because the object @@ -67,13 +85,19 @@ public: //m_pDevice->AddResourceToHash( this ); - ERROR! } - DeviceObjectBase( const DeviceObjectBase& ) = delete; - DeviceObjectBase( DeviceObjectBase&& ) = delete; - DeviceObjectBase& operator = ( const DeviceObjectBase& ) = delete; - DeviceObjectBase& operator = ( DeviceObjectBase&& ) = delete; + DeviceObjectBase (const DeviceObjectBase& ) = delete; + DeviceObjectBase ( DeviceObjectBase&&) = delete; + DeviceObjectBase& operator = (const DeviceObjectBase& ) = delete; + DeviceObjectBase& operator = ( DeviceObjectBase&&) = delete; virtual ~DeviceObjectBase() { + FREE(GetStringAllocator(), const_cast(m_Desc.Name)); + + if (!m_bIsDeviceInternal) + { + m_pDevice->Release(); + } } inline virtual Atomics::Long Release()override final @@ -85,7 +109,7 @@ public: // // 1. A::~A() completes // 2. A::~DeviceObjectBase() completes - // 3. A::m_spDevice is released + // 3. A::m_pDevice is released // Render device is destroyed, all allocators are invalid // 4. RefCountersImpl::ObjectWrapperBase::DestroyObject() calls // m_pAllocator->Free(m_pObject) - crash! @@ -96,7 +120,10 @@ public: { // We must keep the device alive while the object is being destroyed // Note that internal device objects do not keep strong reference to the device - pDevice = m_spDevice; + if (!m_bIsDeviceInternal) + { + pDevice = m_pDevice; + } } ); } @@ -121,35 +148,17 @@ public: RenderDeviceImplType* GetDevice()const{return m_pDevice;} -private: - /// Strong reference to the device - RefCntAutoPtr m_spDevice; - protected: /// Pointer to the device RenderDeviceImplType* const m_pDevice; - /// Copy of a device object name. - - /// When new object is created, its description structure is copied - /// to m_Desc, the name is copied to m_ObjectNameCopy, and - /// m_Desc.Name pointer is set to m_ObjectNameCopy.c_str(). - const String m_ObjectNameCopy; - /// Object description ObjectDescType m_Desc; // Template argument is only used to separate counters for // different groups of objects UniqueIdHelper m_UniqueID; - -private: - String ThisToString()const - { - std::stringstream ss; - ss << this; - return ss.str(); - } + const bool m_bIsDeviceInternal; }; } diff --git a/Graphics/GraphicsEngine/include/EngineMemory.h b/Graphics/GraphicsEngine/include/EngineMemory.h index afa38557..cf84193d 100644 --- a/Graphics/GraphicsEngine/include/EngineMemory.h +++ b/Graphics/GraphicsEngine/include/EngineMemory.h @@ -37,6 +37,8 @@ namespace Diligent /// Returns raw memory allocator IMemoryAllocator& GetRawAllocator(); + IMemoryAllocator& GetStringAllocator(); + #define ALLOCATE(Allocator, Desc, Size) (Allocator).Allocate(Size, Desc, __FILE__, __LINE__) #define FREE(Allocator, Ptr) Allocator.Free(Ptr) diff --git a/Graphics/GraphicsEngine/src/EngineMemory.cpp b/Graphics/GraphicsEngine/src/EngineMemory.cpp index ea8bde24..aa764563 100644 --- a/Graphics/GraphicsEngine/src/EngineMemory.cpp +++ b/Graphics/GraphicsEngine/src/EngineMemory.cpp @@ -48,6 +48,11 @@ IMemoryAllocator& GetRawAllocator() return g_pRawAllocator != nullptr ? *g_pRawAllocator : DefaultRawMemoryAllocator::GetAllocator(); } +IMemoryAllocator& GetStringAllocator() +{ + return GetRawAllocator(); +} + } #if 0 -- cgit v1.2.3