summaryrefslogtreecommitdiff
path: root/tool/ruby_vm/views
diff options
context:
space:
mode:
Diffstat (limited to 'tool/ruby_vm/views')
-rw-r--r--tool/ruby_vm/views/_comptime_insn_stack_increase.erb25
-rw-r--r--tool/ruby_vm/views/_insn_leaf_info.erb18
-rw-r--r--tool/ruby_vm/views/_insn_len_info.erb12
-rw-r--r--tool/ruby_vm/views/_insn_name_info.erb33
-rw-r--r--tool/ruby_vm/views/_insn_operand_info.erb32
-rw-r--r--tool/ruby_vm/views/_leaf_helpers.erb6
-rw-r--r--tool/ruby_vm/views/_zjit_helpers.erb31
-rw-r--r--tool/ruby_vm/views/_zjit_instruction.erb12
-rw-r--r--tool/ruby_vm/views/insns.inc.erb17
-rw-r--r--tool/ruby_vm/views/insns_info.inc.erb5
-rw-r--r--tool/ruby_vm/views/lib/ruby_vm/rjit/instruction.rb.erb14
-rw-r--r--tool/ruby_vm/views/optinsn.inc.erb4
-rw-r--r--tool/ruby_vm/views/optunifs.inc.erb5
-rw-r--r--tool/ruby_vm/views/vm.inc.erb12
-rw-r--r--tool/ruby_vm/views/vmtc.inc.erb10
15 files changed, 192 insertions, 44 deletions
diff --git a/tool/ruby_vm/views/_comptime_insn_stack_increase.erb b/tool/ruby_vm/views/_comptime_insn_stack_increase.erb
index cb895815ce..8bb28db1c1 100644
--- a/tool/ruby_vm/views/_comptime_insn_stack_increase.erb
+++ b/tool/ruby_vm/views/_comptime_insn_stack_increase.erb
@@ -6,6 +6,16 @@
%# conditions mentioned in the file COPYING are met. Consult the file for
%# 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(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)
{
static const signed char t[] = {
-% RubyVM::Instructions.each_slice 8 do |a|
- <%= a.map { |i|
- if i.has_attribute?('sp_inc')
- '-127'
- else
- sprintf("%4d", i.rets.size - i.pops.size)
- end
- }.join(', ') -%>,
+% insns.each_slice(8) do |row|
+ <%= row.map(&stack_increase).join(', ') -%>,
+% end
+#if USE_ZJIT
+% zjit_insns.each_slice(8) do |row|
+ <%= row.map(&stack_increase).join(', ') -%>,
% end
+#endif
};
signed char c = t[insn];
diff --git a/tool/ruby_vm/views/_insn_leaf_info.erb b/tool/ruby_vm/views/_insn_leaf_info.erb
new file mode 100644
index 0000000000..f30366ffda
--- /dev/null
+++ b/tool/ruby_vm/views/_insn_leaf_info.erb
@@ -0,0 +1,18 @@
+MAYBE_UNUSED(static bool insn_leaf(int insn, const VALUE *opes));
+static bool
+insn_leaf(int insn, const VALUE *opes)
+{
+ switch (insn) {
+% RubyVM::Instructions.each do |insn|
+% next if insn.is_a?(RubyVM::TraceInstruction) || insn.is_a?(RubyVM::ZJITInstruction)
+ case <%= insn.bin %>:
+ return attr_leaf_<%= insn.name %>(<%=
+ insn.operands.map.with_index do |ope, i|
+ "(#{ope[:type]})opes[#{i}]"
+ end.join(', ')
+ %>);
+% end
+ default:
+ return false;
+ }
+}
diff --git a/tool/ruby_vm/views/_insn_len_info.erb b/tool/ruby_vm/views/_insn_len_info.erb
index 569dca5845..b29a405918 100644
--- a/tool/ruby_vm/views/_insn_len_info.erb
+++ b/tool/ruby_vm/views/_insn_len_info.erb
@@ -5,6 +5,9 @@
%# granted, to either redistribute and/or modify this file, provided that the
%# conditions mentioned in the file COPYING are met. Consult the file for
%# details.
+%
+% zjit_insns, insns = RubyVM::Instructions.partition { |i| i.name.start_with?('zjit_') }
+%
CONSTFUNC(MAYBE_UNUSED(static int insn_len(VALUE insn)));
RUBY_SYMBOL_EXPORT_BEGIN /* for debuggers */
@@ -13,9 +16,14 @@ RUBY_SYMBOL_EXPORT_END
#ifdef RUBY_VM_INSNS_INFO
const uint8_t rb_vm_insn_len_info[] = {
-% RubyVM::Instructions.each_slice 23 do |a|
- <%= a.map(&:width).join(', ') -%>,
+% insns.each_slice(23) do |row|
+ <%= row.map(&:width).join(', ') -%>,
% 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);
diff --git a/tool/ruby_vm/views/_insn_name_info.erb b/tool/ruby_vm/views/_insn_name_info.erb
index e7ded75e65..2862908631 100644
--- a/tool/ruby_vm/views/_insn_name_info.erb
+++ b/tool/ruby_vm/views/_insn_name_info.erb
@@ -6,10 +6,14 @@
%# conditions mentioned in the file COPYING are met. Consult the file for
%# details.
%
-% a = RubyVM::Instructions.map {|i| i.name }
-% b = (0...a.size)
-% c = a.inject([0]) {|r, i| r << (r[-1] + i.length + 1) }
-% c.pop
+% zjit_insns, insns = RubyVM::Instructions.partition { |i| i.name.start_with?('zjit_') }
+%
+% next_offset = 0
+% 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)));
@@ -20,18 +24,29 @@ extern const unsigned short rb_vm_insn_name_offset[VM_INSTRUCTION_SIZE];
RUBY_SYMBOL_EXPORT_END
#ifdef RUBY_VM_INSNS_INFO
-const int rb_vm_max_insn_name_size = <%= a.map(&:size).max %>;
+%# "trace_" is longer than "zjit_", so USE_ZJIT doesn't impact the max name size.
+const int rb_vm_max_insn_name_size = <%= RubyVM::Instructions.map { |i| i.name.size }.max %>;
const char rb_vm_insn_name_base[] =
-% a.each do |i|
- <%=cstr i%> "\0"
+% insns.each do |i|
+ <%= cstr i.name %> "\0"
+% end
+#if USE_ZJIT
+% zjit_insns.each do |i|
+ <%= cstr i.name %> "\0"
% end
+#endif
;
const unsigned short rb_vm_insn_name_offset[] = {
-% c.each_slice 12 do |d|
- <%= d.map {|i| sprintf("%4d", i) }.join(', ') %>,
+% insns.each_slice(12) do |row|
+ <%= row.map(&name_offset).join(', ') %>,
+% 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);
diff --git a/tool/ruby_vm/views/_insn_operand_info.erb b/tool/ruby_vm/views/_insn_operand_info.erb
index 996c33e960..410869fcd3 100644
--- a/tool/ruby_vm/views/_insn_operand_info.erb
+++ b/tool/ruby_vm/views/_insn_operand_info.erb
@@ -6,10 +6,16 @@
%# conditions mentioned in the file COPYING are met. Consult the file for
%# details.
%
-% a = RubyVM::Instructions.map {|i| i.operands_info }
-% b = (0...a.size)
-% c = a.inject([0]) {|r, i| r << (r[-1] + i.length + 1) }
-% c.pop
+% zjit_insns, insns = RubyVM::Instructions.partition { |i| i.name.start_with?('zjit_') }
+%
+% operands_info = proc { |i| sprintf("%-6s", cstr(i.operands_info)) }
+%
+% 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 int insn_op_type(VALUE insn, long pos)));
@@ -21,15 +27,25 @@ RUBY_SYMBOL_EXPORT_END
#ifdef RUBY_VM_INSNS_INFO
const char rb_vm_insn_op_base[] =
-% a.each_slice 5 do |d|
- <%= d.map {|i| sprintf("%-6s", cstr(i)) }.join(' "\0" ') %> "\0"
+% insns.each_slice(5) do |row|
+ <%= row.map(&operands_info).join(' "\0" ') %> "\0"
+% 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[] = {
-% c.each_slice 12 do |d|
- <%= d.map {|i| sprintf("%3d", i) }.join(', ') %>,
+% insns.each_slice(12) do |row|
+ <%= row.map(&op_offset).join(', ') %>,
+% 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);
diff --git a/tool/ruby_vm/views/_leaf_helpers.erb b/tool/ruby_vm/views/_leaf_helpers.erb
index 6dae554a51..2756fa2dec 100644
--- a/tool/ruby_vm/views/_leaf_helpers.erb
+++ b/tool/ruby_vm/views/_leaf_helpers.erb
@@ -10,10 +10,6 @@
#include "iseq.h"
-// This is used to tell JIT that this insn would be leaf if CHECK_INTS didn't exist.
-// It should be used only when RUBY_VM_CHECK_INTS is directly written in insns.def.
-static bool leafness_of_check_ints = false;
-
static bool
leafness_of_defined(rb_num_t op_type)
{
@@ -25,7 +21,7 @@ leafness_of_defined(rb_num_t op_type)
case DEFINED_YIELD:
case DEFINED_REF:
case DEFINED_ZSUPER:
- return false;
+ return true;
case DEFINED_CONST:
case DEFINED_CONST_FROM:
/* has rb_autoload_load(); */
diff --git a/tool/ruby_vm/views/_zjit_helpers.erb b/tool/ruby_vm/views/_zjit_helpers.erb
new file mode 100644
index 0000000000..1185dbd9d8
--- /dev/null
+++ b/tool/ruby_vm/views/_zjit_helpers.erb
@@ -0,0 +1,31 @@
+#if USE_ZJIT
+
+MAYBE_UNUSED(static int vm_bare_insn_to_zjit_insn(int insn));
+static int
+vm_bare_insn_to_zjit_insn(int insn)
+{
+ switch (insn) {
+% RubyVM::ZJITInstruction.all.each do |insn|
+ case BIN(<%= insn.jump_destination %>):
+ return <%= insn.bin %>;
+% end
+ default:
+ return insn;
+ }
+}
+
+MAYBE_UNUSED(static int vm_zjit_insn_to_bare_insn(int insn));
+static int
+vm_zjit_insn_to_bare_insn(int insn)
+{
+ switch (insn) {
+% RubyVM::ZJITInstruction.all.each do |insn|
+ case <%= insn.bin %>:
+ return BIN(<%= insn.jump_destination %>);
+% end
+ default:
+ return insn;
+ }
+}
+
+#endif
diff --git a/tool/ruby_vm/views/_zjit_instruction.erb b/tool/ruby_vm/views/_zjit_instruction.erb
new file mode 100644
index 0000000000..7fd657697c
--- /dev/null
+++ b/tool/ruby_vm/views/_zjit_instruction.erb
@@ -0,0 +1,12 @@
+#if USE_ZJIT
+
+/* insn <%= insn.pretty_name %> */
+INSN_ENTRY(<%= insn.name %>)
+{
+ START_OF_ORIGINAL_INSN(<%= insn.name %>);
+ rb_zjit_profile_insn(BIN(<%= insn.jump_destination %>), ec);
+ DISPATCH_ORIGINAL_INSN(<%= insn.jump_destination %>);
+ END_INSN(<%= insn.name %>);
+}
+
+#endif
diff --git a/tool/ruby_vm/views/insns.inc.erb b/tool/ruby_vm/views/insns.inc.erb
index 29981a8a2d..6521a89b8a 100644
--- a/tool/ruby_vm/views/insns.inc.erb
+++ b/tool/ruby_vm/views/insns.inc.erb
@@ -6,21 +6,36 @@
%# granted, to either redistribute and/or modify this file, provided that the
%# conditions mentioned in the file COPYING are met. Consult the file for
%# details.
+%
+% zjit_insns, insns = RubyVM::Instructions.partition { |i| i.name.start_with?('zjit_') }
+%
<%= render 'copyright' %>
<%= render 'notice', locals: {
this_file: 'contains YARV instruction list',
edit: __FILE__,
} -%>
+#ifndef INSNS_INC
+#define INSNS_INC 1
+
/* BIN : Basic Instruction Name */
#define BIN(n) YARVINSN_##n
enum ruby_vminsn_type {
-% RubyVM::Instructions.each do |i|
+% insns.each do |i|
+ <%= i.bin %>,
+% end
+#if USE_ZJIT
+% zjit_insns.each do |i|
<%= i.bin %>,
% end
+#endif
VM_INSTRUCTION_SIZE
};
+#define VM_BARE_INSTRUCTION_SIZE <%= RubyVM::Instructions.count { |i| i.name !~ /\A(trace|zjit)_/ } %>
+
#define ASSERT_VM_INSTRUCTION_SIZE(array) \
STATIC_ASSERT(numberof_##array, numberof(array) == VM_INSTRUCTION_SIZE)
+
+#endif
diff --git a/tool/ruby_vm/views/insns_info.inc.erb b/tool/ruby_vm/views/insns_info.inc.erb
index 110d9dfae5..48dd0e8832 100644
--- a/tool/ruby_vm/views/insns_info.inc.erb
+++ b/tool/ruby_vm/views/insns_info.inc.erb
@@ -11,11 +11,16 @@
this_file: 'contains instruction information for yarv instruction sequence.',
edit: __FILE__,
} %>
+#ifndef INSNS_INFO_INC
+#define INSNS_INFO_INC 1
<%= render 'insn_type_chars' %>
<%= render 'insn_name_info' %>
<%= render 'insn_len_info' %>
<%= render 'insn_operand_info' %>
<%= render 'leaf_helpers' %>
<%= render 'sp_inc_helpers' %>
+<%= render 'zjit_helpers' %>
<%= render 'attributes' %>
+<%= render 'insn_leaf_info' %>
<%= render 'comptime_insn_stack_increase' %>
+#endif
diff --git a/tool/ruby_vm/views/lib/ruby_vm/rjit/instruction.rb.erb b/tool/ruby_vm/views/lib/ruby_vm/rjit/instruction.rb.erb
new file mode 100644
index 0000000000..793528af5d
--- /dev/null
+++ b/tool/ruby_vm/views/lib/ruby_vm/rjit/instruction.rb.erb
@@ -0,0 +1,14 @@
+module RubyVM::RJIT # :nodoc: all
+ Instruction = Data.define(:name, :bin, :len, :operands)
+
+ INSNS = {
+% RubyVM::Instructions.each_with_index do |insn, i|
+ <%= i %> => Instruction.new(
+ name: :<%= insn.name %>,
+ bin: <%= i %>, # BIN(<%= insn.name %>)
+ len: <%= insn.width %>, # insn_len
+ operands: <%= (insn.operands unless insn.name.start_with?(/trace_|zjit_/)).inspect %>,
+ ),
+% end
+ }
+end
diff --git a/tool/ruby_vm/views/optinsn.inc.erb b/tool/ruby_vm/views/optinsn.inc.erb
index de7bb210ea..9d9cf0a43a 100644
--- a/tool/ruby_vm/views/optinsn.inc.erb
+++ b/tool/ruby_vm/views/optinsn.inc.erb
@@ -23,7 +23,7 @@ insn_operands_unification(INSN *iobj)
/* do nothing */;
break;
-% RubyVM::OperandsUnifications.each_group do |orig, unifs|
+% RubyVM::OperandsUnification.each_group do |orig, unifs|
case <%= orig.bin %>:
% unifs.each do |insn|
@@ -56,7 +56,7 @@ rb_insn_unified_local_var_level(VALUE insn)
switch (insn) {
default:
return -1; /* do nothing */;
-% RubyVM::OperandsUnifications.each_group do |orig, unifs|
+% RubyVM::OperandsUnification.each_group do |orig, unifs|
% unifs.each do|insn|
case <%= insn.bin %>:
% insn.spec.map{|(var,val)|val}.reject{|i| i == '*' }.each do |val|
diff --git a/tool/ruby_vm/views/optunifs.inc.erb b/tool/ruby_vm/views/optunifs.inc.erb
index e92a95beff..c096712936 100644
--- a/tool/ruby_vm/views/optunifs.inc.erb
+++ b/tool/ruby_vm/views/optunifs.inc.erb
@@ -7,7 +7,6 @@
%# conditions mentioned in the file COPYING are met. Consult the file for
%# details.
% raise ':FIXME:TBW' if RubyVM::VmOptsH['INSTRUCTIONS_UNIFICATION']
-% n = RubyVM::Instructions.size
<%= render 'copyright' %>
<%= render 'notice', locals: {
this_file: 'is for threaded code',
@@ -16,6 +15,4 @@
/* Let .bss section automatically initialize this variable */
/* cf. Section 6.7.8 of ISO/IEC 9899:1999 */
-static const int *const *const unified_insns_data[<%= n %>];
-
-ASSERT_VM_INSTRUCTION_SIZE(unified_insns_data);
+static const int *const *const unified_insns_data[VM_INSTRUCTION_SIZE];
diff --git a/tool/ruby_vm/views/vm.inc.erb b/tool/ruby_vm/views/vm.inc.erb
index c1a3faf60a..38bf5f05ae 100644
--- a/tool/ruby_vm/views/vm.inc.erb
+++ b/tool/ruby_vm/views/vm.inc.erb
@@ -13,18 +13,22 @@
} -%>
#include "vm_insnhelper.h"
-% RubyVM::BareInstructions.to_a.each do |insn|
+% RubyVM::BareInstruction.all.each do |insn|
<%= render 'insn_entry', locals: { insn: insn } -%>
% end
%
-% RubyVM::OperandsUnifications.to_a.each do |insn|
+% RubyVM::OperandsUnification.all.each do |insn|
<%= render 'insn_entry', locals: { insn: insn } -%>
% end
%
-% RubyVM::InstructionsUnifications.to_a.each do |insn|
+% RubyVM::InstructionsUnification.all.each do |insn|
<%= render 'insn_entry', locals: { insn: insn } -%>
% end
%
-% RubyVM::TraceInstructions.to_a.each do |insn|
+% RubyVM::ZJITInstruction.all.each do |insn|
+<%= render 'zjit_instruction', locals: { insn: insn } -%>
+% end
+%
+% RubyVM::TraceInstruction.all.each do |insn|
<%= render 'trace_instruction', locals: { insn: insn } -%>
% end
diff --git a/tool/ruby_vm/views/vmtc.inc.erb b/tool/ruby_vm/views/vmtc.inc.erb
index 99cbd92614..39dc8bfa6b 100644
--- a/tool/ruby_vm/views/vmtc.inc.erb
+++ b/tool/ruby_vm/views/vmtc.inc.erb
@@ -6,6 +6,9 @@
%# granted, to either redistribute and/or modify this file, provided that the
%# conditions mentioned in the file COPYING are met. Consult the file for
%# details.
+%
+% zjit_insns, insns = RubyVM::Instructions.partition { |i| i.name.start_with?('zjit_') }
+%
<%= render 'copyright' -%>
<%= render 'notice', locals: {
this_file: 'is for threaded code',
@@ -13,9 +16,14 @@
} -%>
static const void *const insns_address_table[] = {
-% RubyVM::Instructions.each do |i|
+% insns.each do |i|
LABEL_PTR(<%= i.name %>),
% end
+#if USE_ZJIT
+% zjit_insns.each do |i|
+ LABEL_PTR(<%= i.name %>),
+% end
+#endif
};
ASSERT_VM_INSTRUCTION_SIZE(insns_address_table);