commit 4fa49d55d7bc1ccb2918c81505c9d0f26002e18c
parent d01b96e7d71e506c57e32e667ac74c58ae3c1695
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Thu, 11 Jun 2026 13:24:07 -0700
docs: add TODO.md for cleanup/symmetry items from the perf work
Records the non-blocking symmetry/dedup items noticed during Round 6:
KIT_HASHSET_DEFINE _reserve (mirror the hashmap one), a SegVec reserve
(readers pre-size the symbol hashmap but not the parallel segvec), the
remaining un-pre-sized linker symbol maps, and the macho/elf/coff emitter
strtab/section duplication. Perf levers stay in doc/plan/PERF.md.
Diffstat:
| A | TODO.md | | | 41 | +++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 41 insertions(+), 0 deletions(-)
diff --git a/TODO.md b/TODO.md
@@ -0,0 +1,41 @@
+# TODO
+
+Cleanup / symmetry items noticed during the Round-6 perf work. None are
+blocking; recorded so they aren't lost. (Forward-looking *perf levers* —
+copy-and-patch codegen, 16B `Tok`, the `writev` object-output micro-lever —
+live in `doc/plan/PERF.md`, not here.)
+
+## Container facility symmetry
+
+- **`KIT_HASHSET_DEFINE` lacks `_reserve`.** Round-6 added `NAME##_reserve(m, n)`
+ to `KIT_HASHMAP_DEFINE` (`include/kit/support/hashmap.h`) so a bulk insert with
+ a known count skips the resize cascade. The hashset variant in the same file
+ was not given the matching primitive. Mirror it (same body: grow `cap` to hold
+ `n` at the load factor, power-of-two) if/when a set needs it — don't ship it
+ unused.
+
+- **`SegVec` has no `_reserve`.** The object readers now pre-size the
+ `SymNameIndex` hashmap (`obj_reserve_symbols`), but the parallel `Symbols`
+ (src/obj) / `LinkSyms` (src/link) segvecs still grow one 64-entry segment at a
+ time — ~16k small allocations for a 1M-symbol object. A `SEGVEC` reserve
+ (pre-allocate ⌈n/seg⌉ segments) would cut that alloc churn on large ingests.
+ Touch points: `src/core/segvec.h`, the readers in `src/obj/*/read.c`, and
+ `link_resolve_symbols`.
+
+## Linker symbol-map pre-sizing (partial)
+
+- Only `img->globals` got `symhash_reserve` (`link_resolve.c`). The other
+ `symhash_init`-without-capacity maps — `alias_map` (`link_resolve.c:~401`),
+ `defined`/`undefs` (`link_resolve.c:~1139`), `globals_by_name`
+ (`link_relocatable.c:~451`) — could pre-size from a known count for
+ consistency. Lower value (the measured resize churn was `img->globals` + the
+ reader `SymNameIndex`); do it if a profile shows them.
+
+## Object-emitter de-duplication (macho / elf / coff)
+
+- The three `src/obj/*/emit.c` carry near-identical code: the `strtab_add`
+ linear-dedup (flatten-to-search), the final strtab flatten+write, and the
+ section-bytes write loop. A small shared `src/obj` helper would de-triplicate
+ them. NB: streaming each section's `Buf` chunks instead of flatten-to-one
+ `write()` was tried and is *slower* (more syscalls) — keep the single big
+ write; only the dedup is wanted here.