mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-23 06:10:02 +08:00
Every release of a LifetimeRegion, and every retry at region creation, ran scr_collect_cycles(): full cycle-collector passes over the thread's heap, to a fixpoint, before checking any region, in case dead cycles of ordinary objects held counted references into it. Freeing a region ran them again whenever the owned ordinary objects left counts behind after the region released its fields. Next to a large heap of candidates (a type checker beside per-file emit regions) those passes cost far more than the regions. A retry now checks the due regions first. A region whose references are all explained frees without a pass; only when one would be kept does the heap get the full pass, after which every due region is judged as before. The first check leaves a region it cannot free as it was, so the backoff, the kept report and SCRIPTC_REGION_DEBUG see only the check after the pass. It keeps what its walk found: a region whose counted references the pass did not change is judged from that, without walking it again. A pass that freed a dead cycle referring only to an owned object leaves the count unchanged; such a region waits for its next attempt. After a region releases its instances' fields, what can still hold counts is the owned ordinary objects' cycles. Each has a member that lost a reference in those releases and is buffered as a candidate, and the release walk entered every cycle member. The cycle collector gains a pass limited to a set of candidates (scr_cyc_collect_set): it takes the set's members out of the buffers up to a given generation, reading only the buffers' pointers, so the candidates it leaves are not touched, and it walks at full depth without moving the schedule's baselines. A dead object such a pass reaches through a candidate it did not take leaves its buffer before it is freed. Freeing a region runs these passes over the walk's objects from the youngest buffer out, and the whole heap only if counts remain. SCRIPTC_REGION_STATS also prints, per thread at exit, how many full passes over the heap regions needed.