Skip to content

Commit 0f3d6ee

Browse files
authored
ZJIT: Disable ZJIT instructions when USE_ZJIT is 0 (ruby#13199)
* ZJIT: Disable ZJIT instructions when USE_ZJIT is 0 * Test the order of ZJIT instructions * Add more jobs that disable JITs * Show instruction names in the message
1 parent 0c44e5a commit 0f3d6ee

File tree

12 files changed

+118
-47
lines changed

12 files changed

+118
-47
lines changed

.github/workflows/compilers.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,9 @@ jobs:
193193
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
194194
with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github }
195195
- { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } }
196-
- { uses: './.github/actions/compilers', name: 'disable-jit', with: { append_configure: '--disable-yjit' } }
196+
- { uses: './.github/actions/compilers', name: 'disable-jit', with: { append_configure: '--disable-yjit --disable-zjit' } }
197+
- { uses: './.github/actions/compilers', name: 'disable-yjit', with: { append_configure: '--disable-yjit' } }
198+
- { uses: './.github/actions/compilers', name: 'disable-zjit', with: { append_configure: '--disable-zjit' } }
197199
- { uses: './.github/actions/compilers', name: 'disable-dln', with: { append_configure: '--disable-dln' } }
198200
- { uses: './.github/actions/compilers', name: 'enable-mkmf-verbose', with: { append_configure: '--enable-mkmf-verbose' } }
199201
- { uses: './.github/actions/compilers', name: 'disable-rubygems', with: { append_configure: '--disable-rubygems' } }

test/ruby/test_zjit.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,19 @@ def fib(n)
479479
}, call_threshold: 5, num_profiles: 3
480480
end
481481

482+
# tool/ruby_vm/views/*.erb relies on the zjit instructions a) being contiguous and
483+
# b) being reliably ordered after all the other instructions.
484+
def test_instruction_order
485+
insn_names = RubyVM::INSTRUCTION_NAMES
486+
zjit, others = insn_names.map.with_index.partition { |name, _| name.start_with?('zjit_') }
487+
zjit_indexes = zjit.map(&:last)
488+
other_indexes = others.map(&:last)
489+
zjit_indexes.product(other_indexes).each do |zjit_index, other_index|
490+
assert zjit_index > other_index, "'#{insn_names[zjit_index]}' at #{zjit_index} "\
491+
"must be defined after '#{insn_names[other_index]}' at #{other_index}"
492+
end
493+
end
494+
482495
private
483496

484497
# Assert that every method call in `test_script` can be compiled by ZJIT

tool/ruby_vm/views/_comptime_insn_stack_increase.erb

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,31 @@
66
%# conditions mentioned in the file COPYING are met. Consult the file for
77
%# details.
88
%#
9+
%
10+
% stack_increase = proc do |i|
11+
% if i.has_attribute?('sp_inc')
12+
% '-127'
13+
% else
14+
% sprintf("%4d", i.rets.size - i.pops.size)
15+
% end
16+
% end
17+
% zjit_insns, insns = RubyVM::Instructions.partition { |i| i.name.start_with?('zjit_') }
18+
%
919
PUREFUNC(MAYBE_UNUSED(static int comptime_insn_stack_increase(int depth, int insn, const VALUE *opes)));
1020
PUREFUNC(static rb_snum_t comptime_insn_stack_increase_dispatch(enum ruby_vminsn_type insn, const VALUE *opes));
1121

1222
rb_snum_t
1323
comptime_insn_stack_increase_dispatch(enum ruby_vminsn_type insn, const VALUE *opes)
1424
{
1525
static const signed char t[] = {
16-
% RubyVM::Instructions.each_slice 8 do |a|
17-
<%= a.map { |i|
18-
if i.has_attribute?('sp_inc')
19-
'-127'
20-
else
21-
sprintf("%4d", i.rets.size - i.pops.size)
22-
end
23-
}.join(', ') -%>,
26+
% insns.each_slice(8) do |row|
27+
<%= row.map(&stack_increase).join(', ') -%>,
28+
% end
29+
#if USE_ZJIT
30+
% zjit_insns.each_slice(8) do |row|
31+
<%= row.map(&stack_increase).join(', ') -%>,
2432
% end
33+
#endif
2534
};
2635
signed char c = t[insn];
2736

tool/ruby_vm/views/_insn_len_info.erb

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
%# granted, to either redistribute and/or modify this file, provided that the
66
%# conditions mentioned in the file COPYING are met. Consult the file for
77
%# details.
8+
%
9+
% zjit_insns, insns = RubyVM::Instructions.partition { |i| i.name.start_with?('zjit_') }
10+
%
811
CONSTFUNC(MAYBE_UNUSED(static int insn_len(VALUE insn)));
912

1013
RUBY_SYMBOL_EXPORT_BEGIN /* for debuggers */
@@ -13,9 +16,14 @@ RUBY_SYMBOL_EXPORT_END
1316

1417
#ifdef RUBY_VM_INSNS_INFO
1518
const uint8_t rb_vm_insn_len_info[] = {
16-
% RubyVM::Instructions.each_slice 23 do |a|
17-
<%= a.map(&:width).join(', ') -%>,
19+
% insns.each_slice(23) do |row|
20+
<%= row.map(&:width).join(', ') -%>,
1821
% end
22+
#if USE_ZJIT
23+
% zjit_insns.each_slice(23) do |row|
24+
<%= row.map(&:width).join(', ') -%>,
25+
% end
26+
#endif
1927
};
2028

2129
ASSERT_VM_INSTRUCTION_SIZE(rb_vm_insn_len_info);

tool/ruby_vm/views/_insn_name_info.erb

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@
66
%# conditions mentioned in the file COPYING are met. Consult the file for
77
%# details.
88
%
9-
% a = RubyVM::Instructions.map {|i| i.name }
10-
% b = (0...a.size)
11-
% c = a.inject([0]) {|r, i| r << (r[-1] + i.length + 1) }
12-
% c.pop
9+
% zjit_insns, insns = RubyVM::Instructions.partition { |i| i.name.start_with?('zjit_') }
10+
%
11+
% next_offset = 0
12+
% name_offset = proc do |i|
13+
% offset = sprintf("%4d", next_offset)
14+
% next_offset += i.name.length + 1 # insn.name + \0
15+
% offset
16+
% end
1317
%
1418
CONSTFUNC(MAYBE_UNUSED(static const char *insn_name(VALUE insn)));
1519

@@ -20,18 +24,28 @@ extern const unsigned short rb_vm_insn_name_offset[VM_INSTRUCTION_SIZE];
2024
RUBY_SYMBOL_EXPORT_END
2125

2226
#ifdef RUBY_VM_INSNS_INFO
23-
const int rb_vm_max_insn_name_size = <%= a.map(&:size).max %>;
27+
const int rb_vm_max_insn_name_size = <%= RubyVM::Instructions.map { |i| i.name.size }.max %>;
2428

2529
const char rb_vm_insn_name_base[] =
26-
% a.each do |i|
27-
<%=cstr i%> "\0"
30+
% insns.each do |i|
31+
<%= cstr i.name %> "\0"
32+
% end
33+
#if USE_ZJIT
34+
% zjit_insns.each do |i|
35+
<%= cstr i.name %> "\0"
2836
% end
37+
#endif
2938
;
3039

3140
const unsigned short rb_vm_insn_name_offset[] = {
32-
% c.each_slice 12 do |d|
33-
<%= d.map {|i| sprintf("%4d", i) }.join(', ') %>,
41+
% insns.each_slice(12) do |row|
42+
<%= row.map(&name_offset).join(', ') %>,
43+
% end
44+
#if USE_ZJIT
45+
% zjit_insns.each_slice(12) do |row|
46+
<%= row.map(&name_offset).join(', ') %>,
3447
% end
48+
#endif
3549
};
3650

3751
ASSERT_VM_INSTRUCTION_SIZE(rb_vm_insn_name_offset);

tool/ruby_vm/views/_insn_operand_info.erb

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@
66
%# conditions mentioned in the file COPYING are met. Consult the file for
77
%# details.
88
%
9-
% a = RubyVM::Instructions.map {|i| i.operands_info }
10-
% b = (0...a.size)
11-
% c = a.inject([0]) {|r, i| r << (r[-1] + i.length + 1) }
12-
% c.pop
9+
% zjit_insns, insns = RubyVM::Instructions.partition { |i| i.name.start_with?('zjit_') }
10+
%
11+
% operands_info = proc { |i| sprintf("%-6s", cstr(i.operands_info)) }
12+
%
13+
% next_offset = 0
14+
% op_offset = proc do |i|
15+
% offset = sprintf("%3d", next_offset)
16+
% next_offset += i.operands_info.length + 1 # insn.operands_info + \0
17+
% offset
18+
% end
1319
%
1420
CONSTFUNC(MAYBE_UNUSED(static const char *insn_op_types(VALUE insn)));
1521
CONSTFUNC(MAYBE_UNUSED(static int insn_op_type(VALUE insn, long pos)));
@@ -21,15 +27,25 @@ RUBY_SYMBOL_EXPORT_END
2127

2228
#ifdef RUBY_VM_INSNS_INFO
2329
const char rb_vm_insn_op_base[] =
24-
% a.each_slice 5 do |d|
25-
<%= d.map {|i| sprintf("%-6s", cstr(i)) }.join(' "\0" ') %> "\0"
30+
% insns.each_slice(5) do |row|
31+
<%= row.map(&operands_info).join(' "\0" ') %> "\0"
32+
% end
33+
#if USE_ZJIT
34+
% zjit_insns.each_slice(5) do |row|
35+
<%= row.map(&operands_info).join(' "\0" ') %> "\0"
2636
% end
37+
#endif
2738
;
2839

2940
const unsigned short rb_vm_insn_op_offset[] = {
30-
% c.each_slice 12 do |d|
31-
<%= d.map {|i| sprintf("%3d", i) }.join(', ') %>,
41+
% insns.each_slice(12) do |row|
42+
<%= row.map(&op_offset).join(', ') %>,
43+
% end
44+
#if USE_ZJIT
45+
% zjit_insns.each_slice(12) do |row|
46+
<%= row.map(&op_offset).join(', ') %>,
3247
% end
48+
#endif
3349
};
3450

3551
ASSERT_VM_INSTRUCTION_SIZE(rb_vm_insn_op_offset);

tool/ruby_vm/views/_zjit_helpers.erb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#if USE_ZJIT
2+
13
MAYBE_UNUSED(static int vm_bare_insn_to_zjit_insn(int insn));
24
static int
35
vm_bare_insn_to_zjit_insn(int insn)
@@ -25,3 +27,5 @@ vm_zjit_insn_to_bare_insn(int insn)
2527
return insn;
2628
}
2729
}
30+
31+
#endif

tool/ruby_vm/views/_zjit_instruction.erb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#if USE_ZJIT
2+
13
/* insn <%= insn.pretty_name %> */
24
INSN_ENTRY(<%= insn.name %>)
35
{
@@ -6,3 +8,5 @@ INSN_ENTRY(<%= insn.name %>)
68
DISPATCH_ORIGINAL_INSN(<%= insn.jump_destination %>);
79
END_INSN(<%= insn.name %>);
810
}
11+
12+
#endif

tool/ruby_vm/views/insns.inc.erb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
%# granted, to either redistribute and/or modify this file, provided that the
77
%# conditions mentioned in the file COPYING are met. Consult the file for
88
%# details.
9+
%
10+
% zjit_insns, insns = RubyVM::Instructions.partition { |i| i.name.start_with?('zjit_') }
11+
%
912
<%= render 'copyright' %>
1013
<%= render 'notice', locals: {
1114
this_file: 'contains YARV instruction list',
@@ -19,9 +22,14 @@
1922
#define BIN(n) YARVINSN_##n
2023

2124
enum ruby_vminsn_type {
22-
% RubyVM::Instructions.each do |i|
25+
% insns.each do |i|
2326
<%= i.bin %>,
2427
% end
28+
#if USE_ZJIT
29+
% zjit_insns.each do |i|
30+
<%= i.bin %>,
31+
% end
32+
#endif
2533
VM_INSTRUCTION_SIZE
2634
};
2735

tool/ruby_vm/views/optunifs.inc.erb

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
%# conditions mentioned in the file COPYING are met. Consult the file for
88
%# details.
99
% raise ':FIXME:TBW' if RubyVM::VmOptsH['INSTRUCTIONS_UNIFICATION']
10-
% n = RubyVM::Instructions.size
1110
<%= render 'copyright' %>
1211
<%= render 'notice', locals: {
1312
this_file: 'is for threaded code',
@@ -16,6 +15,4 @@
1615

1716
/* Let .bss section automatically initialize this variable */
1817
/* cf. Section 6.7.8 of ISO/IEC 9899:1999 */
19-
static const int *const *const unified_insns_data[<%= n %>];
20-
21-
ASSERT_VM_INSTRUCTION_SIZE(unified_insns_data);
18+
static const int *const *const unified_insns_data[VM_INSTRUCTION_SIZE];

0 commit comments

Comments
 (0)