From 7cec7d14c33d0043b2c122aee5c88fc5ec884e8a Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Fri, 15 Sep 2023 19:03:48 -0400 Subject: YJIT: Fix object movement bug in iseq guard for invokeblock Since the compile-time iseq used in the guard was not marked and updated during compaction, a runtime value reusing the address could falsely pass the guard. Co-authored-by: Takashi Kokubun --- bootstraptest/test_yjit.rb | 12 ++++++++++++ yjit/src/codegen.rs | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb index 82fd1e1376..f5cfaabe72 100644 --- a/bootstraptest/test_yjit.rb +++ b/bootstraptest/test_yjit.rb @@ -1,3 +1,15 @@ +# regression test for invokeblock iseq guard +assert_equal 'ok', %q{ + return :ok unless defined?(GC.compact) + def foo = yield + 10.times do |i| + ret = eval("foo { #{i} }") + raise "failed at #{i}" unless ret == i + GC.compact + end + :ok +} unless defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled? # Not yet working on RJIT + # regression test for overly generous guard elision assert_equal '[0, :sum, 0, :sum]', %q{ # In faulty versions, the following happens: diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index afa4a4cf6f..06444461b2 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -7494,7 +7494,7 @@ fn gen_invokeblock_specialized( asm_comment!(asm, "guard known ISEQ"); let captured_opnd = asm.and(block_handler_opnd, Opnd::Imm(!0x3)); let iseq_opnd = asm.load(Opnd::mem(64, captured_opnd, SIZEOF_VALUE_I32 * 2)); - asm.cmp(iseq_opnd, (comptime_iseq as usize).into()); + asm.cmp(iseq_opnd, VALUE::from(comptime_iseq).into()); jit_chain_guard( JCC_JNE, jit, -- cgit v1.2.3