diff options
| author | Stefan Boberg <[email protected]> | 2024-11-25 09:56:23 +0100 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2024-11-25 09:56:23 +0100 |
| commit | 8b8de92e51db4cc4c1727712c736dcba5f79d369 (patch) | |
| tree | 1f58edaaad389837a7652daebab246125762240e /src/zencore/memory/fmalloc.cpp | |
| parent | 5.5.13 (diff) | |
| download | zen-8b8de92e51db4cc4c1727712c736dcba5f79d369.tar.xz zen-8b8de92e51db4cc4c1727712c736dcba5f79d369.zip | |
Insights-compatible memory tracking (#214)
This change introduces support for tracing of memory allocation activity. The code is ported from UE5, and Unreal Insights can be used to analyze the output. This is currently only fully supported on Windows, but will be extended to Mac/Linux in the near future.
To activate full memory tracking, pass `--trace=memory` on the commandline alongside `--tracehost=<ip>` or `-tracefile=<path>`. For more control over how much detail is traced you can instead pass some combination of `callstack`, `memtag`, `memalloc` instead. In practice, `--trace=memory` is an alias for `--trace=callstack,memtag,memalloc`). For convenience we also support `--trace=memory_light` which omits call stacks.
This change also introduces multiple memory allocators, which may be selected via command-line option `--malloc=<allocator>`:
* `mimalloc` - mimalloc (default, same as before)
* `rpmalloc` - rpmalloc is another high performance allocator for multithreaded applications which may be a better option than mimalloc (to be evaluated). Due to toolchain limitations this is currently only supported on Windows.
* `stomp` - an allocator intended to be used during development/debugging to help track down memory issues such as use-after-free or out-of-bounds access. Currently only supported on Windows.
* `ansi` - fallback to default system allocator
Diffstat (limited to 'src/zencore/memory/fmalloc.cpp')
| -rw-r--r-- | src/zencore/memory/fmalloc.cpp | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/src/zencore/memory/fmalloc.cpp b/src/zencore/memory/fmalloc.cpp new file mode 100644 index 000000000..3e96003f5 --- /dev/null +++ b/src/zencore/memory/fmalloc.cpp @@ -0,0 +1,156 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include <string.h> +#include <zencore/memory/fmalloc.h> +#include <zencore/memory/memory.h> + +namespace zen { + +////////////////////////////////////////////////////////////////////////// + +class FInitialMalloc : public FMalloc +{ + virtual void* Malloc(size_t Count, uint32_t Alignment = DEFAULT_ALIGNMENT) override + { + Memory::Initialize(); + return GMalloc->Malloc(Count, Alignment); + } + virtual void* TryMalloc(size_t Count, uint32_t Alignment = DEFAULT_ALIGNMENT) override + { + Memory::Initialize(); + return GMalloc->TryMalloc(Count, Alignment); + } + virtual void* Realloc(void* Original, size_t Count, uint32_t Alignment = DEFAULT_ALIGNMENT) override + { + Memory::Initialize(); + return GMalloc->Realloc(Original, Count, Alignment); + } + virtual void* TryRealloc(void* Original, size_t Count, uint32_t Alignment = DEFAULT_ALIGNMENT) override + { + Memory::Initialize(); + return GMalloc->TryRealloc(Original, Count, Alignment); + } + virtual void Free(void* Original) override + { + Memory::Initialize(); + return GMalloc->Free(Original); + } + virtual void* MallocZeroed(size_t Count, uint32_t Alignment = DEFAULT_ALIGNMENT) override + { + Memory::Initialize(); + return GMalloc->MallocZeroed(Count, Alignment); + } + + virtual void* TryMallocZeroed(size_t Count, uint32_t Alignment = DEFAULT_ALIGNMENT) override + { + Memory::Initialize(); + return GMalloc->TryMallocZeroed(Count, Alignment); + } + virtual size_t QuantizeSize(size_t Count, uint32_t Alignment) override + { + Memory::Initialize(); + return GMalloc->QuantizeSize(Count, Alignment); + } + virtual bool GetAllocationSize(void* Original, size_t& SizeOut) override + { + Memory::Initialize(); + return GMalloc->GetAllocationSize(Original, SizeOut); + } + virtual void OnMallocInitialized() override {} + virtual void Trim(bool bTrimThreadCaches) override { ZEN_UNUSED(bTrimThreadCaches); } +} GInitialMalloc; + +FMalloc* GMalloc = &GInitialMalloc; /* Memory allocator */ + +////////////////////////////////////////////////////////////////////////// + +void* +FUseSystemMallocForNew::operator new(size_t Size) +{ + return Memory::SystemMalloc(Size); +} + +void +FUseSystemMallocForNew::operator delete(void* Ptr) +{ + Memory::SystemFree(Ptr); +} + +void* +FUseSystemMallocForNew::operator new[](size_t Size) +{ + return Memory::SystemMalloc(Size); +} + +void +FUseSystemMallocForNew::operator delete[](void* Ptr) +{ + Memory::SystemFree(Ptr); +} + +////////////////////////////////////////////////////////////////////////// + +void* +FMalloc::TryRealloc(void* Original, size_t Count, uint32_t Alignment) +{ + return Realloc(Original, Count, Alignment); +} + +void* +FMalloc::TryMalloc(size_t Count, uint32_t Alignment) +{ + return Malloc(Count, Alignment); +} + +void* +FMalloc::TryMallocZeroed(size_t Count, uint32_t Alignment) +{ + return MallocZeroed(Count, Alignment); +} + +void* +FMalloc::MallocZeroed(size_t Count, uint32_t Alignment) +{ + void* const Memory = Malloc(Count, Alignment); + + if (Memory) + { + ::memset(Memory, 0, Count); + } + + return Memory; +} + +void +FMalloc::OutOfMemory(size_t Size, uint32_t Alignment) +{ + ZEN_UNUSED(Size, Alignment); + // no-op by default +} + +void +FMalloc::Trim(bool bTrimThreadCaches) +{ + ZEN_UNUSED(bTrimThreadCaches); +} + +void +FMalloc::OnMallocInitialized() +{ +} + +bool +FMalloc::GetAllocationSize(void* Original, size_t& SizeOut) +{ + ZEN_UNUSED(Original, SizeOut); + return false; // Generic implementation has no way of determining this +} + +size_t +FMalloc::QuantizeSize(size_t Count, uint32_t Alignment) +{ + ZEN_UNUSED(Alignment); + return Count; // Generic implementation has no way of determining this +} + +} // namespace zen |