From 0a5b4c13ad16bacfa5659f7ac92eb7abf9416261 Mon Sep 17 00:00:00 2001 From: shyouhei Date: Fri, 25 Jan 2019 14:09:10 +0000 Subject: [PATCH] vm.inc now in C99 This changeset modifies the VM generator so that vm.inc is written in C99. Also added some comments in _insn_entry.erb so that the intention of each parts to be made more clear. I think this improves overall readability of the generated VM. Confirmed that the exact same binary is generated before/after this changeset. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66923 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- tool/ruby_vm/helpers/dumper.rb | 4 +- tool/ruby_vm/models/bare_instructions.rb | 8 ++++ tool/ruby_vm/models/operands_unifications.rb | 9 +++- tool/ruby_vm/views/_insn_entry.erb | 48 +++++++++++++------- tool/ruby_vm/views/_mjit_compile_insn.erb | 2 +- vm_insnhelper.h | 1 + 6 files changed, 50 insertions(+), 22 deletions(-) diff --git a/tool/ruby_vm/helpers/dumper.rb b/tool/ruby_vm/helpers/dumper.rb index c0a45b19e2..00c301c01c 100644 --- a/tool/ruby_vm/helpers/dumper.rb +++ b/tool/ruby_vm/helpers/dumper.rb @@ -49,8 +49,8 @@ class RubyVM::Dumper end def replace_pragma_line str, lineno - if str == "#pragma RubyVM reset source\n" then - return "#line #{lineno + 2} #{@file}\n" + if /#(\s*)pragma RubyVM reset source\n/ =~ str then + return "##{$1}line #{lineno + 2} #{@file}\n" else return str end diff --git a/tool/ruby_vm/models/bare_instructions.rb b/tool/ruby_vm/models/bare_instructions.rb index 302c375589..e0fac5ff91 100755 --- a/tool/ruby_vm/models/bare_instructions.rb +++ b/tool/ruby_vm/models/bare_instructions.rb @@ -131,6 +131,14 @@ class RubyVM::BareInstructions sprintf "#<%s %s@%s:%d>", self.class.name, @name, @loc[0], @loc[1] end + def has_ope? var + return @opes.any? {|i| i[:name] == var[:name] } + end + + def has_pop? var + return @pops.any? {|i| i[:name] == var[:name] } + end + private def generate_attribute t, k, v diff --git a/tool/ruby_vm/models/operands_unifications.rb b/tool/ruby_vm/models/operands_unifications.rb index 1bc1a2a153..ee4e3a695d 100644 --- a/tool/ruby_vm/models/operands_unifications.rb +++ b/tool/ruby_vm/models/operands_unifications.rb @@ -31,7 +31,8 @@ class RubyVM::OperandsUnifications < RubyVM::BareInstructions @preamble = parts[:preamble] @spec = parts[:spec] super json.merge(:template => template) - parts[:vars].each do |v| + @konsts = parts[:vars] + @konsts.each do |v| @variables[v[:name]] ||= v end end @@ -63,6 +64,10 @@ class RubyVM::OperandsUnifications < RubyVM::BareInstructions end end + def has_ope? var + super or @konsts.any? {|i| i[:name] == var[:name] } + end + private def namegen signature @@ -101,7 +106,7 @@ class RubyVM::OperandsUnifications < RubyVM::BareInstructions vars << k src << { location: location, - expr: " #{k[:name]} = #{j};" + expr: " const #{k[:decl]} = #{j};" } end end diff --git a/tool/ruby_vm/views/_insn_entry.erb b/tool/ruby_vm/views/_insn_entry.erb index b790729611..cdadd93abc 100644 --- a/tool/ruby_vm/views/_insn_entry.erb +++ b/tool/ruby_vm/views/_insn_entry.erb @@ -6,32 +6,36 @@ %# conditions mentioned in the file COPYING are met. Consult the file for %# details. %; +% body = render_c_expr(insn.expr).gsub(/^#/, '# ') /* insn <%= insn.pretty_name %> */ INSN_ENTRY(<%= insn.name %>) { -%# NAME_OF_CURRENT_INSN is used in vm_exec.h -# define NAME_OF_CURRENT_INSN <%= insn.name %> -# define INSN_ATTR(x) <%= insn.call_attribute(' ## x ## ') %> - bool leaf; - MAYBE_UNUSED(VALUE *) canary; -% unless insn.declarations.empty? - <%= insn.declarations.join(";\n ") %>; - -% end + /* ### Declare that we have just entered into an instruction. ### */ START_OF_ORIGINAL_INSN(<%= insn.name %>); + DEBUG_ENTER_INSN(<%=cstr insn.name %>); + + /* ### Declare and assign variables. ### */ % insn.preamble.each do |konst| <%= render_c_expr konst -%> % end +% % insn.opes.each_with_index do |ope, i| - <%= ope[:name] %> = (<%= ope[:type] %>)GET_OPERAND(<%= i + 1 %>); + <%= ope[:decl] %> = (<%= ope[:type] %>)GET_OPERAND(<%= i + 1 %>); +% end +# define INSN_ATTR(x) <%= insn.call_attribute(' ## x ## ') %> + bool leaf = INSN_ATTR(leaf); +% insn.pops.reverse_each.with_index.reverse_each do |pop, i| + <%= pop[:decl] %> = <%= insn.cast_from_VALUE pop, "TOPN(#{i})"%>; % end % -% insn.pops.reverse_each.with_index.reverse_each do |pop, i| - <%= pop[:name] %> = <%= insn.cast_from_VALUE pop, "TOPN(#{i})"%>; +% insn.rets.each do |ret| +% next if insn.has_ope?(ret) or insn.has_pop?(ret) + <%= ret[:decl] %>; % end - DEBUG_ENTER_INSN(INSN_ATTR(name)); - if (! (leaf = INSN_ATTR(leaf))) ADD_PC(INSN_ATTR(width)); + + /* ### Instruction preambles. ### */ + if (! leaf) ADD_PC(INSN_ATTR(width)); % if insn.handles_sp? POPN(INSN_ATTR(popn)); % end @@ -40,7 +44,16 @@ INSN_ENTRY(<%= insn.name %>) % insn.opes.each_with_index do |ope, i| COLLECT_USAGE_OPERAND(INSN_ATTR(bin), <%= i %>, <%= ope[:name] %>); % end -<%= render_c_expr insn.expr -%> +% unless body.empty? + + /* ### Here we do the instruction body. ### */ +%# NAME_OF_CURRENT_INSN is used in vm_exec.h +# define NAME_OF_CURRENT_INSN <%= insn.name %> +<%= body -%> +# undef NAME_OF_CURRENT_INSN +% end + + /* ### Instruction trailers. ### */ CHECK_VM_STACK_OVERFLOW_FOR_INSN(VM_REG_CFP, INSN_ATTR(retn)); <%= insn.handle_canary "CHECK_CANARY()" -%> % if insn.handles_sp? @@ -54,7 +67,8 @@ INSN_ENTRY(<%= insn.name %>) % end % end if (leaf) ADD_PC(INSN_ATTR(width)); - END_INSN(<%= insn.name %>); # undef INSN_ATTR -# undef NAME_OF_CURRENT_INSN + + /* ### Leave the instruction. ### */ + END_INSN(<%= insn.name %>); } diff --git a/tool/ruby_vm/views/_mjit_compile_insn.erb b/tool/ruby_vm/views/_mjit_compile_insn.erb index 26c011ecd5..dc6f45f433 100644 --- a/tool/ruby_vm/views/_mjit_compile_insn.erb +++ b/tool/ruby_vm/views/_mjit_compile_insn.erb @@ -25,7 +25,7 @@ % # JIT: Set const expressions for `RubyVM::OperandsUnifications` insn % insn.preamble.each do |amble| - fprintf(f, "<%= amble.expr %>\n"); + fprintf(f, "<%= amble.expr.sub(/const \S+\s+/, '') %>\n"); % end % % # JIT: Initialize operands diff --git a/vm_insnhelper.h b/vm_insnhelper.h index 7541b02276..b96c794d4f 100644 --- a/vm_insnhelper.h +++ b/vm_insnhelper.h @@ -137,6 +137,7 @@ enum vm_regan_acttype { #if VM_CHECK_MODE > 0 #define SETUP_CANARY() \ + VALUE * canary; \ if (leaf) { \ canary = GET_SP(); \ SET_SV(vm_stack_canary); \