Skip to content

gc: reduce safepoint density (safepoint polling instead of every-call statepoints) #8596

Description

@proggeramlug

Summary

Perry treats every call as a GC safepoint: rewrite-statepoints-for-gc wraps each non-leaf call in a gc.statepoint and relocates every live root across it. That is correct (any callee might collect) but it makes the safepoint count of a function equal to its call count, which is the × safepoints term in the RS4GC relocation fan-out live_roots × safepoints behind #8583 (the Claude Code @main has ~106k call sites).

Many production GC'd VMs instead use safepoint polling: collection can only begin at a bounded set of poll points — loop back-edges, function returns/entries, and allocation sites — and ordinary calls are not safepoints unless the callee itself polls. This shrinks the safepoint set dramatically without losing the guarantee that a collection can always make progress, because a thread reaches a poll in bounded time.

Proposal (exploratory — needs design)

Move from "every call is a safepoint" toward a polling model:

  • take safepoints at loop back-edges, allocation sites, and returns, rather than at every call;
  • a non-allocating / non-polling call is a gc-leaf-style edge that does not relocate roots;
  • keep a mechanism to bring a thread to a safepoint on demand (poll flag the callee checks), which perry already has pieces of (GC_SAFEPOINT_PENDING, js_gc_loop_safepoint, the loop-poll path).

Why it's worth it

Unlike #8595 (outlining), which fixes the giant-function symptom, reducing safepoint density shrinks the × safepoints factor for every function in the codebase, not just the outlier — lowering RS4GC cost and stack-map size across the board, and reducing the number of points at which roots must be kept live (better register allocation).

Scope / risk

This is the largest of the three and a genuine GC-architecture change: it affects collection latency/progress guarantees, the interaction with the moving scavenge (#7019), write barriers, and the conservative-scan fallback. It should be scoped and prototyped carefully — filed here so the option is tracked rather than lost, not as ready work.

Context: surfaced while fixing #8583 (RS4GC relocation fan-out). Complements #8595 (outlining) and the root-spilling stopgap in #8583. Root-lowering background: #7370 (native roots default), #7280/#7173/#7174.

Metadata

Metadata

Assignees

No one assigned

    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