From 655a44484711d503db28dfe0bc0d75d3fa8719e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lancelot=20de=20Ferri=C3=A8re?= Date: Tue, 27 May 2025 09:22:17 +0200 Subject: [PATCH] Always allow last-ditch GCs As noted on #7979, we run into OOMs since commit af32d386b9. The reason is that the default incremental GC budget is unlimited, which actually doesn't perform incremental GCs. Our settings can lead to situation where the incremental GCs don't actually sweep, thus not freeing memory. SM has a mechanism to avoid OOM anyways with LAST_DITCH GCs, but by default these can only occur ever 30 seconds. Turn this off. Reported by: langbart (cherry picked from commit e3e542b1f9dab064e0a617884392696237929cff) Signed-off-by: Itms --- source/scriptinterface/ScriptContext.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/source/scriptinterface/ScriptContext.cpp b/source/scriptinterface/ScriptContext.cpp index 29303ebc1f..3d02a3f049 100644 --- a/source/scriptinterface/ScriptContext.cpp +++ b/source/scriptinterface/ScriptContext.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2024 Wildfire Games. +/* Copyright (C) 2025 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -59,7 +59,8 @@ void GCSliceCallbackHook(JSContext* UNUSED(cx), JS::GCProgress progress, const J if (progress == JS::GCProgress::GC_CYCLE_BEGIN) printf("starting cycle ===========================================\n"); - const char16_t* str = desc.formatMessage(cx); + //const char16_t* str = desc.formatMessage(cx); + const char16_t* str = desc.formatSliceMessage(cx); int len = 0; for(int i = 0; i < 10000; i++) @@ -77,6 +78,13 @@ void GCSliceCallbackHook(JSContext* UNUSED(cx), JS::GCProgress progress, const J } printf("---------------------------------------\n: %ls \n---------------------------------------\n", outstring); + + const uint32_t gcBytes = JS_GetGCParameter(cx, JSGC_BYTES); + + printf("gcBytes: %i KB\n", gcBytes / 1024); + + if (progress == JS::GCProgress::GC_SLICE_END) + printf("ending cycle ===========================================\n"); #endif } @@ -112,12 +120,10 @@ ScriptContext::ScriptContext(int contextSize, uint32_t heapGrowthBytesGCTrigger) JS_SetGCParameter(m_cx, JSGC_INCREMENTAL_GC_ENABLED, true); JS_SetGCParameter(m_cx, JSGC_PER_ZONE_GC_ENABLED, false); - // Attempt to turn off Spidermonkey-led GCs. - JS_SetGCParameter(m_cx, JSGC_HEAP_GROWTH_FACTOR, contextSize); - JS_SetGCParameter(m_cx, JSGC_LOW_FREQUENCY_HEAP_GROWTH, 300); - JS_SetGCParameter(m_cx, JSGC_HIGH_FREQUENCY_SMALL_HEAP_GROWTH, 500); - JS_SetGCParameter(m_cx, JSGC_HIGH_FREQUENCY_LARGE_HEAP_GROWTH, 300); + // Set a low time budget to avoid lag spikes, but allow any number of last ditch GCs + // to avoid OOM errors. JS_SetGCParameter(m_cx, JSGC_SLICE_TIME_BUDGET_MS, 10); + JS_SetGCParameter(m_cx, JSGC_MIN_LAST_DITCH_GC_PERIOD, 0); JS_SetOffthreadIonCompilationEnabled(m_cx, true);