perf(web): disable icount by default (4.7x faster book open)

icount throttled TCG and starved the guest watchdog. Measured book open dropped from 146s to 31s. Off by default; ?icount restores it, ?noicount removed in favor of the new default. Harness now reports open-file timing.
This commit is contained in:
2026-07-21 20:19:46 -04:00
parent 223500ab09
commit 080a264b5c
3 changed files with 15 additions and 5 deletions
+6 -2
View File
@@ -12,9 +12,13 @@ Opening `/Test/example.txt` through QEMU `vvfat` could corrupt coroutine/guest s
Opening a book panics **only in WASM** (`Invalid read ... reason: rejected` → Load access fault) inside `uzlib_uncompress` during the reader's font `prewarmCache` **if** compiled guest stores are enabled. Native QEMU from the same submodule renders fine.
Root cause (confirmed by full diff against pristine upstream): `wasm_tci_only_tb = true` in `tcg_out_qemu_st` is **upstream qemu-wasm's own design**. Upstream forces every store-containing TB to the TCI interpreter because its compiled restartable-block store path is not rewind-safe (a yielded softmmu helper replays the block; safe for loads, corrupting for stores). This is the dominant cost of book open (font inflate is store-heavy, so the hot loop never JIT-promotes).
Root cause (confirmed by full diff against pristine upstream): `wasm_tci_only_tb = true` in `tcg_out_qemu_st` is **upstream qemu-wasm's own design**. Upstream forces every store-containing TB to the TCI interpreter because its compiled restartable-block store path is not rewind-safe (a yielded softmmu helper replays the block; safe for loads, corrupting for stores). Font inflate is store-heavy, so that hot loop never JIT-promotes — a real but secondary perf ceiling.
The real fix is to make compiled stores rewind-safe and drop the blanket TCI — a substantial TCG-backend task, ~15 min per browser iteration, no native repro. Full analysis: `docs/wasm-inflate-panic.md`.
Remaining fix is to make compiled stores rewind-safe and drop the blanket TCI — a substantial TCG-backend task, ~15 min per browser iteration, no native repro. Full analysis: `docs/wasm-inflate-panic.md`.
## Resolved: `-icount` throttled book open ~4.7x
The browser ran with `-icount shift=auto,align=off,sleep=off`, which serialized TCG and starved the guest watchdog (the earlier `wdt timeout` panics). Measured book open: 146s with icount, 31s without. icount is now off by default in `web/app.js`; `?icount` restores it. Guest timekeeping tracks host wall-clock, which is fine here because running flat-out feeds the watchdog faster, not slower.
## Resolved: reader grayscale rendered inverted and muddled
+4 -1
View File
@@ -163,7 +163,9 @@ try:
press(confirm, 'opening Browse Files')
press(confirm, 'opening Test directory')
press(confirm, 'highlighting example.txt')
open_start = time.monotonic()
press(confirm, 'opening example.txt')
open_seconds = time.monotonic() - open_start
down = driver.find_element(By.CSS_SELECTOR, '[data-button="down"]')
up = driver.find_element(By.CSS_SELECTOR, '[data-button="up"]')
@@ -187,7 +189,8 @@ try:
print(
f'browser {MODE} test passed at frame generation '
f'{final_state["generation"]}, '
f'wasm heap {final_state["wasmHeap"] / 1024 / 1024:.1f} MiB'
f'wasm heap {final_state["wasmHeap"] / 1024 / 1024:.1f} MiB, '
f'open example.txt took {open_seconds:.1f}s'
)
except Exception:
state = save_artifacts()
+5 -2
View File
@@ -462,14 +462,17 @@ async function boot(file, variant, setStatus) {
logLine(sdMessage);
const { default: createQemu } = await import(qemuUrl);
const qemuLogFlags = new URL(location.href).searchParams.has('trace')
const params = new URL(location.href).searchParams;
const qemuLogFlags = params.has('trace')
? 'guest_errors,unimp,in_asm'
: 'guest_errors,unimp';
// icount throttles TCG ~4.7x here and starves the guest watchdog; off by default. ?icount restores it.
const icount = params.has('icount') ? ['-icount', 'shift=auto,align=off,sleep=off'] : [];
const options = {
arguments: [
'-machine', `xteink,variant=${variant}`,
'-accel', 'tcg,tb-size=16',
'-icount', 'shift=auto,align=off,sleep=off',
...icount,
'-L', '/bios',
'-display', 'none',
'-serial', 'stdio',