Skip to content

Allocate proc bodies in a separate mimalloc heap - #487

Open
ZeWaka wants to merge 1 commit into
SpaceManiac:masterfrom
ZeWaka:proc-body-heap
Open

ZeWaka wants to merge 1 commit into
SpaceManiac:masterfrom
ZeWaka:proc-body-heap

Conversation

@ZeWaka

@ZeWaka ZeWaka commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Supersedes #486, per:

I'm not a fan of double-parsing. I'd prefer to put proc bodies in some set-aside heap so that dropping them afterwards actually works.

This time, the parser gets a hook that runs around each proc body. The langserver uses it to switch mimalloc's default heap to a separate proc heap while a body is being parsed, so everything a proc body allocates ends up there.

Once the Find References table and dreamchecker are done with the tree, the proc bodies get dropped and the proc heap is collected. Errors registered while parsing a proc body are copied back out of the proc heap so they don't pin its pages.

The background jobs wake up the main loop when they finish, so the memory is released right away. VSCode doesn't send anything while idle, so otherwise it'd sit there until the next hover or keystroke.

Diagram

A thick border means it's kept in memory while idle

flowchart TD
    S[Load or reparse] --> P[Parse]
    P -->|everything else| M[Object tree<br/>for hover, completion, goto]
    P -->|proc bodies| H[Proc heap]
    H --> R[Build Find References table]
    H --> D[Run dreamchecker]
    R --> T[Find References table]
    R --> F[Proc bodies dropped,<br/>proc heap collected]
    D --> F
    classDef kept stroke-width:3px
    class M,T kept
Loading

Median of 3 runs each on my local Windows machine:

Repo Build Editor Ready Errors ready Peak memory (load) Idle memory Peak memory (reparse) Idle memory (after reparse)
goon master 1.99 s 2.55 s 515 MB 435 MB 809 MB 551 MB
goon this 1.96 s 2.54 s 505 MB 232 MB (-47%) 606 MB (-25%) 279 MB (-49%)
tg master 2.63 s 3.37 s 652 MB 579 MB 1060 MB 700 MB
tg this 2.62 s 3.36 s 678 MB 357 MB (-38%) 849 MB (-20%) 433 MB (-38%)

Similar percentages on Debian WSL using glibc.

Thoughts

Unlike #486 there's no speedups, since that came from the main thread skipping proc bodies. There's no extra memory overhead from double-parsing, though.

I don't think waiting for custom allocators in 1.100 would help here since String/Cow/IndexMap still won't take an allocator, so a lot of proc body memory would still land in the main heap.

Related: #113

@ZeWaka
ZeWaka force-pushed the proc-body-heap branch 4 times, most recently from e2c6104 to a84bf5f Compare October 5, 2026 00:36
Parse proc bodies into their own mimalloc heap, then drop
them and collect that heap once both background jobs finish, so their
pages actually return to the OS.
@ZeWaka
ZeWaka marked this pull request as ready for review October 5, 2026 01:05
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