diff --git a/include/basalt_defines.h b/include/basalt_defines.h index c10cdea..975cabe 100644 --- a/include/basalt_defines.h +++ b/include/basalt_defines.h @@ -1,5 +1,7 @@ #pragma once +#define BASALT_ENABLE_ALLOC_RECORDS 1 + #if defined(__clang__) || defined(__gcc__) #define STATIC_ASSERT(x,y) _Static_assert(x,y) #else @@ -40,6 +42,10 @@ STATIC_ASSERT(sizeof(i64) == 8, "Expected sizeof(i64) == 8"); STATIC_ASSERT(sizeof(f32) == 4, "Expected sizeof(f32) == 4"); STATIC_ASSERT(sizeof(f64) == 8, "Expected sizeof(f64) == 8"); +#define BCLAMP(val, min, max) (val) = (val) > (max) ? (max) : (val) < (min) ? (min) : (val) +#define BCLAMP_EXTENT(val, min, max) \ + (val).width = ((val).width > (max).width) ? (max).width : ((val).width < (min).width) ? (min).width : (val).width; \ + (val).height = ((val).height > (max).height) ? (max).height : ((val).height < (min).height) ? (min).height : (val).height #if defined(WIN32) || defined(_WIN32) || defined (__WIN32__) #define BPLATFORM_WINDOWS 1 diff --git a/src/core/basalt_memory.cpp b/src/core/basalt_memory.cpp index 430b304..298b76d 100644 --- a/src/core/basalt_memory.cpp +++ b/src/core/basalt_memory.cpp @@ -7,11 +7,15 @@ #include "core/basalt_logger.h" #include "basalt_defines.h" +#include static struct { i64 alloc_total; i64 class_alloc[MEMORY_TAG_CLASS_MAX+1]; i64 zone_alloc[MEMORY_TAG_ZONE_MAX + 1]; +#if BASALT_ENABLE_ALLOC_RECORDS + std::map records; +#endif } basalt_memory_state; static const char* basalt_memory_class_names[MEMORY_TAG_CLASS_MAX_BUILTIN] = { @@ -49,9 +53,24 @@ void basalt::mem::initialize_memory(void) basalt_memory_class_name_lengths[i] = strnlen(basalt_memory_class_names[i], 64); for (size_t i = 0; i < MEMORY_TAG_ZONE_MAX_BUILTIN; ++i) basalt_memory_zone_name_lengths[i] = strnlen(basalt_memory_zone_names[i], 64); +#if BASALT_ENABLE_ALLOC_RECORDS + new (&basalt_memory_state.records) std::map(); +#endif } -void basalt::mem::terminate_memory(void) {} +void basalt::mem::terminate_memory(void) +{ +#if BASALT_ENABLE_ALLOC_RECORDS + if (basalt_memory_state.records.size() > 0) + { + BERROR("Memory leak detected!\n"); + for (auto const& [k, v] : basalt_memory_state.records) + { + BERROR("\tAllocation at %p leaked %llu bytes\n", k, v); + } + } +#endif +} void* basalt::mem::alloc(u64 num_bytes, MEMORY_TAG tag) { @@ -71,6 +90,9 @@ void* basalt::mem::alloc(u64 num_bytes, MEMORY_TAG tag) basalt_memory_state.alloc_total += num_bytes; basalt_memory_state.class_alloc[(MEMORY_TAG_MASK_CLASS & tag) >> MEMORY_TAG_SHIFT_CLASS] += num_bytes; basalt_memory_state.zone_alloc[(MEMORY_TAG_MASK_ZONE & tag) >> MEMORY_TAG_SHIFT_ZONE] += num_bytes; +#if BASALT_ENABLE_ALLOC_RECORDS + basalt_memory_state.records.emplace(ptr, num_bytes); +#endif } return ptr; } @@ -83,6 +105,9 @@ void basalt::mem::dealloc(void* ptr, u64 num_bytes, MEMORY_TAG tag) basalt_memory_state.alloc_total -= num_bytes; basalt_memory_state.class_alloc[(MEMORY_TAG_MASK_CLASS & tag) >> MEMORY_TAG_SHIFT_CLASS] -= num_bytes; basalt_memory_state.zone_alloc[(MEMORY_TAG_MASK_ZONE & tag) >> MEMORY_TAG_SHIFT_ZONE] -= num_bytes; +#if BASALT_ENABLE_ALLOC_RECORDS + basalt_memory_state.records.erase(ptr); +#endif } void* basalt::mem::setzero(void* dst, u64 num_bytes)