Commit Graph
6 Commits
Author SHA1 Message Date
ddidderr 8af6ab68d3 fix: C allocator contract, shadertoy overloads/MSL stride, minidumps
Closes the remaining library rows of the final completeness audit
(docs/rewrite/notes/final-Z3.md):
- libghostty-vt: OSC parser storage goes through the caller-supplied C
  allocator via a ByteStorage abstraction; ghostty_osc_new reports
  GHOSTTY_OUT_OF_MEMORY and failed grows invalidate the OSC like Zig.
  Tested with a counting/failing/limiting C allocator.
- shadertoy: sampler parameter rewriting is keyed by full signature so
  overloads work; the Metal uniform block keeps std140 strides for
  iChannelTime[4] (MSL offsets checked against the upload layout).
- tripwire.zig ported (named trip points, hit counts, verification) and
  used to port the previously skipped allocation-failure tests that have
  a fallible Rust path; the rest are documented.
- crash: fatal signals capture siginfo + registers and a forked helper
  writes a minidump (minidump-writer) as an envelope attachment, like
  sentry-native/Breakpad; tests parse it with the minidump crate.
- kitty LoadingImage::debug_dump (debug builds) and the Darwin
  Instruments signpost around benchmark runs.

Test Plan:
- cargo test -p ghostty-vt-capi --test c_allocator
- cargo test -p ghostty-crash --test minidump
2026-10-12 08:14:02 +02:00
ddidderr 4787565397 feat: port GTK version fallbacks, helpgen, bench modes, CLI leftovers
- apprt-gtk: Ghostty's runtime+build-time version gating (at_least)
  with cargo features adw_1_3/adw_1_4/adw_1_5/gtk_4_16 (default on) and
  the fallbacks for older libraries: MessageDialog (adw < 1.5),
  clipboard dialog without SwitchRow, pre-Banner debug warning and
  child-exited widgets, the old about dialog, GTK 4.16 CSS error source
  bytes. The minimum stays GTK 4.14 / libadwaita 1.5 (Ghostty's floor).
  The root build links with -z lazy so version-gated symbols don't keep
  older libraries from loading.
- ghostty-helpgen (port of helpgen.zig) generates CLI action help and
  keybinding action docs from doc comments at build time, replacing the
  checked-in help/*.txt; +help and +list-actions --docs stay
  byte-identical to Ghostty 1.3.1.
- ghostty-bench: libc wcwidth mode and separate simd/table and
  uucode/table code paths like Zig.
- ghostty-cli: Windows branches of edit-config, list-colors,
  list-keybinds and boo; ssh-cache DiskCache flock locking (no-op on
  Windows, as in Zig) with an exclusivity test.

Test Plan:
- cargo test --workspace
- diff <(cargo run -q -- +list-actions --docs) \
  <(ghostty +list-actions --docs)
2026-10-12 06:38:33 +02:00
ddidderr 7d48a4bf29 perf: close the last benchmark gaps to Zig (render state, parser)
- RenderState stores styles sparsely (per-cell u16 style ids plus one
  Style per distinct run) and skips plain cells with a single mask test
  (Cell::is_plain). screen-clone render: 11.5 ms -> 4.1 ms (Zig 4.7).
  row::never_extend_bg now takes a style accessor instead of a slice.
- Parser::next_with(byte, |action| ..) hands actions to a closure
  instead of moving a 64-byte action array out; Parser::next remains a
  wrapper over the same core (equivalence test added).
  terminal-parser SGR: 538 ms -> 231 ms (Zig 354).

All Ghostty benchmarks are now at or below Zig's time; table in
docs/rewrite/notes/perf-P1.md (the parser benchmark uses next_with with
a discarding closure, which like Zig's `_ = actions` lets the optimizer
skip unused work).

Test Plan:
- cargo test --workspace
- ghostty-bench +screen-clone --mode=render / +terminal-parser
2026-10-12 05:22:01 +02:00
ddidderr 126da77a37 style: apply nightly rustfmt import grouping across the workspace
rustfmt.toml sets group_imports, imports_granularity and imports_layout,
which are nightly-only; agents formatted with stable rustfmt, which
ignored them. This is a formatting-only pass with `cargo +nightly fmt`.

Test Plan:
- cargo clippy --workspace --all-targets -- -D warnings
- cargo test --workspace
2026-10-12 05:03:37 +02:00
ddidderr e9fdce0b26 perf(terminal): make screen clone match Zig, batch OSC payload copies
screen-clone was 2.6x slower than Zig. The main cost was in
PageList::clone_range: it created a throwaway page, recycled it into the
pool and Page::reinit then memset the entire page again, faulting in
every cell. Untouched pages now go to a clean_pool that create_node
reuses without re-zeroing. Page::init allocates cells with
bytemuck::allocation::try_zeroed_vec (Cell derives Zeroable), getting
lazily-zeroed memory from the allocator without unsafe code, and
clone_partial_row_from bulk-copies plain-cell runs in rows with managed
memory. screen-clone clone: 78 ms -> ~28 ms (Zig ~27.8 ms).

osc::Parser::next_slice appends payload bytes in bulk while behaving
exactly like per-byte next() (2048 limit, overflow), verified by a
property test; the osc-parser bench uses it (54.5 -> ~32 ms, Zig ~28).

Still slower: screen-clone render (~2.4x), dominated by per-row style
vectors in RenderState::update.

Test Plan:
- cargo test --workspace (no failures)
- ghostty-bench +screen-clone / +osc-parser with --profile production
2026-10-12 03:51:46 +02:00
ddidderr 062c643ea8 perf: add ghostty-bench and bring terminal throughput to Zig parity
Adds crates/ghostty-bench, a port of ZIG/src/benchmark and src/synthetic:
the ghostty-bench binary (terminal-stream, terminal-parser,
codepoint-width, grapheme-break, is-symbol, osc-parser, screen-clone
with Zig's CLI) and ghostty-synthetic data generators (+ascii, +utf8,
+osc, plus a Rust-only +sgr mode).

Measured against Ghostty's own ghostty-bench built with Zig 0.15.2
(ReleaseFast) vs --profile production, the hot paths were optimized
without behaviour changes:
- Terminal::print single-lookup fast path for width-1 chars mid-line
- page grapheme allocator: bitmap first-fit instead of a linear scan
  (was 38% of utf8 stream time; randomized equivalence test added)
- plain cells skip per-cell work in clear_cells and row cloning
- ASCII fast path + strict hand-written UTF-8 decoder (exhaustive
  equivalence test against std)
- parser/OSC parser split into inlined fast and state-change paths
- RenderState allocates grapheme vectors only for grapheme rows
- Page::assert_integrity no-op stub so the production profile builds

terminal-stream is now at parity (ascii 1.08x, utf8 0.97x, SGR 1.04x of
Zig's time). Still slower: screen-clone (~2.6x, zero-filling fresh
cell Vecs vs Zig's lazily-zeroed mmap), osc-parser (1.9x), and the raw
parser on SGR data (1.5x). Full table in docs/rewrite/notes/perf-P1.md.

Test Plan:
- cargo test --workspace (no failures)
- cargo run --profile production -p ghostty-bench -- +terminal-stream
  --data=<file> and compare with Zig's ghostty-bench
2026-10-12 02:08:01 +02:00