gc: function-entry polls at indirect entries and recursive SCCs (RFC deferred collection S5, polls) - #11631
Draft
proggeramlug wants to merge 30 commits into
Draft
gc: function-entry polls at indirect entries and recursive SCCs (RFC deferred collection S5, polls)#11631proggeramlug wants to merge 30 commits into
proggeramlug wants to merge 30 commits into
Conversation
added 11 commits
September 28, 2026 13:25
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
proggeramlug
pushed a commit
that referenced
this pull request
Sep 28, 2026
proggeramlug
force-pushed
the
gc/s5-entry-polls
branch
from
September 28, 2026 12:45
3b34d3e to
978d7c3
Compare
proggeramlug
pushed a commit
that referenced
this pull request
Sep 28, 2026
proggeramlug
force-pushed
the
gc/s5-entry-polls
branch
from
September 28, 2026 13:05
978d7c3 to
4c83a6f
Compare
proggeramlug
pushed a commit
that referenced
this pull request
Sep 28, 2026
proggeramlug
force-pushed
the
gc/s5-entry-polls
branch
from
September 28, 2026 14:42
30d37e6 to
cd9aae1
Compare
added 9 commits
September 28, 2026 17:37
…; no spec-ABI name in docs
…ecker counts pump calls and merges back edges
proggeramlug
force-pushed
the
gc/s5-entry-polls
branch
from
September 28, 2026 15:38
cd9aae1 to
593a229
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
RFC deferred collection (#11528), step S5, the polls (decision 2). Stacked on #11630 (
gc/s5-runtime-invariant): review that first. The diff here is the last commits.What it adds
__perry_wrap_*forwarders that make a top-level function a callback value.How a poll is placed.
argumentsmaterialisation (which can allocate). The scaffold is the armed-wordload volatile, a branch, andcall void @js_gc_entry_safepoint(). It is the back-edge poll under another symbol: same runtime body, same seeded-schedule candidacy, samePERRY_GC_SCHEDULE_ALLOC_KBpacing.entry_polls::finalize_modulekeeps a scaffold only in a function that the module leaf analysis, with entry polls ignored, already proves collecting. So every call to it was already a statepoint, and no call changes classification (S5 must not; S6 does that). A dropped scaffold's load becomes a constant and LLVM folds the branch away.js_gc_entry_safepoint_argsroots them across the collection and writes the relocated values back.Kill switch. It is the loop polls' own,
PERRY_GC_MOVING_LOOP_POLLS=0. There is no new knob.S1 tables.
js_gc_entry_safepointandjs_gc_entry_safepoint_argsareReentersin all threegc_effects/*.tsvfiles, and declaredpollseeds inseeds.txt. The wasm ABI table is regenerated.Proposed refinement of decision 2, with evidence
Decision 2 says "one poll per recursive SCC". Implemented literally, that put a poll in
benchmarks/suite/05_fibonacci:fib's numeric fast clone and its boxed fallback form an SCC. The run cost +59.98% instructions, a poll on every call of a recursion that allocates nothing.This PR therefore polls a recursive SCC only when the recursion itself allocates without a poll: some member has a collecting edge of its own, or calls out of the SCC to a function that may collect and does not poll at its entry. SCCs are visited callees first, so a callee's poll is known in time.
Result:
05_fibonaccirectree(loop-free recursive allocator)The rule is stated as a proposal on #11528. The checker (
scripts/gc_poll_coverage_check.py) applies the same definition, so a violation of either reading shows up there.Poll-coverage checker
scripts/gc_poll_coverage_check.py, run over emitted IR:--max-uncovered-loops/--max-uncovered-sccsturn the counts into a ratchet.--self-testproves it can fail.It also answers the §2 open item: the specialized
for/for-of/for-inlowerings named in thestmt/loops.rscomment are now measured rather than assumed.Measurements
qb4, same base, same 32 programs as #11630, instructions as medians of 5.
Compute and RSS.
05_fibonaccirectree(loop-free recursive allocator)Poll counts and cost. From
--statepoint-report=text, which now prints anentry polls:line:09_method_calls14_closure05_fibonaccirectreecc bundle (claude-code 2.1.112):
--versioninstructions--helpinstructions--versionpeak RSS--helppeak RSSCompile wall (67 min) and compile peak RSS (37.8 GB) are equal to main. The cc poll count is not reported: that compile predates the report line.
Decision 3 (straight-line bodies).
max_poll_wait_bytesis 0 on:The valve never fired on any of them, so no statement-boundary polls were added. The cc bundle's init chunks under a real session remain unmeasured until #11559 lets cc run
-pturns.Tests
crates/perry/tests/gc_entry_polls_s5.rs(real TS → IR):entry_polls.rsunit tests: Tarjan on cycles and self-loops, a 50k-deep chain without recursion, callees-first order.gc_poll_coverage_check.py --self-test.perry-codegen: twoshadow_inlinetests pin exact register numbers; their pins moved by the scaffold's two registers.