Skip to content

perf(gc): full/fallback weak processing is an unsliced O(total heap) atomic pause #7874

Description

@proggeramlug

Summary

#6182 made copied-minor weak processing proportional to registered weak holders, but the full/fallback path was deliberately left unchanged. As a result, one live WeakRef/WeakMap/WeakSet/FinalizationRegistry holder makes every full/fallback weak-processing phase walk every live arena object.

The code says this directly:

This is also performed as one unsliced atomic-finalize step:

Impact

  • Full GC latency scales with unrelated heap size when a program uses even one weak holder.
  • js_gc_step_us / mutator-assist budgeting cannot bound the pause: a step with one unit can run the full walk.
  • The recent full-mark-sweep pacing work reduces how often this happens, but does not bound the individual pause when it does happen.

Proposed direction

Use WEAK_HOLDERS for full/fallback processing as well. The full cycle already has ValidPointerSet / FullCycleLiveness, and full/fallback pruning already removes dead holders via prune_dead_weak_holders. Make iteration state part of AtomicFinalizeState so the holder registry is processed in budgeted slices.

Acceptance criteria

  • Full/fallback weak processing cost is O(registered holders), not O(all live arena objects).
  • Dead/stale registry entries are safely classified and pruned before dereference; full-cycle evacuation continues to rekey addresses.
  • WeakProcessing maintains a cursor/snapshot and honors the supplied work budget across calls.
  • Add a scaling regression: a fixed one-holder workload with 10x unrelated live objects must not produce ~10x weak-processing work/pause.
  • Add correctness coverage for WeakRef, FinalizationRegistry, WeakMap, and WeakSet on full and fallback cycles, including dead holders and moved holders.

Successor to the copied-minor-only optimization in #6182.

Metadata

Metadata

Assignees

Labels

performanceRuntime, compile-time, build-size, or memory performance

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions