Merge pull request #6390 from aws-lumberyard-dev/memory/overrideshim_removal
Memory/overrideshim removal
This commit is contained in:
@@ -152,8 +152,6 @@ namespace AZ
|
||||
m_reservedDebug = 0;
|
||||
m_recordingMode = Debug::AllocationRecords::RECORD_STACK_IF_NO_FILE_LINE;
|
||||
m_stackRecordLevels = 5;
|
||||
m_useOverrunDetection = false;
|
||||
m_useMalloc = false;
|
||||
}
|
||||
|
||||
bool AppDescriptorConverter(SerializeContext& serialize, SerializeContext::DataElementNode& node)
|
||||
@@ -323,9 +321,6 @@ namespace AZ
|
||||
->Field("blockSize", &Descriptor::m_memoryBlocksByteSize)
|
||||
->Field("reservedOS", &Descriptor::m_reservedOS)
|
||||
->Field("reservedDebug", &Descriptor::m_reservedDebug)
|
||||
->Field("useOverrunDetection", &Descriptor::m_useOverrunDetection)
|
||||
->Field("useMalloc", &Descriptor::m_useMalloc)
|
||||
->Field("allocatorRemappings", &Descriptor::m_allocatorRemappings)
|
||||
->Field("modules", &Descriptor::m_modules)
|
||||
;
|
||||
|
||||
@@ -361,8 +356,6 @@ namespace AZ
|
||||
->Attribute(Edit::Attributes::Step, &Descriptor::m_pageSize)
|
||||
->DataElement(Edit::UIHandlers::SpinBox, &Descriptor::m_reservedOS, "OS reserved memory", "System memory reserved for OS (used only when 'Allocate all memory at startup' is true)")
|
||||
->DataElement(Edit::UIHandlers::SpinBox, &Descriptor::m_reservedDebug, "Memory reserved for debugger", "System memory reserved for Debug allocator, like memory tracking (used only when 'Allocate all memory at startup' is true)")
|
||||
->DataElement(Edit::UIHandlers::CheckBox, &Descriptor::m_useOverrunDetection, "Use Overrun Detection", "Use the overrun detection memory manager (only available on some platforms, ignored in Release builds)")
|
||||
->DataElement(Edit::UIHandlers::CheckBox, &Descriptor::m_useMalloc, "Use Malloc", "Use malloc for memory allocations (for memory debugging only, ignored in Release builds)")
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -881,7 +874,7 @@ namespace AZ
|
||||
AZ::AllocatorInstance<AZ::SystemAllocator>::Create(desc);
|
||||
AZ::Debug::Trace::Instance().Init();
|
||||
|
||||
AZ::Debug::AllocationRecords* records = AllocatorInstance<SystemAllocator>::GetAllocator().GetRecords();
|
||||
AZ::Debug::AllocationRecords* records = AllocatorInstance<SystemAllocator>::Get().GetRecords();
|
||||
if (records)
|
||||
{
|
||||
records->SetMode(m_descriptor.m_recordingMode);
|
||||
@@ -893,35 +886,6 @@ namespace AZ
|
||||
|
||||
m_isSystemAllocatorOwner = true;
|
||||
}
|
||||
|
||||
#ifndef RELEASE
|
||||
if (m_descriptor.m_useOverrunDetection)
|
||||
{
|
||||
OverrunDetectionSchema::Descriptor overrunDesc(false);
|
||||
s_overrunDetectionSchema = Environment::CreateVariable<OverrunDetectionSchema>(AzTypeInfo<OverrunDetectionSchema>::Name(), overrunDesc);
|
||||
OverrunDetectionSchema* schemaPtr = &s_overrunDetectionSchema.Get();
|
||||
|
||||
AZ::AllocatorManager::Instance().SetOverrideAllocatorSource(schemaPtr);
|
||||
}
|
||||
|
||||
if (m_descriptor.m_useMalloc)
|
||||
{
|
||||
AZ_Printf("Malloc", "WARNING: Malloc override is enabled. Registered allocators will use malloc instead of their normal allocation schemas.");
|
||||
s_mallocSchema = Environment::CreateVariable<MallocSchema>(AzTypeInfo<MallocSchema>::Name());
|
||||
MallocSchema* schemaPtr = &s_mallocSchema.Get();
|
||||
|
||||
AZ::AllocatorManager::Instance().SetOverrideAllocatorSource(schemaPtr);
|
||||
}
|
||||
#endif
|
||||
|
||||
AllocatorManager& allocatorManager = AZ::AllocatorManager::Instance();
|
||||
|
||||
for (const auto& remapping : m_descriptor.m_allocatorRemappings)
|
||||
{
|
||||
allocatorManager.AddAllocatorRemapping(remapping.m_from.c_str(), remapping.m_to.c_str());
|
||||
}
|
||||
|
||||
allocatorManager.FinalizeConfiguration();
|
||||
}
|
||||
|
||||
void ComponentApplication::MergeSettingsToRegistry(SettingsRegistryInterface& registry)
|
||||
|
||||
@@ -142,10 +142,6 @@ namespace AZ
|
||||
AZ::u64 m_reservedDebug; //!< Reserved memory for Debugging (allocation,etc.). Used only when m_grabAllMemory is set to true. (default: 0)
|
||||
Debug::AllocationRecords::Mode m_recordingMode; //!< When to record stack traces (default: AZ::Debug::AllocationRecords::RECORD_STACK_IF_NO_FILE_LINE)
|
||||
AZ::u64 m_stackRecordLevels; //!< If stack recording is enabled, how many stack levels to record. (default: 5)
|
||||
bool m_useOverrunDetection; //!< True to use the overrun detection memory management scheme. Only available on some platforms; greatly increases memory consumption.
|
||||
bool m_useMalloc; //!< True to use malloc instead of the internal memory manager. Intended for debugging purposes only.
|
||||
|
||||
AllocatorRemappings m_allocatorRemappings; //!< List of remappings of allocators to perform, so that they can alias each other.
|
||||
|
||||
ModuleDescriptorList m_modules; //!< Dynamic modules used by the application.
|
||||
//!< These will be loaded on startup.
|
||||
@@ -159,7 +155,7 @@ namespace AZ
|
||||
|
||||
//! If set, this allocator is used to allocate the temporary bootstrap memory, as well as the main \ref SystemAllocator heap.
|
||||
//! If it's left nullptr (default), the \ref OSAllocator will be used.
|
||||
IAllocatorAllocate* m_allocator = nullptr;
|
||||
IAllocator* m_allocator = nullptr;
|
||||
|
||||
//! Callback to create AZ::Modules for the static libraries linked by this application.
|
||||
//! Leave null if the application uses no static AZ::Modules.
|
||||
@@ -372,7 +368,7 @@ namespace AZ
|
||||
bool m_isOSAllocatorOwner{ false };
|
||||
bool m_ownsConsole{};
|
||||
void* m_fixedMemoryBlock{ nullptr }; //!< Pointer to the memory block allocator, so we can free it OnDestroy.
|
||||
IAllocatorAllocate* m_osAllocator{ nullptr };
|
||||
IAllocator* m_osAllocator{ nullptr };
|
||||
EntitySetType m_entities;
|
||||
|
||||
AZ::SettingsRegistryInterface::NotifyEventHandler m_projectPathChangedHandler;
|
||||
|
||||
@@ -15,7 +15,7 @@ struct z_stream_s;
|
||||
namespace AZ
|
||||
{
|
||||
class IAllocator;
|
||||
class IAllocatorAllocate;
|
||||
class IAllocatorSchema;
|
||||
|
||||
/**
|
||||
* The most well known and used compression algorithm. It gives the best compression ratios even on level 1,
|
||||
@@ -90,7 +90,7 @@ namespace AZ
|
||||
|
||||
z_stream_s* m_strDeflate;
|
||||
z_stream_s* m_strInflate;
|
||||
IAllocatorAllocate* m_workMemoryAllocator;
|
||||
IAllocatorSchema* m_workMemoryAllocator;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ ZLib::ZLib(IAllocator* workMemAllocator)
|
||||
: m_strDeflate(nullptr)
|
||||
, m_strInflate(nullptr)
|
||||
{
|
||||
m_workMemoryAllocator = workMemAllocator ? workMemAllocator->GetAllocationSource() : nullptr;
|
||||
m_workMemoryAllocator = workMemAllocator->GetSchema();
|
||||
if (!m_workMemoryAllocator)
|
||||
{
|
||||
m_workMemoryAllocator = &AllocatorInstance<SystemAllocator>::Get();
|
||||
@@ -55,7 +55,7 @@ ZLib::~ZLib()
|
||||
//=========================================================================
|
||||
void* ZLib::AllocateMem(void* userData, unsigned int items, unsigned int size)
|
||||
{
|
||||
IAllocatorAllocate* allocator = reinterpret_cast<IAllocatorAllocate*>(userData);
|
||||
IAllocator* allocator = reinterpret_cast<IAllocator*>(userData);
|
||||
return allocator->Allocate(items * size, 4, 0, "ZLib", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ void* ZLib::AllocateMem(void* userData, unsigned int items, unsigned int size)
|
||||
//=========================================================================
|
||||
void ZLib::FreeMem(void* userData, void* address)
|
||||
{
|
||||
IAllocatorAllocate* allocator = reinterpret_cast<IAllocatorAllocate*>(userData);
|
||||
IAllocator* allocator = reinterpret_cast<IAllocator*>(userData);
|
||||
allocator->DeAllocate(address);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
using namespace AZ;
|
||||
|
||||
ZStd::ZStd(IAllocatorAllocate* workMemAllocator)
|
||||
ZStd::ZStd(IAllocator* workMemAllocator)
|
||||
{
|
||||
m_workMemoryAllocator = workMemAllocator;
|
||||
if (!m_workMemoryAllocator)
|
||||
@@ -41,13 +41,13 @@ ZStd::~ZStd()
|
||||
|
||||
void* ZStd::AllocateMem(void* userData, size_t size)
|
||||
{
|
||||
IAllocatorAllocate* allocator = reinterpret_cast<IAllocatorAllocate*>(userData);
|
||||
IAllocator* allocator = reinterpret_cast<IAllocator*>(userData);
|
||||
return allocator->Allocate(size, 4, 0, "ZStandard", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
void ZStd::FreeMem(void* userData, void* address)
|
||||
{
|
||||
IAllocatorAllocate* allocator = reinterpret_cast<IAllocatorAllocate*>(userData);
|
||||
IAllocator* allocator = reinterpret_cast<IAllocator*>(userData);
|
||||
allocator->DeAllocate(address);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,12 +17,11 @@
|
||||
namespace AZ
|
||||
{
|
||||
class IAllocator;
|
||||
class IAllocatorAllocate;
|
||||
|
||||
class ZStd
|
||||
{
|
||||
public:
|
||||
ZStd(IAllocatorAllocate* workMemAllocator = 0);
|
||||
ZStd(IAllocator* workMemAllocator = 0);
|
||||
~ZStd();
|
||||
|
||||
enum FlushType
|
||||
@@ -77,7 +76,7 @@ namespace AZ
|
||||
|
||||
ZSTD_CStream* m_streamCompression;
|
||||
ZSTD_DStream* m_streamDecompression;
|
||||
IAllocatorAllocate* m_workMemoryAllocator;
|
||||
IAllocator* m_workMemoryAllocator;
|
||||
ZSTD_inBuffer m_inBuffer;
|
||||
ZSTD_outBuffer m_outBuffer;
|
||||
size_t m_nextBlockSize;
|
||||
|
||||
@@ -53,7 +53,6 @@ namespace AZ::Dom
|
||||
ValueAllocator()
|
||||
: Base("DomValueAllocator", "Allocator for AZ::Dom::Value")
|
||||
{
|
||||
DisableOverriding();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace AZ
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(CompressorZStdData, AZ::SystemAllocator, 0);
|
||||
|
||||
CompressorZStdData(IAllocatorAllocate* zstdMemAllocator = 0)
|
||||
CompressorZStdData(IAllocator* zstdMemAllocator = 0)
|
||||
{
|
||||
m_zstd = zstdMemAllocator;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace AZ::IO::IStreamerTypes
|
||||
: m_allocator(AZ::AllocatorInstance<AZ::SystemAllocator>::Get())
|
||||
{}
|
||||
|
||||
DefaultRequestMemoryAllocator::DefaultRequestMemoryAllocator(AZ::IAllocatorAllocate& allocator)
|
||||
DefaultRequestMemoryAllocator::DefaultRequestMemoryAllocator(AZ::IAllocator& allocator)
|
||||
: m_allocator(allocator)
|
||||
{}
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ namespace AZ::IO::IStreamerTypes
|
||||
public:
|
||||
//! DefaultRequestMemoryAllocator wraps around the AZ::SystemAllocator by default.
|
||||
DefaultRequestMemoryAllocator();
|
||||
explicit DefaultRequestMemoryAllocator(AZ::IAllocatorAllocate& allocator);
|
||||
explicit DefaultRequestMemoryAllocator(AZ::IAllocator& allocator);
|
||||
~DefaultRequestMemoryAllocator() override;
|
||||
|
||||
void LockAllocator() override;
|
||||
@@ -151,7 +151,7 @@ namespace AZ::IO::IStreamerTypes
|
||||
private:
|
||||
AZStd::atomic_int m_lockCounter{ 0 };
|
||||
AZStd::atomic_int m_allocationCounter{ 0 };
|
||||
AZ::IAllocatorAllocate& m_allocator;
|
||||
AZ::IAllocator& m_allocator;
|
||||
};
|
||||
|
||||
// The following alignment functions are put here until they're available in AzCore's math library.
|
||||
|
||||
@@ -9,11 +9,12 @@
|
||||
#include <AzCore/Memory/Memory.h>
|
||||
#include <AzCore/Memory/AllocatorManager.h>
|
||||
|
||||
#define RECORDING_ENABLED 0
|
||||
// Only used to create recordings of memory operations to use for memory benchmarks
|
||||
#define O3DE_RECORDING_ENABLED 0
|
||||
|
||||
#if RECORDING_ENABLED
|
||||
#if O3DE_RECORDING_ENABLED
|
||||
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/containers/map.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/std/parallel/mutex.h>
|
||||
#include <AzCore/std/parallel/scoped_lock.h>
|
||||
@@ -62,23 +63,24 @@ namespace
|
||||
|
||||
static constexpr size_t s_maxNumberOfAllocationsToRecord = 16384;
|
||||
static size_t s_numberOfAllocationsRecorded = 0;
|
||||
static constexpr size_t s_allocationOperationCount = 5 * 1024;
|
||||
static constexpr size_t s_allocationOperationCount = 8 * 1024;
|
||||
static AZStd::array<AllocatorOperation, s_allocationOperationCount> s_operations = {};
|
||||
static uint64_t s_operationCounter = 0;
|
||||
|
||||
static unsigned int s_nextRecordId = 1;
|
||||
using AllocatorOperationByAddress = AZStd::unordered_map<void*, AllocatorOperation, AZStd::less<void*>, DebugAllocator>;
|
||||
using AllocatorOperationByAddress = AZStd::map<void*, AllocatorOperation, AZStd::less<void*>, DebugAllocator>;
|
||||
static AllocatorOperationByAddress s_allocatorOperationByAddress;
|
||||
using AvailableRecordIds = AZStd::vector<unsigned int, DebugAllocator>;
|
||||
AvailableRecordIds s_availableRecordIds;
|
||||
|
||||
void RecordAllocatorOperation(AllocatorOperation::OperationType type, void* ptr, size_t size = 0, size_t alignment = 0)
|
||||
{
|
||||
AZStd::scoped_lock<AZStd::mutex> lock(s_operationsMutex);
|
||||
AZStd::scoped_lock lock(s_operationsMutex);
|
||||
if (s_operationCounter == s_allocationOperationCount)
|
||||
{
|
||||
AZ::IO::SystemFile file;
|
||||
int mode = AZ::IO::SystemFile::OpenMode::SF_OPEN_APPEND | AZ::IO::SystemFile::OpenMode::SF_OPEN_WRITE_ONLY;
|
||||
// memoryrecordings.bin is being output to the current working directory
|
||||
if (!file.Exists("memoryrecordings.bin"))
|
||||
{
|
||||
mode |= AZ::IO::SystemFile::OpenMode::SF_OPEN_CREATE;
|
||||
@@ -158,8 +160,8 @@ namespace
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
AllocatorBase::AllocatorBase(IAllocatorAllocate* allocationSource, const char* name, const char* desc)
|
||||
: IAllocator(allocationSource)
|
||||
AllocatorBase::AllocatorBase(IAllocatorSchema* allocationSchema, const char* name, const char* desc)
|
||||
: IAllocator(allocationSchema)
|
||||
, m_name(name)
|
||||
, m_desc(desc)
|
||||
{
|
||||
@@ -184,11 +186,6 @@ namespace AZ
|
||||
return m_desc;
|
||||
}
|
||||
|
||||
IAllocatorAllocate* AllocatorBase::GetSchema()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Debug::AllocationRecords* AllocatorBase::GetRecords()
|
||||
{
|
||||
return m_records;
|
||||
@@ -205,11 +202,6 @@ namespace AZ
|
||||
return m_isReady;
|
||||
}
|
||||
|
||||
bool AllocatorBase::CanBeOverridden() const
|
||||
{
|
||||
return m_canBeOverridden;
|
||||
}
|
||||
|
||||
void AllocatorBase::PostCreate()
|
||||
{
|
||||
if (m_registrationEnabled)
|
||||
@@ -272,11 +264,6 @@ namespace AZ
|
||||
return m_isProfilingActive;
|
||||
}
|
||||
|
||||
void AllocatorBase::DisableOverriding()
|
||||
{
|
||||
m_canBeOverridden = false;
|
||||
}
|
||||
|
||||
void AllocatorBase::DisableRegistration()
|
||||
{
|
||||
m_registrationEnabled = false;
|
||||
@@ -285,10 +272,6 @@ namespace AZ
|
||||
void AllocatorBase::ProfileAllocation(
|
||||
void* ptr, size_t byteSize, size_t alignment, const char* name, const char* fileName, int lineNum, int suppressStackRecord)
|
||||
{
|
||||
#if defined(AZ_HAS_VARIADIC_TEMPLATES) && defined(AZ_DEBUG_BUILD)
|
||||
++suppressStackRecord; // one more for the fact the ebus is a function
|
||||
#endif // AZ_HAS_VARIADIC_TEMPLATES
|
||||
|
||||
if (m_isProfilingActive)
|
||||
{
|
||||
auto records = GetRecords();
|
||||
@@ -298,7 +281,7 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
#if RECORDING_ENABLED
|
||||
#if O3DE_RECORDING_ENABLED
|
||||
RecordAllocatorOperation(AllocatorOperation::ALLOCATE, ptr, byteSize, alignment);
|
||||
#endif
|
||||
}
|
||||
@@ -313,7 +296,7 @@ namespace AZ
|
||||
records->UnregisterAllocation(ptr, byteSize, alignment, info);
|
||||
}
|
||||
}
|
||||
#if RECORDING_ENABLED
|
||||
#if O3DE_RECORDING_ENABLED
|
||||
RecordAllocatorOperation(AllocatorOperation::DEALLOCATE, ptr, byteSize, alignment);
|
||||
#endif
|
||||
}
|
||||
@@ -330,7 +313,7 @@ namespace AZ
|
||||
ProfileDeallocation(ptr, 0, 0, &info);
|
||||
ProfileAllocation(newPtr, newSize, newAlignment, info.m_name, info.m_fileName, info.m_lineNum, 0);
|
||||
}
|
||||
#if RECORDING_ENABLED
|
||||
#if O3DE_RECORDING_ENABLED
|
||||
RecordAllocatorOperation(AllocatorOperation::DEALLOCATE, ptr);
|
||||
RecordAllocatorOperation(AllocatorOperation::ALLOCATE, newPtr, newSize, newAlignment);
|
||||
#endif
|
||||
@@ -351,7 +334,7 @@ namespace AZ
|
||||
records->ResizeAllocation(ptr, newSize);
|
||||
}
|
||||
}
|
||||
#if RECORDING_ENABLED
|
||||
#if O3DE_RECORDING_ENABLED
|
||||
RecordAllocatorOperation(AllocatorOperation::ALLOCATE, ptr, newSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace AZ
|
||||
class AllocatorBase : public IAllocator
|
||||
{
|
||||
protected:
|
||||
AllocatorBase(IAllocatorAllocate* allocationSource, const char* name, const char* desc);
|
||||
AllocatorBase(IAllocatorSchema* allocationSchema, const char* name, const char* desc);
|
||||
~AllocatorBase();
|
||||
|
||||
public:
|
||||
@@ -32,11 +32,9 @@ namespace AZ
|
||||
//---------------------------------------------------------------------
|
||||
const char* GetName() const override;
|
||||
const char* GetDescription() const override;
|
||||
IAllocatorAllocate* GetSchema() override;
|
||||
Debug::AllocationRecords* GetRecords() final;
|
||||
void SetRecords(Debug::AllocationRecords* records) final;
|
||||
bool IsReady() const final;
|
||||
bool CanBeOverridden() const final;
|
||||
void PostCreate() override;
|
||||
void PreDestroy() final;
|
||||
void SetLazilyCreated(bool lazy) final;
|
||||
@@ -68,10 +66,6 @@ namespace AZ
|
||||
return byteSize;
|
||||
}
|
||||
|
||||
/// Call to disallow this allocator from being overridden.
|
||||
/// Only kernel-level allocators where it would be especially problematic for them to be overridden should do this.
|
||||
void DisableOverriding();
|
||||
|
||||
/// Call to disallow this allocator from being registered with the AllocatorManager.
|
||||
/// Only kernel-level allocators where it would be especially problematic for them to be registered with the AllocatorManager should do this.
|
||||
void DisableRegistration();
|
||||
@@ -107,7 +101,6 @@ namespace AZ
|
||||
bool m_isLazilyCreated = false;
|
||||
bool m_isProfilingActive = false;
|
||||
bool m_isReady = false;
|
||||
bool m_canBeOverridden = true;
|
||||
bool m_registrationEnabled = true;
|
||||
};
|
||||
|
||||
|
||||
@@ -12,17 +12,12 @@
|
||||
|
||||
#include <AzCore/Memory/OSAllocator.h>
|
||||
#include <AzCore/Memory/AllocationRecords.h>
|
||||
#include <AzCore/Memory/AllocatorOverrideShim.h>
|
||||
#include <AzCore/Memory/MallocSchema.h>
|
||||
|
||||
#include <AzCore/std/parallel/lock.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/std/containers/array.h>
|
||||
|
||||
#if !defined(RELEASE) && !defined(AZCORE_MEMORY_ENABLE_OVERRIDES)
|
||||
# define AZCORE_MEMORY_ENABLE_OVERRIDES
|
||||
#endif
|
||||
|
||||
namespace AZ::Internal
|
||||
{
|
||||
struct AMStringHasher
|
||||
@@ -54,18 +49,6 @@ namespace AZ::Internal
|
||||
namespace AZ
|
||||
{
|
||||
|
||||
struct AllocatorManager::InternalData
|
||||
{
|
||||
explicit InternalData(const AZStdIAllocator& alloc)
|
||||
: m_allocatorMap(alloc)
|
||||
, m_remappings(alloc)
|
||||
, m_remappingsReverse(alloc)
|
||||
{}
|
||||
Internal::AllocatorNameMap m_allocatorMap;
|
||||
Internal::AllocatorRemappings m_remappings;
|
||||
Internal::AllocatorRemappings m_remappingsReverse;
|
||||
};
|
||||
|
||||
static EnvironmentVariable<AllocatorManager> s_allocManager = nullptr;
|
||||
static AllocatorManager* s_allocManagerDebug = nullptr; // For easier viewing in crash dumps
|
||||
|
||||
@@ -81,16 +64,6 @@ static Internal::PreEnvironmentAttachData& GetPreEnvironmentAttachData()
|
||||
void AllocatorManager::PreRegisterAllocator(IAllocator* allocator)
|
||||
{
|
||||
auto& data = GetPreEnvironmentAttachData();
|
||||
|
||||
#ifdef AZCORE_MEMORY_ENABLE_OVERRIDES
|
||||
// All allocators must switch to an OverrideEnabledAllocationSource proxy if they are to support allocator overriding.
|
||||
if (allocator->CanBeOverridden())
|
||||
{
|
||||
auto shim = Internal::AllocatorOverrideShim::Create(allocator, &data.m_mallocSchema);
|
||||
allocator->SetAllocationSource(shim);
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
AZStd::lock_guard<AZStd::mutex> lock(data.m_mutex);
|
||||
AZ_Assert(data.m_unregisteredAllocatorCount < Internal::PreEnvironmentAttachData::MAX_UNREGISTERED_ALLOCATORS, "Too many allocators trying to register before environment attached!");
|
||||
@@ -175,12 +148,9 @@ AllocatorManager::AllocatorManager()
|
||||
}
|
||||
)
|
||||
{
|
||||
m_overrideSource = nullptr;
|
||||
m_numAllocators = 0;
|
||||
m_isAllocatorLeaking = false;
|
||||
m_configurationFinalized = false;
|
||||
m_defaultTrackingRecordMode = Debug::AllocationRecords::RECORD_NO_RECORDS;
|
||||
m_data = new (m_mallocSchema->Allocate(sizeof(InternalData), AZStd::alignment_of<InternalData>::value, 0)) InternalData(AZStdIAllocator(m_mallocSchema.get()));
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -210,10 +180,6 @@ AllocatorManager::RegisterAllocator(class IAllocator* alloc)
|
||||
alloc->SetProfilingActive(m_profilingRefcount.load() > 0);
|
||||
|
||||
m_allocators[m_numAllocators++] = alloc;
|
||||
|
||||
#ifdef AZCORE_MEMORY_ENABLE_OVERRIDES
|
||||
ConfigureAllocatorOverrides(alloc);
|
||||
#endif
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -232,81 +198,12 @@ AllocatorManager::InternalDestroy()
|
||||
// Do not actually destroy the lazy allocator as it may have work to do during non-deterministic shutdown
|
||||
}
|
||||
|
||||
if (m_data)
|
||||
{
|
||||
m_data->~InternalData();
|
||||
m_mallocSchema->DeAllocate(m_data);
|
||||
m_data = nullptr;
|
||||
}
|
||||
|
||||
if (!m_isAllocatorLeaking)
|
||||
{
|
||||
AZ_Assert(m_numAllocators == 0, "There are still %d registered allocators!", m_numAllocators);
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// ConfigureAllocatorOverrides
|
||||
// [10/14/2018]
|
||||
//=========================================================================
|
||||
void
|
||||
AllocatorManager::ConfigureAllocatorOverrides(IAllocator* alloc)
|
||||
{
|
||||
auto record = m_data->m_allocatorMap.emplace(AZStd::piecewise_construct, AZStd::forward_as_tuple(alloc->GetName(), AZStdIAllocator(m_mallocSchema.get())), AZStd::forward_as_tuple(alloc));
|
||||
|
||||
// We only need to keep going if the allocator supports overrides.
|
||||
if (!alloc->CanBeOverridden())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!alloc->IsAllocationSourceChanged())
|
||||
{
|
||||
// All allocators must switch to an OverrideEnabledAllocationSource proxy if they are to support allocator overriding.
|
||||
auto overrideEnabled = Internal::AllocatorOverrideShim::Create(alloc, m_mallocSchema.get());
|
||||
alloc->SetAllocationSource(overrideEnabled);
|
||||
}
|
||||
|
||||
auto itr = m_data->m_remappings.find(record.first->first);
|
||||
|
||||
if (itr != m_data->m_remappings.end())
|
||||
{
|
||||
auto remapTo = m_data->m_allocatorMap.find(itr->second);
|
||||
|
||||
if (remapTo != m_data->m_allocatorMap.end())
|
||||
{
|
||||
static_cast<Internal::AllocatorOverrideShim*>(alloc->GetAllocationSource())->SetOverride(remapTo->second->GetOriginalAllocationSource());
|
||||
}
|
||||
}
|
||||
|
||||
itr = m_data->m_remappingsReverse.find(record.first->first);
|
||||
|
||||
if (itr != m_data->m_remappingsReverse.end())
|
||||
{
|
||||
auto remapFrom = m_data->m_allocatorMap.find(itr->second);
|
||||
|
||||
if (remapFrom != m_data->m_allocatorMap.end())
|
||||
{
|
||||
AZ_Assert(!m_configurationFinalized, "Allocators may only remap to allocators that have been created before configuration finalization");
|
||||
static_cast<Internal::AllocatorOverrideShim*>(remapFrom->second->GetAllocationSource())->SetOverride(alloc->GetOriginalAllocationSource());
|
||||
}
|
||||
}
|
||||
|
||||
if (m_overrideSource)
|
||||
{
|
||||
static_cast<Internal::AllocatorOverrideShim*>(alloc->GetAllocationSource())->SetOverride(m_overrideSource);
|
||||
}
|
||||
|
||||
if (m_configurationFinalized)
|
||||
{
|
||||
// We can get rid of the intermediary if configuration won't be changing any further.
|
||||
// (The creation of it at the top of this function was superflous, but it made it easier to set things up going through a single code path.)
|
||||
auto shim = static_cast<Internal::AllocatorOverrideShim*>(alloc->GetAllocationSource());
|
||||
alloc->SetAllocationSource(shim->GetOverride());
|
||||
Internal::AllocatorOverrideShim::Destroy(shim);
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// UnRegisterAllocator
|
||||
// [9/17/2009]
|
||||
@@ -365,7 +262,7 @@ AllocatorManager::GarbageCollect()
|
||||
|
||||
for (int i = 0; i < m_numAllocators; ++i)
|
||||
{
|
||||
m_allocators[i]->GetAllocationSource()->GarbageCollect();
|
||||
m_allocators[i]->GetSchema()->GarbageCollect();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -414,94 +311,6 @@ AllocatorManager::SetTrackingMode(Debug::AllocationRecords::Mode mode)
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// SetOverrideSchema
|
||||
// [8/17/2018]
|
||||
//=========================================================================
|
||||
void
|
||||
AllocatorManager::SetOverrideAllocatorSource(IAllocatorAllocate* source, bool overrideExistingAllocators)
|
||||
{
|
||||
(void)source;
|
||||
(void)overrideExistingAllocators;
|
||||
|
||||
#ifdef AZCORE_MEMORY_ENABLE_OVERRIDES
|
||||
AZ_Assert(!m_configurationFinalized, "You cannot set an allocator source after FinalizeConfiguration() has been called.");
|
||||
m_overrideSource = source;
|
||||
|
||||
if (overrideExistingAllocators)
|
||||
{
|
||||
AZStd::lock_guard<AZStd::mutex> lock(m_allocatorListMutex);
|
||||
for (int i = 0; i < m_numAllocators; ++i)
|
||||
{
|
||||
if (m_allocators[i]->CanBeOverridden())
|
||||
{
|
||||
auto shim = static_cast<Internal::AllocatorOverrideShim*>(m_allocators[i]->GetAllocationSource());
|
||||
shim->SetOverride(source);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// AddAllocatorRemapping
|
||||
// [8/27/2018]
|
||||
//=========================================================================
|
||||
void
|
||||
AllocatorManager::AddAllocatorRemapping(const char* fromName, const char* toName)
|
||||
{
|
||||
(void)fromName;
|
||||
(void)toName;
|
||||
|
||||
#ifdef AZCORE_MEMORY_ENABLE_OVERRIDES
|
||||
AZ_Assert(!m_configurationFinalized, "You cannot set an allocator remapping after FinalizeConfiguration() has been called.");
|
||||
m_data->m_remappings.emplace(AZStd::piecewise_construct, AZStd::forward_as_tuple(fromName, m_mallocSchema.get()), AZStd::forward_as_tuple(toName, m_mallocSchema.get()));
|
||||
m_data->m_remappingsReverse.emplace(AZStd::piecewise_construct, AZStd::forward_as_tuple(toName, m_mallocSchema.get()), AZStd::forward_as_tuple(fromName, m_mallocSchema.get()));
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
AllocatorManager::FinalizeConfiguration()
|
||||
{
|
||||
if (m_configurationFinalized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef AZCORE_MEMORY_ENABLE_OVERRIDES
|
||||
{
|
||||
AZStd::lock_guard<AZStd::mutex> lock(m_allocatorListMutex);
|
||||
|
||||
for (int i = 0; i < m_numAllocators; ++i)
|
||||
{
|
||||
if (!m_allocators[i]->CanBeOverridden())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto shim = static_cast<Internal::AllocatorOverrideShim*>(m_allocators[i]->GetAllocationSource());
|
||||
|
||||
if (!shim->IsOverridden())
|
||||
{
|
||||
m_allocators[i]->ResetAllocationSource();
|
||||
Internal::AllocatorOverrideShim::Destroy(shim);
|
||||
}
|
||||
else if (!shim->HasOrphanedAllocations())
|
||||
{
|
||||
m_allocators[i]->SetAllocationSource(shim->GetOverride());
|
||||
Internal::AllocatorOverrideShim::Destroy(shim);
|
||||
}
|
||||
else
|
||||
{
|
||||
shim->SetFinalizedConfiguration();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
m_configurationFinalized = true;
|
||||
}
|
||||
|
||||
void
|
||||
AllocatorManager::EnterProfilingMode()
|
||||
{
|
||||
@@ -545,27 +354,18 @@ AllocatorManager::DumpAllocators()
|
||||
size_t totalConsumedBytes = 0;
|
||||
|
||||
memset(m_dumpInfo, 0, sizeof(m_dumpInfo));
|
||||
void* sourceList[m_maxNumAllocators];
|
||||
|
||||
AZ_Printf(TAG, "%d allocators active\n", m_numAllocators);
|
||||
AZ_Printf(TAG, "Index,Name,Used kb,Reserved kb,Consumed kb\n");
|
||||
|
||||
for (int i = 0; i < m_numAllocators; i++)
|
||||
{
|
||||
auto allocator = m_allocators[i];
|
||||
auto source = allocator->GetAllocationSource();
|
||||
IAllocator* allocator = GetAllocator(i);
|
||||
const char* name = allocator->GetName();
|
||||
size_t usedBytes = source->NumAllocatedBytes();
|
||||
size_t reservedBytes = source->Capacity();
|
||||
size_t usedBytes = allocator->NumAllocatedBytes();
|
||||
size_t reservedBytes = allocator->Capacity();
|
||||
size_t consumedBytes = reservedBytes;
|
||||
|
||||
// Very hacky and inefficient check to see if this allocator obtains its memory from another allocator
|
||||
sourceList[i] = source;
|
||||
if (AZStd::find(sourceList, sourceList + i, allocator->GetSchema()) != sourceList + i)
|
||||
{
|
||||
consumedBytes = 0;
|
||||
}
|
||||
|
||||
totalUsedBytes += usedBytes;
|
||||
totalReservedBytes += reservedBytes;
|
||||
totalConsumedBytes += consumedBytes;
|
||||
@@ -585,61 +385,21 @@ void AllocatorManager::GetAllocatorStats(size_t& allocatedBytes, size_t& capacit
|
||||
|
||||
AZStd::lock_guard<AZStd::mutex> lock(m_allocatorListMutex);
|
||||
const int allocatorCount = GetNumAllocators();
|
||||
AZStd::unordered_map<IAllocatorAllocate*, IAllocator*> existingAllocators;
|
||||
AZStd::unordered_map<IAllocatorAllocate*, IAllocator*> sourcesToAllocators;
|
||||
|
||||
// Build a mapping of original allocator sources to their allocators
|
||||
for (int i = 0; i < allocatorCount; ++i)
|
||||
{
|
||||
IAllocator* allocator = GetAllocator(i);
|
||||
sourcesToAllocators.emplace(allocator->GetOriginalAllocationSource(), allocator);
|
||||
}
|
||||
|
||||
for (int i = 0; i < allocatorCount; ++i)
|
||||
{
|
||||
IAllocator* allocator = GetAllocator(i);
|
||||
IAllocatorAllocate* source = allocator->GetAllocationSource();
|
||||
IAllocatorAllocate* originalSource = allocator->GetOriginalAllocationSource();
|
||||
IAllocatorAllocate* schema = allocator->GetSchema();
|
||||
IAllocator* alias = (source != originalSource) ? sourcesToAllocators[source] : nullptr;
|
||||
|
||||
if (schema && !alias)
|
||||
{
|
||||
// Check to see if this allocator's source maps to another allocator
|
||||
// Need to check both the schema and the allocator itself, as either one might be used as the alias depending on how it's implemented
|
||||
AZStd::array<IAllocatorAllocate*, 2> checkAllocators = { { schema, allocator->GetAllocationSource() } };
|
||||
|
||||
for (IAllocatorAllocate* check : checkAllocators)
|
||||
{
|
||||
auto existing = existingAllocators.emplace(check, allocator);
|
||||
|
||||
if (!existing.second)
|
||||
{
|
||||
alias = existing.first->second;
|
||||
// Do not break out of the loop as we need to add to the map for all entries
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const IAllocator* OS_ALLOCATOR = &AllocatorInstance<OSAllocator>::GetAllocator();
|
||||
size_t sourceAllocatedBytes = source->NumAllocatedBytes();
|
||||
size_t sourceCapacityBytes = source->Capacity();
|
||||
|
||||
if (allocator == OS_ALLOCATOR)
|
||||
{
|
||||
// Need to special case the OS allocator because its capacity is a made-up number. Better to just use the allocated amount, it will hopefully be small anyway.
|
||||
sourceCapacityBytes = sourceAllocatedBytes;
|
||||
}
|
||||
|
||||
allocatedBytes += allocator->NumAllocatedBytes();
|
||||
capacityBytes += allocator->Capacity();
|
||||
|
||||
if (outStats)
|
||||
{
|
||||
outStats->emplace(outStats->end(), allocator->GetName(), alias ? alias->GetName() : allocator->GetDescription(), sourceAllocatedBytes, sourceCapacityBytes, alias != nullptr);
|
||||
}
|
||||
|
||||
if (!alias)
|
||||
{
|
||||
allocatedBytes += sourceAllocatedBytes;
|
||||
capacityBytes += sourceCapacityBytes;
|
||||
outStats->emplace(outStats->end(),
|
||||
allocator->GetName(),
|
||||
allocator->GetDescription(),
|
||||
allocator->NumAllocatedBytes(),
|
||||
allocator->Capacity());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,17 +87,6 @@ namespace AZ
|
||||
/// Especially for great code and engines...
|
||||
void SetAllocatorLeaking(bool allowLeaking) { m_isAllocatorLeaking = allowLeaking; }
|
||||
|
||||
/// Set an override allocator
|
||||
/// All allocators registered with the AllocatorManager will automatically redirect to this allocator
|
||||
/// if set.
|
||||
void SetOverrideAllocatorSource(IAllocatorAllocate* source, bool overrideExistingAllocators = true);
|
||||
|
||||
/// Retrieve the override schema
|
||||
IAllocatorAllocate* GetOverrideAllocatorSource() const { return m_overrideSource; }
|
||||
|
||||
void AddAllocatorRemapping(const char* fromName, const char* toName);
|
||||
void FinalizeConfiguration();
|
||||
|
||||
/// Enter or exit profiling mode; calls to Enter must be matched with calls to Exit
|
||||
void EnterProfilingMode();
|
||||
void ExitProfilingMode();
|
||||
@@ -116,19 +105,17 @@ namespace AZ
|
||||
|
||||
struct AllocatorStats
|
||||
{
|
||||
AllocatorStats(const char* name, const char* aliasOrDescription, size_t allocatedBytes, size_t capacityBytes, bool isAlias)
|
||||
AllocatorStats(const char* name, const char* aliasOrDescription, size_t allocatedBytes, size_t capacityBytes)
|
||||
: m_name(name)
|
||||
, m_aliasOrDescription(aliasOrDescription)
|
||||
, m_allocatedBytes(allocatedBytes)
|
||||
, m_capacityBytes(capacityBytes)
|
||||
, m_isAlias(isAlias)
|
||||
{}
|
||||
|
||||
AZStd::string m_name;
|
||||
AZStd::string m_aliasOrDescription;
|
||||
size_t m_allocatedBytes;
|
||||
size_t m_capacityBytes;
|
||||
bool m_isAlias;
|
||||
};
|
||||
|
||||
void GetAllocatorStats(size_t& usedBytes, size_t& reservedBytes, AZStd::vector<AllocatorStats>* outStats = nullptr);
|
||||
@@ -160,7 +147,6 @@ namespace AZ
|
||||
|
||||
private:
|
||||
void InternalDestroy();
|
||||
void ConfigureAllocatorOverrides(IAllocator* alloc);
|
||||
void DebugBreak(void* address, const Debug::AllocationInfo& info);
|
||||
AZ::MallocSchema* CreateMallocSchema();
|
||||
|
||||
@@ -175,14 +161,9 @@ namespace AZ
|
||||
MemoryBreak m_memoryBreak[MaxNumMemoryBreaks];
|
||||
char m_activeBreaks;
|
||||
AZStd::mutex m_allocatorListMutex;
|
||||
IAllocatorAllocate* m_overrideSource;
|
||||
|
||||
DumpInfo m_dumpInfo[m_maxNumAllocators];
|
||||
|
||||
struct InternalData;
|
||||
|
||||
InternalData* m_data;
|
||||
bool m_configurationFinalized;
|
||||
AZStd::atomic<int> m_profilingRefcount;
|
||||
|
||||
AZ::Debug::AllocationRecords::Mode m_defaultTrackingRecordMode;
|
||||
|
||||
@@ -1,227 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Memory/AllocatorOverrideShim.h>
|
||||
|
||||
namespace AZ::Internal
|
||||
{
|
||||
AllocatorOverrideShim* AllocatorOverrideShim::Create(IAllocator* owningAllocator, IAllocatorAllocate* shimAllocationSource)
|
||||
{
|
||||
void* memory = shimAllocationSource->Allocate(sizeof(AllocatorOverrideShim), AZStd::alignment_of<AllocatorOverrideShim>::value, 0);
|
||||
auto result = new (memory) AllocatorOverrideShim(owningAllocator, shimAllocationSource);
|
||||
return result;
|
||||
}
|
||||
|
||||
void AllocatorOverrideShim::Destroy(AllocatorOverrideShim* source)
|
||||
{
|
||||
auto shimAllocationSource = source->m_shimAllocationSource;
|
||||
source->~AllocatorOverrideShim();
|
||||
shimAllocationSource->DeAllocate(source);
|
||||
}
|
||||
|
||||
AllocatorOverrideShim::AllocatorOverrideShim(IAllocator* owningAllocator, IAllocatorAllocate* shimAllocationSource)
|
||||
: m_owningAllocator(owningAllocator)
|
||||
, m_source(owningAllocator->GetOriginalAllocationSource())
|
||||
, m_overridingSource(owningAllocator->GetOriginalAllocationSource())
|
||||
, m_shimAllocationSource(shimAllocationSource)
|
||||
, m_records(typename AllocationSet::hasher(), typename AllocationSet::key_eq(), StdAllocationSrc(shimAllocationSource))
|
||||
{
|
||||
}
|
||||
|
||||
void AllocatorOverrideShim::SetOverride(IAllocatorAllocate* source)
|
||||
{
|
||||
m_overridingSource = source;
|
||||
}
|
||||
|
||||
IAllocatorAllocate* AllocatorOverrideShim::GetOverride() const
|
||||
{
|
||||
return m_overridingSource;
|
||||
}
|
||||
|
||||
bool AllocatorOverrideShim::IsOverridden() const
|
||||
{
|
||||
return m_source != m_overridingSource;
|
||||
}
|
||||
|
||||
bool AllocatorOverrideShim::HasOrphanedAllocations() const
|
||||
{
|
||||
return !m_records.empty();
|
||||
}
|
||||
|
||||
void AllocatorOverrideShim::SetFinalizedConfiguration()
|
||||
{
|
||||
m_finalizedConfiguration = true;
|
||||
}
|
||||
|
||||
typename AllocatorOverrideShim::pointer_type AllocatorOverrideShim::Allocate(size_type byteSize, size_type alignment, int flags, const char* name, const char* fileName, int lineNum, unsigned int suppressStackRecord)
|
||||
{
|
||||
pointer_type ptr = m_overridingSource->Allocate(byteSize, alignment, flags, name, fileName, lineNum, suppressStackRecord);
|
||||
|
||||
if (!IsOverridden())
|
||||
{
|
||||
lock_type lock(m_mutex);
|
||||
m_records.insert(ptr); // Record in case we need to orphan this allocation later
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void AllocatorOverrideShim::DeAllocate(pointer_type ptr, size_type byteSize, size_type alignment)
|
||||
{
|
||||
IAllocatorAllocate* source = m_overridingSource;
|
||||
bool destroy = false;
|
||||
|
||||
{
|
||||
lock_type lock(m_mutex);
|
||||
|
||||
// Check to see if this came from a prior allocation source
|
||||
if (m_records.erase(ptr) && IsOverridden())
|
||||
{
|
||||
source = m_source;
|
||||
|
||||
if (m_records.empty() && m_finalizedConfiguration)
|
||||
{
|
||||
// All orphaned records are gone; we are no longer needed
|
||||
m_owningAllocator->SetAllocationSource(m_overridingSource);
|
||||
destroy = true; // Must destroy outside the lock
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
source->DeAllocate(ptr, byteSize, alignment);
|
||||
|
||||
if (destroy)
|
||||
{
|
||||
Destroy(this);
|
||||
}
|
||||
}
|
||||
|
||||
typename AllocatorOverrideShim::size_type AllocatorOverrideShim::Resize(pointer_type ptr, size_type newSize)
|
||||
{
|
||||
IAllocatorAllocate* source = m_overridingSource;
|
||||
|
||||
if (IsOverridden())
|
||||
{
|
||||
// Determine who owns the allocation
|
||||
lock_type lock(m_mutex);
|
||||
|
||||
if (m_records.count(ptr))
|
||||
{
|
||||
source = m_source;
|
||||
}
|
||||
}
|
||||
|
||||
size_t result = source->Resize(ptr, newSize);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
typename AllocatorOverrideShim::pointer_type AllocatorOverrideShim::ReAllocate(pointer_type ptr, size_type newSize, size_type newAlignment)
|
||||
{
|
||||
pointer_type newPtr = nullptr;
|
||||
bool useOverride = true;
|
||||
bool destroy = false;
|
||||
|
||||
if (IsOverridden())
|
||||
{
|
||||
lock_type lock(m_mutex);
|
||||
|
||||
if (m_records.erase(ptr))
|
||||
{
|
||||
// An old allocation needs to be transferred to the new, overriding allocator.
|
||||
useOverride = false; // We'll do the reallocation here
|
||||
size_t oldSize = m_source->AllocationSize(ptr);
|
||||
|
||||
if (newSize)
|
||||
{
|
||||
newPtr = m_overridingSource->Allocate(newSize, newAlignment, 0);
|
||||
memcpy(newPtr, ptr, AZStd::min(newSize, oldSize));
|
||||
}
|
||||
|
||||
m_source->DeAllocate(ptr, oldSize);
|
||||
|
||||
if (m_records.empty() && m_finalizedConfiguration)
|
||||
{
|
||||
// All orphaned records are gone; we are no longer needed
|
||||
m_owningAllocator->SetAllocationSource(m_overridingSource);
|
||||
destroy = true; // Must destroy outside the lock
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (useOverride)
|
||||
{
|
||||
// Default behavior, we weren't deleting an old allocation
|
||||
newPtr = m_overridingSource->ReAllocate(ptr, newSize, newAlignment);
|
||||
|
||||
if (!IsOverridden())
|
||||
{
|
||||
// Still need to do bookkeeping if we haven't been overridden yet
|
||||
lock_type lock(m_mutex);
|
||||
m_records.erase(ptr);
|
||||
m_records.insert(newPtr);
|
||||
}
|
||||
}
|
||||
|
||||
if (destroy)
|
||||
{
|
||||
Destroy(this);
|
||||
}
|
||||
|
||||
return newPtr;
|
||||
}
|
||||
|
||||
typename AllocatorOverrideShim::size_type AllocatorOverrideShim::AllocationSize(pointer_type ptr)
|
||||
{
|
||||
IAllocatorAllocate* source = m_overridingSource;
|
||||
|
||||
if (IsOverridden())
|
||||
{
|
||||
// Determine who owns the allocation
|
||||
lock_type lock(m_mutex);
|
||||
|
||||
if (m_records.count(ptr))
|
||||
{
|
||||
source = m_source;
|
||||
}
|
||||
}
|
||||
|
||||
return source->AllocationSize(ptr);
|
||||
}
|
||||
|
||||
void AllocatorOverrideShim::GarbageCollect()
|
||||
{
|
||||
m_source->GarbageCollect();
|
||||
}
|
||||
|
||||
typename AllocatorOverrideShim::size_type AllocatorOverrideShim::NumAllocatedBytes() const
|
||||
{
|
||||
return m_source->NumAllocatedBytes();
|
||||
}
|
||||
|
||||
typename AllocatorOverrideShim::size_type AllocatorOverrideShim::Capacity() const
|
||||
{
|
||||
return m_source->Capacity();
|
||||
}
|
||||
|
||||
typename AllocatorOverrideShim::size_type AllocatorOverrideShim::GetMaxAllocationSize() const
|
||||
{
|
||||
return m_source->GetMaxAllocationSize();
|
||||
}
|
||||
|
||||
auto AllocatorOverrideShim::GetMaxContiguousAllocationSize() const -> size_type
|
||||
{
|
||||
return m_source->GetMaxContiguousAllocationSize();
|
||||
}
|
||||
|
||||
IAllocatorAllocate* AllocatorOverrideShim::GetSubAllocator()
|
||||
{
|
||||
return m_source->GetSubAllocator();
|
||||
}
|
||||
|
||||
} // namespace AZ::Internal
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Memory/Memory.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/std/parallel/mutex.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class AllocatorManager;
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
/**
|
||||
* A shim schema that solves the problem of overriding lazily-created allocators especially, that perform allocations before the override happens.
|
||||
*
|
||||
* Any allocator that *might* be overridden at some point must have this shim installed as its allocation source. This is done automatically by
|
||||
* the AllocationManager; you generally do not have to interact with this shim directly at all.
|
||||
*
|
||||
* The shim will keep track of any allocations that occur, and if the allocator gets overridden it will ensure that prior allocations are
|
||||
* deallocated with the old schema rather than the new one.
|
||||
*
|
||||
* There is some performance cost to this intrusion, however, in most cases it's only temporary:
|
||||
* * Once the application calls FinalizeConfiguration(), any non-overridden allocators will have their shims destroyed.
|
||||
* * Any overridden allocators that do not have prior allocations will have their shims destroyed.
|
||||
* * Any overridden allocator will automatically destroy its shim once the last of the prior allocations has been deallocated.
|
||||
*
|
||||
* Note that an allocator that gets overridden but has prior allocations that it never intends to deallocate (such as file-level statics that never
|
||||
* get changed) will keep its shim indefinitely. This is an unfortunate cost but only affects those allocators if they are being overridden.
|
||||
*/
|
||||
class AllocatorOverrideShim
|
||||
: public IAllocatorAllocate
|
||||
{
|
||||
friend AllocatorManager;
|
||||
|
||||
public:
|
||||
//---------------------------------------------------------------------
|
||||
// IAllocator implementation
|
||||
//---------------------------------------------------------------------
|
||||
pointer_type Allocate(size_type byteSize, size_type alignment, int flags = 0, const char* name = nullptr, const char* fileName = nullptr, int lineNum = 0, unsigned int suppressStackRecord = 0) override;
|
||||
void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) override;
|
||||
size_type Resize(pointer_type ptr, size_type newSize) override;
|
||||
pointer_type ReAllocate(pointer_type ptr, size_type newSize, size_type newAlignment) override;
|
||||
size_type AllocationSize(pointer_type ptr) override;
|
||||
void GarbageCollect() override;
|
||||
size_type NumAllocatedBytes() const override;
|
||||
size_type Capacity() const override;
|
||||
size_type GetMaxAllocationSize() const override;
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
IAllocatorAllocate* GetSubAllocator() override;
|
||||
|
||||
private:
|
||||
/// Creates a shim using a custom memory source
|
||||
static AllocatorOverrideShim* Create(IAllocator* owningAllocator, IAllocatorAllocate* shimAllocationSource);
|
||||
static void Destroy(AllocatorOverrideShim* source);
|
||||
|
||||
AllocatorOverrideShim(IAllocator* owningAllocator, IAllocatorAllocate* shimAllocationSource);
|
||||
|
||||
/// Overrides the shim's memory source with a different memory source.
|
||||
void SetOverride(IAllocatorAllocate* source);
|
||||
|
||||
/// Returns the override source.
|
||||
IAllocatorAllocate* GetOverride() const;
|
||||
|
||||
/// Returns true if the shim has an override source set on it.
|
||||
bool IsOverridden() const;
|
||||
|
||||
/// Returns true if there are orphaned allocations from before the shim had its override set.
|
||||
bool HasOrphanedAllocations() const;
|
||||
|
||||
/// Called by the AllocatorManager to signify that the configuration has been finalized by the application.
|
||||
void SetFinalizedConfiguration();
|
||||
|
||||
private:
|
||||
class StdAllocationSrc : public AZStdIAllocator
|
||||
{
|
||||
public:
|
||||
StdAllocationSrc(IAllocatorAllocate* schema = nullptr) : AZStdIAllocator(schema)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
typedef AZStd::mutex mutex_type;
|
||||
typedef AZStd::lock_guard<mutex_type> lock_type;
|
||||
typedef AZStd::unordered_set<void*, AZStd::hash<void*>, AZStd::equal_to<void*>, StdAllocationSrc> AllocationSet;
|
||||
|
||||
IAllocator* m_owningAllocator;
|
||||
IAllocatorAllocate* m_source;
|
||||
IAllocatorAllocate* m_overridingSource;
|
||||
IAllocatorAllocate* m_shimAllocationSource;
|
||||
AllocationSet m_records;
|
||||
mutex_type m_mutex;
|
||||
bool m_finalizedConfiguration = false;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -20,8 +20,7 @@ namespace AZ
|
||||
// [1/28/2011]
|
||||
//=========================================================================
|
||||
BestFitExternalMapAllocator::BestFitExternalMapAllocator()
|
||||
: AllocatorBase(this, "BestFitExternalMapAllocator", "Best fit allocator with external tracking storage!")
|
||||
, m_schema(nullptr)
|
||||
: AllocatorBase(nullptr, "BestFitExternalMapAllocator", "Best fit allocator with external tracking storage!")
|
||||
{
|
||||
}
|
||||
|
||||
@@ -182,13 +181,4 @@ namespace AZ
|
||||
return m_schema->GetMaxContiguousAllocationSize();
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// GetSubAllocator
|
||||
// [1/28/2011]
|
||||
//=========================================================================
|
||||
IAllocatorAllocate* BestFitExternalMapAllocator::GetSubAllocator()
|
||||
{
|
||||
return m_schema->GetSubAllocator();
|
||||
}
|
||||
|
||||
} // namespace AZ
|
||||
|
||||
@@ -19,7 +19,6 @@ namespace AZ
|
||||
*/
|
||||
class BestFitExternalMapAllocator
|
||||
: public AllocatorBase
|
||||
, public IAllocatorAllocate
|
||||
{
|
||||
public:
|
||||
AZ_TYPE_INFO(BestFitExternalMapAllocator, "{36266C8B-9A2C-4E3E-9812-3DB260868A2B}")
|
||||
@@ -37,7 +36,7 @@ namespace AZ
|
||||
static const int m_memoryBlockAlignment = 16;
|
||||
void* m_memoryBlock; ///< Pointer to memory to allocate from. Can be uncached.
|
||||
unsigned int m_memoryBlockByteSize; ///< Sizes if the memory block.
|
||||
IAllocatorAllocate* m_mapAllocator; ///< Allocator for the free chunks map. If null the SystemAllocator will be used.
|
||||
IAllocator* m_mapAllocator; ///< Allocator for the free chunks map. If null the SystemAllocator will be used.
|
||||
|
||||
bool m_allocationRecords; ///< True if we want to track memory allocations, otherwise false.
|
||||
unsigned char m_stackRecordLevels; ///< If stack recording is enabled, how many stack levels to record.
|
||||
@@ -52,7 +51,7 @@ namespace AZ
|
||||
AllocatorDebugConfig GetDebugConfig() override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// IAllocatorAllocate
|
||||
// IAllocatorSchema
|
||||
pointer_type Allocate(size_type byteSize, size_type alignment, int flags = 0, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) override;
|
||||
void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) override;
|
||||
size_type Resize(pointer_type ptr, size_type newSize) override;
|
||||
@@ -63,7 +62,6 @@ namespace AZ
|
||||
size_type Capacity() const override;
|
||||
size_type GetMaxAllocationSize() const override;
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
IAllocatorAllocate* GetSubAllocator() override;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected:
|
||||
@@ -71,7 +69,6 @@ namespace AZ
|
||||
BestFitExternalMapAllocator& operator=(const BestFitExternalMapAllocator&);
|
||||
|
||||
Descriptor m_desc;
|
||||
BestFitExternalMapSchema* m_schema;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -42,9 +42,15 @@ namespace AZ
|
||||
// Allocate
|
||||
// [1/28/2011]
|
||||
//=========================================================================
|
||||
BestFitExternalMapSchema::pointer_type BestFitExternalMapSchema::Allocate(size_type byteSize, size_type alignment, int flags)
|
||||
BestFitExternalMapSchema::pointer_type BestFitExternalMapSchema::Allocate(
|
||||
size_type byteSize,
|
||||
size_type alignment,
|
||||
[[maybe_unused]] int flags,
|
||||
[[maybe_unused]] const char* name,
|
||||
[[maybe_unused]] const char* fileName,
|
||||
[[maybe_unused]] int lineNum,
|
||||
[[maybe_unused]] unsigned int suppressStackRecord)
|
||||
{
|
||||
(void)flags;
|
||||
char* address = nullptr;
|
||||
AZ_Assert(alignment > 0 && (alignment & (alignment - 1)) == 0, "Alignment must be >0 and power of 2!");
|
||||
for (int i = 0; i < 2; ++i) // max 2 attempts to allocate
|
||||
@@ -96,7 +102,7 @@ namespace AZ
|
||||
// DeAllocate
|
||||
// [1/28/2011]
|
||||
//=========================================================================
|
||||
void BestFitExternalMapSchema::DeAllocate(pointer_type ptr)
|
||||
void BestFitExternalMapSchema::DeAllocate(pointer_type ptr, [[maybe_unused]] size_type byteSize, [[maybe_unused]] size_type alignment)
|
||||
{
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
@@ -125,6 +131,18 @@ namespace AZ
|
||||
return 0;
|
||||
}
|
||||
|
||||
BestFitExternalMapSchema::size_type BestFitExternalMapSchema::Resize(pointer_type, size_type)
|
||||
{
|
||||
AZ_Assert(false, "%s unsupported", AZ_FUNCTION_SIGNATURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
BestFitExternalMapSchema::pointer_type BestFitExternalMapSchema::ReAllocate(pointer_type, size_type, size_type)
|
||||
{
|
||||
AZ_Assert(false, "%s unsupported", AZ_FUNCTION_SIGNATURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// GetMaxAllocationSize
|
||||
// [1/28/2011]
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace AZ
|
||||
* External map allows us to use this allocator with uncached memory,
|
||||
* because the tracking node is stored outside the main chunk.
|
||||
*/
|
||||
class BestFitExternalMapSchema
|
||||
class BestFitExternalMapSchema : public IAllocatorSchema
|
||||
{
|
||||
public:
|
||||
typedef void* pointer_type;
|
||||
@@ -44,26 +44,27 @@ namespace AZ
|
||||
static const int m_memoryBlockAlignment = 16;
|
||||
void* m_memoryBlock; ///< Pointer to memory to allocate from. Can be uncached.
|
||||
unsigned int m_memoryBlockByteSize; ///< Sizes if the memory block.
|
||||
IAllocatorAllocate* m_mapAllocator; ///< Allocator for the free chunks map. If null the SystemAllocator will be used.
|
||||
IAllocator* m_mapAllocator; ///< Allocator for the free chunks map. If null the SystemAllocator will be used.
|
||||
};
|
||||
|
||||
BestFitExternalMapSchema(const Descriptor& desc);
|
||||
|
||||
pointer_type Allocate(size_type byteSize, size_type alignment, int flags);
|
||||
void DeAllocate(pointer_type ptr);
|
||||
size_type AllocationSize(pointer_type ptr);
|
||||
pointer_type Allocate(size_type byteSize, size_type alignment, int flags = 0, const char* name = nullptr, const char* fileName = nullptr, int lineNum = 0, unsigned int suppressStackRecord = 0) override;
|
||||
void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) override;
|
||||
size_type Resize(pointer_type ptr, size_type newSize) override;
|
||||
pointer_type ReAllocate(pointer_type ptr, size_type newSize, size_type newAlignment) override;
|
||||
size_type AllocationSize(pointer_type ptr) override;
|
||||
|
||||
AZ_FORCE_INLINE size_type NumAllocatedBytes() const { return m_used; }
|
||||
AZ_FORCE_INLINE size_type Capacity() const { return m_desc.m_memoryBlockByteSize; }
|
||||
size_type GetMaxAllocationSize() const;
|
||||
size_type GetMaxContiguousAllocationSize() const;
|
||||
AZ_FORCE_INLINE IAllocatorAllocate* GetSubAllocator() const { return m_desc.m_mapAllocator; }
|
||||
AZ_FORCE_INLINE size_type NumAllocatedBytes() const override { return m_used; }
|
||||
AZ_FORCE_INLINE size_type Capacity() const override { return m_desc.m_memoryBlockByteSize; }
|
||||
size_type GetMaxAllocationSize() const override;
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
|
||||
/**
|
||||
* Since we don't consolidate chucnks at free time (too expensive) we will do it as we need or when we can't
|
||||
* Since we don't consolidate chunks at free time (too expensive) we will do it as we need or when we can't
|
||||
* allocate memory. This function is at least O(nlogn) where 'n' are the free chunks.
|
||||
*/
|
||||
void GarbageCollect();
|
||||
void GarbageCollect() override;
|
||||
|
||||
private:
|
||||
AZ_FORCE_INLINE size_type ChunckSize(pointer_type ptr);
|
||||
|
||||
@@ -107,7 +107,6 @@ namespace AZ
|
||||
m_used = 0;
|
||||
|
||||
m_desc = desc;
|
||||
m_subAllocator = nullptr;
|
||||
|
||||
for (int i = 0; i < Descriptor::m_maxNumBlocks; ++i)
|
||||
{
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace AZ
|
||||
* Internally uses use dlmalloc or version of it (nedmalloc, ptmalloc3).
|
||||
*/
|
||||
class HeapSchema
|
||||
: public IAllocatorAllocate
|
||||
: public IAllocatorSchema
|
||||
{
|
||||
public:
|
||||
typedef void* pointer_type;
|
||||
@@ -52,7 +52,6 @@ namespace AZ
|
||||
size_type Capacity() const override { return m_capacity; }
|
||||
size_type GetMaxAllocationSize() const override;
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
IAllocatorAllocate* GetSubAllocator() override { return m_subAllocator; }
|
||||
void GarbageCollect() override {}
|
||||
|
||||
private:
|
||||
@@ -62,7 +61,7 @@ namespace AZ
|
||||
Descriptor m_desc;
|
||||
size_type m_capacity; ///< Capacity in bytes.
|
||||
size_type m_used; ///< Number of bytes in use.
|
||||
IAllocatorAllocate* m_subAllocator;
|
||||
IAllocatorSchema* m_subAllocator;
|
||||
bool m_ownMemoryBlock[Descriptor::m_maxNumBlocks];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1081,7 +1081,7 @@ namespace AZ {
|
||||
const size_t m_treePageAlignment;
|
||||
const size_t m_poolPageSize;
|
||||
bool m_isPoolAllocations;
|
||||
IAllocatorAllocate* m_subAllocator;
|
||||
IAllocatorSchema* m_subAllocator;
|
||||
|
||||
#if !defined (USE_MUTEX_PER_BUCKET)
|
||||
mutable AZStd::mutex m_mutex;
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace AZ
|
||||
* Heap allocator schema, based on Dimitar Lazarov "High Performance Heap Allocator".
|
||||
*/
|
||||
class HphaSchema
|
||||
: public IAllocatorAllocate
|
||||
: public IAllocatorSchema
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@@ -47,7 +47,7 @@ namespace AZ
|
||||
unsigned int m_isPoolAllocations : 1; ///< True to allow allocations from pools, otherwise false.
|
||||
size_t m_fixedMemoryBlockByteSize; ///< Memory block size, if 0 we use the OS memory allocation functions.
|
||||
void* m_fixedMemoryBlock; ///< Can be NULL if so the we will allocate memory from the subAllocator if m_memoryBlocksByteSize is != 0.
|
||||
IAllocatorAllocate* m_subAllocator; ///< Allocator that m_memoryBlocks memory was allocated from or should be allocated (if NULL).
|
||||
IAllocatorSchema* m_subAllocator; ///< Allocator that m_memoryBlocks memory was allocated from or should be allocated (if NULL).
|
||||
size_t m_systemChunkSize; ///< Size of chunk to request from the OS when more memory is needed (defaults to m_pageSize)
|
||||
size_t m_capacity; ///< Max size this allocator can grow to
|
||||
};
|
||||
@@ -68,7 +68,6 @@ namespace AZ
|
||||
size_type GetMaxAllocationSize() const override;
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
size_type GetUnAllocatedMemory(bool isPrint = false) const override;
|
||||
IAllocatorAllocate* GetSubAllocator() override { return m_desc.m_subAllocator; }
|
||||
|
||||
/// Return unused memory to the OS (if we don't use fixed block). Don't call this unless you really need free memory, it is slow.
|
||||
void GarbageCollect() override;
|
||||
|
||||
@@ -9,23 +9,12 @@
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
IAllocator::IAllocator(IAllocatorAllocate* allocationSource)
|
||||
: m_allocationSource(allocationSource)
|
||||
, m_originalAllocationSource(allocationSource)
|
||||
IAllocator::IAllocator(IAllocatorSchema* schema)
|
||||
: m_schema(schema)
|
||||
{
|
||||
}
|
||||
|
||||
IAllocator::~IAllocator()
|
||||
{
|
||||
}
|
||||
|
||||
void IAllocator::SetAllocationSource(IAllocatorAllocate* allocationSource)
|
||||
{
|
||||
m_allocationSource = allocationSource;
|
||||
}
|
||||
|
||||
void IAllocator::ResetAllocationSource()
|
||||
{
|
||||
m_allocationSource = m_originalAllocationSource;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,19 +28,18 @@ namespace AZ
|
||||
class AllocatorManager;
|
||||
|
||||
/**
|
||||
* Allocator alloc/free basic interface. It is separate because it can be used
|
||||
* for user provided allocators overrides
|
||||
* Allocator schema interface
|
||||
*/
|
||||
class IAllocatorAllocate
|
||||
class IAllocatorSchema
|
||||
{
|
||||
public:
|
||||
typedef void* pointer_type;
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
virtual ~IAllocatorAllocate() {}
|
||||
virtual ~IAllocatorSchema() = default;
|
||||
|
||||
virtual pointer_type Allocate(size_type byteSize, size_type alignment, int flags = 0, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) = 0;
|
||||
virtual pointer_type Allocate(size_type byteSize, size_type alignment, int flags = 0, const char* name = nullptr, const char* fileName = nullptr, int lineNum = 0, unsigned int suppressStackRecord = 0) = 0;
|
||||
virtual void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) = 0;
|
||||
/// Resize an allocated memory block. Returns the new adjusted size (as close as possible or equal to the requested one) or 0 (if you don't support resize at all).
|
||||
virtual size_type Resize(pointer_type ptr, size_type newSize) = 0;
|
||||
@@ -70,8 +69,6 @@ namespace AZ
|
||||
* that will be reported.
|
||||
*/
|
||||
virtual size_type GetUnAllocatedMemory(bool isPrint = false) const { (void)isPrint; return 0; }
|
||||
/// Returns a pointer to a sub-allocator or NULL.
|
||||
virtual IAllocatorAllocate* GetSubAllocator() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -100,56 +97,19 @@ namespace AZ
|
||||
/**
|
||||
* Interface class for all allocators.
|
||||
*/
|
||||
class IAllocator
|
||||
class IAllocator : public IAllocatorSchema
|
||||
{
|
||||
public:
|
||||
IAllocator(IAllocatorAllocate* allocationSource);
|
||||
IAllocator(IAllocatorSchema* schema = nullptr);
|
||||
virtual ~IAllocator();
|
||||
|
||||
// @{ Every system allocator is required to provide name this is how
|
||||
// Every system allocator is required to provide name this is how
|
||||
// it will be registered with the allocator manager.
|
||||
virtual const char* GetName() const = 0;
|
||||
virtual const char* GetDescription() const = 0;
|
||||
// @}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Code releating to the allocation source is made concrete within this
|
||||
// interface as a performance optimization.
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
/// Returns the current allocation source, which may be used to perform memory allocations.
|
||||
AZ_FORCE_INLINE IAllocatorAllocate* GetAllocationSource() const
|
||||
{
|
||||
return m_allocationSource;
|
||||
}
|
||||
|
||||
/// Returns the original allocation source. Generally only used for debugging purposes.
|
||||
AZ_FORCE_INLINE IAllocatorAllocate* GetOriginalAllocationSource() const
|
||||
{
|
||||
return m_originalAllocationSource;
|
||||
}
|
||||
|
||||
/// Returns true if the allocation source has changed from its original value.
|
||||
AZ_FORCE_INLINE bool IsAllocationSourceChanged() const
|
||||
{
|
||||
return m_allocationSource != m_originalAllocationSource;
|
||||
}
|
||||
|
||||
/// Sets the allocation source, effectively overriding the allocator.
|
||||
/// Be very careful doing this, as existing allocations will be deallocated through the new source,
|
||||
/// typically leading to unwanted effects (such as crashes).
|
||||
void SetAllocationSource(IAllocatorAllocate* allocationSource);
|
||||
|
||||
/// Restores the allocation source to its original value.
|
||||
/// Be very careful doing this, as allocations that came from the new source will now be deallocated
|
||||
/// through the original source, typically leading to unwanted effects (such as crashes).
|
||||
void ResetAllocationSource();
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
/// Returns the schema, if the allocator uses one. Returns nullptr if the allocator does not use a schema.
|
||||
/// This is mainly used when debugging to determine if allocators alias each other under the hood.
|
||||
virtual IAllocatorAllocate* GetSchema() = 0;
|
||||
/// Returns the schema
|
||||
AZ_FORCE_INLINE IAllocatorSchema* GetSchema() const { return m_schema; };
|
||||
|
||||
/// Returns the debug configuration for this allocator.
|
||||
virtual AllocatorDebugConfig GetDebugConfig() = 0;
|
||||
@@ -163,11 +123,6 @@ namespace AZ
|
||||
/// Returns true if this allocator is ready to use.
|
||||
virtual bool IsReady() const = 0;
|
||||
|
||||
/// Returns true if this allocator can be overridden with a different source.
|
||||
/// Almost all allocators should return true. There are very few minor exceptions, such as the OS Allocator, that are required for direct
|
||||
/// interfacing with the kernel and must never be overridden under any circumstances.
|
||||
virtual bool CanBeOverridden() const = 0;
|
||||
|
||||
/// Returns true if the allocator was lazily created. Exposed primarily for testing systems that need to verify the state of allocators.
|
||||
virtual bool IsLazilyCreated() const = 0;
|
||||
|
||||
@@ -195,9 +150,7 @@ namespace AZ
|
||||
virtual void Destroy() = 0;
|
||||
|
||||
protected:
|
||||
// The allocation source is made a direct member of the interface as a performance optimization.
|
||||
IAllocatorAllocate * m_allocationSource;
|
||||
IAllocatorAllocate* m_originalAllocationSource;
|
||||
IAllocatorSchema* m_schema;
|
||||
|
||||
template<class Allocator>
|
||||
friend class AllocatorStorage::StoragePolicyBase;
|
||||
|
||||
@@ -22,31 +22,15 @@ namespace AZ::Internal
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
static constexpr size_t DEFAULT_ALIGNMENT = sizeof(void*) * 2; // Default malloc alignment
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// MallocSchema methods
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
MallocSchema::MallocSchema(const Descriptor& desc)
|
||||
MallocSchema::MallocSchema(const Descriptor&)
|
||||
: m_bytesAllocated(0)
|
||||
{
|
||||
if (desc.m_useAZMalloc)
|
||||
{
|
||||
static const int DEFAULT_ALIGNMENT = sizeof(void*) * 2; // Default malloc alignment
|
||||
|
||||
m_mallocFn = [](size_t byteSize)
|
||||
{
|
||||
return AZ_OS_MALLOC(byteSize, DEFAULT_ALIGNMENT);
|
||||
};
|
||||
m_freeFn = [](void* ptr)
|
||||
{
|
||||
AZ_OS_FREE(ptr);
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mallocFn = &malloc;
|
||||
m_freeFn = &free;
|
||||
}
|
||||
}
|
||||
|
||||
MallocSchema::~MallocSchema()
|
||||
@@ -84,7 +68,7 @@ namespace AZ
|
||||
((alignment > sizeof(double))
|
||||
? alignment
|
||||
: 0); // Malloc will align to a minimum boundary for native objects, so we only pad if aligning to a large value
|
||||
void* data = (*m_mallocFn)(required);
|
||||
void* data = AZ_OS_MALLOC(required, DEFAULT_ALIGNMENT);
|
||||
void* result = PointerAlignUp(reinterpret_cast<void*>(reinterpret_cast<size_t>(data) + sizeof(Internal::Header)), alignment);
|
||||
Internal::Header* header = PointerAlignDown<Internal::Header>(
|
||||
(Internal::Header*)(reinterpret_cast<size_t>(result) - sizeof(Internal::Header)), AZStd::alignment_of<Internal::Header>::value);
|
||||
@@ -112,7 +96,7 @@ namespace AZ
|
||||
void* freePtr = reinterpret_cast<void*>(reinterpret_cast<size_t>(ptr) - static_cast<size_t>(header->offset));
|
||||
|
||||
m_bytesAllocated -= header->size;
|
||||
(*m_freeFn)(freePtr);
|
||||
AZ_OS_FREE(freePtr);
|
||||
}
|
||||
|
||||
MallocSchema::pointer_type MallocSchema::ReAllocate(pointer_type ptr, size_type newSize, size_type newAlignment)
|
||||
@@ -166,11 +150,6 @@ namespace AZ
|
||||
return AZ_CORE_MAX_ALLOCATOR_SIZE;
|
||||
}
|
||||
|
||||
IAllocatorAllocate* MallocSchema::GetSubAllocator()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void MallocSchema::GarbageCollect()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace AZ
|
||||
* Uses malloc internally. Mainly intended for debugging using host operating system features.
|
||||
*/
|
||||
class MallocSchema
|
||||
: public IAllocatorAllocate
|
||||
: public IAllocatorSchema
|
||||
{
|
||||
public:
|
||||
AZ_TYPE_INFO("MallocSchema", "{2A21D120-A42A-484C-997C-5735DCCA5FE9}");
|
||||
@@ -25,21 +25,13 @@ namespace AZ
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
struct Descriptor
|
||||
{
|
||||
Descriptor(bool useAZMalloc = true)
|
||||
: m_useAZMalloc(useAZMalloc)
|
||||
{
|
||||
}
|
||||
|
||||
bool m_useAZMalloc;
|
||||
};
|
||||
struct Descriptor {};
|
||||
|
||||
MallocSchema(const Descriptor& desc = Descriptor());
|
||||
virtual ~MallocSchema();
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// IAllocatorAllocate
|
||||
// IAllocatorSchema
|
||||
//---------------------------------------------------------------------
|
||||
pointer_type Allocate(size_type byteSize, size_type alignment, int flags, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) override;
|
||||
void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) override;
|
||||
@@ -51,15 +43,9 @@ namespace AZ
|
||||
size_type Capacity() const override;
|
||||
size_type GetMaxAllocationSize() const override;
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
IAllocatorAllocate* GetSubAllocator() override;
|
||||
void GarbageCollect() override;
|
||||
|
||||
private:
|
||||
typedef void* (*MallocFn)(size_t);
|
||||
typedef void (*FreeFn)(void*);
|
||||
|
||||
AZStd::atomic<size_t> m_bytesAllocated;
|
||||
MallocFn m_mallocFn;
|
||||
FreeFn m_freeFn;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -141,9 +141,9 @@ void* operator new[](std::size_t, const AZ::Internal::AllocatorDummy*);
|
||||
*/
|
||||
#define azfree(...) AZ_MACRO_SPECIALIZE(azfree_, AZ_VA_NUM_ARGS(__VA_ARGS__), (__VA_ARGS__))
|
||||
|
||||
/// Returns allocation size, based on it's pointer \ref AZ::IAllocatorAllocate::AllocationSize.
|
||||
/// Returns allocation size, based on it's pointer \ref AZ::IAllocatorSchema::AllocationSize.
|
||||
#define azallocsize(_Ptr, _Allocator) AZ::AllocatorInstance< _Allocator >::Get().AllocationSize(_Ptr)
|
||||
/// Returns the new expanded size or 0 if NOT supported by the allocator \ref AZ::IAllocatorAllocate::Resize.
|
||||
/// Returns the new expanded size or 0 if NOT supported by the allocator \ref AZ::IAllocatorSchema::Resize.
|
||||
#define azallocresize(_Ptr, _NewSize, _Allocator) AZ::AllocatorInstance< _Allocator >::Get().Resize(_Ptr, _NewSize)
|
||||
|
||||
namespace AZ {
|
||||
@@ -734,12 +734,15 @@ namespace AZ
|
||||
public:
|
||||
typedef typename Allocator::Descriptor Descriptor;
|
||||
|
||||
AZ_FORCE_INLINE static IAllocatorAllocate& Get()
|
||||
// Maintained for backwards compatibility, prefer to use Get() instead.
|
||||
// Get was previously used to get the the schema, however, that bypasses what the allocators are doing.
|
||||
// If the schema is needed, call Get().GetSchema()
|
||||
AZ_FORCE_INLINE static IAllocator& GetAllocator()
|
||||
{
|
||||
return *GetAllocator().GetAllocationSource();
|
||||
return StoragePolicy::GetAllocator();
|
||||
}
|
||||
|
||||
AZ_FORCE_INLINE static IAllocator& GetAllocator()
|
||||
AZ_FORCE_INLINE static IAllocator& Get()
|
||||
{
|
||||
return StoragePolicy::GetAllocator();
|
||||
}
|
||||
@@ -781,7 +784,7 @@ namespace AZ
|
||||
// structure of another allocator
|
||||
template <class ParentAllocator>
|
||||
class ChildAllocatorSchema
|
||||
: public IAllocatorAllocate
|
||||
: public IAllocatorSchema
|
||||
{
|
||||
public:
|
||||
// No descriptor is necessary, as the parent allocator is expected to already
|
||||
@@ -792,7 +795,7 @@ namespace AZ
|
||||
ChildAllocatorSchema(const Descriptor&) {}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// IAllocatorAllocate
|
||||
// IAllocatorSchema
|
||||
//---------------------------------------------------------------------
|
||||
pointer_type Allocate(size_type byteSize, size_type alignment, int flags = 0, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) override
|
||||
{
|
||||
@@ -848,11 +851,6 @@ namespace AZ
|
||||
{
|
||||
return AZ::AllocatorInstance<Parent>::Get().GetUnAllocatedMemory(isPrint);
|
||||
}
|
||||
|
||||
IAllocatorAllocate* GetSubAllocator() override
|
||||
{
|
||||
return AZ::AllocatorInstance<Parent>::Get().GetSubAllocator();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -873,7 +871,7 @@ namespace AZ
|
||||
{
|
||||
if (AllocatorInstance<Allocator>::IsReady())
|
||||
{
|
||||
m_name = AllocatorInstance<Allocator>::GetAllocator().GetName();
|
||||
m_name = AllocatorInstance<Allocator>::Get().GetName();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -932,7 +930,7 @@ namespace AZ
|
||||
typedef AZStd::ptrdiff_t difference_type;
|
||||
typedef AZStd::false_type allow_memory_leaks; ///< Regular allocators should not leak.
|
||||
|
||||
AZ_FORCE_INLINE AZStdIAllocator(IAllocatorAllocate* allocator, const char* name = "AZ::AZStdIAllocator")
|
||||
AZ_FORCE_INLINE AZStdIAllocator(IAllocator* allocator, const char* name = "AZ::AZStdIAllocator")
|
||||
: m_allocator(allocator)
|
||||
, m_name(name)
|
||||
{
|
||||
@@ -965,7 +963,7 @@ namespace AZ
|
||||
AZ_FORCE_INLINE bool operator==(const AZStdIAllocator& rhs) const { return m_allocator == rhs.m_allocator; }
|
||||
AZ_FORCE_INLINE bool operator!=(const AZStdIAllocator& rhs) const { return m_allocator != rhs.m_allocator; }
|
||||
private:
|
||||
IAllocatorAllocate* m_allocator;
|
||||
IAllocator* m_allocator;
|
||||
const char* m_name;
|
||||
};
|
||||
|
||||
@@ -982,8 +980,8 @@ namespace AZ
|
||||
using size_type = AZStd::size_t;
|
||||
using difference_type = AZStd::ptrdiff_t;
|
||||
using allow_memory_leaks = AZStd::false_type; ///< Regular allocators should not leak.
|
||||
using functor_type = IAllocatorAllocate&(*)(); ///< Function Pointer must return IAllocatorAllocate&.
|
||||
///< function pointers do not support covariant return types
|
||||
using functor_type = IAllocator&(*)(); ///< Function Pointer must return IAllocator&.
|
||||
///< function pointers do not support covariant return types
|
||||
|
||||
constexpr AZStdFunctorAllocator(functor_type allocatorFunctor, const char* name = "AZ::AZStdFunctorAllocator")
|
||||
: m_allocatorFunctor(allocatorFunctor)
|
||||
|
||||
@@ -19,7 +19,6 @@ namespace AZ
|
||||
, m_custom(nullptr)
|
||||
, m_numAllocatedBytes(0)
|
||||
{
|
||||
DisableOverriding();
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
|
||||
@@ -24,7 +24,6 @@ namespace AZ
|
||||
*/
|
||||
class OSAllocator
|
||||
: public AllocatorBase
|
||||
, public IAllocatorAllocate
|
||||
{
|
||||
public:
|
||||
AZ_TYPE_INFO(OSAllocator, "{9F835EE3-F23C-454E-B4E3-011E2F3C8118}")
|
||||
@@ -39,7 +38,7 @@ namespace AZ
|
||||
{
|
||||
Descriptor()
|
||||
: m_custom(0) {}
|
||||
IAllocatorAllocate* m_custom; ///< You can provide our own allocation scheme. If NULL a HeapScheme will be used with the provided Descriptor.
|
||||
IAllocatorSchema* m_custom; ///< You can provide our own allocation scheme. If NULL a HeapScheme will be used with the provided Descriptor.
|
||||
};
|
||||
|
||||
bool Create(const Descriptor& desc);
|
||||
@@ -51,7 +50,7 @@ namespace AZ
|
||||
AllocatorDebugConfig GetDebugConfig() override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// IAllocatorAllocate
|
||||
// IAllocatorSchema
|
||||
pointer_type Allocate(size_type byteSize, size_type alignment, int flags = 0, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) override;
|
||||
void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) override;
|
||||
size_type Resize(pointer_type ptr, size_type newSize) override { return m_custom ? m_custom->Resize(ptr, newSize) : 0; }
|
||||
@@ -62,13 +61,12 @@ namespace AZ
|
||||
size_type Capacity() const override { return m_custom ? m_custom->Capacity() : AZ_CORE_MAX_ALLOCATOR_SIZE; } // custom size or unlimited
|
||||
size_type GetMaxAllocationSize() const override { return m_custom ? m_custom->GetMaxAllocationSize() : AZ_CORE_MAX_ALLOCATOR_SIZE; } // custom size or unlimited
|
||||
size_type GetMaxContiguousAllocationSize() const override { return m_custom ? m_custom->GetMaxContiguousAllocationSize() : AZ_CORE_MAX_ALLOCATOR_SIZE; } // custom size or unlimited
|
||||
IAllocatorAllocate* GetSubAllocator() override { return m_custom ? m_custom : NULL; }
|
||||
|
||||
protected:
|
||||
OSAllocator(const OSAllocator&);
|
||||
OSAllocator& operator=(const OSAllocator&);
|
||||
|
||||
IAllocatorAllocate* m_custom;
|
||||
IAllocatorSchema* m_custom;
|
||||
size_type m_numAllocatedBytes;
|
||||
};
|
||||
|
||||
|
||||
@@ -233,7 +233,6 @@ namespace AZ
|
||||
size_type Capacity() const;
|
||||
size_type GetMaxAllocationSize() const;
|
||||
size_type GetMaxContiguousAllocationSize() const;
|
||||
IAllocatorAllocate* GetSubAllocator();
|
||||
void GarbageCollect();
|
||||
|
||||
private:
|
||||
@@ -680,11 +679,6 @@ auto AZ::OverrunDetectionSchemaImpl::GetMaxContiguousAllocationSize() const -> s
|
||||
return 0;
|
||||
}
|
||||
|
||||
AZ::IAllocatorAllocate* AZ::OverrunDetectionSchemaImpl::GetSubAllocator()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void AZ::OverrunDetectionSchemaImpl::GarbageCollect()
|
||||
{
|
||||
}
|
||||
@@ -810,11 +804,6 @@ auto AZ::OverrunDetectionSchema::GetMaxContiguousAllocationSize() const -> size_
|
||||
return m_impl->GetMaxContiguousAllocationSize();
|
||||
}
|
||||
|
||||
AZ::IAllocatorAllocate* AZ::OverrunDetectionSchema::GetSubAllocator()
|
||||
{
|
||||
return m_impl->GetSubAllocator();
|
||||
}
|
||||
|
||||
void AZ::OverrunDetectionSchema::GarbageCollect()
|
||||
{
|
||||
m_impl->GarbageCollect();
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace AZ
|
||||
* the requested memory, plus the trap page). On most platforms this is 8kb (4kb * 2 pages).
|
||||
*/
|
||||
class OverrunDetectionSchema
|
||||
: public IAllocatorAllocate
|
||||
: public IAllocatorSchema
|
||||
{
|
||||
public:
|
||||
AZ_TYPE_INFO("OverrunDetectionSchema", "{0DF781AC-1615-40AE-81F7-6CA5841E2914}");
|
||||
@@ -75,7 +75,7 @@ namespace AZ
|
||||
virtual ~OverrunDetectionSchema();
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// IAllocatorAllocate
|
||||
// IAllocatorSchema
|
||||
//---------------------------------------------------------------------
|
||||
pointer_type Allocate(size_type byteSize, size_type alignment, int flags, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) override;
|
||||
void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) override;
|
||||
@@ -87,7 +87,6 @@ namespace AZ
|
||||
size_type Capacity() const override;
|
||||
size_type GetMaxAllocationSize() const override;
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
IAllocatorAllocate* GetSubAllocator() override;
|
||||
void GarbageCollect() override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -102,7 +102,7 @@ namespace AZ
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// IAllocatorAllocate
|
||||
// IAllocatorSchema
|
||||
pointer_type ReAllocate(pointer_type ptr, size_type newSize, size_type newAlignment) override
|
||||
{
|
||||
(void)ptr;
|
||||
|
||||
@@ -163,7 +163,7 @@ namespace AZ
|
||||
}
|
||||
|
||||
using AllocatorType = PoolAllocation<PoolSchemaImpl>;
|
||||
IAllocatorAllocate* m_pageAllocator;
|
||||
IAllocatorSchema* m_pageAllocator;
|
||||
AllocatorType m_allocator;
|
||||
void* m_staticDataBlock;
|
||||
unsigned int m_numStaticPages;
|
||||
@@ -301,7 +301,7 @@ namespace AZ
|
||||
FreePagesType m_freePages;
|
||||
AZStd::vector<ThreadPoolData*> m_threads; ///< Array with all separate thread data. Used to traverse end free elements.
|
||||
|
||||
IAllocatorAllocate* m_pageAllocator;
|
||||
IAllocatorSchema* m_pageAllocator;
|
||||
void* m_staticDataBlock;
|
||||
size_t m_numStaticPages;
|
||||
size_t m_pageSize;
|
||||
@@ -744,15 +744,6 @@ namespace AZ
|
||||
return m_impl->m_numStaticPages * m_impl->m_pageSize;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// GetPageAllocator
|
||||
// [11/17/2010]
|
||||
//=========================================================================
|
||||
IAllocatorAllocate* PoolSchema::GetSubAllocator()
|
||||
{
|
||||
return m_impl->m_pageAllocator;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PollAllocator Implementation
|
||||
@@ -1095,15 +1086,6 @@ namespace AZ
|
||||
return m_impl->m_numStaticPages * m_impl->m_pageSize;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// GetPageAllocator
|
||||
// [11/17/2010]
|
||||
//=========================================================================
|
||||
IAllocatorAllocate* ThreadPoolSchema::GetSubAllocator()
|
||||
{
|
||||
return m_impl->m_pageAllocator;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// ThreadPoolSchemaImpl
|
||||
// [9/15/2009]
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace AZ
|
||||
* use ThreadPool Schema or do the sync yourself.
|
||||
*/
|
||||
class PoolSchema
|
||||
: public IAllocatorAllocate
|
||||
: public IAllocatorSchema
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@@ -51,7 +51,7 @@ namespace AZ
|
||||
* this is the minimum number of pages we will have allocated at all times, otherwise the total number of pages supported.
|
||||
*/
|
||||
unsigned int m_numStaticPages;
|
||||
IAllocatorAllocate* m_pageAllocator; ///< If you provide this interface we will use it for page allocations, otherwise SystemAllocator will be used.
|
||||
IAllocatorSchema* m_pageAllocator; ///< If you provide this interface we will use it for page allocations, otherwise SystemAllocator will be used.
|
||||
};
|
||||
|
||||
PoolSchema(const Descriptor& desc = Descriptor());
|
||||
@@ -72,7 +72,6 @@ namespace AZ
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
size_type NumAllocatedBytes() const override;
|
||||
size_type Capacity() const override;
|
||||
IAllocatorAllocate* GetSubAllocator() override;
|
||||
|
||||
protected:
|
||||
PoolSchema(const PoolSchema&);
|
||||
@@ -89,7 +88,7 @@ namespace AZ
|
||||
* for each thread. So there will be some memory overhead, especially if you use fixed pool sizes.
|
||||
*/
|
||||
class ThreadPoolSchema
|
||||
: public IAllocatorAllocate
|
||||
: public IAllocatorSchema
|
||||
{
|
||||
public:
|
||||
// Functions for getting an instance of a ThreadPoolData when using thread local storage
|
||||
@@ -118,7 +117,6 @@ namespace AZ
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
size_type NumAllocatedBytes() const override;
|
||||
size_type Capacity() const override;
|
||||
IAllocatorAllocate* GetSubAllocator() override;
|
||||
|
||||
protected:
|
||||
ThreadPoolSchema(const ThreadPoolSchema&);
|
||||
|
||||
@@ -22,17 +22,15 @@ namespace AZ
|
||||
template <class Schema, class DescriptorType=typename Schema::Descriptor, bool ProfileAllocations=true, bool ReportOutOfMemory=true>
|
||||
class SimpleSchemaAllocator
|
||||
: public AllocatorBase
|
||||
, public IAllocatorAllocate
|
||||
{
|
||||
public:
|
||||
using Descriptor = DescriptorType;
|
||||
using pointer_type = typename IAllocatorAllocate::pointer_type;
|
||||
using size_type = typename IAllocatorAllocate::size_type;
|
||||
using difference_type = typename IAllocatorAllocate::difference_type;
|
||||
using pointer_type = typename Schema::pointer_type;
|
||||
using size_type = typename Schema::size_type;
|
||||
using difference_type = typename Schema::difference_type;
|
||||
|
||||
SimpleSchemaAllocator(const char* name, const char* desc)
|
||||
: AllocatorBase(this, name, desc)
|
||||
, m_schema(nullptr)
|
||||
: AllocatorBase(nullptr, name, desc)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -65,13 +63,8 @@ namespace AZ
|
||||
return AllocatorDebugConfig();
|
||||
}
|
||||
|
||||
IAllocatorAllocate* GetSchema() override
|
||||
{
|
||||
return m_schema;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// IAllocatorAllocate
|
||||
// IAllocatorSchema
|
||||
//---------------------------------------------------------------------
|
||||
pointer_type Allocate(size_type byteSize, size_type alignment, int flags = 0, const char* name = nullptr, const char* fileName = nullptr, int lineNum = 0, unsigned int suppressStackRecord = 0) override
|
||||
{
|
||||
@@ -188,14 +181,6 @@ namespace AZ
|
||||
{
|
||||
return m_schema->GetUnAllocatedMemory(isPrint);
|
||||
}
|
||||
|
||||
IAllocatorAllocate* GetSubAllocator() override
|
||||
{
|
||||
return m_schema->GetSubAllocator();
|
||||
}
|
||||
|
||||
protected:
|
||||
IAllocatorAllocate* m_schema;
|
||||
|
||||
private:
|
||||
typename AZStd::aligned_storage<sizeof(Schema), AZStd::alignment_of<Schema>::value>::type m_schemaStorage;
|
||||
|
||||
@@ -50,9 +50,8 @@ namespace AZ
|
||||
// [9/2/2009]
|
||||
//=========================================================================
|
||||
SystemAllocator::SystemAllocator()
|
||||
: AllocatorBase(this, "SystemAllocator", "Fundamental generic memory allocator")
|
||||
: AllocatorBase(nullptr, "SystemAllocator", "Fundamental generic memory allocator")
|
||||
, m_isCustom(false)
|
||||
, m_allocator(nullptr)
|
||||
, m_ownsOSAllocator(false)
|
||||
{
|
||||
}
|
||||
@@ -91,7 +90,7 @@ namespace AZ
|
||||
if (desc.m_custom)
|
||||
{
|
||||
m_isCustom = true;
|
||||
m_allocator = desc.m_custom;
|
||||
m_schema = desc.m_custom;
|
||||
isReady = true;
|
||||
}
|
||||
else
|
||||
@@ -119,9 +118,9 @@ namespace AZ
|
||||
AZ_Assert(!g_isSystemSchemaUsed, "AZ::SystemAllocator MUST be created first! It's the source of all allocations!");
|
||||
|
||||
#if AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_HPHA
|
||||
m_allocator = new (&g_systemSchema) HphaSchema(heapDesc);
|
||||
m_schema = new (&g_systemSchema) HphaSchema(heapDesc);
|
||||
#elif AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_MALLOC
|
||||
m_allocator = new (&g_systemSchema) MallocSchema(heapDesc);
|
||||
m_schema = new (&g_systemSchema) MallocSchema(heapDesc);
|
||||
#endif
|
||||
g_isSystemSchemaUsed = true;
|
||||
isReady = true;
|
||||
@@ -134,11 +133,11 @@ namespace AZ
|
||||
"System allocator must be created before any other allocator! They allocate from it.");
|
||||
|
||||
#if AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_HPHA
|
||||
m_allocator = azcreate(HphaSchema, (heapDesc), SystemAllocator);
|
||||
m_schema = azcreate(HphaSchema, (heapDesc), SystemAllocator);
|
||||
#elif AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_MALLOC
|
||||
m_allocator = azcreate(MallocSchema, (heapDesc), SystemAllocator);
|
||||
m_schema = azcreate(MallocSchema, (heapDesc), SystemAllocator);
|
||||
#endif
|
||||
if (m_allocator == nullptr)
|
||||
if (m_schema == nullptr)
|
||||
{
|
||||
isReady = false;
|
||||
}
|
||||
@@ -166,18 +165,18 @@ namespace AZ
|
||||
|
||||
if (!m_isCustom)
|
||||
{
|
||||
if ((void*)m_allocator == (void*)&g_systemSchema)
|
||||
if ((void*)m_schema == (void*)&g_systemSchema)
|
||||
{
|
||||
#if AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_HPHA
|
||||
static_cast<HphaSchema*>(m_allocator)->~HphaSchema();
|
||||
static_cast<HphaSchema*>(m_schema)->~HphaSchema();
|
||||
#elif AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_MALLOC
|
||||
static_cast<MallocSchema*>(m_allocator)->~MallocSchema();
|
||||
static_cast<MallocSchema*>(m_schema)->~MallocSchema();
|
||||
#endif
|
||||
g_isSystemSchemaUsed = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
azdestroy(m_allocator);
|
||||
azdestroy(m_schema);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,11 +196,6 @@ namespace AZ
|
||||
.ExcludeFromDebugging(!m_desc.m_allocationRecords);
|
||||
}
|
||||
|
||||
IAllocatorAllocate* SystemAllocator::GetSchema()
|
||||
{
|
||||
return m_allocator;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// Allocate
|
||||
// [9/2/2009]
|
||||
@@ -224,14 +218,14 @@ namespace AZ
|
||||
|
||||
byteSize = MemorySizeAdjustedUp(byteSize);
|
||||
SystemAllocator::pointer_type address =
|
||||
m_allocator->Allocate(byteSize, alignment, flags, name, fileName, lineNum, suppressStackRecord + 1);
|
||||
m_schema->Allocate(byteSize, alignment, flags, name, fileName, lineNum, suppressStackRecord + 1);
|
||||
|
||||
if (address == nullptr)
|
||||
{
|
||||
// Free all memory we can and try again!
|
||||
AllocatorManager::Instance().GarbageCollect();
|
||||
|
||||
address = m_allocator->Allocate(byteSize, alignment, flags, name, fileName, lineNum, suppressStackRecord + 1);
|
||||
address = m_schema->Allocate(byteSize, alignment, flags, name, fileName, lineNum, suppressStackRecord + 1);
|
||||
}
|
||||
|
||||
if (address == nullptr)
|
||||
@@ -258,7 +252,7 @@ namespace AZ
|
||||
byteSize = MemorySizeAdjustedUp(byteSize);
|
||||
AZ_PROFILE_MEMORY_FREE(MemoryReserved, ptr);
|
||||
AZ_MEMORY_PROFILE(ProfileDeallocation(ptr, byteSize, alignment, nullptr));
|
||||
m_allocator->DeAllocate(ptr, byteSize, alignment);
|
||||
m_schema->DeAllocate(ptr, byteSize, alignment);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -271,7 +265,7 @@ namespace AZ
|
||||
|
||||
AZ_MEMORY_PROFILE(ProfileReallocationBegin(ptr, newSize));
|
||||
AZ_PROFILE_MEMORY_FREE(MemoryReserved, ptr);
|
||||
pointer_type newAddress = m_allocator->ReAllocate(ptr, newSize, newAlignment);
|
||||
pointer_type newAddress = m_schema->ReAllocate(ptr, newSize, newAlignment);
|
||||
AZ_PROFILE_MEMORY_ALLOC(MemoryReserved, newAddress, newSize, "SystemAllocator realloc");
|
||||
AZ_MEMORY_PROFILE(ProfileReallocationEnd(ptr, newAddress, newSize, newAlignment));
|
||||
|
||||
@@ -285,7 +279,7 @@ namespace AZ
|
||||
SystemAllocator::size_type SystemAllocator::Resize(pointer_type ptr, size_type newSize)
|
||||
{
|
||||
newSize = MemorySizeAdjustedUp(newSize);
|
||||
size_type resizedSize = m_allocator->Resize(ptr, newSize);
|
||||
size_type resizedSize = m_schema->Resize(ptr, newSize);
|
||||
|
||||
AZ_MEMORY_PROFILE(ProfileResize(ptr, resizedSize));
|
||||
|
||||
@@ -298,7 +292,7 @@ namespace AZ
|
||||
//=========================================================================
|
||||
SystemAllocator::size_type SystemAllocator::AllocationSize(pointer_type ptr)
|
||||
{
|
||||
size_type allocSize = MemorySizeAdjustedDown(m_allocator->AllocationSize(ptr));
|
||||
size_type allocSize = MemorySizeAdjustedDown(m_schema->AllocationSize(ptr));
|
||||
|
||||
return allocSize;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ namespace AZ
|
||||
*/
|
||||
class SystemAllocator
|
||||
: public AllocatorBase
|
||||
, public IAllocatorAllocate
|
||||
{
|
||||
public:
|
||||
AZ_TYPE_INFO(SystemAllocator, "{424C94D8-85CF-4E89-8CD6-AB5EC173E875}")
|
||||
@@ -38,7 +37,7 @@ namespace AZ
|
||||
* we will allocate system memory using system calls. You can
|
||||
* provide arenas (spaces) with pre-allocated memory, and use the
|
||||
* flag to specify which arena you want to allocate from.
|
||||
* You are also allowed to supply IAllocatorAllocate, but if you do
|
||||
* You are also allowed to supply IAllocatorSchema, but if you do
|
||||
* so you will need to take care of all allocations, we will not use
|
||||
* the default HeapSchema.
|
||||
* \ref HeapSchema::Descriptor
|
||||
@@ -50,7 +49,7 @@ namespace AZ
|
||||
, m_allocationRecords(true)
|
||||
, m_stackRecordLevels(5)
|
||||
{}
|
||||
IAllocatorAllocate* m_custom; ///< You can provide our own allocation scheme. If NULL a HeapScheme will be used with the provided Descriptor.
|
||||
IAllocatorSchema* m_custom; ///< You can provide our own allocation scheme. If NULL a HeapScheme will be used with the provided Descriptor.
|
||||
|
||||
struct Heap
|
||||
{
|
||||
@@ -72,7 +71,7 @@ namespace AZ
|
||||
int m_numFixedMemoryBlocks; ///< Number of memory blocks to use.
|
||||
void* m_fixedMemoryBlocks[m_maxNumFixedBlocks]; ///< Pointers to provided memory blocks or NULL if you want the system to allocate them for you with the System Allocator.
|
||||
size_t m_fixedMemoryBlocksByteSize[m_maxNumFixedBlocks]; ///< Sizes of different memory blocks (MUST be multiple of m_pageSize), if m_memoryBlock is 0 the block will be allocated for you with the System Allocator.
|
||||
IAllocatorAllocate* m_subAllocator; ///< Allocator that m_memoryBlocks memory was allocated from or should be allocated (if NULL).
|
||||
IAllocatorSchema* m_subAllocator; ///< Allocator that m_memoryBlocks memory was allocated from or should be allocated (if NULL).
|
||||
size_t m_systemChunkSize; ///< Size of chunk to request from the OS when more memory is needed (defaults to m_pageSize)
|
||||
} m_heap;
|
||||
bool m_allocationRecords; ///< True if we want to track memory allocations, otherwise false.
|
||||
@@ -86,25 +85,23 @@ namespace AZ
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// IAllocator
|
||||
AllocatorDebugConfig GetDebugConfig() override;
|
||||
IAllocatorAllocate* GetSchema() override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// IAllocatorAllocate
|
||||
// IAllocatorSchema
|
||||
|
||||
pointer_type Allocate(size_type byteSize, size_type alignment, int flags = 0, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) override;
|
||||
void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) override;
|
||||
pointer_type ReAllocate(pointer_type ptr, size_type newSize, size_type newAlignment) override;
|
||||
size_type Resize(pointer_type ptr, size_type newSize) override;
|
||||
size_type AllocationSize(pointer_type ptr) override;
|
||||
void GarbageCollect() override { m_allocator->GarbageCollect(); }
|
||||
void GarbageCollect() override { GetSchema()->GarbageCollect(); }
|
||||
|
||||
size_type NumAllocatedBytes() const override { return m_allocator->NumAllocatedBytes(); }
|
||||
size_type Capacity() const override { return m_allocator->Capacity(); }
|
||||
size_type NumAllocatedBytes() const override { return GetSchema()->NumAllocatedBytes(); }
|
||||
size_type Capacity() const override { return GetSchema()->Capacity(); }
|
||||
/// Keep in mind this operation will execute GarbageCollect to make sure it returns, max allocation. This function WILL be slow.
|
||||
size_type GetMaxAllocationSize() const override { return m_allocator->GetMaxAllocationSize(); }
|
||||
size_type GetMaxContiguousAllocationSize() const override { return m_allocator->GetMaxContiguousAllocationSize(); }
|
||||
size_type GetUnAllocatedMemory(bool isPrint = false) const override { return m_allocator->GetUnAllocatedMemory(isPrint); }
|
||||
IAllocatorAllocate* GetSubAllocator() override { return m_isCustom ? m_allocator : m_allocator->GetSubAllocator(); }
|
||||
size_type GetMaxAllocationSize() const override { return GetSchema()->GetMaxAllocationSize(); }
|
||||
size_type GetMaxContiguousAllocationSize() const override { return GetSchema()->GetMaxContiguousAllocationSize(); }
|
||||
size_type GetUnAllocatedMemory(bool isPrint = false) const override { return GetSchema()->GetUnAllocatedMemory(isPrint); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -114,7 +111,6 @@ namespace AZ
|
||||
|
||||
Descriptor m_desc;
|
||||
bool m_isCustom;
|
||||
IAllocatorAllocate* m_allocator;
|
||||
bool m_ownsOSAllocator;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1457,7 +1457,7 @@ namespace AZ
|
||||
static void* LuaMemoryHook(void* userData, void* ptr, size_t osize, size_t nsize)
|
||||
{
|
||||
(void)osize;
|
||||
IAllocatorAllocate* allocator = reinterpret_cast<IAllocatorAllocate*>(userData);
|
||||
IAllocator* allocator = reinterpret_cast<IAllocator*>(userData);
|
||||
if (nsize == 0)
|
||||
{
|
||||
if (ptr)
|
||||
@@ -4276,7 +4276,7 @@ LUA_API const Node* lua_getDummyNode()
|
||||
AZ_CLASS_ALLOCATOR(ScriptContextImpl, AZ::SystemAllocator, 0);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
ScriptContextImpl(ScriptContext* owner, IAllocatorAllocate* allocator, lua_State* nativeContext)
|
||||
ScriptContextImpl(ScriptContext* owner, IAllocator* allocator, lua_State* nativeContext)
|
||||
: m_owner(owner)
|
||||
, m_context(nullptr)
|
||||
, m_debug(nullptr)
|
||||
@@ -5828,7 +5828,7 @@ LUA_API const Node* lua_getDummyNode()
|
||||
AZStd::thread::id m_ownerThreadId; // Check if Lua methods (including EBus handlers) are called from background threads.
|
||||
};
|
||||
|
||||
ScriptContext::ScriptContext(ScriptContextId id, IAllocatorAllocate* allocator, lua_State* nativeContext)
|
||||
ScriptContext::ScriptContext(ScriptContextId id, IAllocator* allocator, lua_State* nativeContext)
|
||||
{
|
||||
m_id = id;
|
||||
m_impl = aznew ScriptContextImpl(this, allocator, nativeContext);
|
||||
|
||||
@@ -821,7 +821,7 @@ namespace AZ
|
||||
CustomFromLua m_fromLua;
|
||||
};
|
||||
|
||||
ScriptContext(ScriptContextId id = ScriptContextIds::DefaultScriptContextId, IAllocatorAllocate* allocator = nullptr, lua_State* nativeContext = nullptr);
|
||||
ScriptContext(ScriptContextId id = ScriptContextIds::DefaultScriptContextId, IAllocator* allocator = nullptr, lua_State* nativeContext = nullptr);
|
||||
~ScriptContext();
|
||||
|
||||
/// Bind LUA context (VM) a specific behaviorContext
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace AZ
|
||||
* But as the AZStdAssociativeContainer instance will not be accessed outside of the module it was
|
||||
* created within then this will return this .dll/.exe module allocator
|
||||
*/
|
||||
classElement.m_attributes.set_allocator(AZStdFunctorAllocator([]() -> IAllocatorAllocate& { return GetCurrentSerializeContextModule().GetAllocator(); }));
|
||||
classElement.m_attributes.set_allocator(AZStdFunctorAllocator([]() -> IAllocator& { return GetCurrentSerializeContextModule().GetAllocator(); }));
|
||||
|
||||
// Flag the field with the EnumType attribute if we're an enumeration type aliased by RemoveEnum
|
||||
const bool isSpecializedEnum = AZStd::is_enum<ValueType>::value && !AzTypeInfo<ValueType>::Uuid().IsNull();
|
||||
@@ -650,7 +650,7 @@ namespace AZ
|
||||
* But as the AZStdAssociativeContainer instance will not be accessed outside of the module it was
|
||||
* created within then this will return this .dll/.exe module allocator
|
||||
*/
|
||||
m_classElement.m_attributes.set_allocator(AZStdFunctorAllocator([]() -> IAllocatorAllocate& { return GetCurrentSerializeContextModule().GetAllocator(); }));
|
||||
m_classElement.m_attributes.set_allocator(AZStdFunctorAllocator([]() -> IAllocator& { return GetCurrentSerializeContextModule().GetAllocator(); }));
|
||||
|
||||
m_classElement.m_attributes.emplace_back(AZ_CRC("KeyType", 0x15bc5303), CreateModuleAttribute(AZStd::move(uuid)));
|
||||
}
|
||||
|
||||
@@ -3245,7 +3245,7 @@ namespace AZ
|
||||
return genericClassInfoFoundIt != m_moduleLocalGenericClassInfos.end() ? genericClassInfoFoundIt->second : nullptr;
|
||||
}
|
||||
|
||||
AZ::IAllocatorAllocate& SerializeContext::PerModuleGenericClassInfo::GetAllocator()
|
||||
AZ::IAllocator& SerializeContext::PerModuleGenericClassInfo::GetAllocator()
|
||||
{
|
||||
return m_moduleOSAllocator;
|
||||
}
|
||||
|
||||
@@ -574,10 +574,10 @@ namespace AZ
|
||||
GenericClassInfo* m_genericClassInfo = nullptr; ///< Valid when the generic class is set. So you don't search for the actual type in the class register.
|
||||
Edit::ElementData* m_editData{}; ///< Pointer to edit data (generated by EditContext).
|
||||
AZStd::vector<AttributeSharedPair, AZStdFunctorAllocator> m_attributes{
|
||||
AZStdFunctorAllocator([]() -> IAllocatorAllocate& { return AZ::AllocatorInstance<AZ::SystemAllocator>::Get(); })
|
||||
AZStdFunctorAllocator([]() -> IAllocator& { return AZ::AllocatorInstance<AZ::SystemAllocator>::Get(); })
|
||||
}; ///< Attributes attached to ClassElement. Lambda is required here as AZStdFunctorAllocator expects a function pointer
|
||||
///< that returns an IAllocatorAllocate& and the AZ::AllocatorInstance<AZ::SystemAllocator>::Get returns an AZ::SystemAllocator&
|
||||
/// which while it inherits from IAllocatorAllocate, does not work as function pointers do not support covariant return types
|
||||
///< that returns an IAllocator& and the AZ::AllocatorInstance<AZ::SystemAllocator>::Get returns an AZ::SystemAllocator&
|
||||
/// which while it inherits from IAllocator, does not work as function pointers do not support covariant return types
|
||||
AttributeOwnership m_attributeOwnership = AttributeOwnership::Parent;
|
||||
int m_flags{}; ///<
|
||||
};
|
||||
@@ -639,12 +639,12 @@ namespace AZ
|
||||
DataPatchUpgradeHandler m_dataPatchUpgrader;
|
||||
|
||||
///< Attributes for this class type. Lambda is required here as AZStdFunctorAllocator expects a function pointer
|
||||
///< that returns an IAllocatorAllocate& and the AZ::AllocatorInstance<AZ::SystemAllocator>::Get returns an AZ::SystemAllocator&
|
||||
/// which while it inherits from IAllocatorAllocate, does not work as function pointers do not support covariant return types
|
||||
///< that returns an IAllocator& and the AZ::AllocatorInstance<AZ::SystemAllocator>::Get returns an AZ::SystemAllocator&
|
||||
/// which while it inherits from IAllocator, does not work as function pointers do not support covariant return types
|
||||
AZStd::vector<AttributeSharedPair, AZStdFunctorAllocator> m_attributes{AZStdFunctorAllocator(&GetSystemAllocator) };
|
||||
|
||||
private:
|
||||
static IAllocatorAllocate& GetSystemAllocator()
|
||||
static IAllocator& GetSystemAllocator()
|
||||
{
|
||||
return AZ::AllocatorInstance<AZ::SystemAllocator>::Get();
|
||||
}
|
||||
@@ -2483,7 +2483,7 @@ namespace AZ
|
||||
PerModuleGenericClassInfo();
|
||||
~PerModuleGenericClassInfo();
|
||||
|
||||
AZ::IAllocatorAllocate& GetAllocator();
|
||||
AZ::IAllocator& GetAllocator();
|
||||
|
||||
void AddGenericClassInfo(AZ::GenericClassInfo* genericClassInfo);
|
||||
void RemoveGenericClassInfo(const AZ::TypeId& canonicalTypeId);
|
||||
@@ -2546,12 +2546,12 @@ namespace AZ
|
||||
template <typename T, typename ContainerType>
|
||||
AttributePtr CreateModuleAttribute(T&& attrValue)
|
||||
{
|
||||
IAllocatorAllocate& moduleAllocator = GetCurrentSerializeContextModule().GetAllocator();
|
||||
IAllocator& moduleAllocator = GetCurrentSerializeContextModule().GetAllocator();
|
||||
void* rawMemory = moduleAllocator.Allocate(sizeof(ContainerType), alignof(ContainerType));
|
||||
new (rawMemory) ContainerType{ AZStd::forward<T>(attrValue) };
|
||||
auto attributeDeleter = [](Attribute* attribute)
|
||||
{
|
||||
IAllocatorAllocate& moduleAllocator = GetCurrentSerializeContextModule().GetAllocator();
|
||||
IAllocator& moduleAllocator = GetCurrentSerializeContextModule().GetAllocator();
|
||||
attribute->~Attribute();
|
||||
moduleAllocator.DeAllocate(attribute);
|
||||
};
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace AZ
|
||||
* But as the AZStdAssociativeContainer instance will not be accessed outside of the module it was
|
||||
* created within then this will return this .dll/.exe module allocator
|
||||
*/
|
||||
classElement.m_attributes.set_allocator(AZStdFunctorAllocator([]() -> IAllocatorAllocate& { return GetCurrentSerializeContextModule().GetAllocator(); }));
|
||||
classElement.m_attributes.set_allocator(AZStdFunctorAllocator([]() -> IAllocator& { return GetCurrentSerializeContextModule().GetAllocator(); }));
|
||||
}
|
||||
|
||||
template<size_t Index, size_t... Digits>
|
||||
@@ -431,7 +431,7 @@ namespace AZ
|
||||
// the serialize context dll module allocator has to be used to manage the lifetime of the ClassData attributes within a module
|
||||
// If a module which reflects a variant is unloaded, then the dll module allocator will properly unreflect the variant type from the serialize context
|
||||
// for this particular module
|
||||
AZStdFunctorAllocator dllAllocator([]() -> IAllocatorAllocate& { return GetCurrentSerializeContextModule().GetAllocator(); });
|
||||
AZStdFunctorAllocator dllAllocator([]() -> IAllocator& { return GetCurrentSerializeContextModule().GetAllocator(); });
|
||||
m_classData.m_attributes.set_allocator(AZStd::move(dllAllocator));
|
||||
|
||||
// Create the ObjectStreamWriteOverrideCB in the current module
|
||||
|
||||
@@ -369,8 +369,6 @@ set(FILES
|
||||
Memory/AllocatorBase.h
|
||||
Memory/AllocatorManager.cpp
|
||||
Memory/AllocatorManager.h
|
||||
Memory/AllocatorOverrideShim.cpp
|
||||
Memory/AllocatorOverrideShim.h
|
||||
Memory/AllocatorWrapper.h
|
||||
Memory/AllocatorScope.h
|
||||
Memory/BestFitExternalMapAllocator.cpp
|
||||
|
||||
@@ -1400,7 +1400,7 @@ namespace UnitTest
|
||||
{
|
||||
using ContainerType = ContainerTemplate<int32_t, AZStd::hash<int32_t>, AZStd::equal_to<int32_t>, AZ::AZStdIAllocator>;
|
||||
|
||||
static ContainerType Create(std::initializer_list<typename ContainerType::value_type> intList, AZ::IAllocatorAllocate* allocatorInstance)
|
||||
static ContainerType Create(std::initializer_list<typename ContainerType::value_type> intList, AZ::IAllocator* allocatorInstance)
|
||||
{
|
||||
ContainerType allocatorSet(intList, AZStd::hash<int32_t>{}, AZStd::equal_to<int32_t>{}, AZ::AZStdIAllocator{ allocatorInstance });
|
||||
return allocatorSet;
|
||||
@@ -1798,7 +1798,7 @@ namespace UnitTest
|
||||
{
|
||||
using ContainerType = ContainerTemplate<int32_t, int32_t, AZStd::hash<int32_t>, AZStd::equal_to<int32_t>, AZ::AZStdIAllocator>;
|
||||
|
||||
static ContainerType Create(std::initializer_list<typename ContainerType::value_type> intList, AZ::IAllocatorAllocate* allocatorInstance)
|
||||
static ContainerType Create(std::initializer_list<typename ContainerType::value_type> intList, AZ::IAllocator* allocatorInstance)
|
||||
{
|
||||
ContainerType allocatorMap(intList, AZStd::hash<int32_t>{}, AZStd::equal_to<int32_t>{}, AZ::AZStdIAllocator{ allocatorInstance });
|
||||
return allocatorMap;
|
||||
|
||||
@@ -1082,7 +1082,7 @@ namespace UnitTest
|
||||
{
|
||||
using ContainerType = ContainerTemplate<int32_t, AZStd::less<int32_t>, AZ::AZStdIAllocator>;
|
||||
|
||||
static ContainerType Create(std::initializer_list<typename ContainerType::value_type> intList, AZ::IAllocatorAllocate* allocatorInstance)
|
||||
static ContainerType Create(std::initializer_list<typename ContainerType::value_type> intList, AZ::IAllocator* allocatorInstance)
|
||||
{
|
||||
ContainerType allocatorSet(intList, AZStd::less<int32_t>{}, AZ::AZStdIAllocator{ allocatorInstance });
|
||||
return allocatorSet;
|
||||
@@ -1503,7 +1503,7 @@ namespace UnitTest
|
||||
{
|
||||
using ContainerType = ContainerTemplate<int32_t, int32_t, AZStd::less<int32_t>, AZ::AZStdIAllocator>;
|
||||
|
||||
static ContainerType Create(std::initializer_list<typename ContainerType::value_type> intList, AZ::IAllocatorAllocate* allocatorInstance)
|
||||
static ContainerType Create(std::initializer_list<typename ContainerType::value_type> intList, AZ::IAllocator* allocatorInstance)
|
||||
{
|
||||
ContainerType allocatorMap(intList, AZStd::less<int32_t>{}, AZ::AZStdIAllocator{ allocatorInstance });
|
||||
return allocatorMap;
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace UnitTest
|
||||
#endif
|
||||
void* addresses[numAllocations] = {nullptr};
|
||||
|
||||
IAllocatorAllocate& sysAlloc = AllocatorInstance<SystemAllocator>::Get();
|
||||
IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::Get();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Allocate
|
||||
@@ -96,19 +96,19 @@ namespace UnitTest
|
||||
{
|
||||
AZStd::size_t size = AZStd::GetMax(rand() % 256, 1);
|
||||
// supply all debug info, so we don't need to record the stack.
|
||||
addresses[i] = sysAlloc.Allocate(size, 8, 0, "Test Alloc", __FILE__, __LINE__);
|
||||
addresses[i] = sysAllocator.Allocate(size, 8, 0, "Test Alloc", __FILE__, __LINE__);
|
||||
memset(addresses[i], 1, size);
|
||||
totalAllocSize += size;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
EXPECT_GE(sysAlloc.NumAllocatedBytes(), totalAllocSize);
|
||||
EXPECT_GE(sysAllocator.NumAllocatedBytes(), totalAllocSize);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Deallocate
|
||||
for (int i = numAllocations-1; i >=0; --i)
|
||||
{
|
||||
sysAlloc.DeAllocate(addresses[i]);
|
||||
sysAllocator.DeAllocate(addresses[i]);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
@@ -122,21 +122,21 @@ namespace UnitTest
|
||||
{
|
||||
AllocatorInstance<SystemAllocator>::Create();
|
||||
|
||||
IAllocatorAllocate& sysAlloc = AllocatorInstance<SystemAllocator>::Get();
|
||||
IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::Get();
|
||||
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
address[i] = sysAlloc.Allocate(1000, 32, 0);
|
||||
address[i] = sysAllocator.Allocate(1000, 32, 0);
|
||||
EXPECT_NE(nullptr, address[i]);
|
||||
EXPECT_EQ(0, ((size_t)address[i] & 31)); // check alignment
|
||||
EXPECT_GE(sysAlloc.AllocationSize(address[i]), 1000); // check allocation size
|
||||
EXPECT_GE(sysAllocator.AllocationSize(address[i]), 1000); // check allocation size
|
||||
}
|
||||
|
||||
EXPECT_GE(sysAlloc.NumAllocatedBytes(), 100000); // we requested 100 * 1000 so we should have at least this much allocated
|
||||
EXPECT_GE(sysAllocator.NumAllocatedBytes(), 100000); // we requested 100 * 1000 so we should have at least this much allocated
|
||||
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
sysAlloc.DeAllocate(address[i]);
|
||||
sysAllocator.DeAllocate(address[i]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -168,18 +168,17 @@ namespace UnitTest
|
||||
SystemAllocator::Descriptor descriptor;
|
||||
descriptor.m_stackRecordLevels = 20;
|
||||
AllocatorInstance<SystemAllocator>::Create(descriptor);
|
||||
IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::GetAllocator();
|
||||
IAllocatorAllocate& sysAlloc = *sysAllocator.GetAllocationSource();
|
||||
IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::Get();
|
||||
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
address[i] = sysAlloc.Allocate(1000, 32, 0);
|
||||
address[i] = sysAllocator.Allocate(1000, 32, 0);
|
||||
EXPECT_NE(nullptr, address[i]);
|
||||
EXPECT_EQ(0, ((size_t)address[i] & 31)); // check alignment
|
||||
EXPECT_GE(sysAlloc.AllocationSize(address[i]), 1000); // check allocation size
|
||||
EXPECT_GE(sysAllocator.AllocationSize(address[i]), 1000); // check allocation size
|
||||
}
|
||||
|
||||
EXPECT_TRUE(sysAlloc.NumAllocatedBytes() >= 100000); // we requested 100 * 1000 so we should have at least this much allocated
|
||||
EXPECT_TRUE(sysAllocator.NumAllocatedBytes() >= 100000); // we requested 100 * 1000 so we should have at least this much allocated
|
||||
|
||||
// If tracking and recording is enabled, we can verify that the alloc info is valid
|
||||
#if defined(AZ_DEBUG_BUILD)
|
||||
@@ -192,7 +191,7 @@ namespace UnitTest
|
||||
const Debug::AllocationInfo& ai = iter->second;
|
||||
EXPECT_EQ(32, ai.m_alignment);
|
||||
EXPECT_EQ(1000, ai.m_byteSize);
|
||||
EXPECT_EQ(nullptr, ai.m_fileName); // We did not pass fileName or lineNum to sysAlloc.Allocate()
|
||||
EXPECT_EQ(nullptr, ai.m_fileName); // We did not pass fileName or lineNum to sysAllocator.Allocate()
|
||||
EXPECT_EQ(0, ai.m_lineNum); // -- " --
|
||||
# if defined(AZ_PLATFORM_WINDOWS)
|
||||
// if our hardware support stack traces make sure we have them, since we did not provide fileName,lineNum
|
||||
@@ -229,47 +228,47 @@ namespace UnitTest
|
||||
// Free all memory
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
sysAlloc.DeAllocate(address[i]);
|
||||
sysAllocator.DeAllocate(address[i]);
|
||||
}
|
||||
|
||||
sysAlloc.GarbageCollect();
|
||||
EXPECT_LT(sysAlloc.NumAllocatedBytes(), 1024); // We freed everything from a memspace, we should have only a very minor chunk of data
|
||||
sysAllocator.GarbageCollect();
|
||||
EXPECT_LT(sysAllocator.NumAllocatedBytes(), 1024); // We freed everything from a memspace, we should have only a very minor chunk of data
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// realloc test
|
||||
address[0] = nullptr;
|
||||
static const unsigned int checkValue = 0x0badbabe;
|
||||
// create tree (non pool) allocation (we usually pool < 256 bytes)
|
||||
address[0] = sysAlloc.Allocate(2048, 16);
|
||||
address[0] = sysAllocator.Allocate(2048, 16);
|
||||
*(unsigned*)(address[0]) = checkValue; // set check value
|
||||
AZ_TEST_ASSERT_CLOSE(sysAlloc.AllocationSize(address[0]), 2048, 16);
|
||||
address[0] = sysAlloc.ReAllocate(address[0], 1024, 16); // test tree big -> tree small
|
||||
AZ_TEST_ASSERT_CLOSE(sysAllocator.AllocationSize(address[0]), 2048, 16);
|
||||
address[0] = sysAllocator.ReAllocate(address[0], 1024, 16); // test tree big -> tree small
|
||||
EXPECT_EQ(checkValue, *(unsigned*)address[0]);
|
||||
AZ_TEST_ASSERT_CLOSE(sysAlloc.AllocationSize(address[0]), 1024, 16);
|
||||
address[0] = sysAlloc.ReAllocate(address[0], 4096, 16); // test tree small -> tree big
|
||||
AZ_TEST_ASSERT_CLOSE(sysAlloc.AllocationSize(address[0]), 4096, 16);
|
||||
AZ_TEST_ASSERT_CLOSE(sysAllocator.AllocationSize(address[0]), 1024, 16);
|
||||
address[0] = sysAllocator.ReAllocate(address[0], 4096, 16); // test tree small -> tree big
|
||||
AZ_TEST_ASSERT_CLOSE(sysAllocator.AllocationSize(address[0]), 4096, 16);
|
||||
EXPECT_EQ(checkValue, *(unsigned*)address[0]);
|
||||
address[0] = sysAlloc.ReAllocate(address[0], 128, 16); // test tree -> pool,
|
||||
AZ_TEST_ASSERT_CLOSE(sysAlloc.AllocationSize(address[0]), 128, 16);
|
||||
address[0] = sysAllocator.ReAllocate(address[0], 128, 16); // test tree -> pool,
|
||||
AZ_TEST_ASSERT_CLOSE(sysAllocator.AllocationSize(address[0]), 128, 16);
|
||||
EXPECT_EQ(checkValue, *(unsigned*)address[0]);
|
||||
address[0] = sysAlloc.ReAllocate(address[0], 64, 16); // pool big -> pool small
|
||||
AZ_TEST_ASSERT_CLOSE(sysAlloc.AllocationSize(address[0]), 64, 16);
|
||||
address[0] = sysAllocator.ReAllocate(address[0], 64, 16); // pool big -> pool small
|
||||
AZ_TEST_ASSERT_CLOSE(sysAllocator.AllocationSize(address[0]), 64, 16);
|
||||
EXPECT_EQ(checkValue, *(unsigned*)address[0]);
|
||||
address[0] = sysAlloc.ReAllocate(address[0], 64, 16); // pool sanity check
|
||||
AZ_TEST_ASSERT_CLOSE(sysAlloc.AllocationSize(address[0]), 64, 16);
|
||||
address[0] = sysAllocator.ReAllocate(address[0], 64, 16); // pool sanity check
|
||||
AZ_TEST_ASSERT_CLOSE(sysAllocator.AllocationSize(address[0]), 64, 16);
|
||||
EXPECT_EQ(checkValue, *(unsigned*)address[0]);
|
||||
address[0] = sysAlloc.ReAllocate(address[0], 192, 16); // pool small -> pool big
|
||||
AZ_TEST_ASSERT_CLOSE(sysAlloc.AllocationSize(address[0]), 192, 16);
|
||||
address[0] = sysAllocator.ReAllocate(address[0], 192, 16); // pool small -> pool big
|
||||
AZ_TEST_ASSERT_CLOSE(sysAllocator.AllocationSize(address[0]), 192, 16);
|
||||
EXPECT_EQ(checkValue, *(unsigned*)address[0]);
|
||||
address[0] = sysAlloc.ReAllocate(address[0], 2048, 16); // pool -> tree
|
||||
AZ_TEST_ASSERT_CLOSE(sysAlloc.AllocationSize(address[0]), 2048, 16);
|
||||
address[0] = sysAllocator.ReAllocate(address[0], 2048, 16); // pool -> tree
|
||||
AZ_TEST_ASSERT_CLOSE(sysAllocator.AllocationSize(address[0]), 2048, 16);
|
||||
;
|
||||
EXPECT_EQ(checkValue, *(unsigned*)address[0]);
|
||||
address[0] = sysAlloc.ReAllocate(address[0], 2048, 16); // tree sanity check
|
||||
AZ_TEST_ASSERT_CLOSE(sysAlloc.AllocationSize(address[0]), 2048, 16);
|
||||
address[0] = sysAllocator.ReAllocate(address[0], 2048, 16); // tree sanity check
|
||||
AZ_TEST_ASSERT_CLOSE(sysAllocator.AllocationSize(address[0]), 2048, 16);
|
||||
;
|
||||
EXPECT_EQ(checkValue, *(unsigned*)address[0]);
|
||||
sysAlloc.DeAllocate(address[0], 2048, 16);
|
||||
sysAllocator.DeAllocate(address[0], 2048, 16);
|
||||
// TODO realloc with different alignment tests
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -340,8 +339,7 @@ namespace UnitTest
|
||||
|
||||
void run()
|
||||
{
|
||||
IAllocatorAllocate& poolAlloc = AllocatorInstance<PoolAllocator>::Get();
|
||||
IAllocator& poolAllocator = AllocatorInstance<PoolAllocator>::GetAllocator();
|
||||
IAllocator& poolAllocator = AllocatorInstance<PoolAllocator>::Get();
|
||||
// 64 should be the max number of different pool sizes we can allocate.
|
||||
void* address[64];
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -352,12 +350,12 @@ namespace UnitTest
|
||||
int i = 0;
|
||||
for (int size = 8; size <= 256; ++i, size += 8)
|
||||
{
|
||||
address[i] = poolAlloc.Allocate(size, 8);
|
||||
EXPECT_GE(poolAlloc.AllocationSize(address[i]), (AZStd::size_t)size);
|
||||
address[i] = poolAllocator.Allocate(size, 8);
|
||||
EXPECT_GE(poolAllocator.AllocationSize(address[i]), (AZStd::size_t)size);
|
||||
memset(address[i], 1, size);
|
||||
}
|
||||
|
||||
EXPECT_GE(poolAlloc.NumAllocatedBytes(), 4126);
|
||||
EXPECT_GE(poolAllocator.NumAllocatedBytes(), 4126);
|
||||
|
||||
if (poolAllocator.GetRecords())
|
||||
{
|
||||
@@ -369,11 +367,11 @@ namespace UnitTest
|
||||
|
||||
for (i = 0; address[i] != nullptr; ++i)
|
||||
{
|
||||
poolAlloc.DeAllocate(address[i]);
|
||||
poolAllocator.DeAllocate(address[i]);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
EXPECT_EQ(0, poolAlloc.NumAllocatedBytes());
|
||||
EXPECT_EQ(0, poolAllocator.NumAllocatedBytes());
|
||||
|
||||
if (poolAllocator.GetRecords())
|
||||
{
|
||||
@@ -393,13 +391,13 @@ namespace UnitTest
|
||||
memset(address, 0, AZ_ARRAY_SIZE(address)*sizeof(void*));
|
||||
for (unsigned int j = 0; j < AZ_ARRAY_SIZE(address); ++j)
|
||||
{
|
||||
address[j] = poolAlloc.Allocate(256, 8, 0, "Pool Alloc", "This File", 123);
|
||||
EXPECT_GE(poolAlloc.AllocationSize(address[j]), 256);
|
||||
address[j] = poolAllocator.Allocate(256, 8, 0, "Pool Alloc", "This File", 123);
|
||||
EXPECT_GE(poolAllocator.AllocationSize(address[j]), 256);
|
||||
memset(address[j], 1, 256);
|
||||
}
|
||||
// AllocatorManager::Instance().ResetMemoryBreak(0);
|
||||
|
||||
EXPECT_GE(poolAlloc.NumAllocatedBytes(), AZ_ARRAY_SIZE(address)*256);
|
||||
EXPECT_GE(poolAllocator.NumAllocatedBytes(), AZ_ARRAY_SIZE(address)*256);
|
||||
|
||||
if (poolAllocator.GetRecords())
|
||||
{
|
||||
@@ -411,11 +409,11 @@ namespace UnitTest
|
||||
|
||||
for (unsigned int j = 0; j < AZ_ARRAY_SIZE(address); ++j)
|
||||
{
|
||||
poolAlloc.DeAllocate(address[j]);
|
||||
poolAllocator.DeAllocate(address[j]);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
EXPECT_EQ(0, poolAlloc.NumAllocatedBytes());
|
||||
EXPECT_EQ(0, poolAllocator.NumAllocatedBytes());
|
||||
|
||||
if (poolAllocator.GetRecords())
|
||||
{
|
||||
@@ -541,14 +539,14 @@ namespace UnitTest
|
||||
#endif
|
||||
void* addresses[numAllocations] = {nullptr};
|
||||
|
||||
IAllocatorAllocate& poolAlloc = AllocatorInstance<ThreadPoolAllocator>::Get();
|
||||
IAllocator& poolAllocator = AllocatorInstance<ThreadPoolAllocator>::Get();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Allocate
|
||||
for (int i = 0; i < numAllocations; ++i)
|
||||
{
|
||||
AZStd::size_t size = AZStd::GetMax(1, ((i + 1) * 2) % 256);
|
||||
addresses[i] = poolAlloc.Allocate(size, 8, 0, "Test Alloc", __FILE__, __LINE__);
|
||||
addresses[i] = poolAllocator.Allocate(size, 8, 0, "Test Alloc", __FILE__, __LINE__);
|
||||
EXPECT_NE(addresses[i], nullptr);
|
||||
memset(addresses[i], 1, size);
|
||||
}
|
||||
@@ -558,7 +556,7 @@ namespace UnitTest
|
||||
// Deallocate
|
||||
for (int i = numAllocations-1; i >=0; --i)
|
||||
{
|
||||
poolAlloc.DeAllocate(addresses[i]);
|
||||
poolAllocator.DeAllocate(addresses[i]);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
@@ -568,12 +566,12 @@ namespace UnitTest
|
||||
*/
|
||||
void SharedAlloc()
|
||||
{
|
||||
IAllocatorAllocate& poolAlloc = AllocatorInstance<ThreadPoolAllocator>::Get();
|
||||
IAllocator& poolAllocator = AllocatorInstance<ThreadPoolAllocator>::Get();
|
||||
for (int i = 0; i < m_numSharedAlloc; ++i)
|
||||
{
|
||||
AZStd::size_t minSize = sizeof(AllocClass);
|
||||
AZStd::size_t size = AZStd::GetMax((AZStd::size_t)(rand() % 256), minSize);
|
||||
AllocClass* ac = reinterpret_cast<AllocClass*>(poolAlloc.Allocate(size, AZStd::alignment_of<AllocClass>::value, 0, "Shared Alloc", __FILE__, __LINE__));
|
||||
AllocClass* ac = reinterpret_cast<AllocClass*>(poolAllocator.Allocate(size, AZStd::alignment_of<AllocClass>::value, 0, "Shared Alloc", __FILE__, __LINE__));
|
||||
AZStd::lock_guard<AZStd::mutex> lock(m_mutex);
|
||||
m_sharedAlloc.push_back(*ac);
|
||||
}
|
||||
@@ -584,7 +582,7 @@ namespace UnitTest
|
||||
*/
|
||||
void SharedDeAlloc()
|
||||
{
|
||||
IAllocatorAllocate& poolAlloc = AllocatorInstance<ThreadPoolAllocator>::Get();
|
||||
IAllocator& poolAllocator = AllocatorInstance<ThreadPoolAllocator>::Get();
|
||||
AllocClass* ac;
|
||||
int isDone = 0;
|
||||
while (isDone!=2)
|
||||
@@ -594,7 +592,7 @@ namespace UnitTest
|
||||
{
|
||||
ac = &m_sharedAlloc.front();
|
||||
m_sharedAlloc.pop_front();
|
||||
poolAlloc.DeAllocate(ac);
|
||||
poolAllocator.DeAllocate(ac);
|
||||
}
|
||||
|
||||
if (m_doneSharedAlloc) // once we know we don't add more elements, make one last check and exit.
|
||||
@@ -633,8 +631,7 @@ namespace UnitTest
|
||||
|
||||
void run()
|
||||
{
|
||||
IAllocatorAllocate& poolAlloc = AllocatorInstance<ThreadPoolAllocator>::Get();
|
||||
IAllocator& poolAllocator = AllocatorInstance<ThreadPoolAllocator>::GetAllocator();
|
||||
IAllocator& poolAllocator = AllocatorInstance<ThreadPoolAllocator>::Get();
|
||||
// 64 should be the max number of different pool sizes we can allocate.
|
||||
void* address[64];
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -645,12 +642,12 @@ namespace UnitTest
|
||||
int j = 0;
|
||||
for (int size = 8; size <= 256; ++j, size += 8)
|
||||
{
|
||||
address[j] = poolAlloc.Allocate(size, 8);
|
||||
EXPECT_GE(poolAlloc.AllocationSize(address[j]), (AZStd::size_t)size);
|
||||
address[j] = poolAllocator.Allocate(size, 8);
|
||||
EXPECT_GE(poolAllocator.AllocationSize(address[j]), (AZStd::size_t)size);
|
||||
memset(address[j], 1, size);
|
||||
}
|
||||
|
||||
EXPECT_GE(poolAlloc.NumAllocatedBytes(), 4126);
|
||||
EXPECT_GE(poolAllocator.NumAllocatedBytes(), 4126);
|
||||
|
||||
if (poolAllocator.GetRecords())
|
||||
{
|
||||
@@ -662,11 +659,11 @@ namespace UnitTest
|
||||
|
||||
for (int i = 0; address[i] != nullptr; ++i)
|
||||
{
|
||||
poolAlloc.DeAllocate(address[i]);
|
||||
poolAllocator.DeAllocate(address[i]);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
EXPECT_EQ(0, poolAlloc.NumAllocatedBytes());
|
||||
EXPECT_EQ(0, poolAllocator.NumAllocatedBytes());
|
||||
|
||||
if (poolAllocator.GetRecords())
|
||||
{
|
||||
@@ -681,12 +678,12 @@ namespace UnitTest
|
||||
memset(address, 0, AZ_ARRAY_SIZE(address)*sizeof(void*));
|
||||
for (unsigned int i = 0; i < AZ_ARRAY_SIZE(address); ++i)
|
||||
{
|
||||
address[i] = poolAlloc.Allocate(256, 8);
|
||||
EXPECT_GE(poolAlloc.AllocationSize(address[i]), 256);
|
||||
address[i] = poolAllocator.Allocate(256, 8);
|
||||
EXPECT_GE(poolAllocator.AllocationSize(address[i]), 256);
|
||||
memset(address[i], 1, 256);
|
||||
}
|
||||
|
||||
EXPECT_GE(poolAlloc.NumAllocatedBytes(), AZ_ARRAY_SIZE(address)*256);
|
||||
EXPECT_GE(poolAllocator.NumAllocatedBytes(), AZ_ARRAY_SIZE(address)*256);
|
||||
|
||||
if (poolAllocator.GetRecords())
|
||||
{
|
||||
@@ -698,11 +695,11 @@ namespace UnitTest
|
||||
|
||||
for (unsigned int i = 0; i < AZ_ARRAY_SIZE(address); ++i)
|
||||
{
|
||||
poolAlloc.DeAllocate(address[i]);
|
||||
poolAllocator.DeAllocate(address[i]);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
EXPECT_EQ(0, poolAlloc.NumAllocatedBytes());
|
||||
EXPECT_EQ(0, poolAllocator.NumAllocatedBytes());
|
||||
|
||||
if (poolAllocator.GetRecords())
|
||||
{
|
||||
@@ -820,7 +817,7 @@ namespace UnitTest
|
||||
desc.m_memoryBlock = azmalloc(desc.m_memoryBlockByteSize, desc.m_memoryBlockAlignment);
|
||||
|
||||
AllocatorInstance<BestFitExternalMapAllocator>::Create(desc);
|
||||
IAllocatorAllocate& bfAlloc = AllocatorInstance<BestFitExternalMapAllocator>::Get();
|
||||
IAllocator& bfAlloc = AllocatorInstance<BestFitExternalMapAllocator>::Get();
|
||||
|
||||
EXPECT_EQ( desc.m_memoryBlockByteSize, bfAlloc.Capacity() );
|
||||
EXPECT_EQ( 0, bfAlloc.NumAllocatedBytes() );
|
||||
@@ -882,8 +879,8 @@ namespace UnitTest
|
||||
|
||||
void run()
|
||||
{
|
||||
IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::GetAllocator();
|
||||
IAllocator& poolAllocator = AllocatorInstance<PoolAllocator>::GetAllocator();
|
||||
IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::Get();
|
||||
IAllocator& poolAllocator = AllocatorInstance<PoolAllocator>::Get();
|
||||
|
||||
void* ptr = azmalloc(16*1024, 32, SystemAllocator);
|
||||
EXPECT_EQ(0, ((size_t)ptr & 31)); // check alignment
|
||||
@@ -1010,27 +1007,27 @@ namespace UnitTest
|
||||
|
||||
void run()
|
||||
{
|
||||
IAllocator& sysAlloc = AllocatorInstance<SystemAllocator>::GetAllocator();
|
||||
IAllocator& poolAlloc = AllocatorInstance<PoolAllocator>::GetAllocator();
|
||||
IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::Get();
|
||||
IAllocator& poolAllocator = AllocatorInstance<PoolAllocator>::Get();
|
||||
|
||||
MyClass* ptr = aznew MyClass(202); /// this should allocate memory from the pool allocator
|
||||
EXPECT_EQ(0, ((size_t)ptr & 31)); // check alignment
|
||||
EXPECT_EQ(202, ptr->m_data); // check value
|
||||
|
||||
if (poolAlloc.GetRecords())
|
||||
if (poolAllocator.GetRecords())
|
||||
{
|
||||
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*poolAlloc.GetRecords());
|
||||
const Debug::AllocationRecordsType& records = poolAlloc.GetRecords()->GetMap();
|
||||
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*poolAllocator.GetRecords());
|
||||
const Debug::AllocationRecordsType& records = poolAllocator.GetRecords()->GetMap();
|
||||
Debug::AllocationRecordsType::const_iterator iter = records.find(ptr);
|
||||
EXPECT_TRUE(iter!=records.end()); // our allocation is in the list
|
||||
EXPECT_STREQ(iter->second.m_name, "MyClass");
|
||||
}
|
||||
delete ptr;
|
||||
|
||||
if (poolAlloc.GetRecords())
|
||||
if (poolAllocator.GetRecords())
|
||||
{
|
||||
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*poolAlloc.GetRecords());
|
||||
const Debug::AllocationRecordsType& records = poolAlloc.GetRecords()->GetMap();
|
||||
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*poolAllocator.GetRecords());
|
||||
const Debug::AllocationRecordsType& records = poolAllocator.GetRecords()->GetMap();
|
||||
EXPECT_TRUE(records.find(ptr)==records.end()); // our allocation is NOT in the list
|
||||
}
|
||||
|
||||
@@ -1038,19 +1035,19 @@ namespace UnitTest
|
||||
ptr = azcreate(MyClass, (101), SystemAllocator);
|
||||
EXPECT_EQ(0, ((size_t)ptr & 31)); // check alignment
|
||||
EXPECT_EQ(101, ptr->m_data); // check value
|
||||
if (sysAlloc.GetRecords())
|
||||
if (sysAllocator.GetRecords())
|
||||
{
|
||||
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*sysAlloc.GetRecords());
|
||||
const Debug::AllocationRecordsType& records = sysAlloc.GetRecords()->GetMap();
|
||||
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*sysAllocator.GetRecords());
|
||||
const Debug::AllocationRecordsType& records = sysAllocator.GetRecords()->GetMap();
|
||||
Debug::AllocationRecordsType::const_iterator iter = records.find(ptr);
|
||||
EXPECT_TRUE(iter!=records.end()); // our allocation is in the list
|
||||
EXPECT_STREQ(iter->second.m_name, "MyClass");
|
||||
}
|
||||
azdestroy(ptr, SystemAllocator);
|
||||
if (sysAlloc.GetRecords())
|
||||
if (sysAllocator.GetRecords())
|
||||
{
|
||||
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*sysAlloc.GetRecords());
|
||||
const Debug::AllocationRecordsType& records = sysAlloc.GetRecords()->GetMap();
|
||||
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*sysAllocator.GetRecords());
|
||||
const Debug::AllocationRecordsType& records = sysAllocator.GetRecords()->GetMap();
|
||||
EXPECT_TRUE(records.find(ptr)==records.end()); // our allocation is NOT in the list
|
||||
}
|
||||
|
||||
@@ -1059,19 +1056,19 @@ namespace UnitTest
|
||||
ptr = azcreate(MyClass, (505), SystemAllocator, "MyClassNamed");
|
||||
EXPECT_EQ(0, ((size_t)ptr & 31)); // check alignment
|
||||
EXPECT_EQ(505, ptr->m_data); // check value
|
||||
if (sysAlloc.GetRecords())
|
||||
if (sysAllocator.GetRecords())
|
||||
{
|
||||
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*sysAlloc.GetRecords());
|
||||
const Debug::AllocationRecordsType& records = sysAlloc.GetRecords()->GetMap();
|
||||
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*sysAllocator.GetRecords());
|
||||
const Debug::AllocationRecordsType& records = sysAllocator.GetRecords()->GetMap();
|
||||
Debug::AllocationRecordsType::const_iterator iter = records.find(ptr);
|
||||
EXPECT_TRUE(iter!=records.end()); // our allocation is in the list
|
||||
EXPECT_STREQ(iter->second.m_name, "MyClassNamed");
|
||||
}
|
||||
azdestroy(ptr); // imply SystemAllocator
|
||||
if (sysAlloc.GetRecords())
|
||||
if (sysAllocator.GetRecords())
|
||||
{
|
||||
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*sysAlloc.GetRecords());
|
||||
const Debug::AllocationRecordsType& records = sysAlloc.GetRecords()->GetMap();
|
||||
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*sysAllocator.GetRecords());
|
||||
const Debug::AllocationRecordsType& records = sysAllocator.GetRecords()->GetMap();
|
||||
EXPECT_TRUE(records.find(ptr)==records.end()); // our allocation is NOT in the list
|
||||
}
|
||||
|
||||
@@ -1080,20 +1077,20 @@ namespace UnitTest
|
||||
EXPECT_EQ(0, ((size_t)ptr & 31)); // check alignment
|
||||
EXPECT_EQ(303, ptr->m_data); // check value
|
||||
|
||||
if (poolAlloc.GetRecords())
|
||||
if (poolAllocator.GetRecords())
|
||||
{
|
||||
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*poolAlloc.GetRecords());
|
||||
const Debug::AllocationRecordsType& records = poolAlloc.GetRecords()->GetMap();
|
||||
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*poolAllocator.GetRecords());
|
||||
const Debug::AllocationRecordsType& records = poolAllocator.GetRecords()->GetMap();
|
||||
Debug::AllocationRecordsType::const_iterator iter = records.find(ptr);
|
||||
EXPECT_TRUE(iter != records.end()); // our allocation is in the list
|
||||
EXPECT_STREQ(iter->second.m_name, "MyClass");
|
||||
}
|
||||
delete ptr;
|
||||
|
||||
if (poolAlloc.GetRecords())
|
||||
if (poolAllocator.GetRecords())
|
||||
{
|
||||
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*poolAlloc.GetRecords());
|
||||
const Debug::AllocationRecordsType& records = poolAlloc.GetRecords()->GetMap();
|
||||
AZStd::lock_guard<AZ::Debug::AllocationRecords> lock(*poolAllocator.GetRecords());
|
||||
const Debug::AllocationRecordsType& records = poolAllocator.GetRecords()->GetMap();
|
||||
EXPECT_TRUE(records.find(ptr) == records.end()); // our allocation is NOT in the list
|
||||
}
|
||||
}
|
||||
@@ -1140,8 +1137,8 @@ namespace UnitTest
|
||||
return (size_t)1 << (size_t)(MAX_ALIGNMENT_LOG2 * r);
|
||||
}
|
||||
|
||||
class DebugSysAlloc
|
||||
: public AZ::IAllocatorAllocate
|
||||
class DebugSysAllocSchema
|
||||
: public AZ::IAllocatorSchema
|
||||
{
|
||||
pointer_type Allocate(size_type byteSize, size_type alignment, int flags, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) override
|
||||
{
|
||||
@@ -1176,8 +1173,6 @@ namespace UnitTest
|
||||
size_type GetMaxAllocationSize() const override { return 1 * 1024 * 1024 * 1024; }
|
||||
/// Returns max allocation size of a single contiguous allocation
|
||||
size_type GetMaxContiguousAllocationSize() const override { return 1 * 1024 * 1024 * 1024; }
|
||||
/// Returns a pointer to a sub-allocator or NULL.
|
||||
IAllocatorAllocate* GetSubAllocator() override { return NULL; }
|
||||
};
|
||||
public:
|
||||
void SetUp() override
|
||||
@@ -2565,7 +2560,7 @@ namespace UnitTest
|
||||
printf("\n\t\t\t=======================\n");
|
||||
printf("\t\t\tSchemas Benchmark Test!\n");
|
||||
printf("\t\t\t=======================\n");
|
||||
DebugSysAlloc da;
|
||||
DebugSysAllocSchema da;
|
||||
{
|
||||
HphaSchema::Descriptor hphaDesc;
|
||||
hphaDesc.m_fixedMemoryBlockByteSize = AZ_TRAIT_OS_HPHA_MEMORYBLOCKBYTESIZE;
|
||||
|
||||
@@ -113,7 +113,6 @@ namespace Benchmark
|
||||
{
|
||||
}
|
||||
|
||||
// IAllocatorAllocate
|
||||
static void* Allocate(size_t byteSize, size_t)
|
||||
{
|
||||
s_numAllocatedBytes += byteSize;
|
||||
@@ -157,11 +156,9 @@ namespace Benchmark
|
||||
}
|
||||
|
||||
private:
|
||||
static size_t s_numAllocatedBytes;
|
||||
inline static size_t s_numAllocatedBytes = 0;
|
||||
};
|
||||
|
||||
size_t TestAllocatorWrapper<RawMallocAllocator>::s_numAllocatedBytes = 0;
|
||||
|
||||
// Some allocator are not fully declared, those we simply setup from the schema
|
||||
class MallocSchemaAllocator : public AZ::SimpleSchemaAllocator<AZ::MallocSchema>
|
||||
{
|
||||
@@ -581,6 +578,7 @@ namespace Benchmark
|
||||
//BM_REGISTER_ALLOCATOR(BestFitExternalMapAllocator, BestFitExternalMapAllocator); // Requires to pre-allocate blocks and cannot work as a general-purpose allocator
|
||||
//BM_REGISTER_ALLOCATOR(HeapSchemaAllocator, TestHeapSchemaAllocator); // Requires to pre-allocate blocks and cannot work as a general-purpose allocator
|
||||
//BM_REGISTER_SCHEMA(PoolSchema); // Requires special alignment requests while allocating
|
||||
// BM_REGISTER_ALLOCATOR(OSAllocator, OSAllocator); // Requires special treatment to initialize since it will be already initialized, maybe creating a different instance?
|
||||
|
||||
#undef BM_REGISTER_ALLOCATOR
|
||||
#undef BM_REGISTER_SIZE_FIXTURES
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Memory/AllocatorManager.h>
|
||||
#include <AzCore/Memory/AllocatorOverrideShim.h>
|
||||
#include <AzCore/Memory/MallocSchema.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
|
||||
@@ -47,9 +46,6 @@ namespace UnitTest
|
||||
|
||||
void RunTests()
|
||||
{
|
||||
TestAllocatorShimWithDeallocateAfter();
|
||||
TestAllocatorShimRemovedAfterFinalization();
|
||||
TestAllocatorShimUsedForRealloc();
|
||||
TearDownAllocatorManagerTest();
|
||||
}
|
||||
|
||||
@@ -64,7 +60,7 @@ namespace UnitTest
|
||||
EXPECT_EQ(m_manager->GetNumAllocators(), 0);
|
||||
AllocatorInstance<SystemAllocator>::Create();
|
||||
EXPECT_EQ(m_manager->GetNumAllocators(), 2); // SystemAllocator creates the OSAllocator if it doesn't exist
|
||||
m_systemAllocator = &AllocatorInstance<SystemAllocator>::GetAllocator();
|
||||
m_systemAllocator = &AllocatorInstance<SystemAllocator>::Get();
|
||||
}
|
||||
|
||||
void TearDownAllocatorManagerTest()
|
||||
@@ -83,85 +79,6 @@ namespace UnitTest
|
||||
m_systemAllocator = nullptr;
|
||||
}
|
||||
|
||||
void TestAllocatorShimWithDeallocateAfter()
|
||||
{
|
||||
SetUpAllocatorManagerTest();
|
||||
|
||||
// Should begin with a shim installed. If this fails, check that AZCORE_MEMORY_ENABLE_OVERRIDES is enabled in AllocatorManager.cpp.
|
||||
EXPECT_NE(m_systemAllocator->GetAllocationSource(), m_systemAllocator->GetOriginalAllocationSource());
|
||||
|
||||
const int testAllocBytes = TEST_ALLOC_BYTES;
|
||||
|
||||
// Allocate from the shim, which should take from the allocator's original source
|
||||
void* p = m_systemAllocator->GetAllocationSource()->Allocate(testAllocBytes, 0, 0);
|
||||
EXPECT_NE(p, nullptr);
|
||||
EXPECT_EQ(m_systemAllocator->GetOriginalAllocationSource()->NumAllocatedBytes(), testAllocBytes);
|
||||
|
||||
// Add the override schema
|
||||
m_manager->SetOverrideAllocatorSource(&m_mallocSchema);
|
||||
|
||||
// Allocations should go through malloc schema instead of the allocator's regular schema
|
||||
void* q = m_systemAllocator->GetAllocationSource()->Allocate(testAllocBytes, 0, 0);
|
||||
EXPECT_NE(q, nullptr);
|
||||
EXPECT_EQ(m_mallocSchema.NumAllocatedBytes(), testAllocBytes);
|
||||
EXPECT_EQ(m_systemAllocator->GetOriginalAllocationSource()->NumAllocatedBytes(), testAllocBytes);
|
||||
|
||||
// Finalize configuration, no more shims should be created after this point
|
||||
m_manager->FinalizeConfiguration();
|
||||
|
||||
// Deallocating the original orphaned allocation from the SystemAllocator should remove the shim
|
||||
EXPECT_NE(m_systemAllocator->GetAllocationSource(), &m_mallocSchema);
|
||||
m_systemAllocator->GetAllocationSource()->DeAllocate(p);
|
||||
EXPECT_EQ(m_systemAllocator->GetAllocationSource(), &m_mallocSchema);
|
||||
|
||||
// Clean up
|
||||
m_systemAllocator->GetAllocationSource()->DeAllocate(q);
|
||||
}
|
||||
|
||||
void TestAllocatorShimRemovedAfterFinalization()
|
||||
{
|
||||
SetUpAllocatorManagerTest();
|
||||
|
||||
// Should begin with a shim installed
|
||||
EXPECT_NE(m_systemAllocator->GetAllocationSource(), m_systemAllocator->GetOriginalAllocationSource());
|
||||
|
||||
// Finalizing the configuration should remove the shim if it was unused
|
||||
m_manager->FinalizeConfiguration();
|
||||
EXPECT_EQ(m_systemAllocator->GetAllocationSource(), m_systemAllocator->GetOriginalAllocationSource());
|
||||
}
|
||||
|
||||
void TestAllocatorShimUsedForRealloc()
|
||||
{
|
||||
SetUpAllocatorManagerTest();
|
||||
|
||||
// Should begin with a shim installed
|
||||
EXPECT_NE(m_systemAllocator->GetAllocationSource(), m_systemAllocator->GetOriginalAllocationSource());
|
||||
|
||||
const int testAllocBytes = TEST_ALLOC_BYTES;
|
||||
|
||||
// Allocate from the shim, which should take from the allocator's original source
|
||||
void* p = m_systemAllocator->GetAllocationSource()->Allocate(testAllocBytes, 0, 0);
|
||||
EXPECT_NE(p, nullptr);
|
||||
EXPECT_EQ(m_systemAllocator->GetOriginalAllocationSource()->NumAllocatedBytes(), testAllocBytes);
|
||||
|
||||
// Add the override schema and finalize
|
||||
m_manager->SetOverrideAllocatorSource(&m_mallocSchema);
|
||||
m_manager->FinalizeConfiguration();
|
||||
|
||||
// Shim should still be present
|
||||
EXPECT_NE(m_systemAllocator->GetAllocationSource(), &m_mallocSchema);
|
||||
|
||||
// Reallocation should move allocation from the old source to the new source
|
||||
EXPECT_EQ(m_mallocSchema.NumAllocatedBytes(), 0);
|
||||
void* q = m_systemAllocator->GetAllocationSource()->ReAllocate(p, testAllocBytes * 2, 0);
|
||||
EXPECT_NE(p, q);
|
||||
EXPECT_EQ(m_mallocSchema.NumAllocatedBytes(), testAllocBytes * 2);
|
||||
EXPECT_EQ(m_systemAllocator->GetOriginalAllocationSource()->NumAllocatedBytes(), 0);
|
||||
|
||||
// Reallocation should also have removed the shim as it was no longer necessary
|
||||
EXPECT_EQ(m_systemAllocator->GetAllocationSource(), &m_mallocSchema);
|
||||
}
|
||||
|
||||
MallocSchema m_mallocSchema;
|
||||
AllocatorManager* m_manager = nullptr;
|
||||
IAllocator* m_systemAllocator = nullptr;
|
||||
|
||||
@@ -1975,7 +1975,7 @@ namespace AZ::IO
|
||||
AZ_Error("Archive", false, "OSAllocator is not ready. It cannot be used to allocate a MemoryBlock");
|
||||
return {};
|
||||
}
|
||||
AZ::IAllocatorAllocate* allocator = &AZ::AllocatorInstance<AZ::OSAllocator>::Get();
|
||||
AZ::IAllocator* allocator = &AZ::AllocatorInstance<AZ::OSAllocator>::Get();
|
||||
AZStd::intrusive_ptr<AZ::IO::MemoryBlock> memoryBlock{ new (allocator->Allocate(sizeof(AZ::IO::MemoryBlock), alignof(AZ::IO::MemoryBlock))) AZ::IO::MemoryBlock{AZ::IO::MemoryBlockDeleter{ &AZ::AllocatorInstance<AZ::OSAllocator>::Get() }} };
|
||||
auto CreateFunc = [](size_t byteSize, size_t byteAlignment, const char* name)
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace AZ::IO
|
||||
struct MemoryBlockDeleter
|
||||
{
|
||||
void operator()(const AZStd::intrusive_refcount<AZStd::atomic_uint, MemoryBlockDeleter>* ptr) const;
|
||||
AZ::IAllocatorAllocate* m_allocator{};
|
||||
AZ::IAllocator* m_allocator{};
|
||||
};
|
||||
struct MemoryBlock
|
||||
: AZStd::intrusive_refcount<AZStd::atomic_uint, MemoryBlockDeleter>
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace AZ::IO::ZipDir
|
||||
AZ_Error("Archive", false, "OSAllocator is not ready. It cannot be used to allocate a MemoryBlock");
|
||||
return {};
|
||||
}
|
||||
AZ::IAllocatorAllocate* allocator = &AZ::AllocatorInstance<AZ::OSAllocator>::Get();
|
||||
AZ::IAllocator* allocator = &AZ::AllocatorInstance<AZ::OSAllocator>::Get();
|
||||
AZStd::intrusive_ptr<AZ::IO::MemoryBlock> memoryBlock{ new (allocator->Allocate(sizeof(AZ::IO::MemoryBlock), alignof(AZ::IO::MemoryBlock))) AZ::IO::MemoryBlock{AZ::IO::MemoryBlockDeleter{ &AZ::AllocatorInstance<AZ::OSAllocator>::Get() }} };
|
||||
auto CreateFunc = [](size_t byteSize, size_t byteAlignment, const char* name)
|
||||
{
|
||||
@@ -142,14 +142,14 @@ namespace AZ::IO::ZipDir
|
||||
{
|
||||
}
|
||||
|
||||
Cache::Cache(AZ::IAllocatorAllocate* allocator)
|
||||
Cache::Cache(AZ::IAllocator* allocator)
|
||||
: m_fileHandle(AZ::IO::InvalidHandle)
|
||||
, m_nFlags(0)
|
||||
, m_lCDROffset(0)
|
||||
, m_encryptedHeaders(ZipFile::HEADERS_NOT_ENCRYPTED)
|
||||
, m_allocator{ allocator }
|
||||
{
|
||||
AZ_Assert(allocator, "IAllocatorAllocate object is required in order to allocated memory for the ZipDir Cache operations");
|
||||
AZ_Assert(allocator, "IAllocator object is required in order to allocated memory for the ZipDir Cache operations");
|
||||
}
|
||||
|
||||
void Cache::Close()
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace AZ::IO::ZipDir
|
||||
inline static constexpr int compressedBlockHeaderSizeInBytes = 4; //number of bytes we need in front of the compressed block to indicate which compressor was used
|
||||
|
||||
Cache();
|
||||
explicit Cache(AZ::IAllocatorAllocate* allocator);
|
||||
explicit Cache(AZ::IAllocator* allocator);
|
||||
|
||||
~Cache()
|
||||
{
|
||||
@@ -133,7 +133,7 @@ namespace AZ::IO::ZipDir
|
||||
friend class FileEntryTransactionAdd;
|
||||
FileEntryTree m_treeDir;
|
||||
AZ::IO::HandleType m_fileHandle;
|
||||
AZ::IAllocatorAllocate* m_allocator;
|
||||
AZ::IAllocator* m_allocator;
|
||||
AZ::IO::Path m_strFilePath;
|
||||
|
||||
// String Pool for persistently storing paths as long as they reside in the cache
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace AZ::IO::ZipDir
|
||||
{
|
||||
}
|
||||
|
||||
auto FileDataRecord::New(const FileRecord& rThat, AZ::IAllocatorAllocate* allocator) -> AZStd::intrusive_ptr<FileDataRecord>
|
||||
auto FileDataRecord::New(const FileRecord& rThat, AZ::IAllocator* allocator) -> AZStd::intrusive_ptr<FileDataRecord>
|
||||
{
|
||||
auto fileDataRecordAlloc = reinterpret_cast<FileDataRecord*>(allocator->Allocate(
|
||||
sizeof(FileDataRecord) + rThat.pFileEntryBase->desc.lSizeCompressed,
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace AZ::IO::ZipDir
|
||||
{
|
||||
void operator()(const AZStd::intrusive_refcount<AZStd::atomic_uint, FileDataRecordDeleter>* ptr) const;
|
||||
|
||||
AZ::IAllocatorAllocate* m_allocator{};
|
||||
AZ::IAllocator* m_allocator{};
|
||||
};
|
||||
struct FileDataRecord
|
||||
: public FileRecord
|
||||
@@ -36,7 +36,7 @@ namespace AZ::IO::ZipDir
|
||||
{
|
||||
FileDataRecord();
|
||||
|
||||
static auto New(const FileRecord& rThat, AZ::IAllocatorAllocate* allocator) ->AZStd::intrusive_ptr<FileDataRecord>;
|
||||
static auto New(const FileRecord& rThat, AZ::IAllocator* allocator) ->AZStd::intrusive_ptr<FileDataRecord>;
|
||||
|
||||
void* GetData() {return this + 1; }
|
||||
};
|
||||
|
||||
@@ -25,13 +25,13 @@ namespace AZ::IO::ZipDir::ZipDirStructuresInternal
|
||||
{
|
||||
static void* ZlibAlloc(void* userData, uint32_t item, uint32_t size)
|
||||
{
|
||||
auto allocator = reinterpret_cast<AZ::IAllocatorAllocate*>(userData);
|
||||
auto allocator = reinterpret_cast<AZ::IAllocator*>(userData);
|
||||
return allocator->Allocate(item * size, alignof(uint8_t), 0, "ZLibAlloc");
|
||||
}
|
||||
|
||||
static void ZlibFree(void* userData, void* ptr)
|
||||
{
|
||||
auto allocator = reinterpret_cast<AZ::IAllocatorAllocate*>(userData);
|
||||
auto allocator = reinterpret_cast<AZ::IAllocator*>(userData);
|
||||
allocator->DeAllocate(ptr);
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ namespace AZ::IO::ZipDir::ZipDirStructuresInternal
|
||||
return {};
|
||||
}
|
||||
|
||||
AZ::IAllocatorAllocate* allocator = &AZ::AllocatorInstance<AZ::OSAllocator>::Get();
|
||||
AZ::IAllocator* allocator = &AZ::AllocatorInstance<AZ::OSAllocator>::Get();
|
||||
AZStd::intrusive_ptr<AZ::IO::MemoryBlock> memoryBlock{ new (allocator->Allocate(sizeof(AZ::IO::MemoryBlock), alignof(AZ::IO::MemoryBlock))) AZ::IO::MemoryBlock{AZ::IO::MemoryBlockDeleter{ &AZ::AllocatorInstance<AZ::OSAllocator>::Get() }} };
|
||||
auto CreateFunc = [](size_t byteSize, size_t byteAlignment, const char* name)
|
||||
{
|
||||
@@ -451,7 +451,7 @@ namespace AZ::IO::ZipDir
|
||||
if (GetDiskFreeSpaceA(drive.c_str(),nullptr, &bytesPerSector, nullptr, nullptr))
|
||||
{
|
||||
m_nSectorSize = bytesPerSector;
|
||||
AZ::IAllocatorAllocate& allocator = AZ::AllocatorInstance<AZ::OSAllocator>::Get();
|
||||
AZ::IAllocator& allocator = AZ::AllocatorInstance<AZ::OSAllocator>::Get();
|
||||
if (m_pReadTarget)
|
||||
{
|
||||
allocator.DeAllocate(m_pReadTarget);
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace O3DELauncher
|
||||
|
||||
ResourceLimitUpdater m_updateResourceLimits = nullptr; //!< callback for updating system resources, if necessary
|
||||
OnPostApplicationStart m_onPostAppStart = nullptr; //!< callback notifying the platform specific entry point that AzGameFramework::GameApplication::Start has been called
|
||||
AZ::IAllocatorAllocate* m_allocator = nullptr; //!< Used to allocate the temporary bootstrap memory, as well as the main \ref SystemAllocator heap. If null, OSAllocator will be used
|
||||
AZ::IAllocator* m_allocator = nullptr; //!< Used to allocate the temporary bootstrap memory, as well as the main \ref SystemAllocator heap. If null, OSAllocator will be used
|
||||
|
||||
const char* m_appResourcesPath = "."; //!< Path to the device specific assets, default is equivalent to blank path in ParseEngineConfig
|
||||
const char* m_appWriteStoragePath = nullptr; //!< Path to writeable storage if different than assets path, used to override userPath and logPath
|
||||
|
||||
@@ -23,19 +23,9 @@ inline void* CryModuleMallocImpl(size_t size, const char* file, const int line)
|
||||
#define CryModuleFree(ptr) CryModuleFreeImpl(ptr, __FILE__, __LINE__)
|
||||
#define CryModuleMemalignFree(ptr) CryModuleFreeImpl(ptr, __FILE__, __LINE__)
|
||||
|
||||
inline void CryModuleFreeImpl(void* ptr, const char* file, const int line)
|
||||
inline void CryModuleFreeImpl(void* ptr, const char*, const int)
|
||||
{
|
||||
|
||||
AZ::IAllocator& allocator = AZ::AllocatorInstance<AZ::LegacyAllocator>::GetAllocator();
|
||||
|
||||
if (allocator.IsAllocationSourceChanged())
|
||||
{
|
||||
allocator.GetAllocationSource()->DeAllocate(ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
static_cast<AZ::LegacyAllocator&>(allocator).DeAllocate(ptr, file, line);
|
||||
}
|
||||
AZ::AllocatorInstance<AZ::LegacyAllocator>::Get().DeAllocate(ptr, 0, 0);
|
||||
}
|
||||
|
||||
#define CryModuleMemalign(size, alignment) CryModuleMemalignImpl(size, alignment, __FILE__, __LINE__)
|
||||
@@ -79,17 +69,5 @@ inline void* CryModuleReallocAlignImpl(void* prev, size_t size, size_t alignment
|
||||
}
|
||||
#endif
|
||||
|
||||
AZ::IAllocator& allocator = AZ::AllocatorInstance<AZ::LegacyAllocator>::GetAllocator();
|
||||
void *ptr;
|
||||
|
||||
if (allocator.IsAllocationSourceChanged())
|
||||
{
|
||||
ptr = allocator.GetAllocationSource()->ReAllocate(prev, size, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = static_cast<AZ::LegacyAllocator&>(allocator).ReAllocate(prev, size, 0, file, line);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
return AZ::AllocatorInstance<AZ::LegacyAllocator>::Get().ReAllocate(prev, size, 0);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class IAllocatorAllocate;
|
||||
class IAllocator;
|
||||
|
||||
namespace RHI
|
||||
{
|
||||
@@ -66,7 +66,7 @@ namespace AZ
|
||||
DrawPacket() = default;
|
||||
|
||||
// The allocator used to release the memory when Release() is called.
|
||||
IAllocatorAllocate* m_allocator = nullptr;
|
||||
IAllocator* m_allocator = nullptr;
|
||||
|
||||
// The bit-mask of all active filter tags.
|
||||
DrawListMask m_drawListMask = 0;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class IAllocatorAllocate;
|
||||
class IAllocator;
|
||||
|
||||
namespace RHI
|
||||
{
|
||||
@@ -50,7 +50,7 @@ namespace AZ
|
||||
// NOTE: This is configurable; just used to control the amount of memory held by the builder.
|
||||
static const size_t DrawItemCountMax = 16;
|
||||
|
||||
void Begin(IAllocatorAllocate* allocator);
|
||||
void Begin(IAllocator* allocator);
|
||||
|
||||
void SetDrawArguments(const DrawArguments& drawArguments);
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace AZ
|
||||
private:
|
||||
void ClearData();
|
||||
|
||||
IAllocatorAllocate* m_allocator = nullptr;
|
||||
IAllocator* m_allocator = nullptr;
|
||||
DrawArguments m_drawArguments;
|
||||
DrawListMask m_drawListMask = 0;
|
||||
DrawFilterMask m_drawFilterMask = DrawFilterMaskDefaultValue;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace AZ
|
||||
{
|
||||
namespace RHI
|
||||
{
|
||||
void DrawPacketBuilder::Begin(IAllocatorAllocate* allocator)
|
||||
void DrawPacketBuilder::Begin(IAllocator* allocator)
|
||||
{
|
||||
m_allocator = allocator ? allocator : &AllocatorInstance<SystemAllocator>::Get();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user