You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Every dynamic index read and write probes the Set and Map registries before reading the GcHeader that answers (~1% of interp) #7865
value::dyn_index.rs runs set::is_registered_set(raw_ptr) || map::is_registered_map(raw_ptr)
on every dynamic index read and write — js_dyn_index_get (:232) and js_dyn_index_set (:544) — ahead of the GcHeader read the same function performs
about 90 lines later. Both probes already end in exactly that header byte
(set.rs:262 → obj_type == GC_TYPE_SET, map.rs:244 → GC_TYPE_MAP), so the header
can rule both out for free. This is the same shape as #7474 / #7765 / #7850.
plus scattered is_registered_set / is_registered_map leaves elsewhere, for roughly 1% of interp — in a program that constructs no Set and no Map.
Caveat, stated because this family has produced vacuous numbers before: this profile was
taken on a contended dev machine, so treat it as attribution, not a timing claim.
The absolute cost has to be re-measured on the quiet mini before anyone sizes a fix from
it, and this family is workload-dependent (see #7850's sizing caveat — the same probe
measured 6.5% on one program and exactly zero on another, both correctly).
Why the existing latch does not cover it
SET_REGISTRY_EVER_USED / MAP_REGISTRY_EVER_USED (#7469) do their job when idle, but is_registered_set is a real out-of-line pub fn, so even the idle path costs a call
per dynamic index access. Whether the latches are armed on interp was not
established — establishing it is step one of any fix, because it decides whether the
win is "one call" or "a call plus a thread-local resolution plus a hash".
Care required
js_dyn_index_get deliberately probes the registries before the is_valid_obj_ptr
guard and before any header dereference, and both is_registered_set and is_registered_map carry inline comments explaining why: probing addr - 8 for an
arbitrary above-band candidate pointer segfaults on Linux, where freed/foreign pages get
unmapped (mimalloc on macOS retains them and hides it). Any reordering has to keep that
property — addr_class::try_read_gc_header is the safe read, but it is not free either,
so measure the trade rather than assuming it.
Found while fixing #7850; not included there because it is a different function with its
own risk surface, and mixing it in would have made the A/B attribution ambiguous.
Activity
perf(runtime): gate dynamic-index collection probes by GcHeader (#7865)…