mirror of
https://github.com/HeyPuter/gex.git
synced 2026-11-13 20:12:43 -10:00
page: the function JIT on by default for Wine's own loader (W3); ?fjit=0 opts out; its cost reported every 60 s
- nt-page.js: exe=.../lib/wine/<arch>-unix/wine runs with the fjit unless
?fjit=0. Undertale on units-ut2 (worldmachine, 600 s, fps over the last
120 s): 23.1 without, a flat 30.0 with; code no unit holds otherwise
runs on tier-1 behind the units' fallback. ?fjit=0 used to turn the JIT
on (Number('0') || 1).
- fjit.rs: the process's translation time and wasm bytes
(gex_fjit_translate_ms, gex_fjit_wasm_kib, gex_fjit_modules); gex.mjs
prints '[gex] fjit so far: ...' every 60 s while modules are being made,
with this Worker's compile time, since the census at exit never comes
for a game.
W3 page echo (gooner, correctness): default ok with 20 JIT modules, and
?fjit=0 ok with none. The gate legs gate-w3page/run-fjit.sh and
run-nofjit.sh and gate-utpage-fj run each mode explicitly.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_ea9f71488b6e448da93d6c2dabf4879c
This commit is contained in:
1 parent
fc9a7394b6
commit
f6e6c7ef15
3 files changed
+54
-4
No files matched your search
@@ -727,6 +727,9 @@ export class Gex {
|
||||
#tableRetries = 0;
|
||||
#iCopied = 0;
|
||||
#compileMs = 0;
|
||||
/** `#fjitModule`'s compile time, and when it next reports (`[gex] fjit so far`). */
|
||||
#fjitCompileMs = 0;
|
||||
#fjitNextReport = 0;
|
||||
#instantiateMs = 0;
|
||||
#growMs = 0;
|
||||
/// What every Worker pays instantiating the shim and guest before the guest
|
||||
@@ -3584,7 +3587,18 @@ export class Gex {
|
||||
if (dump) globalThis.process.getBuiltinModule('fs').writeFileSync(`${dump}/fjit-${n}.wasm`, bytes);
|
||||
const t0 = performance.now();
|
||||
mod = new WebAssembly.Module(bytes);
|
||||
this.#compileMs += performance.now() - t0;
|
||||
const dt = performance.now() - t0;
|
||||
this.#compileMs += dt;
|
||||
this.#fjitCompileMs += dt;
|
||||
// Every 60 s while the JIT makes modules: what it has cost so far (the
|
||||
// census at exit comes too late for a game that never exits).
|
||||
if (t0 >= this.#fjitNextReport && e.gex_fjit_translate_ms) {
|
||||
if (this.#fjitNextReport) {
|
||||
console.error(`[gex] fjit so far: ${e.gex_fjit_modules()} modules, ${e.gex_fjit_wasm_kib()} KiB of wasm, `
|
||||
+ `${e.gex_fjit_translate_ms()} ms translating (the process), ${this.#fjitCompileMs.toFixed(0)} ms compiling (this Worker)`);
|
||||
}
|
||||
this.#fjitNextReport = t0 + 60000;
|
||||
}
|
||||
this.#sharedModules.set(name, mod);
|
||||
this.#env.shareModule?.(name, mod);
|
||||
return mod;
|
||||
|
||||
@@ -45,6 +45,28 @@ fn trace(s: &str) {
|
||||
}
|
||||
static JIT: OnceLock<gex_xlate::fjit::Jit> = OnceLock::new();
|
||||
|
||||
/// What translating has cost this process: shim time in `translate_root`
|
||||
/// (recovery and emission, declined ones included) and the wasm it made.
|
||||
static TRANSLATE_NS: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
|
||||
static WASM_BYTES: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
|
||||
|
||||
/// Milliseconds this process has spent translating (`TRANSLATE_NS`).
|
||||
#[no_mangle]
|
||||
pub extern "C" fn gex_fjit_translate_ms() -> u32 {
|
||||
(TRANSLATE_NS.load(Ordering::Relaxed) / 1_000_000) as u32
|
||||
}
|
||||
|
||||
/// KiB of wasm the JIT has made in this process, and how many modules.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn gex_fjit_wasm_kib() -> u32 {
|
||||
(WASM_BYTES.load(Ordering::Relaxed) / 1024) as u32
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn gex_fjit_modules() -> u32 {
|
||||
lock(&MODULES).len() as u32
|
||||
}
|
||||
|
||||
/// One translation: its bytes (named `gex-fjit` for profiles), the bridges
|
||||
/// every Worker writes (cgen.rs `bridges`), the pages it numbered and what
|
||||
/// the dispatch tables must hold.
|
||||
@@ -486,7 +508,13 @@ fn translate_root(addr: u64) -> Option<u32> {
|
||||
}
|
||||
}
|
||||
};
|
||||
let Some(wasm) = jit.translate_skipping(0, crate::guest_bytes(), addr, &executable, &served, &read_only, &volatile, &pg, class32) else {
|
||||
let t0 = crate::now_ns();
|
||||
let wasm = jit.translate_skipping(0, crate::guest_bytes(), addr, &executable, &served, &read_only, &volatile, &pg, class32);
|
||||
TRANSLATE_NS.fetch_add(crate::now_ns().saturating_sub(t0), Ordering::Relaxed);
|
||||
if let Some(w) = &wasm {
|
||||
WASM_BYTES.fetch_add(w.len() as u64, Ordering::Relaxed);
|
||||
}
|
||||
let Some(wasm) = wasm else {
|
||||
trace(&format!("declined {addr:#x}"));
|
||||
declined(fresh.into_inner());
|
||||
return None;
|
||||
|
||||
+10
-2
@@ -115,8 +115,16 @@ async function main() {
|
||||
if (q.get('heartbeat')) globalThis.GEX_HEARTBEAT = Number(q.get('heartbeat'));
|
||||
// `?mem64=1`: a 64-bit guest memory (the wasm64 shim; docs/mem64.md step 6).
|
||||
if (q.get('mem64') === '1') globalThis.GEX_MEM64 = 1;
|
||||
// `?fjit=1`: the function JIT (gexc run --fjit's browser half, fjit.rs).
|
||||
if (q.get('fjit')) globalThis.GEX_FJIT = Number(q.get('fjit')) || 1;
|
||||
// `?fjit=1`: the function JIT (gexc run --fjit's browser half, fjit.rs);
|
||||
// `?fjit=2` traces it, `?fjit=0` turns it off. On by default for Wine's
|
||||
// own loader (W3, `exe=.../lib/wine/<arch>-unix/wine`): code no
|
||||
// function-tier unit holds otherwise runs on tier-1 behind the units'
|
||||
// fallback, and Undertale drops from its 30 fps cap to ~15 in some
|
||||
// scenes (worldmachine, units-ut2: 23.1 fps over 120 s without, a flat
|
||||
// 30.0 with).
|
||||
const fjitQ = q.get('fjit');
|
||||
const w3Loader = /\/lib\/wine\/[^/]+-unix\/wine$/.test(q.get('exe') || '');
|
||||
if (fjitQ !== null ? fjitQ !== '0' : w3Loader) globalThis.GEX_FJIT = Number(fjitQ) || 1;
|
||||
// `?wasmdlls=soname=path,...`: shared objects replaced by wasm64 providers (cgen/libprov.rs).
|
||||
if (q.get('wasmdlls')) globalThis.GEX_WASM_DLLS = q.get('wasmdlls');
|
||||
// `?elfunits=name,...`: shared objects that get function-tier units (with `?cgen=1`).
|
||||
|
||||
Reference in new issue
Block a user