Merge pull request #111066 from Ivorforce/memory-namespace

Change `Memory` from a class into a namespace.
This commit is contained in:
Thaddeus Crews
2025-10-06 09:06:42 -05:00
2 changed files with 59 additions and 70 deletions

View File

@ -57,8 +57,8 @@ void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_d
#endif #endif
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
SafeNumeric<uint64_t> Memory::mem_usage; static SafeNumeric<uint64_t> _current_mem_usage;
SafeNumeric<uint64_t> Memory::max_usage; static SafeNumeric<uint64_t> _max_mem_usage;
#endif #endif
void *Memory::alloc_aligned_static(size_t p_bytes, size_t p_alignment) { void *Memory::alloc_aligned_static(size_t p_bytes, size_t p_alignment) {
@ -117,8 +117,8 @@ void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) {
*s = p_bytes; *s = p_bytes;
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
uint64_t new_mem_usage = mem_usage.add(p_bytes); uint64_t new_mem_usage = _current_mem_usage.add(p_bytes);
max_usage.exchange_if_greater(new_mem_usage); _max_mem_usage.exchange_if_greater(new_mem_usage);
#endif #endif
return s8 + DATA_OFFSET; return s8 + DATA_OFFSET;
} else { } else {
@ -148,10 +148,10 @@ void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) {
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
if (p_bytes > *s) { if (p_bytes > *s) {
uint64_t new_mem_usage = mem_usage.add(p_bytes - *s); uint64_t new_mem_usage = _current_mem_usage.add(p_bytes - *s);
max_usage.exchange_if_greater(new_mem_usage); _max_mem_usage.exchange_if_greater(new_mem_usage);
} else { } else {
mem_usage.sub(*s - p_bytes); _current_mem_usage.sub(*s - p_bytes);
} }
#endif #endif
@ -195,7 +195,7 @@ void Memory::free_static(void *p_ptr, bool p_pad_align) {
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
uint64_t *s = (uint64_t *)(mem + SIZE_OFFSET); uint64_t *s = (uint64_t *)(mem + SIZE_OFFSET);
mem_usage.sub(*s); _current_mem_usage.sub(*s);
#endif #endif
free(mem); free(mem);
@ -210,7 +210,7 @@ uint64_t Memory::get_mem_available() {
uint64_t Memory::get_mem_usage() { uint64_t Memory::get_mem_usage() {
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
return mem_usage.get(); return _current_mem_usage.get();
#else #else
return 0; return 0;
#endif #endif
@ -218,7 +218,7 @@ uint64_t Memory::get_mem_usage() {
uint64_t Memory::get_mem_max_usage() { uint64_t Memory::get_mem_max_usage() {
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
return max_usage.get(); return _max_mem_usage.get();
#else #else
return 0; return 0;
#endif #endif

View File

@ -31,18 +31,16 @@
#pragma once #pragma once
#include "core/error/error_macros.h" #include "core/error/error_macros.h"
#include "core/templates/safe_refcount.h"
#include <new> // IWYU pragma: keep // `new` operators. #include <new> // IWYU pragma: keep // `new` operators.
#include <type_traits> #include <type_traits>
class Memory { namespace Memory {
#ifdef DEBUG_ENABLED constexpr size_t get_aligned_address(size_t p_address, size_t p_alignment) {
static SafeNumeric<uint64_t> mem_usage; const size_t n_bytes_unaligned = p_address % p_alignment;
static SafeNumeric<uint64_t> max_usage; return (n_bytes_unaligned == 0) ? p_address : (p_address + p_alignment - n_bytes_unaligned);
#endif }
public:
// Alignment: ↓ max_align_t ↓ uint64_t ↓ max_align_t // Alignment: ↓ max_align_t ↓ uint64_t ↓ max_align_t
// ┌─────────────────┬──┬────────────────┬──┬───────────... // ┌─────────────────┬──┬────────────────┬──┬───────────...
// │ uint64_t │░░│ uint64_t │░░│ T[] // │ uint64_t │░░│ uint64_t │░░│ T[]
@ -50,15 +48,17 @@ public:
// └─────────────────┴──┴────────────────┴──┴───────────... // └─────────────────┴──┴────────────────┴──┴───────────...
// Offset: ↑ SIZE_OFFSET ↑ ELEMENT_OFFSET ↑ DATA_OFFSET // Offset: ↑ SIZE_OFFSET ↑ ELEMENT_OFFSET ↑ DATA_OFFSET
static const size_t SIZE_OFFSET; inline constexpr size_t SIZE_OFFSET = 0;
static const size_t ELEMENT_OFFSET; inline constexpr size_t ELEMENT_OFFSET = get_aligned_address(SIZE_OFFSET + sizeof(uint64_t), alignof(uint64_t));
static const size_t DATA_OFFSET; inline constexpr size_t DATA_OFFSET = get_aligned_address(ELEMENT_OFFSET + sizeof(uint64_t), alignof(max_align_t));
template <bool p_ensure_zero = false> template <bool p_ensure_zero = false>
static void *alloc_static(size_t p_bytes, bool p_pad_align = false); void *alloc_static(size_t p_bytes, bool p_pad_align = false);
_FORCE_INLINE_ static void *alloc_static_zeroed(size_t p_bytes, bool p_pad_align = false) { return alloc_static<true>(p_bytes, p_pad_align); } _FORCE_INLINE_ static void *alloc_static_zeroed(size_t p_bytes, bool p_pad_align = false) {
static void *realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align = false); return alloc_static<true>(p_bytes, p_pad_align);
static void free_static(void *p_ptr, bool p_pad_align = false); }
void *realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align = false);
void free_static(void *p_ptr, bool p_pad_align = false);
// ↓ return value of alloc_aligned_static // ↓ return value of alloc_aligned_static
// ┌─────────────────┬─────────┬─────────┬──────────────────┐ // ┌─────────────────┬─────────┬─────────┬──────────────────┐
@ -76,29 +76,18 @@ public:
// both start and end of the block must add exactly to p_alignment - 1. // both start and end of the block must add exactly to p_alignment - 1.
// //
// p_alignment MUST be a power of 2. // p_alignment MUST be a power of 2.
static void *alloc_aligned_static(size_t p_bytes, size_t p_alignment); void *alloc_aligned_static(size_t p_bytes, size_t p_alignment);
static void *realloc_aligned_static(void *p_memory, size_t p_bytes, size_t p_prev_bytes, size_t p_alignment); void *realloc_aligned_static(void *p_memory, size_t p_bytes, size_t p_prev_bytes, size_t p_alignment);
// Pass the ptr returned by alloc_aligned_static to free it. // Pass the ptr returned by alloc_aligned_static to free it.
// e.g. // e.g.
// void *data = realloc_aligned_static( bytes, 16 ); // void *data = realloc_aligned_static( bytes, 16 );
// free_aligned_static( data ); // free_aligned_static( data );
static void free_aligned_static(void *p_memory); void free_aligned_static(void *p_memory);
static uint64_t get_mem_available(); uint64_t get_mem_available();
static uint64_t get_mem_usage(); uint64_t get_mem_usage();
static uint64_t get_mem_max_usage(); uint64_t get_mem_max_usage();
}; //namespace Memory
static constexpr size_t get_aligned_address(size_t p_address, size_t p_alignment);
};
constexpr size_t Memory::get_aligned_address(size_t p_address, size_t p_alignment) {
const size_t n_bytes_unaligned = p_address % p_alignment;
return (n_bytes_unaligned == 0) ? p_address : (p_address + p_alignment - n_bytes_unaligned);
}
inline constexpr size_t Memory::SIZE_OFFSET = 0;
inline constexpr size_t Memory::ELEMENT_OFFSET = get_aligned_address(SIZE_OFFSET + sizeof(uint64_t), alignof(uint64_t));
inline constexpr size_t Memory::DATA_OFFSET = get_aligned_address(ELEMENT_OFFSET + sizeof(uint64_t), alignof(max_align_t));
class DefaultAllocator { class DefaultAllocator {
public: public: