diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index 62d1ea71f3..e046c7770b 100644 --- a/source/ps/GameSetup/GameSetup.cpp +++ b/source/ps/GameSetup/GameSetup.cpp @@ -358,7 +358,7 @@ static size_t ChooseCacheSize() const ssize_t os = (ssize_t)OperatingSystemFootprint(); const ssize_t game = 300; // estimated working set - ssize_t cache = 500; // upper bound: total size of our data + ssize_t cache = 400; // upper bound: total size of our data // the cache reserves contiguous address space, which is a precious // resource on 32-bit systems, so don't use too much: diff --git a/source/scriptinterface/ScriptInterface.cpp b/source/scriptinterface/ScriptInterface.cpp index a87ee1be47..0377d9636e 100644 --- a/source/scriptinterface/ScriptInterface.cpp +++ b/source/scriptinterface/ScriptInterface.cpp @@ -139,7 +139,8 @@ public: m_rooter(NULL), m_LastGCBytes(0), m_LastGCCheck(0.0f), - m_HeapGrowthBytesGCTrigger(heapGrowthBytesGCTrigger) + m_HeapGrowthBytesGCTrigger(heapGrowthBytesGCTrigger), + m_RuntimeSize(runtimeSize) { m_rt = JS_NewRuntime(runtimeSize, JS_USE_HELPER_THREADS); @@ -161,11 +162,9 @@ public: JS::SetGCSliceCallback(m_rt, GCSliceCallbackHook); - JS_SetGCParameter(m_rt, JSGC_MAX_MALLOC_BYTES, 384 * 1024 * 1024); - JS_SetGCParameter(m_rt, JSGC_MAX_BYTES, 384 * 1024 * 1024); + JS_SetGCParameter(m_rt, JSGC_MAX_MALLOC_BYTES, m_RuntimeSize); + JS_SetGCParameter(m_rt, JSGC_MAX_BYTES, m_RuntimeSize); JS_SetGCParameter(m_rt, JSGC_MODE, JSGC_MODE_INCREMENTAL); - //JS_SetGCParameter(m_rt, JSGC_SLICE_TIME_BUDGET, 5); - JS_SetGCParameter(m_rt, JSGC_ALLOCATION_THRESHOLD, 256); // The whole heap-growth mechanism seems to work only for non-incremental GCs. // We disable it to make it more clear if full GCs happen triggered by this JSAPI internal mechanism. @@ -177,6 +176,7 @@ public: ENSURE(m_dummyContext); } + #define GC_DEBUG_PRINT 0 void MaybeIncrementalGC(double delay) { PROFILE2("MaybeIncrementalGC"); @@ -201,30 +201,66 @@ public: m_LastGCCheck = timer_Time(); int gcBytes = JS_GetGCParameter(m_rt, JSGC_BYTES); - //std::cout << "gcBytes: " << std::endl; // debugging + +#if GC_DEBUG_PRINT + std::cout << "gcBytes: " << gcBytes / 1024 << " KB" << std::endl; +#endif + if (m_LastGCBytes > gcBytes || m_LastGCBytes == 0) { - //printf("Setting m_LastGCBytes: %d \n", gcBytes); // debugging +#if GC_DEBUG_PRINT + printf("Setting m_LastGCBytes: %d KB \n", gcBytes / 1024); +#endif m_LastGCBytes = gcBytes; } - + // Run an additional incremental GC slice if the currently running incremental GC isn't over yet // ... or // start a new incremental GC if the JS heap size has grown enough for a GC to make sense if (JS::IsIncrementalGCInProgress(m_rt) || (gcBytes - m_LastGCBytes > m_HeapGrowthBytesGCTrigger)) - { - // Use for debugging - /*if (JS::IsIncrementalGCInProgress(m_rt)) - printf("Running incremental GC because an incremental cycle is in progress. \n"); + { +#if GC_DEBUG_PRINT + if (JS::IsIncrementalGCInProgress(m_rt)) + printf("An incremental GC cycle is in progress. \n"); else - printf("Running incremental GC because JSGC_BYTES - m_LastGCBytes > m_HeapGrowthBytesGCTrigger " - " ---- JSGC_BYTES: %d m_LastGCBytes: %d m_HeapGrowthBytesGCTrigger: %d ", - gcBytes, - m_LastGCBytes, - m_HeapGrowthBytesGCTrigger); - }*/ - PrepareContextsForIncrementalGC(); - JS::IncrementalGC(m_rt, JS::gcreason::REFRESH_FRAME, GCSliceTimeBudget); + printf("GC needed because JSGC_BYTES - m_LastGCBytes > m_HeapGrowthBytesGCTrigger \n" + " JSGC_BYTES: %d KB \n m_LastGCBytes: %d KB \n m_HeapGrowthBytesGCTrigger: %d KB \n", + gcBytes / 1024, + m_LastGCBytes / 1024, + m_HeapGrowthBytesGCTrigger / 1024); +#endif + + // A hack to make sure we never exceed the runtime size because we can't collect the memory + // fast enough. + if(gcBytes > m_RuntimeSize / 2) + { + if (JS::IsIncrementalGCInProgress(m_rt)) + { +#if GC_DEBUG_PRINT + printf("Finishing incremental GC because gcBytes > m_RuntimeSize / 2. \n"); +#endif + PrepareContextsForIncrementalGC(); + JS::FinishIncrementalGC(m_rt, JS::gcreason::REFRESH_FRAME); + } + else + { +#if GC_DEBUG_PRINT + printf("Running full GC because gcBytes > m_RuntimeSize / 2. \n"); +#endif + JS_GC(m_rt); + } + } + else + { +#if GC_DEBUG_PRINT + if (!JS::IsIncrementalGCInProgress(m_rt)) + printf("Starting incremental GC \n"); + else + printf("Running incremental GC slice \n"); +#endif + PrepareContextsForIncrementalGC(); + JS::IncrementalGC(m_rt, JS::gcreason::REFRESH_FRAME, GCSliceTimeBudget); + } m_LastGCBytes = gcBytes; } } @@ -255,6 +291,7 @@ private: // Workaround for: https://bugzilla.mozilla.org/show_bug.cgi?id=890243 JSContext* m_dummyContext; + int m_RuntimeSize; int m_HeapGrowthBytesGCTrigger; int m_LastGCBytes; double m_LastGCCheck;