Thanks to visit codestin.com
Credit goes to github.com

Skip to content

ZJIT: Stop tracking EP == BP assumption on JIT entry #13752

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
Jul 1, 2025

Conversation

k0kubun
Copy link
Member

@k0kubun k0kubun commented Jun 30, 2025

This PR stops tracking the EP == BP assumption when loading method parameters on JIT entry. It makes test_gc.rb and test_thread.rb pass and reduces the number of failures in test_eval.rb and test_insns.rb.

The current gen_getlocal() function (renamed to gen_entry_param() in this PR) was meant to be used for any Ruby local variable read, so it keeps track of the EP == BP assumption for optimization. However, we ended up using the function only for loading method parameters. In that case, because we load them before the main JIT code, no arbitrary method runs before the loads. So we don't need to invalidate them.

I do think we need to implement a PatchPoint in HIR that assumes EP == BP at some point. So I left the track_no_ep_escape_assumption / iseq_escapes_ep machinery in invariants.rs as is for now.

This comment has been minimized.

@tekknolagi
Copy link
Contributor

I'm unfamiliar with this particular assumption. When might EP not be BP? Is this a global effect or scoped to a frame? An ISEQ? Something else? Is this recognizable statically in HIR or do we have to track it happening somewhere in the runtime with a hook?

@k0kubun
Copy link
Member Author

k0kubun commented Jul 1, 2025

When might EP not be BP?

When an environment is escaped to the heap. As written in the comment, <main> and eval starts with EP pointing to the heap. After entry, methods like proc {} or binding can escape stack-local EP to the heap afterward.

Is this a global effect or scoped to a frame? An ISEQ? Something else?

Scoped to a frame. An ISEQ type (<main>/eval or not) tells you whether EP should point to the heap from the beginning or not.

Is this recognizable statically in HIR or do we have to track it happening somewhere in the runtime with a hook?

Remember #13750 (comment), this is where I suggested any method_call could escape EP of the caller frame (the block given to Numeric#times). Because Ruby allows escaping the EP of any frame in the call stack at any time, yes, we'd have to track it happening somewhere in the runtime with a hook.

Unless we recursively inline every method call, including ones called inside C functions, it's impossible to statically track every arbitrary method call that may happen under the current frame at compile time.

Copy link
Contributor

@tekknolagi tekknolagi left a comment

Choose a reason for hiding this comment

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

nice, thanks, i understand now

@k0kubun k0kubun merged commit 2fda843 into ruby:master Jul 1, 2025
82 of 84 checks passed
@k0kubun k0kubun deleted the zjit-entry-param branch July 1, 2025 18:59
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