grid: skip the per-cell ISO-protection resolve when no protected style exists #418

Merged
natsukium merged 4 commits from grid/iso-protect-skip into main 2026-09-25 06:25:17 +09:00
Owner

Closes #409

EL / ED / ECH go through the ISO-aware erase, which resolved every blanked cell's style to test ISO_PROTECTED. Almost no stream issues SPA, so on kitten's csi payload (EL 2 per chunk) that lookup bought nothing.

Shape

StyleTable::has_iso_protected: intern sets it when the interned pen carries ISO_PROTECTED, and compact recomputes it from the surviving entries. range_blank_inner honors protection only while it is set.

The issue proposed a sticky grid flag set at SPA. This version keeps the flag a function of the table's entries instead. Any StyleId (a live cell, a saved screen's cell, scrollback in the primary ring, a stale pen id) can only resolve to an entry of this table, and an out-of-range id resolves to the default pen. So while the flag is clear, no cell can be protected, however the id got there. It also lets the gate close again after a sweep drops the last protected pen, where a sticky flag would keep charging the session.

What could make it stale, and why it can't:

Path Why the flag holds
RIS replaces the Grid, so the table is fresh
alternate screen both screens share one table; the sweep marks the saved screens
scrollback lives in the primary ring, which the sweep marks
resize / reflow cells keep their ids
sweep drops a protected pen no cell holds the flag clears with it; DECRC re-interns the saved pen and sets it again
DECCARA / DECRARA / wire decode all go through intern

With the flag clear, an ISO-aware erase to row end also lowers the row's watermark, as the plain erase does, since nothing can survive it.

Tests

  • A proptest that has_iso_protected() equals "some id resolves to a protected pen" across arbitrary interns and compactions.
  • Grid tests: DECSCA-only styles leave the gate closed and EL lowers the watermark; protection survives Grid::gc_styles and ScreenBuffer::gc_styles (the daemon's TableGc path), a sweep followed by DECRC of a protected pen, RIS, the alternate screen with a sweep while on it, and resize; a protected survivor keeps the row content in view.
  • Mutation check: a compact that clears the flag unconditionally fails three of the new tests. The watermark test fails without the gate.
  • esctest's ISO group (ED / EL / ECH respectsISOProtection, DECSERA doesNotRespectISOProtect) passes.

Measurements

These use measure_parse_into_grid_floor on kitten's csi payload at 35x106, comparing the release test binary from origin/main 8a6c0361 with this branch. The runs alternated, 6 of each, at load average 2.7 (uptime):

base this branch
instructions:u 10236M 9313M (−9.0%)
MiB/s, median 141.5 148.8 (+5%)

The perf-trace cost map now records the gate and what the resolve costs without it.

Closes #409 EL / ED / ECH go through the ISO-aware erase, which resolved every blanked cell's style to test `ISO_PROTECTED`. Almost no stream issues SPA, so on kitten's csi payload (EL 2 per chunk) that lookup bought nothing. ## Shape `StyleTable::has_iso_protected`: `intern` sets it when the interned pen carries `ISO_PROTECTED`, and `compact` recomputes it from the surviving entries. `range_blank_inner` honors protection only while it is set. The issue proposed a sticky grid flag set at SPA. This version keeps the flag a function of the table's entries instead. Any `StyleId` (a live cell, a saved screen's cell, scrollback in the primary ring, a stale pen id) can only resolve to an entry of this table, and an out-of-range id resolves to the default pen. So while the flag is clear, no cell can be protected, however the id got there. It also lets the gate close again after a sweep drops the last protected pen, where a sticky flag would keep charging the session. What could make it stale, and why it can't: | Path | Why the flag holds | | --- | --- | | RIS | replaces the `Grid`, so the table is fresh | | alternate screen | both screens share one table; the sweep marks the saved screens | | scrollback | lives in the primary ring, which the sweep marks | | resize / reflow | cells keep their ids | | sweep drops a protected pen no cell holds | the flag clears with it; DECRC re-interns the saved pen and sets it again | | DECCARA / DECRARA / wire decode | all go through `intern` | With the flag clear, an ISO-aware erase to row end also lowers the row's watermark, as the plain erase does, since nothing can survive it. ## Tests - A proptest that `has_iso_protected()` equals "some id resolves to a protected pen" across arbitrary interns and compactions. - Grid tests: DECSCA-only styles leave the gate closed and EL lowers the watermark; protection survives `Grid::gc_styles` and `ScreenBuffer::gc_styles` (the daemon's `TableGc` path), a sweep followed by DECRC of a protected pen, RIS, the alternate screen with a sweep while on it, and resize; a protected survivor keeps the row content in view. - Mutation check: a `compact` that clears the flag unconditionally fails three of the new tests. The watermark test fails without the gate. - esctest's ISO group (ED / EL / ECH `respectsISOProtection`, DECSERA `doesNotRespectISOProtect`) passes. ## Measurements These use `measure_parse_into_grid_floor` on kitten's csi payload at 35x106, comparing the release test binary from `origin/main` 8a6c0361 with this branch. The runs alternated, 6 of each, at load average 2.7 (`uptime`): | | base | this branch | | --- | --- | --- | | `instructions:u` | 10236M | 9313M (−9.0%) | | MiB/s, median | 141.5 | 148.8 (+5%) | The perf-trace cost map now records the gate and what the resolve costs without it.
EL and ED go through the ISO-aware erase, which resolved every blanked
cell's style through the style table to test ISO_PROTECTED. Almost no
stream ever issues SPA, so on kitten's csi payload (EL 2 per chunk)
that lookup was paid for nothing: it was about 11% of the csi
parse-into-grid floor's self time, and skipping it cuts the floor's
instructions:u by 9%.

The style table now tracks whether any of its entries carries
ISO_PROTECTED, and the erase honors protection only while one does.
The flag is a function of the table's entries (set by intern,
recomputed by compact) rather than a sticky grid flag, because that is
the one form no handle can outrun: a cell, a saved screen's cell or a
stale pen id can only resolve to an entry of this table, so while the
flag is clear none of them can be protected. It holds through RIS (a
fresh table), the alternate screen and scrollback (one table, and the
sweep marks the saved screens and the ring), resize (cells keep their
ids), and a sweep that drops a protected pen no cell holds (DECRC
re-interns it). A sticky flag would be as safe but would keep taxing a
session after the protected cells are gone.

With the flag clear, an erase to the end of the row also lowers the
row's watermark as the plain erase does, since no cell can survive it.

Assisted-by: Claude Code
The perf-trace cost map named the per-cell ISO-protection resolve as
the next csi lever; with the style table's gate in place, a later pass
reading it would chase a cost that is gone. It now states the gate and
what the resolve costs without it, so a regression that bypasses the
gate is recognizable in a profile.

Assisted-by: Claude Code
grid: pin the row watermark an ISO-aware erase leaves behind
Some checks failed
bench / Criterion full-suite snapshot (pull_request) Has been skipped
fuzz / cargo fuzz nightly long-run (pull_request) Has been skipped
darwin / detect relevant changes (pull_request) Has been cancelled
darwin / build felis (aarch64-darwin) (pull_request) Has been cancelled
darwin / publish felis (aarch64-darwin) (pull_request) Has been cancelled
darwin / darwin docs-only no-op (pull_request) Has been cancelled
fuzz / cargo fuzz smoke (per target) (pull_request) Has been cancelled
pr / nix flake check (pull_request) Has been cancelled
pr / cargo build / clippy / test / deny (pull_request) Has been cancelled
pr / wire schema is compatible with the base (pull_request) Has been cancelled
pr / frontend smoke (x86_64-linux) (pull_request) Has been cancelled
windows / detect relevant changes (pull_request) Has been cancelled
windows / cargo clippy (Windows cross) (pull_request) Has been cancelled
windows / cargo nextest (Windows) (pull_request) Has been cancelled
windows / frontend smoke (Windows) (pull_request) Has been cancelled
windows / package felis (x86_64-pc-windows-msvc) (pull_request) Has been cancelled
windows / windows docs-only no-op (pull_request) Has been cancelled
pr / publish felis (x86_64-linux) (pull_request) Has been cancelled
bench / Criterion regression gate (pull_request) Has been cancelled
b15b7d757b
With no protected style in the table, EL 2 now lowers the row's
occupancy watermark as the plain erase does. The cell reads in the
existing test cannot see that, since a cell past the watermark reads
blank either way; the row's content length can. The companion case
keeps the content up to a protected survivor in view.

Assisted-by: Claude Code
Merge remote-tracking branch 'origin/main' into grid/iso-protect-skip
All checks were successful
bench / Criterion full-suite snapshot (pull_request) Has been skipped
fuzz / cargo fuzz nightly long-run (pull_request) Has been skipped
bench / Criterion regression gate (pull_request) Successful in 5m41s
darwin / detect relevant changes (pull_request) Successful in 5s
darwin / darwin docs-only no-op (pull_request) Has been skipped
darwin / build felis (aarch64-darwin) (pull_request) Successful in 54s
darwin / publish felis (aarch64-darwin) (pull_request) Has been skipped
fuzz / cargo fuzz smoke (per target) (pull_request) Successful in 1m36s
pr / nix flake check (pull_request) Successful in 4m28s
pr / cargo build / clippy / test / deny (pull_request) Successful in 3m40s
pr / wire schema is compatible with the base (pull_request) Successful in 30s
pr / frontend smoke (x86_64-linux) (pull_request) Successful in 5m24s
pr / publish felis (x86_64-linux) (pull_request) Has been skipped
windows / detect relevant changes (pull_request) Successful in 4s
windows / windows docs-only no-op (pull_request) Has been skipped
windows / cargo clippy (Windows cross) (pull_request) Successful in 57s
windows / cargo nextest (Windows) (pull_request) Successful in 3m52s
windows / frontend smoke (Windows) (pull_request) Successful in 1m39s
windows / package felis (x86_64-pc-windows-msvc) (pull_request) Has been skipped
f7efcd4912
natsukium deleted branch grid/iso-protect-skip 2026-09-25 06:25:17 +09:00
Commenting is not possible because the repository is archived.
No description provided.