@@ -404,6 +404,60 @@ def array.itself = :not_itself
404404 end
405405 end
406406
407+ # Test that side exits trigger recompilation after reaching the threshold
408+ def test_side_exit_recompilation
409+ assert_runs 'true' , <<~'RUBY' , call_threshold : 2 , num_profiles : 1 , stats : :quiet , extra_args : %w[ --zjit-recompile-threshold=5 ]
410+ def test(x)
411+ x + 1
412+ end
413+ 100.times { test(42) }
414+ stats = RubyVM::ZJIT.stats
415+ # Should have compiled at least one ISEQ
416+ stats[:compiled_iseq_count] >= 1
417+ RUBY
418+ end
419+
420+ # Test that the deferral mechanism doesn't get stuck (the bug fix)
421+ def test_deferral_does_not_get_stuck
422+ assert_runs '101' , <<~'RUBY' , call_threshold : 2 , num_profiles : 1 , stats : :quiet , extra_args : %w[ --zjit-recompile-threshold=5 ]
423+ def test(x)
424+ x + 1
425+ end
426+ # Warm up with one type
427+ 100.times { test(42) }
428+ # The method should still be callable and return correct results
429+ test(100)
430+ RUBY
431+ end
432+
433+ # Test that threshold=0 disables recompilation
434+ def test_recompile_threshold_zero_disables
435+ assert_runs '0' , <<~'RUBY' , call_threshold : 2 , num_profiles : 1 , stats : :quiet , extra_args : %w[ --zjit-recompile-threshold=0 ]
436+ def test(x)
437+ x + 1
438+ end
439+ 100.times { test(42) }
440+ RubyVM::ZJIT.stats[:recompile_count]
441+ RUBY
442+ end
443+
444+ # Test that the global recompilation cap limits recompilations
445+ def test_recompile_cap
446+ assert_runs 'true' , <<~'RUBY' , call_threshold : 2 , num_profiles : 1 , stats : :quiet , extra_args : %w[ --zjit-recompile-threshold=5 --zjit-recompile-cap=2 ]
447+ results = []
448+ # Create several methods that will each trigger recompilation
449+ 5.times do |i|
450+ define_method(:"cap_test_#{i}") { |x| x + 1 }
451+ end
452+ 5.times do |i|
453+ 100.times { send(:"cap_test_#{i}", 42) }
454+ end
455+ stats = RubyVM::ZJIT.stats
456+ # Recompile count should be capped at 2
457+ stats[:recompile_count] <= 2
458+ RUBY
459+ end
460+
407461 private
408462
409463 # Assert that every method call in `test_script` can be compiled by ZJIT
0 commit comments