Skip to content

fix(highlight): stop a JavaScript line from pinning a core forever - #1007

Merged
tontinton merged 1 commit into
mainfrom
fix-syntect-bug
Sep 12, 2026
Merged

tontinton merged 1 commit into
mainfrom
fix-syntect-bug

Conversation

@tontinton

@tontinton tontinton commented Sep 12, 2026 •

Copy link
Copy Markdown
Owner

Opening a session sent a core to 100% and kept it there until maki was killed, and nothing in the transcript looked unusual.

The thread named highlight was stuck inside a single ParseState::parse_line call on a 20 line JavaScript snippet, and the minimal case turned out to be x /*: two rules in the JavaScript syntax bat ships both match empty at the byte after the identifier and set each other's context back, forever, because syntect's loop guard only watches a push followed by a pop, and a set is neither.

Flat memory the whole time, so it is a real cycle rather than backtracking, and the queue in maki-highlight/src/pool.rs is a single thread with no deadline, so that one line also starved every highlight job that came after it.

Pins syntect to a v5.3.0 backport of trishume/syntect#706, which remembers the (byte, context stack) a non-consuming set was taken from and advances a character on the second visit, exactly what the push/pop guard already does; both syntest baselines are unchanged upstream.

@tontinton
tontinton enabled auto-merge (rebase) September 12, 2026 14:47
@tontinton
tontinton force-pushed the fix-syntect-bug branch 2 times, most recently from 868e24c to b4eeb57 Compare September 12, 2026 14:55
Opening a session sent a core to 100% and kept it there until maki was
killed, and nothing in the transcript looked unusual.

The thread named `highlight` was stuck inside a single
`ParseState::parse_line` call on a 20 line JavaScript snippet, and the
minimal case turned out to be `x /*`: two rules in the JavaScript syntax
`bat` ships both match empty at the byte after the identifier and `set`
each other's context back, forever, because syntect's loop guard only
watches a push followed by a pop, and a `set` is neither.

Flat memory the whole time, so it is a real cycle rather than
backtracking, and the queue in `maki-highlight/src/pool.rs` is a single
thread with no deadline, so that one line also starved every highlight
job that came after it.

Pins syntect to a `v5.3.0` backport of trishume/syntect#706, which
remembers the `(byte, context stack)` a non-consuming `set` was taken
from and advances a character on the second visit, exactly what the
push/pop guard already does; both syntest baselines are unchanged
upstream.
@tontinton
tontinton merged commit 75ae8b2 into main Sep 12, 2026
11 checks passed
@tontinton
tontinton deleted the fix-syntect-bug branch September 12, 2026 15:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant