diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb index 6b7d483926..c7a5883986 100644 --- a/bootstraptest/test_yjit.rb +++ b/bootstraptest/test_yjit.rb @@ -4770,6 +4770,19 @@ assert_equal '[:ok, :ok, :ok]', %q{ tests } +# regression test for invalidating an empty block +assert_equal '0', %q{ + def foo = (* = 1).pred + + foo # compile it + + class Integer + def to_ary = [] # invalidate + end + + foo # try again +} unless rjit_enabled? # doesn't work on RJIT + # test integer left shift with constant rhs assert_equal [0x80000000000, 'a+', :ok].inspect, %q{ def shift(val) = val << 43 diff --git a/yjit/src/core.rs b/yjit/src/core.rs index fb7d52cc5d..4152eab02c 100644 --- a/yjit/src/core.rs +++ b/yjit/src/core.rs @@ -2643,6 +2643,12 @@ fn regenerate_branch(cb: &mut CodeBlock, branch: &Branch) { branch.get_target_address(1).map(|addr| Target::CodePtr(addr)), ); + // If the entire block is the branch and the block could be invalidated, + // we need to pad to ensure there is room for invalidation patching. + if branch.start_addr == block.start_addr && branch_terminates_block && block.entry_exit.is_some() { + asm.pad_inval_patch(); + } + // Rewrite the branch let old_write_pos = cb.get_write_pos(); let old_dropped_bytes = cb.has_dropped_bytes();