Skip to content

Commit 89e8ab1

Browse files
committed
ZJIT: Add insns keyword to test that a certain opcode is present
1 parent 5b3f1c4 commit 89e8ab1

1 file changed

Lines changed: 34 additions & 13 deletions

File tree

test/ruby/test_zjit.rb

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ def test_opt_eq
134134
def test(a, b) = a == b
135135
test(0, 2) # profile opt_eq
136136
[test(1, 1), test(0, 1)]
137-
}, call_threshold: 2
137+
}, insns: [:opt_eq], call_threshold: 2
138138
end
139139

140140
def test_opt_neq_dynamic
@@ -144,7 +144,7 @@ def test_opt_neq_dynamic
144144
def test(a, b) = a != b
145145
test(0, 2) # profile opt_neq
146146
[test(1, 1), test(0, 1)]
147-
}, call_threshold: 1
147+
}, insns: [:opt_neq], call_threshold: 1
148148
end
149149

150150
def test_opt_neq_fixnum
@@ -160,46 +160,46 @@ def test_opt_lt
160160
def test(a, b) = a < b
161161
test(2, 3) # profile opt_lt
162162
[test(0, 1), test(0, 0), test(1, 0)]
163-
}, call_threshold: 2
163+
}, insns: [:opt_lt], call_threshold: 2
164164
end
165165

166166
def test_opt_lt_with_literal_lhs
167167
assert_compiles '[false, false, true]', %q{
168168
def test(n) = 2 < n
169169
test(2) # profile opt_lt
170170
[test(1), test(2), test(3)]
171-
}, call_threshold: 2
171+
}, insns: [:opt_lt], call_threshold: 2
172172
end
173173

174174
def test_opt_le
175175
assert_compiles '[true, true, false]', %q{
176176
def test(a, b) = a <= b
177177
test(2, 3) # profile opt_le
178178
[test(0, 1), test(0, 0), test(1, 0)]
179-
}, call_threshold: 2
179+
}, insns: [:opt_le], call_threshold: 2
180180
end
181181

182182
def test_opt_gt
183183
assert_compiles '[false, false, true]', %q{
184184
def test(a, b) = a > b
185185
test(2, 3) # profile opt_gt
186186
[test(0, 1), test(0, 0), test(1, 0)]
187-
}, call_threshold: 2
187+
}, insns: [:opt_gt], call_threshold: 2
188188
end
189189

190190
def test_opt_ge
191191
assert_compiles '[false, true, true]', %q{
192192
def test(a, b) = a >= b
193193
test(2, 3) # profile opt_ge
194194
[test(0, 1), test(0, 0), test(1, 0)]
195-
}, call_threshold: 2
195+
}, insns: [:opt_ge], call_threshold: 2
196196
end
197197

198198
def test_new_array_empty
199199
assert_compiles '[]', %q{
200200
def test = []
201201
test
202-
}
202+
}, insns: [:newarray]
203203
end
204204

205205
def test_new_array_nonempty
@@ -504,26 +504,47 @@ def test_instruction_order
504504

505505
# Assert that every method call in `test_script` can be compiled by ZJIT
506506
# at a given call_threshold
507-
def assert_compiles(expected, test_script, **opts)
507+
def assert_compiles(expected, test_script, insns: [], **opts)
508508
pipe_fd = 3
509509

510510
script = <<~RUBY
511511
_test_proc = -> {
512512
RubyVM::ZJIT.assert_compiles
513513
#{test_script}
514514
}
515-
result = _test_proc.call
516-
IO.open(#{pipe_fd}).write(result.inspect)
515+
ret_val = _test_proc.call
516+
result = {
517+
ret_val:,
518+
#{ unless insns.empty?
519+
'insns: RubyVM::InstructionSequence.of(_test_proc).enum_for(:each_child).map(&:to_a)'
520+
end}
521+
}
522+
IO.open(#{pipe_fd}).write(Marshal.dump(result))
517523
RUBY
518524

519-
status, out, err, actual = eval_with_jit(script, pipe_fd:, **opts)
525+
status, out, err, result = eval_with_jit(script, pipe_fd:, **opts)
520526

521527
message = "exited with status #{status.to_i}"
522528
message << "\nstdout:\n```\n#{out}```\n" unless out.empty?
523529
message << "\nstderr:\n```\n#{err}```\n" unless err.empty?
524530
assert status.success?, message
525531

526-
assert_equal expected, actual
532+
result = Marshal.load(result)
533+
assert_equal expected, result.fetch(:ret_val).inspect
534+
535+
unless insns.empty?
536+
iseqs = result.fetch(:insns)
537+
iseqs.filter! { it[9] == :method } # ISeq type
538+
assert_equal 1, iseqs.size, "Opcode assertions tests must define exactly one method"
539+
iseq_insns = iseqs.first.last
540+
541+
expected_insns = Set.new(insns)
542+
iseq_insns.each do
543+
next unless it.is_a?(Array)
544+
expected_insns.delete(it.first)
545+
end
546+
assert(expected_insns.empty?, -> { "Not present in ISeq: #{expected_insns.to_a}" })
547+
end
527548
end
528549

529550
# Run a Ruby process with ZJIT options and a pipe for writing test results

0 commit comments

Comments
 (0)