summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-01-29 06:47:05 (GMT)
committershyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-01-29 06:47:05 (GMT)
commit9a8b38cacfa029aa9bbc5f1600b1ead3903a8c88 (patch)
treee7e453f3dc0f360a00e2bf406b4e76134f177433
parent582951e2c8995d6bab5ddaf98cd3816310f8d506 (diff)
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
-rw-r--r--common.mk1
-rw-r--r--tool/ruby_vm/models/bare_instructions.rb37
-rw-r--r--tool/ruby_vm/views/_insn_entry.erb21
-rw-r--r--vm_insnhelper.c1
4 files changed, 30 insertions, 30 deletions
diff --git a/common.mk b/common.mk
index c888815..04061ab 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 246222b..f269050 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 f2f0f64..708f637 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 1ba3cce..9903bcc 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -10,6 +10,7 @@
/* finish iseq array */
#include "insns.inc"
+#include "insns_info.inc"
#include <math.h>
#include "constant.h"
#include "internal.h"