ZJIT: Add insns
param that tests for opcode presence
This commit is contained in:
parent
998e5791c5
commit
01f6bd8bc3
Notes:
git
2025-06-05 14:45:57 +00:00
Merged: https://github.com/ruby/ruby/pull/13470 Merged-By: XrXr
@ -152,7 +152,7 @@ class TestZJIT < Test::Unit::TestCase
|
|||||||
def test(a, b) = a == b
|
def test(a, b) = a == b
|
||||||
test(0, 2) # profile opt_eq
|
test(0, 2) # profile opt_eq
|
||||||
[test(1, 1), test(0, 1)]
|
[test(1, 1), test(0, 1)]
|
||||||
}, call_threshold: 2
|
}, insns: [:opt_eq], call_threshold: 2
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_opt_neq_dynamic
|
def test_opt_neq_dynamic
|
||||||
@ -162,7 +162,7 @@ class TestZJIT < Test::Unit::TestCase
|
|||||||
def test(a, b) = a != b
|
def test(a, b) = a != b
|
||||||
test(0, 2) # profile opt_neq
|
test(0, 2) # profile opt_neq
|
||||||
[test(1, 1), test(0, 1)]
|
[test(1, 1), test(0, 1)]
|
||||||
}, call_threshold: 1
|
}, insns: [:opt_neq], call_threshold: 1
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_opt_neq_fixnum
|
def test_opt_neq_fixnum
|
||||||
@ -178,7 +178,7 @@ class TestZJIT < Test::Unit::TestCase
|
|||||||
def test(a, b) = a < b
|
def test(a, b) = a < b
|
||||||
test(2, 3) # profile opt_lt
|
test(2, 3) # profile opt_lt
|
||||||
[test(0, 1), test(0, 0), test(1, 0)]
|
[test(0, 1), test(0, 0), test(1, 0)]
|
||||||
}, call_threshold: 2
|
}, insns: [:opt_lt], call_threshold: 2
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_opt_lt_with_literal_lhs
|
def test_opt_lt_with_literal_lhs
|
||||||
@ -186,7 +186,7 @@ class TestZJIT < Test::Unit::TestCase
|
|||||||
def test(n) = 2 < n
|
def test(n) = 2 < n
|
||||||
test(2) # profile opt_lt
|
test(2) # profile opt_lt
|
||||||
[test(1), test(2), test(3)]
|
[test(1), test(2), test(3)]
|
||||||
}, call_threshold: 2
|
}, insns: [:opt_lt], call_threshold: 2
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_opt_le
|
def test_opt_le
|
||||||
@ -194,7 +194,7 @@ class TestZJIT < Test::Unit::TestCase
|
|||||||
def test(a, b) = a <= b
|
def test(a, b) = a <= b
|
||||||
test(2, 3) # profile opt_le
|
test(2, 3) # profile opt_le
|
||||||
[test(0, 1), test(0, 0), test(1, 0)]
|
[test(0, 1), test(0, 0), test(1, 0)]
|
||||||
}, call_threshold: 2
|
}, insns: [:opt_le], call_threshold: 2
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_opt_gt
|
def test_opt_gt
|
||||||
@ -202,7 +202,7 @@ class TestZJIT < Test::Unit::TestCase
|
|||||||
def test(a, b) = a > b
|
def test(a, b) = a > b
|
||||||
test(2, 3) # profile opt_gt
|
test(2, 3) # profile opt_gt
|
||||||
[test(0, 1), test(0, 0), test(1, 0)]
|
[test(0, 1), test(0, 0), test(1, 0)]
|
||||||
}, call_threshold: 2
|
}, insns: [:opt_gt], call_threshold: 2
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_opt_ge
|
def test_opt_ge
|
||||||
@ -210,14 +210,14 @@ class TestZJIT < Test::Unit::TestCase
|
|||||||
def test(a, b) = a >= b
|
def test(a, b) = a >= b
|
||||||
test(2, 3) # profile opt_ge
|
test(2, 3) # profile opt_ge
|
||||||
[test(0, 1), test(0, 0), test(1, 0)]
|
[test(0, 1), test(0, 0), test(1, 0)]
|
||||||
}, call_threshold: 2
|
}, insns: [:opt_ge], call_threshold: 2
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_new_array_empty
|
def test_new_array_empty
|
||||||
assert_compiles '[]', %q{
|
assert_compiles '[]', %q{
|
||||||
def test = []
|
def test = []
|
||||||
test
|
test
|
||||||
}
|
}, insns: [:newarray]
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_new_array_nonempty
|
def test_new_array_nonempty
|
||||||
@ -551,7 +551,7 @@ class TestZJIT < Test::Unit::TestCase
|
|||||||
|
|
||||||
# Assert that every method call in `test_script` can be compiled by ZJIT
|
# Assert that every method call in `test_script` can be compiled by ZJIT
|
||||||
# at a given call_threshold
|
# at a given call_threshold
|
||||||
def assert_compiles(expected, test_script, **opts)
|
def assert_compiles(expected, test_script, insns: [], **opts)
|
||||||
pipe_fd = 3
|
pipe_fd = 3
|
||||||
|
|
||||||
script = <<~RUBY
|
script = <<~RUBY
|
||||||
@ -559,18 +559,39 @@ class TestZJIT < Test::Unit::TestCase
|
|||||||
RubyVM::ZJIT.assert_compiles
|
RubyVM::ZJIT.assert_compiles
|
||||||
#{test_script}
|
#{test_script}
|
||||||
}
|
}
|
||||||
result = _test_proc.call
|
ret_val = _test_proc.call
|
||||||
IO.open(#{pipe_fd}).write(result.inspect)
|
result = {
|
||||||
|
ret_val:,
|
||||||
|
#{ unless insns.empty?
|
||||||
|
'insns: RubyVM::InstructionSequence.of(_test_proc).enum_for(:each_child).map(&:to_a)'
|
||||||
|
end}
|
||||||
|
}
|
||||||
|
IO.open(#{pipe_fd}).write(Marshal.dump(result))
|
||||||
RUBY
|
RUBY
|
||||||
|
|
||||||
status, out, err, actual = eval_with_jit(script, pipe_fd:, **opts)
|
status, out, err, result = eval_with_jit(script, pipe_fd:, **opts)
|
||||||
|
|
||||||
message = "exited with status #{status.to_i}"
|
message = "exited with status #{status.to_i}"
|
||||||
message << "\nstdout:\n```\n#{out}```\n" unless out.empty?
|
message << "\nstdout:\n```\n#{out}```\n" unless out.empty?
|
||||||
message << "\nstderr:\n```\n#{err}```\n" unless err.empty?
|
message << "\nstderr:\n```\n#{err}```\n" unless err.empty?
|
||||||
assert status.success?, message
|
assert status.success?, message
|
||||||
|
|
||||||
assert_equal expected, actual
|
result = Marshal.load(result)
|
||||||
|
assert_equal expected, result.fetch(:ret_val).inspect
|
||||||
|
|
||||||
|
unless insns.empty?
|
||||||
|
iseqs = result.fetch(:insns)
|
||||||
|
iseqs.filter! { it[9] == :method } # ISeq type
|
||||||
|
assert_equal 1, iseqs.size, "Opcode assertions tests must define exactly one method"
|
||||||
|
iseq_insns = iseqs.first.last
|
||||||
|
|
||||||
|
expected_insns = Set.new(insns)
|
||||||
|
iseq_insns.each do
|
||||||
|
next unless it.is_a?(Array)
|
||||||
|
expected_insns.delete(it.first)
|
||||||
|
end
|
||||||
|
assert(expected_insns.empty?, -> { "Not present in ISeq: #{expected_insns.to_a}" })
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Run a Ruby process with ZJIT options and a pipe for writing test results
|
# Run a Ruby process with ZJIT options and a pipe for writing test results
|
||||||
|
Loading…
x
Reference in New Issue
Block a user