Repository navigation
Various memory optimizations - #64734
Jake Bailey (jakebailey) wants to merge 25 commits into
Conversation
|
TypeScript Bot (@typescript-bot) perf test this faster |
|
Jake Bailey (@jakebailey) Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
TypeScript Bot (@typescript-bot) perf test this faster |
|
Jake Bailey (@jakebailey) Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
TypeScript Bot (@typescript-bot) perf test this faster |
|
Jake Bailey (@jakebailey) Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
TypeScript Bot (@typescript-bot) perf test this faster |
|
Jake Bailey (@jakebailey) Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
CPU regression appears to be due to #64735 |
|
TypeScript Bot (@typescript-bot) perf test this faster |
|
Jake Bailey (@jakebailey) Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
TypeScript Bot (@typescript-bot) perf test this faster |
|
Jake Bailey (@jakebailey) Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
🔵 Needs a closer look
The broad unsafe layout and memory-lifetime refactor warrants final human validation despite extensive tests.
0 open findings
What changed in this PR
Optimizes memory usage across the native Go compiler while preserving compiler and language-service behavior.
Changes:
- Replaces interface-backed AST, type, and mapper payloads with compact tagged layouts.
- Adds arenas, pointer-free indexes, lazy metadata, and reusable checker workspaces.
- Adds regression tests, benchmarks, and compiler baselines.
| File | Description |
|---|---|
tsc/testdata/tests/cases/compiler/instantiatedReferenceMemberResolution.ts |
Adds member-resolution regression coverage. |
tsc/testdata/baselines/reference/compiler/instantiatedReferenceMemberResolution.types |
Records inferred types. |
tsc/testdata/baselines/reference/compiler/instantiatedReferenceMemberResolution.symbols |
Records resolved symbols. |
tsc/testdata/baselines/reference/compiler/instantiatedReferenceMemberResolution.js |
Records emit and declarations. |
tsc/testdata/baselines/reference/compiler/instantiatedReferenceMemberResolution.errors.txt |
Records expected diagnostics. |
tsc/internal/fourslash/tests/completionListForGenericInstance1_test.go |
Tests generic completion stability. |
tsc/internal/core/linkstore.go |
Compresses paged link storage. |
tsc/internal/core/linkstore_test.go |
Tests and benchmarks arenas/link stores. |
tsc/internal/core/arena.go |
Bounds arena chunks and adds indexed arenas. |
tsc/internal/checker/utilities.go |
Adds reusable checker workspaces. |
tsc/internal/checker/types.go |
Compacts checker types and metadata. |
tsc/internal/checker/types_test.go |
Tests layouts, caches, and allocation behavior. |
tsc/internal/checker/tracer.go |
Updates tracing for tagged types. |
tsc/internal/checker/services.go |
Uses compact member and metadata accessors. |
tsc/internal/checker/relater.go |
Compresses relation caches and signature access. |
tsc/internal/checker/pseudotypenodebuilder.go |
Uses compact signature accessors. |
tsc/internal/checker/nodecopy.go |
Updates signature type-parameter access. |
tsc/internal/checker/nodebuilderscopes.go |
Updates signature scope handling. |
tsc/internal/checker/nodebuilderimpl.go |
Adapts node building to compact metadata. |
tsc/internal/checker/mapper.go |
Replaces mapper interfaces with tagged dispatch. |
tsc/internal/checker/jsx.go |
Uses optional composite signature metadata. |
tsc/internal/checker/inference.go |
Embeds inference mapper storage. |
tsc/internal/checker/flow.go |
Uses compact signature accessors. |
tsc/internal/checker/exports.go |
Updates symbol metadata access. |
tsc/internal/checker/checker_test.go |
Adds member-resolution tests and benchmarks. |
tsc/internal/binder/binder.go |
Allocates optional symbol metadata in arenas. |
tsc/internal/ast/utilities.go |
Updates member/export initialization APIs. |
tsc/internal/ast/symbol.go |
Moves optional symbol fields out of hot records. |
tsc/internal/ast/symbol_test.go |
Tests compact symbol storage and lifetime. |
tsc/internal/ast/nodeaccessors_test.go |
Tests kind-dispatched AST accessors. |
tsc/internal/ast/nodeaccessors_bench_test.go |
Benchmarks AST accessor dispatch. |
tsc/internal/ast/kind_stringer_generated.go |
Includes synthetic flow-node kinds. |
tsc/internal/ast/flow.go |
Tags synthetic flow-node payloads. |
tsc/internal/ast/ast.go |
Removes AST payload interfaces. |
tools/scripts/tsc/generate-go-ast.ts |
Generates compact kind-based AST dispatch. |
Files not reviewed (1)
- tsc/internal/ast/kind_stringer_generated.go: Generated file
🧠 Review effort: Balanced
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
Dynamic interface dispatch obscures the concrete AST layout and adds indirection to frequently used compiler accessors. Generated kind-based dispatch keeps those access paths explicit and checked against the node schema. Keep the method-generation foundation together so it can be reviewed or removed independently of the subsequent storage optimizations.
Each type carries a self-referential interface solely to recover its concrete representation. That costs space in every type and adds GC pointer work even though the representation is fixed at construction. A compact concrete-kind tag saves 16 bytes per type on 64-bit hosts. Keep it separate from mutable semantic flags so casts stay valid as checking discovers more information.
Dense checker link stores still keep a pointer for every occupied slot. Those tables cost memory and require GC scanning even though values already live in arenas. Use four-byte indexes in the page tables. Retain bounded arena blocks so references stay stable without geometrically over-allocating large stores. Keep map-backed stores unchanged: compressing those did not improve allocation usage.
Common type representations create many small heap objects during checking, adding allocator and GC bookkeeping costs. Use the existing bounded typed arenas for frequently allocated types. Unlike an arena that owns the entire graph, old blocks can still be reclaimed when no live type references them.
Large type lists repeatedly grow temporary hash buffers even though
their encoded length is already known. These discarded allocations
account for a substantial part of checker allocation traffic.
Reserve enough capacity before writing each list, retaining the small
inline path and the exact existing hash byte stream. Allocation tests
cover the inline boundary and large lists, and a fresh-program benchmark
includes parsing and binding rather than relying only on warmed ASTs.
CPU wall timings are noisy on this machine; report bytes and allocation
counts instead.
goos: linux
goarch: amd64
pkg: github.com/microsoft/TypeScript/tsc/internal/checker
cpu: Intel(R) Core(TM) i9-10900K CPU @ 3.70GHz
│ key-before.txt │ key-reserve.txt │
│ B/op │ B/op vs base │
TypeListKey/8-20 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=6) ¹
TypeListKey/46-20 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=6) ¹
TypeListKey/47-20 576.0 ± 0% 208.0 ± 0% -63.89% (p=0.002 n=6)
TypeListKey/256-20 2.375Ki ± 0% 1.125Ki ± 0% -52.63% (p=0.002 n=6)
TypeListKey/4096-20 81.25Ki ± 0% 18.00Ki ± 0% -77.85% (p=0.002 n=6)
geomean ² -48.03% ²
¹ all samples are equal
² summaries must be >0 to compute geomean
│ key-before.txt │ key-reserve.txt │
│ allocs/op │ allocs/op vs base │
TypeListKey/8-20 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=6) ¹
TypeListKey/46-20 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=6) ¹
TypeListKey/47-20 2.000 ± 0% 1.000 ± 0% -50.00% (p=0.002 n=6)
TypeListKey/256-20 4.000 ± 0% 1.000 ± 0% -75.00% (p=0.002 n=6)
TypeListKey/4096-20 13.000 ± 0% 1.000 ± 0% -92.31% (p=0.002 n=6)
geomean ² -60.50% ²
¹ all samples are equal
² summaries must be >0 to compute geomean
A presence query needs only the page entry, not its value. Resolving an occupied index adds arena lookup work to a boolean check. Keep presence checks on the compressed page table, and apply the repository linter fixes to the link-store tests.
The linter rewrites integer formatting calls without updating their imports. Keep the corrected test code buildable with strconv.
Union and intersection normalization creates temporary lists even when
an equivalent type already exists. Mapping and narrowing repeat this work
throughout checking, producing unnecessary garbage. Reentrant, bounded
workspaces let canonicalization reuse that storage while published types
and subtype-reduction caches retain independently owned constituents.
Fresh parse, bind, and check of the compiler fixture (six samples):
│ before │ after │
│ B/op │ B/op vs base │
CheckFreshProgram-20 303.0Mi 277.2Mi -8.51% (p=0.002 n=6)
│ before │ after │
│ allocs/op │ allocs/op vs base │
CheckFreshProgram-20 1.393M 1.139M -18.26% (p=0.002 n=6)
VS Code src: identical diagnostics and compiler counts, 31.01M to 28.52M
allocations. One fixed-work instruction sample fell from 344.57B to
324.08B; timing is noisy and not evidence of a reliable wall-time gain.
Retained memory was effectively unchanged at 5.38 GiB.
npx hereby validate passed; focused ownership tests also passed with race
and checkptr instrumentation.
Every mapper currently carries a self-referential interface, and each
inference context separately allocates two mappers with the same lifetime.
A concrete kind header eliminates the interface and lets inference
contexts own their fixing and non-fixing mappers in one allocation.
Fresh parse, bind, and check versus reusable normalization workspaces:
│ before │ after │
│ B/op │ B/op vs base │
CheckFreshProgram-20 277.2Mi 276.0Mi -0.44% (p=0.002 n=6)
│ before │ after │
│ allocs/op │ allocs/op vs base │
CheckFreshProgram-20 1.139M 1.094M -3.90% (p=0.002 n=6)
VS Code allocations decrease from 28.52M to 27.17M with identical
compiler counts and diagnostics. Retained memory is effectively unchanged.
Three interleaved fixture runs show fewer fixed-work instructions, but a
single VS Code run is noisy; no wall-time claim is made.
npx hereby validate and focused race/checkptr tests passed.
Most value symbols never need write types, computed names, or containing
types. These three pointers nevertheless occupy every checker link record,
which is the largest retained allocation on the VS Code workload.
Allocate that metadata only when it is used, shrinking the hot record
from 56 to 40 bytes without changing symbol identity or cache semantics.
VS Code src, six samples versus compact inference mappers:
│ before │ after │
│ retained-B │ retained-B vs base │
ExternalProgram-20 5.029Gi 4.874Gi -3.09% (p=0.002 n=6)
│ before │ after │
│ scan-B │ scan-B vs base │
ExternalProgram-20 4.664Gi 4.508Gi -3.33% (p=0.002 n=6)
│ before │ after │
│ B/op │ B/op vs base │
ExternalProgram-20 6.200Gi 6.043Gi -2.54% (p=0.002 n=6)
Allocation count is unchanged. All 321 semantic diagnostics and all
10284 files are identical. CLI diagnostic text and compiler counts match
exactly as well. No GC tuning is used.
npx hereby validate and focused race/checkptr ownership tests passed.
Instantiated and inherited object types retain a name-to-symbol map beside
their ordered property list. Those maps duplicate symbol pointers and
string headers across millions of types, increasing both live heap and
the amount of memory the collector must scan.
Use the existing property list as the source of truth for immutable named
members. Small types need no separate index; larger types need only
pointer-free integer slots. Keep map semantics for mutable module exports,
reserved members, mismatched names, and recursive member resolution.
VS Code src, six samples versus cold value-symbol links:
goos: linux
goarch: amd64
pkg: github.com/microsoft/TypeScript/tsc/internal/checker
cpu: Intel(R) Core(TM) i9-10900K CPU @ 3.70GHz
│ vscode-cold-links.txt │ vscode-member-index-owned.txt │
│ retained-B │ retained-B vs base │
ExternalProgram-20 4.874Gi ± 0% 4.503Gi ± 0% -7.61% (p=0.002 n=6)
│ vscode-cold-links.txt │ vscode-member-index-owned.txt │
│ scan-B │ scan-B vs base │
ExternalProgram-20 4.508Gi ± 0% 4.062Gi ± 0% -9.89% (p=0.002 n=6)
│ vscode-cold-links.txt │ vscode-member-index-owned.txt │
│ B/op │ B/op vs base │
ExternalProgram-20 6.043Gi ± 0% 5.982Gi ± 0% -1.00% (p=0.002 n=6)
│ vscode-cold-links.txt │ vscode-member-index-owned.txt │
│ allocs/op │ allocs/op vs base │
ExternalProgram-20 26.23M ± 0% 26.04M ± 0% -0.71% (p=0.002 n=6)
All 321 semantic diagnostics and 10284 files are identical. CLI diagnostic
text and compiler counts match exactly. Instruction measurements remain
noisy; this change does not claim an established CPU improvement.
No GC tuning is used.
npx hereby validate and focused race/checkptr tests passed. Existing
compiler and editor baselines are unchanged, including recursive CommonJS
member resolution.
Every node retains a self-referential interface even though its concrete allocation embeds the node header and its kind already selects dispatch. Across the VS Code source tree, that redundant metadata keeps hundreds of megabytes live and exposes another pointer per node to the collector. Remove the redundant reference without compressing parent or child pointers. The node header shrinks from 48 to 32 bytes on amd64, while generated casts check the concrete kind and enforce offset-zero embedding at compile time. Direct pointers preserve cheap navigation and do not introduce factory-wide ownership or cross-factory lookup tables. Baseline: 70510c0, which already includes the existing generated nodeData accessor work and all preceding checker optimizations. These numbers do not attribute the accessor foundation's gains to this change. VS Code src, six interleaved fresh-process samples: goos: linux goarch: amd64 pkg: github.com/microsoft/TypeScript/tsc/internal/checker cpu: Intel(R) Core(TM) i9-10900K CPU @ 3.70GHz │ vscode-direct-node-foundation.txt │ vscode-direct-node.txt │ │ retained-B │ retained-B vs base │ ExternalProgram-20 4.504Gi ± 0% 4.180Gi ± 0% -7.18% (p=0.002 n=6) │ vscode-direct-node-foundation.txt │ vscode-direct-node.txt │ │ scan-B │ scan-B vs base │ ExternalProgram-20 4.063Gi ± 0% 3.738Gi ± 0% -8.00% (p=0.002 n=6) │ vscode-direct-node-foundation.txt │ vscode-direct-node.txt │ │ B/op │ B/op vs base │ ExternalProgram-20 5.983Gi ± 0% 5.659Gi ± 0% -5.41% (p=0.002 n=6) │ vscode-direct-node-foundation.txt │ vscode-direct-node.txt │ │ allocs/op │ allocs/op vs base │ ExternalProgram-20 26.04M ± 0% 26.05M ± 0% ~ (p=0.589 n=6) │ direct-node-foundation-instructions.txt │ direct-node-instructions.txt │ │ instructions/op │ instructions/op vs base │ ExternalProgram-20 315.0G ± 5% 302.7G ± 4% ~ (p=0.132 n=6) Instruction counts are statistically inconclusive on this noisy machine. All 321 semantic diagnostics and 10284 files are unchanged. CLI diagnostic text and symbol, type, and instantiation counts match exactly. No GC settings are changed. npx hereby validate --all passed. Compiler and editor baselines remain unchanged. Focused race/checkptr checks cover layout, wrong-kind casts, canonical token representations, shared kinds, cloning, and GC reachability.
Most symbols do not need members, exports, or an export-symbol link. Keeping all three pointers in every symbol's shared metadata charges every property, parameter, and synthetic symbol for those features. Move them into optional shared metadata, reducing SymbolWithData from 104 to 88 bytes on amd64. Binder- and checker-owned typed arenas batch the sidecars without adding an allocator pointer to every symbol. Shared symbolData still sees sidecars created through either alias. Compared with 823a64b, which already includes the checker storage and direct-header AST changes. Six fresh-process interleaved samples parse, bind, and check ../vscode/src with the same single checker and normal GC settings. Both workloads report 321 diagnostics, 10284 files. Exact CLI diagnostics and compiler counts also match. CPU timings are noisy. Hardware instructions and allocation counts show no statistically established difference; do not claim CPU gains. Validation: npx hereby validate --all passed. Focused symbol tests also passed with -race and -gcflags=all=-d=checkptr=2. goos: linux goarch: amd64 pkg: github.com/microsoft/TypeScript/tsc/internal/checker cpu: Intel(R) Core(TM) i9-10900K CPU @ 3.70GHz │ vscode-symbol-batched-before.txt │ vscode-symbol-batched.txt │ │ retained-B │ retained-B vs base │ ExternalProgram-20 4.180Gi ± 0% 4.129Gi ± 0% -1.21% (p=0.002 n=6) │ vscode-symbol-batched-before.txt │ vscode-symbol-batched.txt │ │ scan-B │ scan-B vs base │ ExternalProgram-20 3.738Gi ± 0% 3.687Gi ± 0% -1.34% (p=0.002 n=6) │ vscode-symbol-batched-before.txt │ vscode-symbol-batched.txt │ │ B/op │ B/op vs base │ ExternalProgram-20 5.659Gi ± 2% 5.606Gi ± 0% -0.93% (p=0.002 n=6) │ vscode-symbol-batched-before.txt │ vscode-symbol-batched.txt │ │ allocs/op │ allocs/op vs base │ ExternalProgram-20 26.06M ± 2% 26.08M ± 0% ~ (p=0.310 n=6) │ symbol-batched-before-instructions.txt │ symbol-batched-instructions.txt │ │ instructions/op │ instructions/op vs base │ ExternalInstructions-20 302.1G ± 4% 299.9G ± 3% ~ (p=0.589 n=6)
Every object, union, and intersection paid for signature and index-info slice headers, a call-signature count, and a node-builder cache, even when none were needed. Those fields made StructuredType 144 bytes on amd64. Keep them in an optional checker-arena sidecar and reduce the hot record to 88 bytes. Preserve signature publication during recursive anonymous resolution, clipped public signature slices, index-info nil/empty distinctions, and independent node-builder cache identity. Empty unresolved shape does not allocate a sidecar. Compared with 1ef0b40, including unified member resolution and all previous checker, AST, and symbol reductions. Six fresh-process interleaved samples parse, bind, and check the actual VS Code project using one checker and normal GC settings. Live heap falls another 1.81%, GC scan bytes fall 2.01%, and allocated bytes fall 1.28%. Allocation counts do not differ significantly. Neither hardware instructions nor elapsed time establishes a change; this does not claim a CPU improvement. Exact CLI diagnostic text and compiler counts match the baseline. Validation passed: npx hereby validate --all, plus focused checker tests with -race and -gcflags=all=-d=checkptr=2. Exact benchstat output: goos: linux goarch: amd64 pkg: github.com/microsoft/TypeScript/tsc/internal/checker cpu: Intel(R) Core(TM) i9-10900K CPU @ 3.70GHz │ vscode-shape-before.txt │ vscode-shape.txt │ │ sec/op │ sec/op vs base │ ExternalProgram-20 41.55 ± 6% 41.84 ± 13% ~ (p=0.937 n=6) │ vscode-shape-before.txt │ vscode-shape.txt │ │ diagnostics │ diagnostics vs base │ ExternalProgram-20 321.0 ± 0% 321.0 ± 0% ~ (p=1.000 n=6) ¹ ¹ all samples are equal │ vscode-shape-before.txt │ vscode-shape.txt │ │ files │ files vs base │ ExternalProgram-20 10.28k ± 0% 10.28k ± 0% ~ (p=1.000 n=6) ¹ ¹ all samples are equal │ vscode-shape-before.txt │ vscode-shape.txt │ │ retained-B │ retained-B vs base │ ExternalProgram-20 3.959Gi ± 0% 3.887Gi ± 0% -1.81% (p=0.002 n=6) │ vscode-shape-before.txt │ vscode-shape.txt │ │ scan-B │ scan-B vs base │ ExternalProgram-20 3.553Gi ± 0% 3.482Gi ± 0% -2.01% (p=0.002 n=6) │ vscode-shape-before.txt │ vscode-shape.txt │ │ symbols │ symbols vs base │ ExternalProgram-20 4.154M ± 0% 4.154M ± 0% ~ (p=1.000 n=6) ¹ ¹ all samples are equal │ vscode-shape-before.txt │ vscode-shape.txt │ │ B/op │ B/op vs base │ ExternalProgram-20 5.577Gi ± 0% 5.506Gi ± 0% -1.28% (p=0.002 n=6) │ vscode-shape-before.txt │ vscode-shape.txt │ │ allocs/op │ allocs/op vs base │ ExternalProgram-20 27.36M ± 0% 27.35M ± 0% ~ (p=0.818 n=6) │ shape-before-instructions.txt │ shape-instructions.txt │ │ instructions/op │ instructions/op vs base │ ExternalInstructions-20 292.5G ± 4% 301.6G ± 4% ~ (p=0.093 n=6)
Most resolved type nodes never need an anonymous object's outer type parameter list. Reserving a slice header for every node makes the common case needlessly expensive to retain and scan. TypeNodeLinks now occupies 16 rather than 32 bytes on amd64. An optional checker-owned arena entry preserves computed-empty lists and the original slice aliasing without introducing a separate allocation per cached list. VS Code src/tsconfig.json versus 1d11625, six fresh-process interleaved pairs with the normal GC policy. Retained bytes fall 0.43%, scan bytes 0.47%, and allocated bytes 0.33%. Allocation events and instruction counts are not statistically different; no CPU improvement is claimed. Exact production diagnostics and semantic counts match. Compiler, fourslash, unit, focused race/checkptr tests, and hereby validate --all pass. goos: linux goarch: amd64 pkg: github.com/microsoft/TypeScript/tsc/internal/checker cpu: Intel(R) Core(TM) i9-10900K CPU @ 3.70GHz │ vscode-typeparams-before.txt │ vscode-typeparams.txt │ │ retained-B │ retained-B vs base │ ExternalProgram-20 3.864Gi ± 0% 3.847Gi ± 0% -0.43% (p=0.002 n=6) │ vscode-typeparams-before.txt │ vscode-typeparams.txt │ │ scan-B │ scan-B vs base │ ExternalProgram-20 3.459Gi ± 0% 3.443Gi ± 0% -0.47% (p=0.002 n=6) │ vscode-typeparams-before.txt │ vscode-typeparams.txt │ │ B/op │ B/op vs base │ ExternalProgram-20 5.484Gi ± 0% 5.466Gi ± 0% -0.33% (p=0.002 n=6) │ vscode-typeparams-before.txt │ vscode-typeparams.txt │ │ allocs/op │ allocs/op vs base │ ExternalProgram-20 27.38M ± 0% 27.35M ± 0% ~ (p=0.093 n=6) │ typeparams-before-instructions.txt │ typeparams-instructions.txt │ │ instructions/op │ instructions/op vs base │ ExternalInstructions-20 297.2G ± 2% 290.9G ± 4% ~ (p=0.310 n=6)
Most signatures have no type parameters, explicit this parameter, predicate, composite constituents, or isolated-type cache. Reserving this state for every instantiated signature wastes memory and GC scanning. Negative predicate results need no pointer at all. Signature shrinks from 128 to 80 bytes on amd64. Checker-owned cold storage preserves slice aliasing and independent clone caches; a private, non-propagating flag retains the recursive no-predicate guard. A full VS Code field census found 648637 signatures and only 84956 requiring cold storage (13.1%). Six fresh-process interleaved comparisons against efe6e90, with normal GC, save 0.65% retained bytes, 0.73% scan bytes, and 0.49% allocated bytes. Allocation events and instructions are not statistically different. This is incremental, not a CPU breakthrough. Production diagnostics and semantic counts match exactly. Full compiler, fourslash and unit tests, focused race/checkptr tests, and npx hereby validate --all pass. goos: linux goarch: amd64 pkg: github.com/microsoft/TypeScript/tsc/internal/checker cpu: Intel(R) Core(TM) i9-10900K CPU @ 3.70GHz │ vscode-signature-before.txt │ vscode-signature.txt │ │ retained-B │ retained-B vs base │ ExternalProgram-20 3.848Gi ± 0% 3.823Gi ± 0% -0.65% (p=0.002 n=6) │ vscode-signature-before.txt │ vscode-signature.txt │ │ scan-B │ scan-B vs base │ ExternalProgram-20 3.443Gi ± 0% 3.418Gi ± 0% -0.73% (p=0.002 n=6) │ vscode-signature-before.txt │ vscode-signature.txt │ │ B/op │ B/op vs base │ ExternalProgram-20 5.468Gi ± 0% 5.441Gi ± 0% -0.49% (p=0.002 n=6) │ vscode-signature-before.txt │ vscode-signature.txt │ │ allocs/op │ allocs/op vs base │ ExternalProgram-20 27.36M ± 0% 27.36M ± 0% ~ (p=0.589 n=6) │ signature-before-instructions.txt │ signature-instructions.txt │ │ instructions/op │ instructions/op vs base │ ExternalInstructions-20 297.9G ± 3% 296.1G ± 3% ~ (p=0.699 n=6)
A live pointer into an arena chunk retains the entire backing allocation, including unused capacity and unrelated dead values. Resetting typed parser and binder arenas at every file multiplies terminal chunk slack. Uniform 256-object chunks are especially wasteful for large records. Target 512 bytes per chunk before allocator rounding, preserving stable direct pointers and exact-capacity slices. Larger contiguous slices keep their separate allocation path. Indexed arenas retain their index layout. No GC settings, cross-file pooling, or pointer decoding are introduced. Six fresh-process interleaved VS Code comparisons against 69d9821, using normal GC, reduce retained bytes 8.54%, scan bytes 10.44%, allocated bytes 5.74%, and whole-process instructions 9.43%. Allocation events rise 13.91%; wall time is inconclusive on the shared machine (p=0.937). Four-object chunks saved slightly more heap but raised allocation events 32.15%. A 512-byte target keeps most of the memory savings with less than half that allocation penalty. Reusing partial parser and binder chunks also saved memory but would couple otherwise independent file lifetimes. The retention regression fails with the old allocator. Mixed singleton, slice, clone, growth, zero-size, and GC cases preserve addresses and data. Focused race/checkptr checks and npx hereby validate --all pass, including 166152 Go tests and 954 API tests. Production diagnostics and file, line, identifier, symbol, type, and instantiation counts match exactly. goos: linux goarch: amd64 pkg: github.com/microsoft/TypeScript/tsc/internal/checker cpu: Intel(R) Core(TM) i9-10900K CPU @ 3.70GHz │ vscode-arena-before.txt │ vscode-arena.txt │ │ retained-B │ retained-B vs base │ ExternalProgram-20 3.823Gi ± 0% 3.497Gi ± 0% -8.54% (p=0.002 n=6) │ vscode-arena-before.txt │ vscode-arena.txt │ │ scan-B │ scan-B vs base │ ExternalProgram-20 3.418Gi ± 0% 3.062Gi ± 0% -10.44% (p=0.002 n=6) │ vscode-arena-before.txt │ vscode-arena.txt │ │ B/op │ B/op vs base │ ExternalProgram-20 5.442Gi ± 0% 5.130Gi ± 0% -5.74% (p=0.002 n=6) │ vscode-arena-before.txt │ vscode-arena.txt │ │ allocs/op │ allocs/op vs base │ ExternalProgram-20 27.36M ± 0% 31.17M ± 0% +13.91% (p=0.002 n=6) │ arena-before-instructions.txt │ arena-instructions.txt │ │ instructions/op │ instructions/op vs base │ ExternalInstructions-20 300.8G ± 3% 272.5G ± 6% -9.43% (p=0.002 n=6)
Resolved type nodes and signatures still kept AST pointers as map keys despite already having stable node identities. Those maps add redundant pointer storage, GC scanning, hashing, and growth allocations. Reuse the existing node-link store's pointer-free paged indexes for these two high-volume caches. Ordinary IDs and IDs outside the dense reserved range retain the existing fallback, and caches stay checker-local. Six fresh-process interleaved VS Code comparisons against e97c4aa, using normal GC, reduce retained heap 1.20%, scan bytes 2.12%, allocated bytes 2.11%, and allocation events 0.20%. Instructions are inconclusive. This saves another roughly 43 MiB of heap and 66 MiB of scanning. Production diagnostics and semantic counts match exactly. The full compiler, fourslash, and unit suite passes, as do focused race/checkptr checks for cache identity, ordinary/reserved IDs, clone isolation, growth, GC reachability, and independent checkers. goos: linux goarch: amd64 pkg: github.com/microsoft/TypeScript/tsc/internal/checker cpu: Intel(R) Core(TM) i9-10900K CPU @ 3.70GHz │ vscode-paged-before-6.txt │ vscode-paged-6.txt │ │ retained-B │ retained-B vs base │ ExternalProgram-20 3.497Gi ± 0% 3.455Gi ± 0% -1.20% (p=0.002 n=6) │ vscode-paged-before-6.txt │ vscode-paged-6.txt │ │ scan-B │ scan-B vs base │ ExternalProgram-20 3.061Gi ± 0% 2.997Gi ± 0% -2.12% (p=0.002 n=6) │ vscode-paged-before-6.txt │ vscode-paged-6.txt │ │ B/op │ B/op vs base │ ExternalProgram-20 5.129Gi ± 0% 5.021Gi ± 0% -2.11% (p=0.002 n=6) │ vscode-paged-before-6.txt │ vscode-paged-6.txt │ │ allocs/op │ allocs/op vs base │ ExternalProgram-20 31.16M ± 0% 31.09M ± 0% -0.20% (p=0.002 n=6) │ paged-before-instructions.txt │ paged-instructions.txt │ │ instructions/op │ instructions/op vs base │ ExternalInstructions-20 279.8G ± 5% 270.5G ± 2% ~ (p=0.589 n=6)
Ordinary type comparisons need only two 32-bit IDs and intersection context, but retained a 128-bit hash for every cached result. Hashing and storing twice the necessary key width wastes allocations and memory. Keep exact 64-bit pairs in separate maps for the four intersection states. Generic-reference normalization still uses its original full-width hash. An explicit key tag separates both namespaces, including recursion guards, without sacrificing hash bits or changing constrained generic behavior. Six fresh-process interleaved VS Code comparisons against 27786ef, using normal GC, reduce retained heap 0.94% (roughly 33 MiB) and total allocated bytes 1.29%. GC scanning, allocation events, and instruction counts are not statistically different. Tests cover directional and identity comparisons, all intersection contexts, result replacement, exact high-bit IDs, namespace isolation, generic parameter normalization, and constrained versus unconstrained recursion keys. Focused race/checkptr checks and npx hereby validate --all pass, including 166156 Go tests and 954 API tests. Production diagnostics and all semantic counts match exactly. goos: linux goarch: amd64 pkg: github.com/microsoft/TypeScript/tsc/internal/checker cpu: Intel(R) Core(TM) i9-10900K CPU @ 3.70GHz │ vscode-relation-before-6.txt │ vscode-relation-6.txt │ │ retained-B │ retained-B vs base │ ExternalProgram-20 3.456Gi ± 0% 3.424Gi ± 0% -0.94% (p=0.002 n=6) │ vscode-relation-before-6.txt │ vscode-relation-6.txt │ │ scan-B │ scan-B vs base │ ExternalProgram-20 2.998Gi ± 0% 2.997Gi ± 0% ~ (p=0.310 n=6) │ vscode-relation-before-6.txt │ vscode-relation-6.txt │ │ B/op │ B/op vs base │ ExternalProgram-20 5.021Gi ± 0% 4.956Gi ± 0% -1.29% (p=0.002 n=6) │ vscode-relation-before-6.txt │ vscode-relation-6.txt │ │ allocs/op │ allocs/op vs base │ ExternalProgram-20 31.08M ± 0% 31.07M ± 0% ~ (p=0.240 n=6) │ relation-before-instructions.txt │ relation-instructions.txt │ │ instructions/op │ instructions/op vs base │ ExternalInstructions-20 269.3G ± 2% 270.0G ± 3% ~ (p=0.937 n=6)
Complete non-augmented properties are valid for augmented lookup, but copying each result into both caches retains duplicate name tables. MUI keeps 2,734,919 identical entries this way, nearly doubling its union/intersection cache storage without adding semantic information. Preserve independent augmented results and partial-property behavior while sharing complete entries. A failed lookup needs no empty table. The MUI census falls from 230242 tables and 5628201 entries to 116635 tables and 2893282 entries; all distinct cached identities remain. Six fresh-process interleaved single-checker comparisons against 72f191f, with ordinary GC, save 135.63 MiB of retained MUI heap (-8.15%) and 132.00 MiB of GC scanning (-9.22%). Total allocated bytes fall 4.45% and allocation events fall 1.46%. VS Code's corresponding reductions are small: retained -0.15%, scan -0.17%, allocated -0.16%. Instruction differences in these single-checker comparisons are inconclusive; elapsed time is noisy on the shared machine. Six default-threaded production CLI pairs confirm MUI's reported heap falls 9.29% and instructions fall 2.60%. VS Code and Webpack have small heap reductions and inconclusive instruction differences. These are incremental savings on top of the earlier branch optimizations. CLI-reported heap is not the forced-GC retained-heap measure above. MUI uses the CI-pinned source and restored scenario dependencies at 6780195595c12252a130aa5ae5c5bd461229c6b7. VS Code uses 8bf178e1e1c2be3723f14683f7b1e5fdb3f780e4. Webpack uses an isolated 2289141381f2c1c965cb65118fa0ffe2e9e19834 with restored dependencies. Production diagnostics and all semantic counts match exactly. Tests cover both query orders, both composite kinds, cache growth and GC reachability, missing entries, read/write partial flags, differing mode-specific identities, and real function-property augmentation. The storage regressions fail before this change. Focused race/checkptr and npx hereby validate --all pass, including 166172 Go tests and 954 API tests. Temporary profiling helpers are not part of the change. Single-checker retained heap and allocation measurements: │ mui-shared-union-before.txt │ mui-shared-union-shared.txt │ │ retained-B │ retained-B vs base │ ExternalMemory-20 1.624Gi ± 0% 1.492Gi ± 0% -8.15% (p=0.002 n=6) │ mui-shared-union-before.txt │ mui-shared-union-shared.txt │ │ scan-B │ scan-B vs base │ ExternalMemory-20 1.398Gi ± 0% 1.270Gi ± 0% -9.22% (p=0.002 n=6) │ mui-shared-union-before.txt │ mui-shared-union-shared.txt │ │ B/op │ B/op vs base │ ExternalMemory-20 5.364Gi ± 0% 5.125Gi ± 0% -4.45% (p=0.002 n=6) │ mui-shared-union-before.txt │ mui-shared-union-shared.txt │ │ allocs/op │ allocs/op vs base │ ExternalMemory-20 25.17M ± 0% 24.80M ± 1% -1.46% (p=0.002 n=6) │ vscode-shared-union-before.txt │ vscode-shared-union-shared.txt │ │ retained-B │ retained-B vs base │ ExternalMemory-20 2.619Gi ± 0% 2.615Gi ± 0% -0.15% (p=0.002 n=6) │ vscode-shared-union-before.txt │ vscode-shared-union-shared.txt │ │ scan-B │ scan-B vs base │ ExternalMemory-20 2.291Gi ± 0% 2.287Gi ± 0% -0.17% (p=0.002 n=6) │ vscode-shared-union-before.txt │ vscode-shared-union-shared.txt │ │ B/op │ B/op vs base │ ExternalMemory-20 3.754Gi ± 0% 3.748Gi ± 0% -0.16% (p=0.002 n=6) │ vscode-shared-union-before.txt │ vscode-shared-union-shared.txt │ │ allocs/op │ allocs/op vs base │ ExternalMemory-20 23.61M ± 0% 23.59M ± 0% -0.08% (p=0.002 n=6) Single-checker instructions: │ mui-shared-union-before.instructions │ mui-shared-union-shared.instructions │ │ instructions/op │ instructions/op vs base │ ExternalInstructions-20 218.9G ± 3% 217.3G ± 2% ~ (p=0.310 n=6) │ vscode-shared-union-before.instructions │ vscode-shared-union-shared.instructions │ │ instructions/op │ instructions/op vs base │ ExternalInstructions-20 188.8G ± 3% 192.1G ± 2% ~ (p=0.394 n=6) Default-threaded production CLI: │ shared-union-cli-before.txt │ shared-union-cli-after.txt │ │ instructions/op │ instructions/op vs base │ mui-20 283.3G ± 1% 275.9G ± 2% -2.60% (p=0.015 n=6) vscode-20 308.2G ± 7% 293.0G ± 6% ~ (p=0.818 n=6) webpack-20 51.96G ± 5% 51.82G ± 4% ~ (p=1.000 n=6) geomean 165.6G 161.2G -2.62% │ shared-union-cli-before.txt │ shared-union-cli-after.txt │ │ heap-B/op │ heap-B/op vs base │ mui-20 2.059Gi ± 0% 1.868Gi ± 0% -9.29% (p=0.002 n=6) vscode-20 2.835Gi ± 0% 2.829Gi ± 0% -0.21% (p=0.004 n=6) webpack-20 666.9Mi ± 0% 663.0Mi ± 0% -0.57% (p=0.002 n=6) geomean 1.561Gi 1.507Gi -3.45% │ shared-union-cli-before.txt │ shared-union-cli-after.txt │ │ allocs/op │ allocs/op vs base │ mui-20 29.84M ± 0% 29.55M ± 0% -0.97% (p=0.002 n=6) vscode-20 36.67M ± 2% 36.64M ± 0% ~ (p=0.132 n=6) webpack-20 6.235M ± 2% 6.208M ± 0% -0.43% (p=0.002 n=6) geomean 18.97M 18.87M -0.49% │ shared-union-cli-before.txt │ shared-union-cli-after.txt │ │ check-sec/op │ check-sec/op vs base │ mui-20 8.986 ± 6% 8.559 ± 4% -4.75% (p=0.026 n=6) vscode-20 8.345 ± 4% 8.900 ± 10% ~ (p=0.132 n=6) webpack-20 1.851 ± 8% 1.818 ± 8% ~ (p=0.310 n=6) geomean 5.178 5.173 -0.08%
Intersection reduction repeatedly allocates temporary property-count tables. On MUI, this one allocation site accounts for roughly a quarter of all allocated bytes, despite none of the tables needing to survive the reduction. Reusing this workspace removes substantial allocation churn without changing the first-seen property order or caching results. Each recursive reduction borrows an independent checker-local table. Returning a table clears its names and counts, including on early returns; tables exceeding 4096 properties are not retained. Against parent 6801884, six fresh-process MUI single-checker pairs save 1.36 GiB of allocation per run, reduce allocation events by 7.59%, and reduce instructions by 6.02%. Default-threaded production MUI instructions decrease 8.88%. Retained heap and scannable heap are essentially unchanged: this is an allocation-churn optimization. VS Code allocation savings are smaller. Production VS Code instructions remain inconclusive after twelve pairs, with a higher point estimate; Webpack instructions are also inconclusive. Wall times are noisy on this shared host. All production diagnostic text and semantic counts match between revisions. The regression test allocated 21 times per warmed reduction before this change and now allocates zero times. Tests also cover nested borrowing, property order, clearing, oversized tables, and early-return cleanup. Validation passed: focused race and checkptr tests, and npx hereby validate --all (166175 Go tests and 954 API tests). Six fresh-process single-checker pairs, ordinary GC: │ mui-property-counts-memory-before.txt │ mui-property-counts-memory-after.txt │ │ retained-B │ retained-B vs base │ ExternalMemory-20 1.492Gi ± 0% 1.492Gi ± 0% ~ (p=0.310 n=6) │ mui-property-counts-memory-before.txt │ mui-property-counts-memory-after.txt │ │ scan-B │ scan-B vs base │ ExternalMemory-20 1.270Gi ± 0% 1.270Gi ± 0% ~ (p=0.310 n=6) │ mui-property-counts-memory-before.txt │ mui-property-counts-memory-after.txt │ │ B/op │ B/op vs base │ ExternalMemory-20 5.122Gi ± 0% 3.757Gi ± 0% -26.64% (p=0.002 n=6) │ mui-property-counts-memory-before.txt │ mui-property-counts-memory-after.txt │ │ allocs/op │ allocs/op vs base │ ExternalMemory-20 24.77M ± 0% 22.89M ± 0% -7.59% (p=0.002 n=6) │ mui-property-counts-memory-before.instructions │ mui-property-counts-memory-after.instructions │ │ instructions/op │ instructions/op vs base │ mui-20 213.7G ± 3% 200.8G ± 3% -6.02% (p=0.002 n=6) │ vscode-property-counts-memory-before.txt │ vscode-property-counts-memory-after.txt │ │ retained-B │ retained-B vs base │ ExternalMemory-20 2.615Gi ± 0% 2.615Gi ± 0% ~ (p=0.589 n=6) │ vscode-property-counts-memory-before.txt │ vscode-property-counts-memory-after.txt │ │ scan-B │ scan-B vs base │ ExternalMemory-20 2.287Gi ± 0% 2.287Gi ± 0% ~ (p=0.589 n=6) │ vscode-property-counts-memory-before.txt │ vscode-property-counts-memory-after.txt │ │ B/op │ B/op vs base │ ExternalMemory-20 3.749Gi ± 0% 3.714Gi ± 0% -0.92% (p=0.002 n=6) │ vscode-property-counts-memory-before.txt │ vscode-property-counts-memory-after.txt │ │ allocs/op │ allocs/op vs base │ ExternalMemory-20 23.60M ± 0% 23.49M ± 0% -0.47% (p=0.002 n=6) │ vscode-property-counts-memory-before.instructions │ vscode-property-counts-memory-after.instructions │ │ instructions/op │ instructions/op vs base │ vscode-20 193.0G ± 4% 193.2G ± 5% ~ (p=0.818 n=6) Default-threaded production CLI (six pairs; VS Code twelve pairs): │ mui-property-counts-cli-before.txt │ mui-property-counts-cli-after.txt │ │ heap-B/op │ heap-B/op vs base │ mui-20 1.867Gi ± 0% 1.868Gi ± 0% ~ (p=0.589 n=6) │ mui-property-counts-cli-before.txt │ mui-property-counts-cli-after.txt │ │ allocs/op │ allocs/op vs base │ mui-20 29.52M ± 0% 27.84M ± 0% -5.69% (p=0.002 n=6) │ mui-property-counts-cli-before.txt │ mui-property-counts-cli-after.txt │ │ check-sec/op │ check-sec/op vs base │ mui-20 11.59 ± 3% 10.67 ± 5% -7.86% (p=0.004 n=6) │ mui-property-counts-cli-before.instructions │ mui-property-counts-cli-after.instructions │ │ instructions/op │ instructions/op vs base │ mui-20 274.6G ± 2% 250.2G ± 4% -8.88% (p=0.002 n=6) │ vscode-property-counts-cli-before.txt │ vscode-property-counts-cli-after.txt │ │ heap-B/op │ heap-B/op vs base │ vscode-20 2.828Gi ± 0% 2.828Gi ± 0% ~ (p=0.843 n=12) │ vscode-property-counts-cli-before.txt │ vscode-property-counts-cli-after.txt │ │ allocs/op │ allocs/op vs base │ vscode-20 36.62M ± 0% 36.54M ± 0% -0.21% (p=0.000 n=12) │ vscode-property-counts-cli-before.txt │ vscode-property-counts-cli-after.txt │ │ check-sec/op │ check-sec/op vs base │ vscode-20 8.671 ± 21% 8.409 ± 26% ~ (p=0.799 n=12) │ vscode-property-counts-cli-before.instructions │ vscode-property-counts-cli-after.instructions │ │ instructions/op │ instructions/op vs base │ vscode-20 296.5G ± 4% 307.6G ± 3% ~ (p=0.242 n=12) │ webpack-property-counts-cli-before.txt │ webpack-property-counts-cli-after.txt │ │ heap-B/op │ heap-B/op vs base │ webpack-20 663.0Mi ± 0% 663.1Mi ± 0% ~ (p=0.699 n=6) │ webpack-property-counts-cli-before.txt │ webpack-property-counts-cli-after.txt │ │ allocs/op │ allocs/op vs base │ webpack-20 6.208M ± 0% 6.096M ± 0% -1.80% (p=0.002 n=6) │ webpack-property-counts-cli-before.txt │ webpack-property-counts-cli-after.txt │ │ check-sec/op │ check-sec/op vs base │ webpack-20 1.765 ± 8% 1.711 ± 6% ~ (p=0.180 n=6) │ webpack-property-counts-cli-before.instructions │ webpack-property-counts-cli-after.instructions │ │ instructions/op │ instructions/op vs base │ webpack-20 52.37G ± 2% 51.78G ± 3% ~ (p=0.394 n=6)
The compact compiler layouts depend on every header belonging to the concrete allocation identified by its tag. Unchecked kinds, retagging, and detached headers can otherwise turn a routine mistake into an invalid memory access. Keep that invariant mechanically enforced without adding layout tags or checks to hot accessors.
The function-augmentation regression needs the global callable function shape, but its virtual filesystem cannot read the on-disk libraries in noembed builds. The inherited call property is therefore absent in that configuration, causing CI to fail before exercising the cache invariant. Both configurations need the same explicit function shape to exercise the intended property-lookup and enumeration behavior.
Go 1.27 duplicates promoted AST wrappers, making whole-module coverage builds exhaust ARM64 CI disk quotas. Test executables discard DWARF, but temporary and cached object archives still retain it. Avoid generating discarded metadata to restore disk headroom without changing coverage or production compiler behavior. Keep DWARF available for explicitly requested debug runs.
8cf1e6d to
05fdf40
Compare
|
Ripped #64735 out for now. This still includes #64063. TypeScript Bot (@typescript-bot) perf test this faster |
|
Jake Bailey (@jakebailey) Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Overall performance
The latest perf-bot run, with 12 iterations per revision, reports 22.15–29.66% lower memory usage across all nine scenarios. Allocation counts decrease in seven of nine scenarios, by 3.59–16.58%.
Allocation counts increase slightly for Compiler-Unions (+0.37%) and Angular (+1.24%). Error counts are unchanged across all nine scenarios.
Changes
nodeDatainterface's method dispatch with generated kind-based AST accessors.SymbolWithDatashrinks 104 → 88 bytes.StructuredTypeshrinks 144 → 88 bytes.