Parent: #475 Related: #493, #480, #477, #513
Defect
WeakMap/WeakSet keep an auxiliary pointer -> entry position table. Moving collection clears that table because every live key address changes, but ordinary get/has do not rebuild it. Every subsequent lookup therefore linearly scans the complete live entry array until a mutation happens to repopulate an individual key. A wide live weak collection becomes quadratic under a full pass after compaction.
Index insertion also currently swallows allocation failure after publishing the entry. Correctness falls back to the same linear scan, but the collection can remain partially indexed indefinitely. Dead-key pruning swap-removes entries while retaining historical list and hash capacity, so a long-lived empty WeakMap can retain its peak backing.
Required change
- Add deterministic 1K/2K/4K post-moving-GC WeakMap/WeakSet lookup witnesses with exact object/Symbol, hit/miss, value, and survivor checksums.
- Use relocation-stable exact key identity for an authoritative lookup index; preserve exact identity on hash collision and use a securely seeded hash policy rather than an attacker-predictable collision surface.
- Reserve entry and index storage before publication so OOM leaves the collection exact, unchanged, and still usable; no partially authoritative index.
- Keep GC ephemeron semantics exact: weak keys never become strong, dead keys prune before relocation, live keys/values relocate, and the index remains valid after movement without pointer repair or a full lookup scan.
- Bound historical backing after GC removes most or all keys, while preserving the old exact state if an optional shrink allocation fails.
- Cover WeakMap and WeakSet object/non-registered-Symbol keys, duplicate/update/delete, moving nursery/full collection, OOM, GC pruning, no-GIL, and TSan.
- Record exact-parent CPU, allocation, and peak/retained-memory evidence with an ordinary no-movement weak-collection control.
No-workaround rules
No disabled moving GC, forced strong retention, address pinning, property-count limit, lookup-time full rebuild, swallowed semantic OOM, global key table, predictable collision shortcut, stale pointer key, or benchmark-specific engine path.