From 7ac1291b25097e1aaf047a80182915d78905f13e Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Wed, 9 Sep 2026 20:49:31 +0100 Subject: [PATCH 1/2] size_t for gc globals --- include/hx/GC.h | 6 +++--- src/hx/gc/GcCommon.cpp | 42 ++++++++++++++++++++++++------------------ src/hx/gc/Immix.cpp | 26 +++++++++++--------------- 3 files changed, 38 insertions(+), 36 deletions(-) diff --git a/include/hx/GC.h b/include/hx/GC.h index 8a44e29a1..f147ab150 100644 --- a/include/hx/GC.h +++ b/include/hx/GC.h @@ -159,13 +159,13 @@ extern std::atomic_uint gPauseForCollect; // Minimum total memory - used + buffer for new objects -extern int sgMinimumWorkingMemory; +extern size_t sgMinimumWorkingMemory; // Minimum free memory - not counting used memory -extern int sgMinimumFreeSpace; +extern size_t sgMinimumFreeSpace; // Also ensure that the free memory is larger than this amount of used memory -extern int sgTargetFreeSpacePercentage; +extern size_t sgTargetFreeSpacePercentage; extern HXCPP_EXTERN_CLASS_ATTRIBUTES int gByteMarkID; diff --git a/src/hx/gc/GcCommon.cpp b/src/hx/gc/GcCommon.cpp index fceae021c..815f0d656 100644 --- a/src/hx/gc/GcCommon.cpp +++ b/src/hx/gc/GcCommon.cpp @@ -27,14 +27,14 @@ extern void __hxt_new_string(void* result, int size); namespace hx { #if defined(HX_MACOS) || defined(HX_WINDOWS) || defined(HX_LINUX) || defined(__ORBIS__) -int sgMinimumWorkingMemory = 20*1024*1024; -int sgMinimumFreeSpace = 10*1024*1024; +size_t sgMinimumWorkingMemory = 20*1024*1024; +size_t sgMinimumFreeSpace = 10*1024*1024; #else -int sgMinimumWorkingMemory = 8*1024*1024; -int sgMinimumFreeSpace = 4*1024*1024; +size_t sgMinimumWorkingMemory = 8*1024*1024; +size_t sgMinimumFreeSpace = 4*1024*1024; #endif // Once you use more than the minimum, this kicks in... -int sgTargetFreeSpacePercentage = 100; +size_t sgTargetFreeSpacePercentage = 100; @@ -44,30 +44,36 @@ int sgTargetFreeSpacePercentage = 100; // Called internally before and GC operations void CommonInitAlloc() { + // It is probably safe to use something like strtoull for parsing the size_t values as I'm sure every reasonable implementation treats them as uint64_t. + // But just to be pedantic let's use sscanf which is the only "official" way to do this in C++11. + // C++17 gives us std::charconv but I haven't twisted enough arms yet to have 17 be the minimum version. + #if !defined(HX_WINRT) && !defined(__SNC__) && !defined(__ORBIS__) - const char *minimumWorking = getenv("HXCPP_MINIMUM_WORKING_MEMORY"); + const char *minimumWorking{ getenv("HXCPP_MINIMUM_WORKING_MEMORY") }; if (minimumWorking) { - int mem = atoi(minimumWorking); - if (mem>0) - sgMinimumWorkingMemory = mem; + if (1 != std::sscanf(minimumWorking, "%zu", &sgMinimumWorkingMemory)) + { + hx::CriticalError(HX_CSTRING("Failed to parse number from HXCPP_MINIMUM_WORKING_MEMORY environment variable")); + } } - const char *minimumFreeSpace = getenv("HXCPP_MINIMUM_FREE_SPACE"); + const char* minimumFreeSpace{ getenv("HXCPP_MINIMUM_FREE_SPACE") }; if (minimumFreeSpace) { - int mem = atoi(minimumFreeSpace); - if (mem>0) - sgMinimumFreeSpace = mem; + if (1 != std::sscanf(minimumFreeSpace, "%zu", &sgMinimumFreeSpace)) + { + hx::CriticalError(HX_CSTRING("Failed to parse number from HXCPP_MINIMUM_FREE_SPACE environment variable")); + } } - - const char *targetFree = getenv("HXCPP_TARGET_FREE_SPACE"); + const char* targetFree{ getenv("HXCPP_TARGET_FREE_SPACE") }; if (targetFree) { - int percent = atoi(targetFree); - if (percent>0) - sgTargetFreeSpacePercentage = percent; + if (1 != std::sscanf(targetFree, "%zu", &sgTargetFreeSpacePercentage)) + { + hx::CriticalError(HX_CSTRING("Failed to parse number from HXCPP_TARGET_FREE_SPACE environment variable")); + } } #endif } diff --git a/src/hx/gc/Immix.cpp b/src/hx/gc/Immix.cpp index 58b2006ec..49e3e1ce8 100644 --- a/src/hx/gc/Immix.cpp +++ b/src/hx/gc/Immix.cpp @@ -97,7 +97,6 @@ void DebuggerTrap() static bool sgAllocInit = 0; static bool sgInternalEnable = true; -static void *sgObject_root = 0; // With virtual inheritance, stack pointers can point to the middle of an object #ifdef _MSC_VER // MSVC optimizes by taking the address of an initernal data member @@ -5126,13 +5125,13 @@ class GlobalAllocator else { size_t mem = mRowsInUse< sWorkingMemorySize + allowExtra ) { @@ -5176,9 +5175,9 @@ class GlobalAllocator if (doRelease) { size_t mem = mRowsInUse< Date: Thu, 10 Sep 2026 09:13:31 +0100 Subject: [PATCH 2/2] Remove commented out log referring to now non existing global --- src/hx/gc/Immix.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hx/gc/Immix.cpp b/src/hx/gc/Immix.cpp index 49e3e1ce8..1e0ed9791 100644 --- a/src/hx/gc/Immix.cpp +++ b/src/hx/gc/Immix.cpp @@ -6556,7 +6556,6 @@ void InitAlloc() sFinalizerLock = new std::mutex(); sGCRootLock = new std::mutex(); - //GCLOG("__root pointer %p\n", sgObject_root); gMainThreadContext = new LocalAllocator(); tlsStackContext = gMainThreadContext;