aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2023-09-15 19:03:48 -0400
committerGitHub <noreply@github.com>2023-09-15 19:03:48 -0400
commit7cec7d14c33d0043b2c122aee5c88fc5ec884e8a (patch)
treeff566d0cbbc87ca2925aaab1c91578d6cf57cb6b
parent1be64e34d0881e5c66be51a892bcd3a056e8f5f0 (diff)
downloadruby-7cec7d14c33d0043b2c122aee5c88fc5ec884e8a.tar.gz
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 <takashikkbn@gmail.com>
-rw-r--r--bootstraptest/test_yjit.rb12
-rw-r--r--yjit/src/codegen.rs2
2 files changed, 13 insertions, 1 deletions
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,