Commit Graph

50 Commits

Author SHA1 Message Date
Mitchell Hashimoto
f2a7652aba mitchell's touchups
- benchmark: avoid buffers to avoid a memcpy
- build: keep frame pointers on macOS. There was some debug changes from
  Zig 0.15 and this helps. Also, Apple actually requires/expects x29 to
  always be a frame pointer.
- build/macos: force libSystem symbols instead of compiler-rt
- global: add InitOpts.tool so that ghostty-gen/bench can parse their
  own actions in `+action`
- quirks: provide our own vectorized memset. see the comment for more
  details why.
- synthetic: fix UB by accessing global.io before it was initialized
- terminal/hash_map: force inline for unique repr types. Zig 0.15
  inlined and 0.16 doesn't, measured a huge slowdown in hyperlink
  benchmarks.
- terminal: add explicit `@Vector` usage for storing a run of identical cells
  as well as for scanning printable cells. This auto-vectorized in Zig
  0.15 but not in Zig 0.16. This produces the same assembly.
- unicode: properties and LUT need power-of-two backing integer to avoid
  bad LLVM codegen
2026-07-21 17:19:16 -07:00
Mitchell Hashimoto
083d9709be terminal: decode ASCII inline in the SIMD scan for ESC
Profiling terminal-stream on a 2.6 GB recording of real terminal
sessions showed ~9% of total time inside the UTF-8 decode stage,
and most of it was not the decode itself: real streams contain an
escape sequence every ~18 bytes, so utf8DecodeUntilControlSeq is
called on short printable runs, and each call paid simdutf setup
plus its scalar rewind_and_convert_with_errors tail (which handles
the last partial SIMD block of every conversion) for only a
handful of bytes. The scalar tail alone accounted for ~3.4% of
total time.

Terminal input is also overwhelmingly ASCII, for which UTF-8 to
UTF-32 "decoding" is just widening each byte to 32 bits. This
fuses the two passes: while scanning each chunk for ESC we also
check for bytes >= 0x80 and widen pure-ASCII chunks straight into
the output vector via PromoteTo, never touching simdutf. The first
non-ASCII byte hands the remainder of the run (up to the next ESC)
to the existing simdutf-based path, so non-ASCII text takes
exactly the same code as before. Inputs shorter than one vector
are handled by a scalar byte loop that likewise skips simdutf for
ASCII.

The widening store needs a dedicated path for the HWY_SCALAR
fallback target (compiled on targets without guaranteed SIMD, e.g.
arm-linux-androideabi): its single-lane vectors cannot be halved
so the one lane is widened directly.

The new differential fuzz test verifies the SIMD implementation
still matches the scalar reference exactly. Measured with
ghostty-bench terminal-stream (2.6 GB real-session corpus, 87%
printable ASCII / 5.5% ESC / 5.6% UTF-8, 120x80, M4 Max,
ReleaseFast, hyperfine means):

| stream            | before          | after           | change |
|-------------------|-----------------|-----------------|--------|
| real 2.6 GB corpus | 9.582 s (272 MB/s) | 9.090 s (287 MB/s) | +5.4% |
2026-07-06 13:51:35 -07:00
Mitchell Hashimoto
cb4c49fbf2 terminal: scalar UTF-8 decode consumes partial sequences cut off by ESC
The scalar fallback of utf8DecodeUntilControlSeq (used when SIMD is
disabled, e.g. wasm builds) treated a valid-so-far but incomplete
UTF-8 sequence at the end of its decode region as pending input in
all cases: it stopped without consuming the bytes so a future chunk
could complete the sequence. That is correct when the region ends
at the end of the input, but the region can also be bounded by an
ESC byte. In that case the sequence can never be completed (the
next byte is already known to be ESC), and the SIMD implementation,
via simdutf, replaces the ill-formed prefix with U+FFFD and
consumes up to the ESC. The two implementations disagreed on both
the consumed count and the decoded output for inputs like
"\xC2\x1B[0m".

The divergence is invisible at the stream level (the pending bytes
take the scalar nextUtf8 path which also emits a replacement
character once it sees the ESC) but it means the scalar decoder is
not a faithful reference for the SIMD one.

This makes the scalar decoder treat a partial sequence bounded by
an ESC as a maximal subpart per Unicode 3-7: one U+FFFD, consumed
through the end of the region. Truncation at the true end of input
still leaves the bytes pending. Also adds a differential fuzz test
that runs 10k random mixtures of ASCII, escapes, controls, and
valid/invalid UTF-8 through both implementations and requires
identical results, which is what caught this.
2026-07-06 12:25:58 -07:00
Mitchell Hashimoto
f3f9af6129 pkg/highway: vendor and modify to remain all libc usage 2026-04-23 20:28:43 -07:00
Mitchell Hashimoto
e51de8b58f libghostty: Remove all libc++ and libc++ ABI dependencies
This updates simdutf to my fork which has a SIMDUTF_NO_LIBCXX option
that removes all libc++ and libc++ ABI dependencies. 

From there, the hand-written simd code we have has been updated to also
no longer use any libc++ features. Part of this required removing utfcpp
since it depended on libc++ (`<iterator>`).

libghostty-vt now only depends on libc.
2026-04-15 10:27:05 -07:00
Mitchell Hashimoto
3e6a65f73f pkg/highway: drop libc++ from vendored hwy
The vendored Highway package was being built with libc++ even though
Ghostty only uses its runtime target selection and dispatch support.
That pulled in extra C++ runtime baggage from upstream support files
such as abort, timer, print, and benchmark helpers.

Build Highway in HWY_NO_LIBCXX mode, only compile the target dispatch
sources we actually need, and compile Ghostty's SIMD translation units
with the same define so the header ABI stays consistent. Replace the
upstream abort implementation with a small local bridge that provides
Highway's Warn/Abort hooks and the target-query shim without depending
on libc++.

This keeps the Highway archive down to the dispatch pieces Ghostty
uses while preserving the existing dynamic dispatch behavior. The
bridge is documented so it is clear why Ghostty carries this small
local replacement.
2026-04-11 14:28:56 -07:00
Mitchell Hashimoto
afa8f059e5 build: skip linkLibCpp on MSVC targets
Zig's bundled libc++/libc++abi conflicts with the MSVC C++ runtime
headers (vcruntime_typeinfo.h, vcruntime_exception.h, etc.) when
targeting native-native-msvc. This caused compilation failures in
the SIMD C++ code due to -nostdinc++ suppressing MSVC headers and
libc++ types clashing with MSVC runtime types.

Skip linkLibCpp() for MSVC targets across all packages (highway,
simdutf, utfcpp) and the main build (SharedDeps, GhosttyZig) since
MSVC provides its own C++ standard library natively. Also add
missing <iterator> and <cstddef> includes that were previously
pulled in transitively through libc++ headers but are not
guaranteed by MSVC's headers.
2026-03-23 11:57:14 -07:00
Mitchell Hashimoto
dbfc3eb679 Remove unused imports 2025-11-27 13:37:53 -08:00
Qwerasd
6d5b4a3426 perf: replace std.debug.assert with inlined version
See doc comment in `quirks.zig` for reasoning
2025-11-17 12:13:56 -07:00
Jacob Sandlund
c2a9c5ee5b fix comment 2025-09-23 09:48:09 -04:00
Jacob Sandlund
b01770c21c Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-09-23 09:36:41 -04:00
Mitchell Hashimoto
8477b6a21a simd: scalar base64 ignores invalid padding 2025-09-22 09:44:58 -07:00
Mitchell Hashimoto
530633b9e9 simd: fix scalar utf8 decoding 2025-09-22 09:29:08 -07:00
Mitchell Hashimoto
6893024c51 simd: add scalar fallbacks to all for build_options.simd false 2025-09-22 08:26:53 -07:00
Jacob Sandlund
cf3b514efc pr feedback: get, remove todos for case_folding_simple 2025-09-19 01:24:13 -04:00
Jacob Sandlund
6bd5da7354 update commented out test 2025-09-18 14:24:24 -04:00
Jacob Sandlund
2af08bdbe3 trying a bunch of things to get performance to match 2025-09-06 10:42:02 -04:00
Jacob Sandlund
e84d8535f5 removing all ziglyph imports (aside from unicode/grapheme.zig) 2025-08-17 21:24:27 -04:00
Mitchell Hashimoto
601acf4059 pkg/highway: upgrade to fix compilation issues on LLVM18 2025-03-12 11:03:54 -07:00
Mitchell Hashimoto
29de3e80f1 config: yeet usingns 2024-08-16 10:49:37 -07:00
Mitchell Hashimoto
27acd71105 simd: add base64 functions from simdutf 2024-07-16 20:12:45 -07:00
Mitchell Hashimoto
4e2502c11e simd/codepoint-width: assertions for avx512 padding 2024-02-07 15:23:43 -08:00
Mitchell Hashimoto
e5c7d4e3ee simd: increase padding for avx 2024-02-07 14:43:08 -08:00
Mitchell Hashimoto
ae74117269 simd: use less vector ops for 16-bit 2024-02-07 14:31:06 -08:00
Mitchell Hashimoto
a69d3c7f1c simd/codepoint-width: split by 16-bit 2024-02-07 14:04:48 -08:00
Mitchell Hashimoto
17dc64053e terminal: swap codepointwidth implementations 2024-02-07 09:38:17 -08:00
Mitchell Hashimoto
3c31217f3c simd: minor tweaks 2024-02-07 09:28:56 -08:00
Mitchell Hashimoto
46a887578a simd: remove ziglyph fallback 2024-02-07 09:21:33 -08:00
Mitchell Hashimoto
697fbe21ec simd/codepoint-width: reinclude correct file 2024-02-07 09:18:02 -08:00
Mitchell Hashimoto
d949f1bd84 simd/codepoint-width: match ziglyph 2024-02-07 09:11:02 -08:00
Mitchell Hashimoto
88d81602fa simd/codepoint-width: wip 2024-02-06 22:28:26 -08:00
Mitchell Hashimoto
fdc67a08f4 terminal: add tests for incomplete utf-8, fix one bug 2024-02-06 08:45:41 -08:00
Mitchell Hashimoto
120273aa1a pkg/utfcpp 2024-02-05 21:22:27 -08:00
Mitchell Hashimoto
626d4170fe move simdutf to a pkg 2024-02-05 21:22:27 -08:00
Mitchell Hashimoto
12885a445a simd: remove old attempts 2024-02-05 21:22:27 -08:00
Mitchell Hashimoto
50e7159288 simd: implement utf8 decode until esc in C++ 2024-02-05 21:22:27 -08:00
Mitchell Hashimoto
c751619b7e terminal: use highway-based indexOf to support all targets 2024-02-05 21:22:26 -08:00
Mitchell Hashimoto
4fa3ea604b simd/aarch64: additional intrinsics 2024-02-05 21:22:04 -08:00
Mitchell Hashimoto
c042b052b2 simd: convert indexOf, mess around with simdvt 2024-02-05 21:22:04 -08:00
Mitchell Hashimoto
a66174678b simd: utf decode using simdutf 2024-02-05 21:22:04 -08:00
Mitchell Hashimoto
9391048e1a simd: utf8 decode 2024-02-05 21:22:04 -08:00
Mitchell Hashimoto
fe098f80cc simd: simplify isa.funcMap, find Zig compiler bug 2024-02-05 21:22:04 -08:00
Mitchell Hashimoto
1e51cedd94 simd: isa.funcMap to ensure only possible ISAs are analyzed 2024-02-05 21:22:04 -08:00
Mitchell Hashimoto
6523721846 simd: utf8 count 2024-02-05 21:22:04 -08:00
Mitchell Hashimoto
5b295cf6e2 simd: only ref buildable decls 2024-02-05 21:22:03 -08:00
Mitchell Hashimoto
e682cea911 simd/utf8: document neon better 2024-02-05 21:22:03 -08:00
Mitchell Hashimoto
987c5d213e simd: utf8 validation 2024-02-05 21:22:03 -08:00
Mitchell Hashimoto
dc041f86fd src/simd: improve isa detection 2024-02-05 21:22:03 -08:00
Mitchell Hashimoto
7feba12eab simd: indexOf implementation using NEON 2024-02-05 21:22:03 -08:00
Mitchell Hashimoto
31d5785105 simd: basic ISA detection, boilerplate 2024-02-05 21:22:03 -08:00