Skip to content

Commit 4a85f2c

Browse files
committed
Add high-performance, carefully engineered allocator (Addendum to 5dc09d9)
1 parent 15bcf47 commit 4a85f2c

File tree

7 files changed

+1258
-265
lines changed

7 files changed

+1258
-265
lines changed

Client/core/CSettings.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,7 @@ void CSettings::CreateGUI()
11491149
m_pDebugSettingCombo->AddItem("#0000 Lua trace")->SetData((void*)EDiagnosticDebug::LUA_TRACE_0000);
11501150
m_pDebugSettingCombo->AddItem("#0000 Resize always")->SetData((void*)EDiagnosticDebug::RESIZE_ALWAYS_0000);
11511151
m_pDebugSettingCombo->AddItem("#0000 Resize never")->SetData((void*)EDiagnosticDebug::RESIZE_NEVER_0000);
1152+
m_pDebugSettingCombo->AddItem("#0000 Memory allocation debug")->SetData((void*)EDiagnosticDebug::BAD_ALLOC);
11521153
m_pDebugSettingCombo->SetReadOnly(true);
11531154
vecTemp.fY += fLineHeight;
11541155

Client/mods/deathmatch/logic/luadefs/CLuaDrawingDefs.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,6 +1773,8 @@ int CLuaDrawingDefs::DxGetStatus(lua_State* luaVM)
17731773
return "#0000 Resize always";
17741774
case EDiagnosticDebug::RESIZE_NEVER_0000:
17751775
return "#0000 Resize never";
1776+
case EDiagnosticDebug::BAD_ALLOC:
1777+
return "#0000 Memory allocation debug";
17761778
default:
17771779
return "Default";
17781780
}

Client/multiplayer_sa/CMemoryAllocatorDiagnostics.cpp

Lines changed: 441 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*****************************************************************************
2+
*
3+
* PROJECT: Multi Theft Auto v1.0
4+
* LICENSE: See LICENSE in the top level directory
5+
* FILE: multiplayer_sa/CMemoryAllocatorDiagnostics.h
6+
* PURPOSE: Memory allocator diagnostic logging system
7+
*
8+
* Multi Theft Auto is available from https://www.multitheftauto.com/
9+
*
10+
*****************************************************************************/
11+
12+
#pragma once
13+
14+
#include <cstddef> // For std::size_t
15+
#include <cstdint> // For std::uintptr_t
16+
17+
namespace mta
18+
{
19+
namespace memory
20+
{
21+
namespace diagnostics
22+
{
23+
// Check if memory allocation debugging should be enabled
24+
// Returns true in debug builds OR when user has enabled EDiagnosticDebug::BAD_ALLOC (#0000 Memory allocation debug) in MTA advanced settings > "Debug setting:"
25+
bool IsMemoryAllocationDebuggingEnabled() noexcept;
26+
27+
// Core diagnostic logging function
28+
void LogAllocationFailure(const char* reason, void* ptr = nullptr, std::size_t size = 0, std::size_t alignment = 0,
29+
void* caller = nullptr) noexcept;
30+
31+
// Specialized logging functions for different failure scenarios
32+
void LogHeapAllocationFailure(const char* reason, void* ptr, std::size_t size, std::size_t alignment, void* caller) noexcept;
33+
void LogVirtualAllocFailure(const char* reason, void* ptr, std::size_t size, std::size_t alignment, void* caller) noexcept;
34+
void LogSafetyRejection(const char* reason, void* ptr, std::size_t size, std::size_t alignment, const char* safety_condition,
35+
void* caller) noexcept;
36+
void LogCriticalSystemFailure(const char* reason, void* ptr, std::size_t size, std::size_t alignment, void* caller) noexcept;
37+
38+
// Memory pressure analysis
39+
void LogMemoryPressureDetails() noexcept;
40+
}
41+
}
42+
}
43+
44+
// Conditional compilation macros for diagnostic logging
45+
// These provide zero overhead when diagnostics are disabled
46+
#if defined(MTA_DEBUG) || defined(MTA_ENABLE_DIAGNOSTIC_LOGGING) || defined(DEBUG) || defined(_DEBUG)
47+
#include <intrin.h> // For _ReturnAddress() intrinsic
48+
49+
// Debug builds: always enabled
50+
#if defined(MTA_DEBUG) || defined(DEBUG) || defined(_DEBUG)
51+
#define MTA_MEMORY_LOG_ALLOCATION_FAILURE(reason, ptr, size, alignment) \
52+
mta::memory::diagnostics::LogAllocationFailure(reason, ptr, size, alignment, _ReturnAddress())
53+
54+
#define MTA_MEMORY_LOG_DEALLOCATION_FAILURE(reason, ptr) \
55+
mta::memory::diagnostics::LogAllocationFailure(reason, ptr, 0, 0, _ReturnAddress())
56+
57+
#define MTA_MEMORY_LOG_HEAP_FAILURE(reason, ptr, size, alignment) \
58+
mta::memory::diagnostics::LogHeapAllocationFailure(reason, ptr, size, alignment, _ReturnAddress())
59+
60+
#define MTA_MEMORY_LOG_VIRTUAL_FAILURE(reason, ptr, size, alignment) \
61+
mta::memory::diagnostics::LogVirtualAllocFailure(reason, ptr, size, alignment, _ReturnAddress())
62+
63+
#define MTA_MEMORY_LOG_SAFETY_REJECTION(reason, ptr, size, alignment, condition) \
64+
mta::memory::diagnostics::LogSafetyRejection(reason, ptr, size, alignment, condition, _ReturnAddress())
65+
66+
#define MTA_MEMORY_LOG_CRITICAL_FAILURE(reason, ptr, size, alignment) \
67+
mta::memory::diagnostics::LogCriticalSystemFailure(reason, ptr, size, alignment, _ReturnAddress())
68+
69+
// Release builds: conditional on user setting
70+
#else
71+
#define MTA_MEMORY_LOG_ALLOCATION_FAILURE(reason, ptr, size, alignment) \
72+
do { if (mta::memory::diagnostics::IsMemoryAllocationDebuggingEnabled()) \
73+
mta::memory::diagnostics::LogAllocationFailure(reason, ptr, size, alignment, _ReturnAddress()); } while(0)
74+
75+
#define MTA_MEMORY_LOG_DEALLOCATION_FAILURE(reason, ptr) \
76+
do { if (mta::memory::diagnostics::IsMemoryAllocationDebuggingEnabled()) \
77+
mta::memory::diagnostics::LogAllocationFailure(reason, ptr, 0, 0, _ReturnAddress()); } while(0)
78+
79+
#define MTA_MEMORY_LOG_HEAP_FAILURE(reason, ptr, size, alignment) \
80+
do { if (mta::memory::diagnostics::IsMemoryAllocationDebuggingEnabled()) \
81+
mta::memory::diagnostics::LogHeapAllocationFailure(reason, ptr, size, alignment, _ReturnAddress()); } while(0)
82+
83+
#define MTA_MEMORY_LOG_VIRTUAL_FAILURE(reason, ptr, size, alignment) \
84+
do { if (mta::memory::diagnostics::IsMemoryAllocationDebuggingEnabled()) \
85+
mta::memory::diagnostics::LogVirtualAllocFailure(reason, ptr, size, alignment, _ReturnAddress()); } while(0)
86+
87+
#define MTA_MEMORY_LOG_SAFETY_REJECTION(reason, ptr, size, alignment, condition) \
88+
do { if (mta::memory::diagnostics::IsMemoryAllocationDebuggingEnabled()) \
89+
mta::memory::diagnostics::LogSafetyRejection(reason, ptr, size, alignment, condition, _ReturnAddress()); } while(0)
90+
91+
#define MTA_MEMORY_LOG_CRITICAL_FAILURE(reason, ptr, size, alignment) \
92+
do { if (mta::memory::diagnostics::IsMemoryAllocationDebuggingEnabled()) \
93+
mta::memory::diagnostics::LogCriticalSystemFailure(reason, ptr, size, alignment, _ReturnAddress()); } while(0)
94+
#endif
95+
96+
#else
97+
// Release builds without diagnostic support: no-op macros for zero overhead
98+
#define MTA_MEMORY_LOG_ALLOCATION_FAILURE(reason, ptr, size, alignment) ((void)0)
99+
#define MTA_MEMORY_LOG_DEALLOCATION_FAILURE(reason, ptr) ((void)0)
100+
#define MTA_MEMORY_LOG_HEAP_FAILURE(reason, ptr, size, alignment) ((void)0)
101+
#define MTA_MEMORY_LOG_VIRTUAL_FAILURE(reason, ptr, size, alignment) ((void)0)
102+
#define MTA_MEMORY_LOG_SAFETY_REJECTION(reason, ptr, size, alignment, condition) ((void)0)
103+
#define MTA_MEMORY_LOG_CRITICAL_FAILURE(reason, ptr, size, alignment) ((void)0)
104+
105+
#endif // MTA_DEBUG || MTA_ENABLE_DIAGNOSTIC_LOGGING

0 commit comments

Comments
 (0)