Skip to content

ZJIT: Avoid compiling failed ISEQs repeatedly #14195

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 12, 2025

Conversation

k0kubun
Copy link
Member

@k0kubun k0kubun commented Aug 12, 2025

This PR lets function_stub_hit exit quickly when the ISEQ has failed to compile before, instead of attempting it repeatedly.

I updated start_ptr: Option<CodePtr> to status: IseqStatus to avoid consuming more memory. We should also fix the compiler to emit a side-exit when there's an unsupported instruction so that we exit more efficiently without calling the Rust function, but it's for another PR.

@k0kubun k0kubun marked this pull request as ready for review August 12, 2025 19:22
@matzbot matzbot requested a review from a team August 12, 2025 19:22
// If we already know we can't compile the ISEQ, fail early without cb.mark_all_executable().
let cb = ZJITState::get_code_block();
let payload = get_or_create_iseq_payload(iseq);
if cb.has_dropped_bytes() || payload.status == IseqStatus::CantCompile {
Copy link
Member

Choose a reason for hiding this comment

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

I think the payload status part of this check can happen without the VM lock, since the whole code path can be made read-only. But you still need the check as is while holding the VM lock in any case. Ractor concerns are far out, though. Could you leave a TODO?

Copy link
Member Author

Choose a reason for hiding this comment

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

Left a TODO, quoting your comment as is 28f9f3c.

TBH I didn't understand what you said though. I interpreted your comment like "you can check payload.status == IseqStatus::CantCompile without the VM lock, but you still need the check with the VM lock". Can you elaborate more on when you can check it without the VM lock and when it needs to be checked with the VM lock?

Also, as explained above fn function_stub_hit, the primary use of this path is for cb.has_dropped_bytes() like YJIT (once we implement side exits for unsupported instructions). To get cb, we'd still need the VM lock (we could have an atomic global variable separately from cb if needed though).

Copy link
Member

@XrXr XrXr Aug 12, 2025

Choose a reason for hiding this comment

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

Both checks are necessary. If you find payload.status == IseqStatus::CantCompile outside the lock, you can exit without taking the lock. But if you do contend for the lock, by the time you get it you might've lost the race so you repeat the same check once you have the lock.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, that makes sense. Thanks.

@tekknolagi
Copy link
Contributor

Does this speed up some of the issues on yjit-bench?

@k0kubun k0kubun linked an issue Aug 12, 2025 that may be closed by this pull request
Copy link

launchable-app bot commented Aug 12, 2025

Tests Failed

✖️no tests failed ✔️62282 tests passed(1 flake)

@k0kubun
Copy link
Member Author

k0kubun commented Aug 12, 2025

Does this speed up some of the issues on yjit-bench?

Oh yeah they're waaay faster. I'll update the issue.

@k0kubun k0kubun merged commit 231407c into ruby:master Aug 12, 2025
75 of 81 checks passed
@k0kubun k0kubun deleted the zjit-fix-stub branch August 12, 2025 20:40
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.

ZJIT: Stub triggers failed recompiles over and over
4 participants