SlangBridge's destructor never freed its SlangBridgeData, leaking the
slang global session it owns, and ShaderCompiler::Run constructed a new
SlangBridge for every shader file - one leaked global session (each
holding a compiled slang core module, ~160 MB) per shader. Cooking 65
shaders peaked at ~10.1 GiB RSS and climbed monotonically, OOMing the
CI runner.
Delete the bridge data in the destructor and construct a single bridge
above the shader loop; a global session is designed to be shared for a
whole compilation run, and each redundant one was also recompiling the
slang core module.
Measured on a full 65-shader force recook (Release, 16 threads):
peak RSS 10.1 GiB -> 272 MB, wall time 24.0s -> 11.9s.
SlangBridge's destructor never freed its SlangBridgeData, leaking the slang global session it owns, and ShaderCompiler::Run constructed a new SlangBridge for every shader file - one leaked global session (each holding a compiled slang core module, ~160 MB) per shader. Cooking 65 shaders peaked at ~10.1 GiB RSS and climbed monotonically, OOMing the CI runner.
Delete the bridge data in the destructor and construct a single bridge above the shader loop; a global session is designed to be shared for a whole compilation run, and each redundant one was also recompiling the slang core module.
Measured on a full 65-shader force recook (Release, 16 threads): peak RSS 10.1 GiB -> 272 MB, wall time 24.0s -> 11.9s.