autocompile: pin the overlay flavor through the spawn env (PSX_OVERLAY_FLAVOR)

The runtime pins the cache dir and captures path into the spawned
compile's environment so the cache can never drift from where the loader
reads - but not the FLAVOR. compile_overlays.py's --flavor defaults to 0
(play), so an instrumented (flavor 2) runtime spawned compiles whose
shards its own loader then rejected: the overlay_loader_status message
said it plainly - "this build reads ..._f2 but shards exist under ..._f0
-> ALL overlays run INTERPRETED". On mod-heavy titles (WipEout 3's
framerate packages patch most of the game text) that is the difference
between full speed and ~0.2x, misread as general slowness for weeks.

The runtime now exports PSX_OVERLAY_FLAVOR alongside the other pins, and
the tool honors it over --flavor, so each build population self-heals.

Measured after the fix (instrumented, WipEout 3 ntsc120full8): shard
loads 0 -> 8 (45 funcs), interpreted insns 6.6M/s -> 1.0M/s.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
tetrisgm
2026-08-19 02:56:27 -07:00
parent ae7925c1b5
commit 45f9d0f866
2 changed files with 23 additions and 0 deletions
+10
View File
@@ -855,6 +855,16 @@ int autocompile_request(void) {
if (s_cache_dir[0]) SetEnvironmentVariableA("PSX_OVERLAY_CACHE_DIR", s_cache_dir);
if (s_captures[0]) SetEnvironmentVariableA("PSX_OVERLAY_CAPTURES", s_captures);
SetEnvironmentVariableA("PSX_OVERLAY_LIVE_AUTOCOMPILE", "1");
/* Pin the FLAVOR the same way: the tool's --flavor defaults to 0 (play),
* so an instrumented (flavor 2) runtime spawned a compile whose shards it
* could never load — the loader's flavor guard rejected them and EVERY
* overlay ran interpreted, forever, on debug builds. The child must
* always write the flavor this runtime reads. */
{
char flavor_buf[16];
snprintf(flavor_buf, sizeof flavor_buf, "%d", (int)PSX_OVERLAY_FLAVOR);
SetEnvironmentVariableA("PSX_OVERLAY_FLAVOR", flavor_buf);
}
/* cmd.exe /C resolves the command via PATH and supports the relative
* paths in the configured line (cwd = project root). The WHOLE command is
+13
View File
@@ -5262,6 +5262,19 @@ def main():
if _env_cap != args.captures:
print(f'[cache] PSX_OVERLAY_CAPTURES overrides --captures: {_env_cap}')
args.captures = _env_cap
# Flavor is pinned by the spawning runtime the same way as the cache
# locations: --flavor defaults to 0 (play), so an instrumented (flavor 2)
# runtime used to spawn compiles whose shards its loader then rejected —
# every overlay ran interpreted on debug builds, silently.
_env_flavor = os.environ.get('PSX_OVERLAY_FLAVOR')
if _env_flavor:
try:
_fl = int(_env_flavor, 0)
except ValueError:
_fl = None
if _fl is not None and _fl != args.flavor:
print(f'[cache] PSX_OVERLAY_FLAVOR overrides --flavor: {_fl}')
args.flavor = _fl
if not args.captures:
ap.error('no captures file: set PSX_OVERLAY_CAPTURES (runtime injects it) '
'or pass --captures for manual/offline use')