diff --git a/core/os/memory.cpp b/core/os/memory.cpp index a8eec8401c7..0ce32ad6807 100644 --- a/core/os/memory.cpp +++ b/core/os/memory.cpp @@ -30,6 +30,7 @@ #include "memory.h" +#include "core/profiling/profiling.h" #include "core/templates/safe_refcount.h" #include @@ -68,6 +69,7 @@ void *Memory::alloc_aligned_static(size_t p_bytes, size_t p_alignment) { if ((p1 = (void *)malloc(p_bytes + p_alignment - 1 + sizeof(uint32_t))) == nullptr) { return nullptr; } + GodotProfileAlloc(p1, p_bytes + p_alignment - 1 + sizeof(uint32_t)); p2 = (void *)(((uintptr_t)p1 + sizeof(uint32_t) + p_alignment - 1) & ~((p_alignment)-1)); *((uint32_t *)p2 - 1) = (uint32_t)((uintptr_t)p2 - (uintptr_t)p1); @@ -90,6 +92,7 @@ void *Memory::realloc_aligned_static(void *p_memory, size_t p_bytes, size_t p_pr void Memory::free_aligned_static(void *p_memory) { uint32_t offset = *((uint32_t *)p_memory - 1); void *p = (void *)((uint8_t *)p_memory - offset); + GodotProfileFree(p); free(p); } @@ -107,6 +110,7 @@ void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) { } else { mem = malloc(p_bytes + (prepad ? DATA_OFFSET : 0)); } + GodotProfileAlloc(mem, p_bytes + (prepad ? DATA_OFFSET : 0)); ERR_FAIL_NULL_V(mem, nullptr); @@ -156,13 +160,16 @@ void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) { #endif if (p_bytes == 0) { + GodotProfileFree(mem); free(mem); return nullptr; } else { *s = p_bytes; + GodotProfileFree(mem); mem = (uint8_t *)realloc(mem, p_bytes + DATA_OFFSET); ERR_FAIL_NULL_V(mem, nullptr); + GodotProfileAlloc(mem, p_bytes + DATA_OFFSET); s = (uint64_t *)(mem + SIZE_OFFSET); @@ -171,7 +178,9 @@ void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) { return mem + DATA_OFFSET; } } else { + GodotProfileFree(mem); mem = (uint8_t *)realloc(mem, p_bytes); + GodotProfileAlloc(mem, p_bytes); ERR_FAIL_COND_V(mem == nullptr && p_bytes > 0, nullptr); @@ -198,8 +207,10 @@ void Memory::free_static(void *p_ptr, bool p_pad_align) { _current_mem_usage.sub(*s); #endif + GodotProfileFree(mem); free(mem); } else { + GodotProfileFree(mem); free(mem); } } diff --git a/core/profiling/profiling.h b/core/profiling/profiling.h index 35bdbf7142e..55c02002fb3 100644 --- a/core/profiling/profiling.h +++ b/core/profiling/profiling.h @@ -66,6 +66,10 @@ new (&__godot_tracy_zone_##m_group_name) tracy::ScopedZone(&TracyConcat(__tracy_source_location, TracyLine), TRACY_CALLSTACK, true) #endif +// Memory allocation +#define GodotProfileAlloc(m_ptr, m_size) TracyAlloc(m_ptr, m_size) +#define GodotProfileFree(m_ptr) TracyFree(m_ptr) + void godot_init_profiler(); #elif defined(GODOT_USE_PERFETTO) @@ -98,6 +102,8 @@ struct PerfettoGroupedEventEnder { __godot_perfetto_zone_##m_group_name._end_now(); \ TRACE_EVENT_BEGIN("godot", m_zone_name); +#define GodotProfileAlloc(m_ptr, m_size) +#define GodotProfileFree(m_ptr) void godot_init_profiler(); #else @@ -117,5 +123,9 @@ void godot_init_profiler(); // Replace the profile zone group's current profile zone. // The new zone ends either when the next zone starts, or when the scope ends. #define GodotProfileZoneGrouped(m_group_name, m_zone_name) - +// Tell the profiling backend that an allocation happened, with its location and size. +#define GodotProfileAlloc(m_ptr, m_size) +// Tell the profiling backend that an allocation was freed. +// There must be a one to one correspondence of GodotProfileAlloc and GodotProfileFree calls. +#define GodotProfileFree(m_ptr) #endif