Skip to content

Add interrupt checks to fast array search loops - #1791

Open
josefguenther wants to merge 1 commit into
quickjs-ng:masterfrom
josefguenther:fix/fast-array-search-interrupts
Open

josefguenther wants to merge 1 commit into
quickjs-ng:masterfrom
josefguenther:fix/fast-array-search-interrupts

Conversation

@josefguenther

Copy link
Copy Markdown
Contributor

#1674 polls in the generic loops of indexOf, lastIndexOf and includes, but not in their fast-array loops. So a call on a dense array counts as one tick however long it is, and a loop over such calls reaches the handler every few thousand calls:

const a = new Array(1e6).fill(0)
for (;;) a.indexOf(42)

Seconds between interrupt handler calls, with a loop like the one above (6a9b531, Release, arm64 macOS):

input master this PR
a.indexOf(-1), 1M elements 9.2 0.000019
a.includes(-1), 1M elements 13.5 0.000027
a.lastIndexOf(-1), 1M elements 9.0 0.000018
indexOf on {length: 1e6} 0.000146 0.000147

This adds the same per-element poll to the three fast loops, plus a test for each in tests/bug1672/ (each hangs on master). The per-call cost on a 1M-element array is unchanged within noise. make test, api-test and test262 show no new failures.

Written with AI assistance (Claude Code); I have reviewed the change.

@saghul

saghul commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Probably that should happen every X elements or we'd make things too slow I think. How much X is, I don't know.

@richarddd

Copy link
Copy Markdown
Contributor

@saghul @josefguenther maybe every 2048 elements. that should be fast enough for both cases

Comment thread quickjs.c
}
if (js_get_fast_array(ctx, obj, &arrp, &count)) {
for (; n < count; n++) {
if (js_poll_interrupts(ctx))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (js_poll_interrupts(ctx))
if (n % 2048 == 0 && js_poll_interrupts(ctx))

Comment thread quickjs.c
}
if (js_get_fast_array(ctx, obj, &arrp, &count)) {
for (; n < count; n++) {
if (js_poll_interrupts(ctx))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (js_poll_interrupts(ctx))
if (n % 2048 == 0 && js_poll_interrupts(ctx))

Comment thread quickjs.c
}
if (js_get_fast_array(ctx, obj, &arrp, &count) && count == len) {
for (; n >= 0; n--) {
if (js_poll_interrupts(ctx))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (js_poll_interrupts(ctx))
if (n % 2048 == 0 && js_poll_interrupts(ctx))

@saghul

saghul commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Whatever number we land on (say it's 2048) we should likely define a constant and use it consistently across the code.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants