mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-01 07:33:12 +08:00
In a worker program, every loop without a pending test on each iteration decremented a cancellation budget in its body and polled the exception flag every 64 iterations. The poll's early return made each loop an early-exit loop, which LLVM's loop vectorizer does not vectorize. A counted for loop (integer counter, invariant limit), or a loop to a typed array's length, whose body reads or writes a typed-array element outside nested loops and closures, now runs as blocks of at most 64 iterations: the outer header tests the counter against the limit, the inner loop runs to the nearer of the limit and 64 steps on, and the poll follows each block. A typed array's length is fixed, so each block takes it as its limit. The loop polls as often as the budget did, and the inner loop's only exit besides break and return is its bound. The block bound lives in one slot shared by the loop's speculative copies, which resume iterations in each other's bodies. Other loops keep the budget, which costs less in loops of a few iterations. An elementwise Float64Array loop in a worker-enabled program vectorizes again: 949 ms to 691 ms. A byte-classifying loop over a 100M-byte Uint8Array takes 13 ms instead of 141 ms. New corpus program: native-worker-terminate-counted-loops.ts.