Skip to content
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

YJIT: Make block invalidation more robust #5145

Merged
merged 1 commit into from
Nov 22, 2021
Merged

Conversation

XrXr
Copy link
Member

@XrXr XrXr commented Nov 18, 2021

This commit adds an entry_exit field to block_t for use in
invalidate_block_version(). By patching the start of the block while
invalidating it, invalidate_block_version() can function correctly
while there is no executable memory left for new branch stubs.

This change additionally fixes correctness for situations where we
cannot patch incoming jumps to the invalidated block. In situations
such as Shopify/yjit#226, the address to the start of the block
is saved and used later, possibly after the block is invalidated.

The assume_* family of function now generate block->entry_exit before
remembering blocks for invalidation.

RubyVM::YJIT.simulate_oom! is introduced for testing out of memory
conditions. The test for it is disabled for now because OOM triggers
other failure conditions not addressed by this commit.

Fixes Shopify/yjit#226

@@ -657,43 +677,45 @@ yjit_gen_block(block_t *block, rb_execution_context_t *ec)

// Lookup the codegen function for this instruction
codegen_fn gen_fn = gen_fns[opcode];
if (!gen_fn) {
Copy link
Member Author

Choose a reason for hiding this comment

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

This change unifies the !gen_fn case and the case where gen_fn returns CANT_COMPILE. They were doing the same thing

@XrXr
Copy link
Member Author

XrXr commented Nov 18, 2021

There are CI failures from the OOM test tripping on trying to generate new entry points while OOM. Looks like we can't have OOM tests until that's fixed because it's too easy to trigger with YJIT.simulate_oom!. Skipping entry point generation should be easier to do in a separate PR.

This commit adds an entry_exit field to block_t for use in
invalidate_block_version(). By patching the start of the block while
invalidating it, invalidate_block_version() can function correctly
while there is no executable memory left for new branch stubs.

This change additionally fixes correctness for situations where we
cannot patch incoming jumps to the invalidated block. In situations
such as Shopify/yjit#226, the address to the start of the block
is saved and used later, possibly after the block is invalidated.

The assume_* family of function now generate block->entry_exit before
remembering blocks for invalidation.

RubyVM::YJIT.simulate_oom! is introduced for testing out of memory
conditions. The test for it is disabled for now because OOM triggers
other failure conditions not addressed by this commit.

Fixes Shopify/yjit#226
@XrXr XrXr marked this pull request as ready for review November 22, 2021 18:03
Copy link
Contributor

@maximecb maximecb left a comment

Choose a reason for hiding this comment

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

Thanks for tackling this difficult challenge Alan 🙏

@XrXr XrXr merged commit 13d1ded into ruby:master Nov 22, 2021
@XrXr XrXr deleted the exit-for-inval branch November 22, 2021 23:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants