aboutsummaryrefslogtreecommitdiffstats
path: root/bootstraptest
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2023-12-04 10:13:40 -0500
committerGitHub <noreply@github.com>2023-12-04 10:13:40 -0500
commitb5a62eb9abf7a69e6a7288eba880652d7cd075a4 (patch)
tree83eabe5553c127368b6efa40d62d45356971a9d3 /bootstraptest
parentf40727f4aa32dd89cffc0474c7b8dac367e6b308 (diff)
downloadruby-b5a62eb9abf7a69e6a7288eba880652d7cd075a4.tar.gz
YJIT: Mark and update stubs in invalidated blocks (#9104)
Like in the example given in delayed_deallocation(), stubs can be hit even if the block housing it is invalidated. Mark them so we don't work with invalidate ISeqs when hitting these stubs.
Diffstat (limited to 'bootstraptest')
-rw-r--r--bootstraptest/test_yjit.rb22
1 files changed, 22 insertions, 0 deletions
diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index f55c319707..1a4db302d0 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -1,3 +1,25 @@
+# regression test for GC marking stubs in invalidated code
+assert_normal_exit %q{
+ garbage = Array.new(10_000) { [] } # create garbage to cause iseq movement
+ eval(<<~RUBY)
+ def foo(n, garbage)
+ if n == 2
+ # 1.times.each to create a cfunc frame to preserve the JIT frame
+ # which will return to a stub housed in an invalidated block
+ return 1.times.each do
+ Object.define_method(:foo) {}
+ garbage.clear
+ GC.verify_compaction_references(toward: :empty, expand_heap: true)
+ end
+ end
+
+ foo(n + 1, garbage)
+ end
+ RUBY
+
+ foo(1, garbage)
+}
+
# regression test for callee block handler overlapping with arguments
assert_equal '3', %q{
def foo(_req, *args) = args.last