Skip to content

Commit b1730ad

Browse files
committed
ZJIT: Add integration tests for recompilation
Test the side-exit recompilation trigger, deferral mechanism (doesn't get stuck), threshold=0 disabling, and global recompilation cap.
1 parent 0d27eab commit b1730ad

1 file changed

Lines changed: 54 additions & 0 deletions

File tree

test/ruby/test_zjit.rb

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)