ZJIT: Disable ZJIT instructions when USE_ZJIT is 0 (#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
This commit is contained in:
parent
0c44e5ab5e
commit
0f3d6ee578
Notes:
git
2025-04-29 18:03:32 +00:00
Merged-By: k0kubun <takashikkbn@gmail.com>
4
.github/workflows/compilers.yml
vendored
4
.github/workflows/compilers.yml
vendored
@ -193,7 +193,9 @@ jobs:
|
|||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github }
|
with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github }
|
||||||
- { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } }
|
- { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true, fetch-depth: 10 } }
|
||||||
- { uses: './.github/actions/compilers', name: 'disable-jit', with: { append_configure: '--disable-yjit' } }
|
- { uses: './.github/actions/compilers', name: 'disable-jit', with: { append_configure: '--disable-yjit --disable-zjit' } }
|
||||||
|
- { uses: './.github/actions/compilers', name: 'disable-yjit', with: { append_configure: '--disable-yjit' } }
|
||||||
|
- { uses: './.github/actions/compilers', name: 'disable-zjit', with: { append_configure: '--disable-zjit' } }
|
||||||
- { uses: './.github/actions/compilers', name: 'disable-dln', with: { append_configure: '--disable-dln' } }
|
- { uses: './.github/actions/compilers', name: 'disable-dln', with: { append_configure: '--disable-dln' } }
|
||||||
- { uses: './.github/actions/compilers', name: 'enable-mkmf-verbose', with: { append_configure: '--enable-mkmf-verbose' } }
|
- { uses: './.github/actions/compilers', name: 'enable-mkmf-verbose', with: { append_configure: '--enable-mkmf-verbose' } }
|
||||||
- { uses: './.github/actions/compilers', name: 'disable-rubygems', with: { append_configure: '--disable-rubygems' } }
|
- { uses: './.github/actions/compilers', name: 'disable-rubygems', with: { append_configure: '--disable-rubygems' } }
|
||||||
|
@ -479,6 +479,19 @@ class TestZJIT < Test::Unit::TestCase
|
|||||||
}, call_threshold: 5, num_profiles: 3
|
}, call_threshold: 5, num_profiles: 3
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# tool/ruby_vm/views/*.erb relies on the zjit instructions a) being contiguous and
|
||||||
|
# b) being reliably ordered after all the other instructions.
|
||||||
|
def test_instruction_order
|
||||||
|
insn_names = RubyVM::INSTRUCTION_NAMES
|
||||||
|
zjit, others = insn_names.map.with_index.partition { |name, _| name.start_with?('zjit_') }
|
||||||
|
zjit_indexes = zjit.map(&:last)
|
||||||
|
other_indexes = others.map(&:last)
|
||||||
|
zjit_indexes.product(other_indexes).each do |zjit_index, other_index|
|
||||||
|
assert zjit_index > other_index, "'#{insn_names[zjit_index]}' at #{zjit_index} "\
|
||||||
|
"must be defined after '#{insn_names[other_index]}' at #{other_index}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# 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
|
||||||
|
@ -6,6 +6,16 @@
|
|||||||
%# conditions mentioned in the file COPYING are met. Consult the file for
|
%# conditions mentioned in the file COPYING are met. Consult the file for
|
||||||
%# details.
|
%# details.
|
||||||
%#
|
%#
|
||||||
|
%
|
||||||
|
% stack_increase = proc do |i|
|
||||||
|
% if i.has_attribute?('sp_inc')
|
||||||
|
% '-127'
|
||||||
|
% else
|
||||||
|
% sprintf("%4d", i.rets.size - i.pops.size)
|
||||||
|
% end
|
||||||
|
% end
|
||||||
|
% zjit_insns, insns = RubyVM::Instructions.partition { |i| i.name.start_with?('zjit_') }
|
||||||
|
%
|
||||||
PUREFUNC(MAYBE_UNUSED(static int comptime_insn_stack_increase(int depth, int insn, const VALUE *opes)));
|
PUREFUNC(MAYBE_UNUSED(static int comptime_insn_stack_increase(int depth, int insn, const VALUE *opes)));
|
||||||
PUREFUNC(static rb_snum_t comptime_insn_stack_increase_dispatch(enum ruby_vminsn_type insn, const VALUE *opes));
|
PUREFUNC(static rb_snum_t comptime_insn_stack_increase_dispatch(enum ruby_vminsn_type insn, const VALUE *opes));
|
||||||
|
|
||||||
@ -13,15 +23,14 @@ rb_snum_t
|
|||||||
comptime_insn_stack_increase_dispatch(enum ruby_vminsn_type insn, const VALUE *opes)
|
comptime_insn_stack_increase_dispatch(enum ruby_vminsn_type insn, const VALUE *opes)
|
||||||
{
|
{
|
||||||
static const signed char t[] = {
|
static const signed char t[] = {
|
||||||
% RubyVM::Instructions.each_slice 8 do |a|
|
% insns.each_slice(8) do |row|
|
||||||
<%= a.map { |i|
|
<%= row.map(&stack_increase).join(', ') -%>,
|
||||||
if i.has_attribute?('sp_inc')
|
|
||||||
'-127'
|
|
||||||
else
|
|
||||||
sprintf("%4d", i.rets.size - i.pops.size)
|
|
||||||
end
|
|
||||||
}.join(', ') -%>,
|
|
||||||
% end
|
% end
|
||||||
|
#if USE_ZJIT
|
||||||
|
% zjit_insns.each_slice(8) do |row|
|
||||||
|
<%= row.map(&stack_increase).join(', ') -%>,
|
||||||
|
% end
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
signed char c = t[insn];
|
signed char c = t[insn];
|
||||||
|
|
||||||
|
@ -5,6 +5,9 @@
|
|||||||
%# granted, to either redistribute and/or modify this file, provided that the
|
%# granted, to either redistribute and/or modify this file, provided that the
|
||||||
%# conditions mentioned in the file COPYING are met. Consult the file for
|
%# conditions mentioned in the file COPYING are met. Consult the file for
|
||||||
%# details.
|
%# details.
|
||||||
|
%
|
||||||
|
% zjit_insns, insns = RubyVM::Instructions.partition { |i| i.name.start_with?('zjit_') }
|
||||||
|
%
|
||||||
CONSTFUNC(MAYBE_UNUSED(static int insn_len(VALUE insn)));
|
CONSTFUNC(MAYBE_UNUSED(static int insn_len(VALUE insn)));
|
||||||
|
|
||||||
RUBY_SYMBOL_EXPORT_BEGIN /* for debuggers */
|
RUBY_SYMBOL_EXPORT_BEGIN /* for debuggers */
|
||||||
@ -13,9 +16,14 @@ RUBY_SYMBOL_EXPORT_END
|
|||||||
|
|
||||||
#ifdef RUBY_VM_INSNS_INFO
|
#ifdef RUBY_VM_INSNS_INFO
|
||||||
const uint8_t rb_vm_insn_len_info[] = {
|
const uint8_t rb_vm_insn_len_info[] = {
|
||||||
% RubyVM::Instructions.each_slice 23 do |a|
|
% insns.each_slice(23) do |row|
|
||||||
<%= a.map(&:width).join(', ') -%>,
|
<%= row.map(&:width).join(', ') -%>,
|
||||||
% end
|
% end
|
||||||
|
#if USE_ZJIT
|
||||||
|
% zjit_insns.each_slice(23) do |row|
|
||||||
|
<%= row.map(&:width).join(', ') -%>,
|
||||||
|
% end
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
ASSERT_VM_INSTRUCTION_SIZE(rb_vm_insn_len_info);
|
ASSERT_VM_INSTRUCTION_SIZE(rb_vm_insn_len_info);
|
||||||
|
@ -6,10 +6,14 @@
|
|||||||
%# conditions mentioned in the file COPYING are met. Consult the file for
|
%# conditions mentioned in the file COPYING are met. Consult the file for
|
||||||
%# details.
|
%# details.
|
||||||
%
|
%
|
||||||
% a = RubyVM::Instructions.map {|i| i.name }
|
% zjit_insns, insns = RubyVM::Instructions.partition { |i| i.name.start_with?('zjit_') }
|
||||||
% b = (0...a.size)
|
%
|
||||||
% c = a.inject([0]) {|r, i| r << (r[-1] + i.length + 1) }
|
% next_offset = 0
|
||||||
% c.pop
|
% name_offset = proc do |i|
|
||||||
|
% offset = sprintf("%4d", next_offset)
|
||||||
|
% next_offset += i.name.length + 1 # insn.name + \0
|
||||||
|
% offset
|
||||||
|
% end
|
||||||
%
|
%
|
||||||
CONSTFUNC(MAYBE_UNUSED(static const char *insn_name(VALUE insn)));
|
CONSTFUNC(MAYBE_UNUSED(static const char *insn_name(VALUE insn)));
|
||||||
|
|
||||||
@ -20,18 +24,28 @@ extern const unsigned short rb_vm_insn_name_offset[VM_INSTRUCTION_SIZE];
|
|||||||
RUBY_SYMBOL_EXPORT_END
|
RUBY_SYMBOL_EXPORT_END
|
||||||
|
|
||||||
#ifdef RUBY_VM_INSNS_INFO
|
#ifdef RUBY_VM_INSNS_INFO
|
||||||
const int rb_vm_max_insn_name_size = <%= a.map(&:size).max %>;
|
const int rb_vm_max_insn_name_size = <%= RubyVM::Instructions.map { |i| i.name.size }.max %>;
|
||||||
|
|
||||||
const char rb_vm_insn_name_base[] =
|
const char rb_vm_insn_name_base[] =
|
||||||
% a.each do |i|
|
% insns.each do |i|
|
||||||
<%=cstr i%> "\0"
|
<%= cstr i.name %> "\0"
|
||||||
% end
|
% end
|
||||||
|
#if USE_ZJIT
|
||||||
|
% zjit_insns.each do |i|
|
||||||
|
<%= cstr i.name %> "\0"
|
||||||
|
% end
|
||||||
|
#endif
|
||||||
;
|
;
|
||||||
|
|
||||||
const unsigned short rb_vm_insn_name_offset[] = {
|
const unsigned short rb_vm_insn_name_offset[] = {
|
||||||
% c.each_slice 12 do |d|
|
% insns.each_slice(12) do |row|
|
||||||
<%= d.map {|i| sprintf("%4d", i) }.join(', ') %>,
|
<%= row.map(&name_offset).join(', ') %>,
|
||||||
% end
|
% end
|
||||||
|
#if USE_ZJIT
|
||||||
|
% zjit_insns.each_slice(12) do |row|
|
||||||
|
<%= row.map(&name_offset).join(', ') %>,
|
||||||
|
% end
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
ASSERT_VM_INSTRUCTION_SIZE(rb_vm_insn_name_offset);
|
ASSERT_VM_INSTRUCTION_SIZE(rb_vm_insn_name_offset);
|
||||||
|
@ -6,10 +6,16 @@
|
|||||||
%# conditions mentioned in the file COPYING are met. Consult the file for
|
%# conditions mentioned in the file COPYING are met. Consult the file for
|
||||||
%# details.
|
%# details.
|
||||||
%
|
%
|
||||||
% a = RubyVM::Instructions.map {|i| i.operands_info }
|
% zjit_insns, insns = RubyVM::Instructions.partition { |i| i.name.start_with?('zjit_') }
|
||||||
% b = (0...a.size)
|
%
|
||||||
% c = a.inject([0]) {|r, i| r << (r[-1] + i.length + 1) }
|
% operands_info = proc { |i| sprintf("%-6s", cstr(i.operands_info)) }
|
||||||
% c.pop
|
%
|
||||||
|
% next_offset = 0
|
||||||
|
% op_offset = proc do |i|
|
||||||
|
% offset = sprintf("%3d", next_offset)
|
||||||
|
% next_offset += i.operands_info.length + 1 # insn.operands_info + \0
|
||||||
|
% offset
|
||||||
|
% end
|
||||||
%
|
%
|
||||||
CONSTFUNC(MAYBE_UNUSED(static const char *insn_op_types(VALUE insn)));
|
CONSTFUNC(MAYBE_UNUSED(static const char *insn_op_types(VALUE insn)));
|
||||||
CONSTFUNC(MAYBE_UNUSED(static int insn_op_type(VALUE insn, long pos)));
|
CONSTFUNC(MAYBE_UNUSED(static int insn_op_type(VALUE insn, long pos)));
|
||||||
@ -21,15 +27,25 @@ RUBY_SYMBOL_EXPORT_END
|
|||||||
|
|
||||||
#ifdef RUBY_VM_INSNS_INFO
|
#ifdef RUBY_VM_INSNS_INFO
|
||||||
const char rb_vm_insn_op_base[] =
|
const char rb_vm_insn_op_base[] =
|
||||||
% a.each_slice 5 do |d|
|
% insns.each_slice(5) do |row|
|
||||||
<%= d.map {|i| sprintf("%-6s", cstr(i)) }.join(' "\0" ') %> "\0"
|
<%= row.map(&operands_info).join(' "\0" ') %> "\0"
|
||||||
% end
|
% end
|
||||||
|
#if USE_ZJIT
|
||||||
|
% zjit_insns.each_slice(5) do |row|
|
||||||
|
<%= row.map(&operands_info).join(' "\0" ') %> "\0"
|
||||||
|
% end
|
||||||
|
#endif
|
||||||
;
|
;
|
||||||
|
|
||||||
const unsigned short rb_vm_insn_op_offset[] = {
|
const unsigned short rb_vm_insn_op_offset[] = {
|
||||||
% c.each_slice 12 do |d|
|
% insns.each_slice(12) do |row|
|
||||||
<%= d.map {|i| sprintf("%3d", i) }.join(', ') %>,
|
<%= row.map(&op_offset).join(', ') %>,
|
||||||
% end
|
% end
|
||||||
|
#if USE_ZJIT
|
||||||
|
% zjit_insns.each_slice(12) do |row|
|
||||||
|
<%= row.map(&op_offset).join(', ') %>,
|
||||||
|
% end
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
ASSERT_VM_INSTRUCTION_SIZE(rb_vm_insn_op_offset);
|
ASSERT_VM_INSTRUCTION_SIZE(rb_vm_insn_op_offset);
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#if USE_ZJIT
|
||||||
|
|
||||||
MAYBE_UNUSED(static int vm_bare_insn_to_zjit_insn(int insn));
|
MAYBE_UNUSED(static int vm_bare_insn_to_zjit_insn(int insn));
|
||||||
static int
|
static int
|
||||||
vm_bare_insn_to_zjit_insn(int insn)
|
vm_bare_insn_to_zjit_insn(int insn)
|
||||||
@ -25,3 +27,5 @@ vm_zjit_insn_to_bare_insn(int insn)
|
|||||||
return insn;
|
return insn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#if USE_ZJIT
|
||||||
|
|
||||||
/* insn <%= insn.pretty_name %> */
|
/* insn <%= insn.pretty_name %> */
|
||||||
INSN_ENTRY(<%= insn.name %>)
|
INSN_ENTRY(<%= insn.name %>)
|
||||||
{
|
{
|
||||||
@ -6,3 +8,5 @@ INSN_ENTRY(<%= insn.name %>)
|
|||||||
DISPATCH_ORIGINAL_INSN(<%= insn.jump_destination %>);
|
DISPATCH_ORIGINAL_INSN(<%= insn.jump_destination %>);
|
||||||
END_INSN(<%= insn.name %>);
|
END_INSN(<%= insn.name %>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
%# granted, to either redistribute and/or modify this file, provided that the
|
%# granted, to either redistribute and/or modify this file, provided that the
|
||||||
%# conditions mentioned in the file COPYING are met. Consult the file for
|
%# conditions mentioned in the file COPYING are met. Consult the file for
|
||||||
%# details.
|
%# details.
|
||||||
|
%
|
||||||
|
% zjit_insns, insns = RubyVM::Instructions.partition { |i| i.name.start_with?('zjit_') }
|
||||||
|
%
|
||||||
<%= render 'copyright' %>
|
<%= render 'copyright' %>
|
||||||
<%= render 'notice', locals: {
|
<%= render 'notice', locals: {
|
||||||
this_file: 'contains YARV instruction list',
|
this_file: 'contains YARV instruction list',
|
||||||
@ -19,9 +22,14 @@
|
|||||||
#define BIN(n) YARVINSN_##n
|
#define BIN(n) YARVINSN_##n
|
||||||
|
|
||||||
enum ruby_vminsn_type {
|
enum ruby_vminsn_type {
|
||||||
% RubyVM::Instructions.each do |i|
|
% insns.each do |i|
|
||||||
<%= i.bin %>,
|
<%= i.bin %>,
|
||||||
% end
|
% end
|
||||||
|
#if USE_ZJIT
|
||||||
|
% zjit_insns.each do |i|
|
||||||
|
<%= i.bin %>,
|
||||||
|
% end
|
||||||
|
#endif
|
||||||
VM_INSTRUCTION_SIZE
|
VM_INSTRUCTION_SIZE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
%# conditions mentioned in the file COPYING are met. Consult the file for
|
%# conditions mentioned in the file COPYING are met. Consult the file for
|
||||||
%# details.
|
%# details.
|
||||||
% raise ':FIXME:TBW' if RubyVM::VmOptsH['INSTRUCTIONS_UNIFICATION']
|
% raise ':FIXME:TBW' if RubyVM::VmOptsH['INSTRUCTIONS_UNIFICATION']
|
||||||
% n = RubyVM::Instructions.size
|
|
||||||
<%= render 'copyright' %>
|
<%= render 'copyright' %>
|
||||||
<%= render 'notice', locals: {
|
<%= render 'notice', locals: {
|
||||||
this_file: 'is for threaded code',
|
this_file: 'is for threaded code',
|
||||||
@ -16,6 +15,4 @@
|
|||||||
|
|
||||||
/* Let .bss section automatically initialize this variable */
|
/* Let .bss section automatically initialize this variable */
|
||||||
/* cf. Section 6.7.8 of ISO/IEC 9899:1999 */
|
/* cf. Section 6.7.8 of ISO/IEC 9899:1999 */
|
||||||
static const int *const *const unified_insns_data[<%= n %>];
|
static const int *const *const unified_insns_data[VM_INSTRUCTION_SIZE];
|
||||||
|
|
||||||
ASSERT_VM_INSTRUCTION_SIZE(unified_insns_data);
|
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
%# granted, to either redistribute and/or modify this file, provided that the
|
%# granted, to either redistribute and/or modify this file, provided that the
|
||||||
%# conditions mentioned in the file COPYING are met. Consult the file for
|
%# conditions mentioned in the file COPYING are met. Consult the file for
|
||||||
%# details.
|
%# details.
|
||||||
|
%
|
||||||
|
% zjit_insns, insns = RubyVM::Instructions.partition { |i| i.name.start_with?('zjit_') }
|
||||||
|
%
|
||||||
<%= render 'copyright' -%>
|
<%= render 'copyright' -%>
|
||||||
<%= render 'notice', locals: {
|
<%= render 'notice', locals: {
|
||||||
this_file: 'is for threaded code',
|
this_file: 'is for threaded code',
|
||||||
@ -13,9 +16,14 @@
|
|||||||
} -%>
|
} -%>
|
||||||
|
|
||||||
static const void *const insns_address_table[] = {
|
static const void *const insns_address_table[] = {
|
||||||
% RubyVM::Instructions.each do |i|
|
% insns.each do |i|
|
||||||
LABEL_PTR(<%= i.name %>),
|
LABEL_PTR(<%= i.name %>),
|
||||||
% end
|
% end
|
||||||
|
#if USE_ZJIT
|
||||||
|
% zjit_insns.each do |i|
|
||||||
|
LABEL_PTR(<%= i.name %>),
|
||||||
|
% end
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
ASSERT_VM_INSTRUCTION_SIZE(insns_address_table);
|
ASSERT_VM_INSTRUCTION_SIZE(insns_address_table);
|
||||||
|
14
yjit/src/cruby_bindings.inc.rs
generated
14
yjit/src/cruby_bindings.inc.rs
generated
@ -949,19 +949,7 @@ pub const YARVINSN_trace_setlocal_WC_0: ruby_vminsn_type = 218;
|
|||||||
pub const YARVINSN_trace_setlocal_WC_1: ruby_vminsn_type = 219;
|
pub const YARVINSN_trace_setlocal_WC_1: ruby_vminsn_type = 219;
|
||||||
pub const YARVINSN_trace_putobject_INT2FIX_0_: ruby_vminsn_type = 220;
|
pub const YARVINSN_trace_putobject_INT2FIX_0_: ruby_vminsn_type = 220;
|
||||||
pub const YARVINSN_trace_putobject_INT2FIX_1_: ruby_vminsn_type = 221;
|
pub const YARVINSN_trace_putobject_INT2FIX_1_: ruby_vminsn_type = 221;
|
||||||
pub const YARVINSN_zjit_opt_send_without_block: ruby_vminsn_type = 222;
|
pub const VM_INSTRUCTION_SIZE: ruby_vminsn_type = 222;
|
||||||
pub const YARVINSN_zjit_opt_plus: ruby_vminsn_type = 223;
|
|
||||||
pub const YARVINSN_zjit_opt_minus: ruby_vminsn_type = 224;
|
|
||||||
pub const YARVINSN_zjit_opt_mult: ruby_vminsn_type = 225;
|
|
||||||
pub const YARVINSN_zjit_opt_div: ruby_vminsn_type = 226;
|
|
||||||
pub const YARVINSN_zjit_opt_mod: ruby_vminsn_type = 227;
|
|
||||||
pub const YARVINSN_zjit_opt_eq: ruby_vminsn_type = 228;
|
|
||||||
pub const YARVINSN_zjit_opt_neq: ruby_vminsn_type = 229;
|
|
||||||
pub const YARVINSN_zjit_opt_lt: ruby_vminsn_type = 230;
|
|
||||||
pub const YARVINSN_zjit_opt_le: ruby_vminsn_type = 231;
|
|
||||||
pub const YARVINSN_zjit_opt_gt: ruby_vminsn_type = 232;
|
|
||||||
pub const YARVINSN_zjit_opt_ge: ruby_vminsn_type = 233;
|
|
||||||
pub const VM_INSTRUCTION_SIZE: ruby_vminsn_type = 234;
|
|
||||||
pub type ruby_vminsn_type = u32;
|
pub type ruby_vminsn_type = u32;
|
||||||
pub type rb_iseq_callback = ::std::option::Option<
|
pub type rb_iseq_callback = ::std::option::Option<
|
||||||
unsafe extern "C" fn(arg1: *const rb_iseq_t, arg2: *mut ::std::os::raw::c_void),
|
unsafe extern "C" fn(arg1: *const rb_iseq_t, arg2: *mut ::std::os::raw::c_void),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user