From 9a8b38cacfa029aa9bbc5f1600b1ead3903a8c88 Mon Sep 17 00:00:00 2001 From: shyouhei Date: Mon, 29 Jan 2018 06:47:05 +0000 Subject: extensive use of instruction attributes Instead of using magic numbers, let us define a series of attributes and use them from the VM core. Proper function declarations makes these attributes inlined in most modern compilers. On my machine exact same binary is generated with or without this changeset. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62085 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- common.mk | 1 + tool/ruby_vm/models/bare_instructions.rb | 37 ++++++++++++++------------------ tool/ruby_vm/views/_insn_entry.erb | 21 ++++++++++-------- vm_insnhelper.c | 1 + 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/common.mk b/common.mk index c888815395..04061ab513 100644 --- a/common.mk +++ b/common.mk @@ -2798,6 +2798,7 @@ vm.$(OBJEXT): {$(VPATH)}id.h vm.$(OBJEXT): {$(VPATH)}id_table.h vm.$(OBJEXT): {$(VPATH)}insns.def vm.$(OBJEXT): {$(VPATH)}insns.inc +vm.$(OBJEXT): {$(VPATH)}insns_info.inc vm.$(OBJEXT): {$(VPATH)}intern.h vm.$(OBJEXT): {$(VPATH)}internal.h vm.$(OBJEXT): {$(VPATH)}io.h diff --git a/tool/ruby_vm/models/bare_instructions.rb b/tool/ruby_vm/models/bare_instructions.rb index 246222b03c..f2690501fc 100644 --- a/tool/ruby_vm/models/bare_instructions.rb +++ b/tool/ruby_vm/models/bare_instructions.rb @@ -49,15 +49,8 @@ class RubyVM::BareInstructions end def call_attribute name - return sprintf 'CALL_ATTRIBUTE(%s)', [ - name, @name, @opes.map {|i| i[:name] } - ].flatten.compact.join(', ') - end - - def sp_inc - return @attrs.fetch "sp_inc" do |k| - return generate_attribute k, 'rb_snum_t', rets.size - pops.size - end + return sprintf 'attr_%s_%s(%s)', name, @name, \ + @opes.map {|i| i[:name] }.compact.join(', ') end def has_attribute? k @@ -65,10 +58,6 @@ class RubyVM::BareInstructions end def attributes - # need to generate predefined attribute defaults - sp_inc - # other_attribute - # ... return @attrs.values end @@ -120,19 +109,25 @@ class RubyVM::BareInstructions private - def generate_attribute k, t, v - attr = RubyVM::Attribute.new \ - insn: self, \ - name: k, \ - type: t, \ - location: [], \ + def generate_attribute t, k, v + @attrs[k] ||= RubyVM::Attribute.new \ + insn: self, \ + name: k, \ + type: t, \ + location: [], \ expr: v.to_s + ';' return @attrs[k] ||= attr end def predefine_attributes - generate_attribute 'sp_inc', 'rb_snum_t', rets.size - pops.size - generate_attribute 'handles_frame', 'bool', \ + generate_attribute 'const char*', 'name', "insn_name(#{bin})" + generate_attribute 'enum ruby_vminsn_type', 'bin', bin + generate_attribute 'rb_num_t', 'open', opes.size + generate_attribute 'rb_num_t', 'popn', pops.size + generate_attribute 'rb_num_t', 'retn', rets.size + generate_attribute 'rb_num_t', 'width', width + generate_attribute 'rb_num_t', 'sp_inc', rets.size - pops.size + generate_attribute 'bool', 'handles_frame', \ opes.any? {|o| /CALL_INFO/ =~ o[:type] } end diff --git a/tool/ruby_vm/views/_insn_entry.erb b/tool/ruby_vm/views/_insn_entry.erb index f2f0f6418e..708f637f83 100644 --- a/tool/ruby_vm/views/_insn_entry.erb +++ b/tool/ruby_vm/views/_insn_entry.erb @@ -8,9 +8,11 @@ %; /* insn <%= insn.pretty_name %> */ -#define NAME_OF_CURRENT_INSN <%= insn.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 ## ') %> % unless insn.declarations.empty? <%= insn.declarations.join(";\n ") %>; @@ -27,28 +29,29 @@ INSN_ENTRY(<%= insn.name %>) % insn.pops.reverse_each.with_index.reverse_each do |pop, i| <%= pop[:name] %> = <%= insn.cast_from_VALUE pop, "TOPN(#{i})"%>; % end - DEBUG_ENTER_INSN(<%=cstr insn.name %>); + DEBUG_ENTER_INSN(INSN_ATTR(name)); % if insn.handles_frame? - ADD_PC(<%= insn.width %>); + ADD_PC(INSN_ATTR(width)); % end % unless insn.pops.empty? - POPN(<%= insn.pops.size %>); + POPN(INSN_ATTR(popn)); % end - COLLECT_USAGE_INSN(<%= insn.bin %>); + COLLECT_USAGE_INSN(INSN_ATTR(bin)); % insn.opes.each_with_index do |ope, i| - COLLECT_USAGE_OPERAND(<%= insn.bin %>, <%= i %>, <%= ope[:name] %>); + COLLECT_USAGE_OPERAND(INSN_ATTR(bin), <%= i %>, <%= ope[:name] %>); % end <%= render_c_expr insn.expr -%> % unless insn.rets.empty? - CHECK_VM_STACK_OVERFLOW_FOR_INSN(VM_REG_CFP, <%= insn.rets.size %>); + CHECK_VM_STACK_OVERFLOW_FOR_INSN(VM_REG_CFP, INSN_ATTR(retn)); % insn.rets.each_with_index do |ret, i| PUSH(<%= insn.cast_to_VALUE ret %>); % end % end % unless insn.handles_frame? - ADD_PC(<%= insn.width %>); + ADD_PC(INSN_ATTR(width)); PREFETCH(GET_PC()); % end END_INSN(<%= insn.name %>); +# undef INSN_ATTR +# undef NAME_OF_CURRENT_INSN } -#undef NAME_OF_CURRENT_INSN diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 1ba3cceb8b..9903bcc176 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -10,6 +10,7 @@ /* finish iseq array */ #include "insns.inc" +#include "insns_info.inc" #include #include "constant.h" #include "internal.h" -- cgit v1.2.3