Skip to content

Commit b10603e

Browse files
committed
Switch all linux release builds to musl + mimalloc, add memory profiling
features, plan memory optimizations
1 parent 5dee2ec commit b10603e

13 files changed

Lines changed: 2130 additions & 33 deletions

File tree

Cargo.toml

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,16 @@ zip = "2"
4747
# musl's built-in malloc is very slow under the multi-threaded,
4848
# allocation-heavy load of parallel indexing and parse workers (4-6x
4949
# slower whole-project analysis), so the static musl binaries we ship
50-
# for Linux use mimalloc instead. Scoped to musl only: glibc, macOS,
51-
# and Windows system allocators perform fine, and mimalloc retains
52-
# freed pages more aggressively than they do, so enabling it where it
53-
# isn't needed just raises resident memory.
54-
[target.'cfg(target_env = "musl")'.dependencies]
50+
# for Linux use mimalloc instead.
51+
#
52+
# Scoped to Linux rather than musl alone so that a local `cargo build`
53+
# on a glibc workstation gets the same allocator as the binaries we
54+
# release: every Linux artifact we publish is musl, so no shipped build
55+
# is affected by widening this, while performance and memory figures
56+
# measured locally now match what users actually run. macOS and Windows
57+
# release from their own targets and use the system allocator both in
58+
# CI and locally, so they are already representative and are left alone.
59+
[target.'cfg(target_os = "linux")'.dependencies]
5560
mimalloc = { version = "0.1.47", optional = true }
5661
libmimalloc-sys = { version = "0.1", optional = true, features = ["extended"] }
5762
libc = { version = "0.2", optional = true }
@@ -67,6 +72,11 @@ flate2 = "1"
6772
# can be toggled off for benchmarking or debugging without editing code.
6873
default = ["mimalloc"]
6974
mimalloc = ["dep:mimalloc", "dep:libmimalloc-sys", "dep:libc"]
75+
# Deep-size accounting of the long-lived symbol stores, printed at the
76+
# end of `analyze` when PHPANTOM_MEM_AUDIT is set. Off by default: it
77+
# installs a counting global allocator that adds two atomics to every
78+
# allocation, so it must never be enabled in a shipped build.
79+
mem-audit = []
7080

7181
[dev-dependencies]
7282
datatest-stable = "0.3"

docs/BUILDING.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,34 @@ The stubs are downloaded on first build and cached in `stubs/`. To update to the
1818

1919
For details on how symbol resolution and stub loading work, see [ARCHITECTURE.md](ARCHITECTURE.md).
2020

21+
### Matching the released binary
22+
23+
The Linux binaries we publish are static musl builds using mimalloc as
24+
the allocator (see the comment on the `mimalloc` dependency in
25+
`Cargo.toml`). A plain `cargo build --release` on a glibc workstation
26+
already uses the same allocator — mimalloc is enabled for Linux, not
27+
just musl — so day-to-day performance and memory testing on any Linux
28+
dev machine is representative without extra setup.
29+
30+
To build the exact target we ship (e.g. to reproduce a memory or
31+
performance report bit-for-bit), build for musl:
32+
33+
```bash
34+
rustup target add x86_64-unknown-linux-musl
35+
sudo apt install musl-tools # provides musl-gcc; adjust for your distro
36+
CARGO_BUILD_TARGET=x86_64-unknown-linux-musl cargo build --release
37+
```
38+
39+
This produces `target/x86_64-unknown-linux-musl/release/phpantom_lsp`
40+
alongside your normal build (it doesn't touch `target/release/`), so it
41+
doesn't disturb incremental builds of your everyday work.
42+
43+
If you're benchmarking or profiling memory and get numbers that look
44+
off from what's documented in `docs/todo/performance.md`, check which
45+
allocator built the binary before assuming a regression — macOS and
46+
Windows use the system allocator in both CI and locally already, so
47+
they need no special steps.
48+
2149
## Testing
2250

2351
Run the full test suite:

docs/todo.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ within the same impact tier.
2727
| --- | --------------------------------------------------------------------------------------------------------------------- | ---------- | ------ |
2828
| P36 | [Diagnostic-path call sites re-merge inheritance per call](todo/performance.md#p36-diagnostic-path-call-sites-re-merge-inheritance-per-call-instead-of-reading-the-resolved-class-cache) | Medium | Low |
2929
| P31 | [Reference index stores per-span entries when consumers only read distinct URIs](todo/performance.md#p31-reference-index-stores-per-span-entries-when-consumers-only-read-distinct-uris) | Medium | Low-Medium |
30+
| P37 | [`PhpType` is 64 bytes and is embedded ~3 M times](todo/performance.md#p37-phptype-is-64-bytes-and-is-embedded-3-m-times) | High | Medium |
31+
| P38 | [Resolved type values are duplicated ~33x](todo/performance.md#p38-resolved-type-values-are-duplicated-33x) | High | High |
32+
| P39 | [`SymbolKind` stores owned strings per span](todo/performance.md#p39-symbolkind-stores-owned-strings-per-span) | Medium | Low-Medium |
33+
| P40 | [`method_index` is a per-class `HashMap` even when the member vec is shared](todo/performance.md#p40-method_index-is-a-per-class-hashmap-even-when-the-member-vec-is-shared) | Low-Medium | Low |
34+
| P41 | [3.8 M live allocations cost ~130 MB in allocator overhead](todo/performance.md#p41-38-m-live-allocations-cost-130-mb-in-allocator-overhead) | Medium | Medium |
3035
| P33 | [Workspace diagnostics leaves the whole project fully resolved in memory](todo/performance.md#p33-workspace-diagnostics-leaves-the-whole-project-fully-resolved-in-memory) | High | Medium-High |
3136
| X10 | [Interactive requests block on the workspace index lock during initial indexing](todo/indexing.md#x10-interactive-requests-block-on-the-workspace-index-lock-during-initial-indexing) | Medium | Medium |
3237
| L21 | [Tighten the supertype-where-subtype comparison escape hatch (blocked on resolver precision)](todo/laravel.md#l21-tighten-the-supertype-where-subtype-comparison-escape-hatch-blocked-on-resolver-precision) | Medium | High |

0 commit comments

Comments
 (0)