Skip to content

[YJIT] Implement getblockparam #5881

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 1 commit into from
May 12, 2022
Merged

Conversation

tenderlove
Copy link
Member

@tenderlove tenderlove commented May 3, 2022

This implements the getblockparam instruction.

There are two cases we need to handle depending on whether or not
VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM is set in the environment flag.

When the modified flag is unset, we need to call rb_vm_bh_to_procval to
get a proc from our passed block, save the proc in the environment, and
set the modified flag.

In the case that the modified flag is set we are able to just use the
existing proc in the environment.

One quirk of this is that we need to call jit_prepare_routine_call early
and ensure we update PC and SP regardless of the branch taken, so that
we have a consistent SP offset at the start of the next instruction.

We considered using a chain guard to generate these two paths
separately, but decided against it because it's very common to see both
and the modified case is basically a subset of the instructions in the
unmodified case.

This includes tests for both getblockparam and getblockparamproxy which
was previously missing a test.

This implements the getblockparam instruction.

There are two cases we need to handle depending on whether or not
VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM is set in the environment flag.

When the modified flag is unset, we need to call rb_vm_bh_to_procval to
get a proc from our passed block, save the proc in the environment, and
set the modified flag.

In the case that the modified flag is set we are able to just use the
existing proc in the environment.

One quirk of this is that we need to call jit_prepare_routine_call early
and ensure we update PC and SP regardless of the branch taken, so that
we have a consistent SP offset at the start of the next instruction.

We considered using a chain guard to generate these two paths
separately, but decided against it because it's very common to see both
and the modified case is basically a subset of the instructions in the
unmodified case.

This includes tests for both getblockparam and getblockparamproxy which
was previously missing a test.
@tenderlove tenderlove changed the title [WIP] Implement getblockparam [YJIT] Implement getblockparam May 12, 2022
@tenderlove tenderlove marked this pull request as ready for review May 12, 2022 19:11
@tenderlove tenderlove requested review from maximecb and XrXr as code owners May 12, 2022 19:11
Comment on lines +5609 to +5612
// If the frame flag has been modified, then the actual proc value is
// already in the EP and we should just use the value.
let frame_flag_modified = cb.new_label("frame_flag_modified".to_string());
jnz_label(cb, frame_flag_modified);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this use as a kind of caching mechanisms for successive calls to a block argument?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah that's the idea. If the code never reads from the block parameter there is no GC allocation to materialize it into a Ruby object.

@tenderlove tenderlove merged commit ebaf56c into ruby:master May 12, 2022
@tenderlove tenderlove deleted the getblockparam branch May 12, 2022 21:34
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