From 07a24cf71dc1167fb286d5910da1589f235ce487 Mon Sep 17 00:00:00 2001 From: jpolo1224 Date: Thu, 20 Aug 2026 00:33:33 -0400 Subject: [PATCH] PPU: stop on a compile out-of-memory rather than limping on Continuing with the modules that did compile is correct -- the dispatcher entry for an uncompiled function interprets, nothing runs garbage -- but it is per-instruction dispatch and it is slower than the interpreter outright. Saint Seiya measured 6fps against 23 with most of its modules missing. A game at that speed looks broken, and it gets reported as broken, when the real answer is one restart away. An honest stop is better than a degraded run that invites the wrong bug report. So this ends the boot the way running out of memory always did. What is different from before is the reason: the message names it and says what to do, and it stays on screen because the overlay is drawn by the RSX thread rather than the one this stops. The fallback itself stays in place for the ordinary case of a single module failing for some other reason, which is upstream's design and is worth keeping -- one bad module costing its own functions is a fair trade. Running out of memory is not that case: it takes most of the executable with it. --- rpcs3/Emu/Cell/PPUThread.cpp | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index b63178cd6..700d9b9ff 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -5729,10 +5729,29 @@ bool ppu_initialize(const ppu_module& info, bool check_only, u64 file_s { // std::string, not a literal: message_item is only instantiated for std::string // and localized_string_id, so a const char* fails to link. + // + // Queued before the throw below, and it survives it: the overlay is drawn by the RSX + // thread, which is not the thread this kills. rsx::overlays::queue_message( - std::string("Ran out of memory while compiling. Some functions will run slowly.\n" - "Close the game and start it again to compile the rest -- progress is kept."), - 10'000'000); + std::string("Ran out of memory while compiling.\n" + "Close the game and start it again -- what already compiled is kept, so each " + "attempt gets further."), + 30'000'000); + + // Stop rather than limp. + // + // Everything that failed here would fall back to ppu_recompiler_fallback, which is + // correct -- the dispatcher entry interprets, nothing runs garbage -- but it is + // per-instruction dispatch, and it is slower than the interpreter outright. Saint + // Seiya measured 6fps against 23 with most of its modules missing. A game at that + // speed looks broken, and it gets reported as broken, when the real answer is one + // restart away. + // + // So this is a deliberate choice of an honest stop over a degraded run. It kills this + // thread the way running out of memory always did; what is different is that the + // reason is now on screen instead of being left to guess at. + fmt::throw_exception("Out of memory while compiling PPU modules -- restart the game to " + "continue compiling. Modules that already compiled are cached."); } }