aboutsummaryrefslogtreecommitdiffstats
path: root/test/ruby/test_yjit.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/ruby/test_yjit.rb')
-rw-r--r--test/ruby/test_yjit.rb71
1 files changed, 23 insertions, 48 deletions
diff --git a/test/ruby/test_yjit.rb b/test/ruby/test_yjit.rb
index 88f8e42813..9ad59bc962 100644
--- a/test/ruby/test_yjit.rb
+++ b/test/ruby/test_yjit.rb
@@ -13,6 +13,7 @@ class TestYJIT < Test::Unit::TestCase
assert_includes(RUBY_DESCRIPTION, '+YJIT')
end
+ # Check that YJIT is in the version string
def test_yjit_in_version
[
%w(--version --yjit),
@@ -42,9 +43,8 @@ class TestYJIT < Test::Unit::TestCase
def test_command_line_switches
assert_in_out_err('--yjit-', '', [], /invalid option --yjit-/)
assert_in_out_err('--yjithello', '', [], /invalid option --yjithello/)
- assert_in_out_err('--yjit-call-threshold', '', [], /--yjit-call-threshold needs an argument/)
- assert_in_out_err('--yjit-call-threshold=', '', [], /--yjit-call-threshold needs an argument/)
- assert_in_out_err('--yjit-greedy-versioning=1', '', [], /warning: argument to --yjit-greedy-versioning is ignored/)
+ #assert_in_out_err('--yjit-call-threshold', '', [], /--yjit-call-threshold needs an argument/)
+ #assert_in_out_err('--yjit-call-threshold=', '', [], /--yjit-call-threshold needs an argument/)
end
def test_yjit_stats_and_v_no_error
@@ -356,7 +356,7 @@ class TestYJIT < Test::Unit::TestCase
end
def test_compile_opt_getinlinecache
- assert_compiles(<<~RUBY, insns: %i[opt_getinlinecache], result: 123, min_calls: 2)
+ assert_compiles(<<~RUBY, insns: %i[opt_getinlinecache], result: 123, call_threshold: 2)
def get_foo
FOO
end
@@ -369,7 +369,7 @@ class TestYJIT < Test::Unit::TestCase
end
def test_opt_getinlinecache_slowpath
- assert_compiles(<<~RUBY, exits: { opt_getinlinecache: 1 }, result: [42, 42, 1, 1], min_calls: 2)
+ assert_compiles(<<~RUBY, exits: { opt_getinlinecache: 1 }, result: [42, 42, 1, 1], call_threshold: 2)
class A
FOO = 42
class << self
@@ -397,7 +397,7 @@ class TestYJIT < Test::Unit::TestCase
end
def test_string_interpolation
- assert_compiles(<<~'RUBY', insns: %i[objtostring anytostring concatstrings], result: "foobar", min_calls: 2)
+ assert_compiles(<<~'RUBY', insns: %i[objtostring anytostring concatstrings], result: "foobar", call_threshold: 2)
def make_str(foo, bar)
"#{foo}#{bar}"
end
@@ -489,7 +489,7 @@ class TestYJIT < Test::Unit::TestCase
# Tests calling a variadic cfunc with many args
def test_build_large_struct
- assert_compiles(<<~RUBY, insns: %i[opt_send_without_block], min_calls: 2)
+ assert_compiles(<<~RUBY, insns: %i[opt_send_without_block], call_threshold: 2)
::Foo = Struct.new(:a, :b, :c, :d, :e, :f, :g, :h)
def build_foo
@@ -530,8 +530,8 @@ class TestYJIT < Test::Unit::TestCase
assert_no_exits('{}.merge(foo: 123, bar: 456, baz: 789)')
end
+ # regression test simplified from URI::Generic#hostname=
def test_ctx_different_mappings
- # regression test simplified from URI::Generic#hostname=
assert_compiles(<<~'RUBY', frozen_string_literal: true)
def foo(v)
!(v&.start_with?('[')) && v&.index(':')
@@ -572,7 +572,7 @@ class TestYJIT < Test::Unit::TestCase
end
ANY = Object.new
- def assert_compiles(test_script, insns: [], min_calls: 1, stdout: nil, exits: {}, result: ANY, frozen_string_literal: nil)
+ def assert_compiles(test_script, insns: [], call_threshold: 1, stdout: nil, exits: {}, result: ANY, frozen_string_literal: nil)
reset_stats = <<~RUBY
RubyVM::YJIT.runtime_stats
RubyVM::YJIT.reset_stats!
@@ -581,29 +581,17 @@ class TestYJIT < Test::Unit::TestCase
write_results = <<~RUBY
stats = RubyVM::YJIT.runtime_stats
- def collect_blocks(blocks)
- blocks.sort_by(&:address).map { |b| [b.iseq_start_index, b.iseq_end_index] }
- end
-
- def collect_iseqs(iseq)
- iseq_array = iseq.to_a
- insns = iseq_array.last.grep(Array)
- blocks = RubyVM::YJIT.blocks_for(iseq)
- h = {
- name: iseq_array[5],
- insns: insns,
- blocks: collect_blocks(blocks),
- }
- arr = [h]
- iseq.each_child { |c| arr.concat collect_iseqs(c) }
- arr
+ def collect_insns(iseq)
+ insns = RubyVM::YJIT.insns_compiled(iseq)
+ iseq.each_child { |c| insns.concat collect_insns(c) }
+ insns
end
iseq = RubyVM::InstructionSequence.of(_test_proc)
IO.open(3).write Marshal.dump({
result: #{result == ANY ? "nil" : "result"},
stats: stats,
- iseqs: collect_iseqs(iseq),
+ insns: collect_insns(iseq),
disasm: iseq.disasm
})
RUBY
@@ -618,7 +606,7 @@ class TestYJIT < Test::Unit::TestCase
#{write_results}
RUBY
- status, out, err, stats = eval_with_jit(script, min_calls: min_calls)
+ status, out, err, stats = eval_with_jit(script, call_threshold: call_threshold)
assert status.success?, "exited with status #{status.to_i}, stderr:\n#{err}"
@@ -629,10 +617,11 @@ class TestYJIT < Test::Unit::TestCase
end
runtime_stats = stats[:stats]
- iseqs = stats[:iseqs]
+ insns_compiled = stats[:insns]
disasm = stats[:disasm]
- # Only available when RUBY_DEBUG enabled
+ # Check that exit counts are as expected
+ # Full stats are only available when RUBY_DEBUG enabled
if runtime_stats[:all_stats]
recorded_exits = runtime_stats.select { |k, v| k.to_s.start_with?("exit_") }
recorded_exits = recorded_exits.reject { |k, v| v == 0 }
@@ -647,38 +636,24 @@ class TestYJIT < Test::Unit::TestCase
# Only available when RUBY_DEBUG enabled
if runtime_stats[:all_stats]
missed_insns = insns.dup
- all_compiled_blocks = {}
- iseqs.each do |iseq|
- compiled_blocks = iseq[:blocks].map { |from, to| (from...to) }
- all_compiled_blocks[iseq[:name]] = compiled_blocks
- compiled_insns = iseq[:insns]
- next_idx = 0
- compiled_insns.map! do |insn|
- # TODO: not sure this is accurate for determining insn size
- idx = next_idx
- next_idx += insn.length
- [idx, *insn]
- end
-
- compiled_insns.each do |idx, op, *arguments|
- next unless missed_insns.include?(op)
- next unless compiled_blocks.any? { |block| block === idx }
+ insns_compiled.each do |op|
+ if missed_insns.include?(op)
# This instruction was compiled
missed_insns.delete(op)
end
end
unless missed_insns.empty?
- flunk "Expected to compile instructions #{missed_insns.join(", ")} but didn't.\nCompiled ranges: #{all_compiled_blocks.inspect}\niseq:\n#{disasm}"
+ flunk "Expected to compile instructions #{missed_insns.join(", ")} but didn't.\niseq:\n#{disasm}"
end
end
end
- def eval_with_jit(script, min_calls: 1, timeout: 1000)
+ def eval_with_jit(script, call_threshold: 1, timeout: 1000)
args = [
"--disable-gems",
- "--yjit-call-threshold=#{min_calls}",
+ "--yjit-call-threshold=#{call_threshold}",
"--yjit-stats"
]
args << "-e" << script