From 7e536b3be26ae48738a036a58be8dfa380bd21da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?= Date: Sun, 12 Jul 2020 14:53:54 +0900 Subject: builtin.h: avoid copy&paste Instead of doubling the invokebuiltin logic here and there, use the same insns.def definition for both MJIT/non-JIT situations. --- builtin.h | 16 ---------- tool/ruby_vm/views/_mjit_compile_insn_body.erb | 4 --- tool/ruby_vm/views/_mjit_compile_invokebuiltin.erb | 34 +++++++++++++--------- tool/ruby_vm/views/mjit_compile.inc.erb | 8 ++--- 4 files changed, 24 insertions(+), 38 deletions(-) diff --git a/builtin.h b/builtin.h index be7bb16a28..0da200f961 100644 --- a/builtin.h +++ b/builtin.h @@ -80,20 +80,4 @@ struct builtin_binary { size_t bin_size; }; -// mjit - -RBIMPL_ATTR_MAYBE_UNUSED() -static void -mjit_invokebuiltin_default_compiler(FILE *f, const struct rb_builtin_function *bf, long index) -{ - if (index >= 0) { - fprintf(f, "val = vm_invoke_builtin(ec, GET_CFP(), %p, STACK_ADDR_FROM_TOP(%d));\n", - (const void *)bf, bf->argc); - } - else { - fprintf(f, "val = vm_invoke_builtin_delegate(ec, GET_CFP(), %p, %ld);\n", - (const void *)bf, index); - } -} - #endif // BUILTIN_H_INCLUDED diff --git a/tool/ruby_vm/views/_mjit_compile_insn_body.erb b/tool/ruby_vm/views/_mjit_compile_insn_body.erb index eb0f8485c3..bc77b02b71 100644 --- a/tool/ruby_vm/views/_mjit_compile_insn_body.erb +++ b/tool/ruby_vm/views/_mjit_compile_insn_body.erb @@ -63,10 +63,6 @@ fprintf(f, " goto label_%lu;\n", arg.base_pos + else_offset); fprintf(f, " }\n"); } -% elsif insn.name == 'invokebuiltin' || insn.name == 'opt_invokebuiltin_delegate' - { -<%= render 'mjit_compile_invokebuiltin', locals: { insn: insn } -%> - } % else % # Before we `goto` next insn, we need to set return values, especially for getinlinecache % insn.rets.reverse_each.with_index do |ret, i| diff --git a/tool/ruby_vm/views/_mjit_compile_invokebuiltin.erb b/tool/ruby_vm/views/_mjit_compile_invokebuiltin.erb index f935f799cb..a95a8a7438 100644 --- a/tool/ruby_vm/views/_mjit_compile_invokebuiltin.erb +++ b/tool/ruby_vm/views/_mjit_compile_invokebuiltin.erb @@ -6,18 +6,24 @@ % # conditions mentioned in the file COPYING are met. Consult the file for % # details. % - /* <%= insn.name %> */ - const struct rb_builtin_function *bf = (const void *)operands[0]; -% -% if insn.name == 'invokebuiltin' then - const rb_num_t index = -1; -% else - const rb_num_t index = (rb_num_t)operands[1]; +% insn.opes.each_with_index do |ope, i| + <%= ope.fetch(:decl) %> = (<%= ope.fetch(:type) %>)operands[<%= i %>]; % end -% - if (bf->compiler) { - bf->compiler(f, index); - } - else { - mjit_invokebuiltin_default_compiler(f, bf, index); - } + rb_snum_t sp_inc = <%= insn.call_attribute('sp_inc') %>; + unsigned sp = b->stack_size + (unsigned)sp_inc; + VM_ASSERT(sp_inc >= 0); + VM_ASSERT(sp_inc < UINT_MAX - b->stack_size); + + if (bf->compiler) { + fprintf(f, "{\n"); + fprintf(f, " VALUE val;\n"); + bf->compiler(f, <%= + insn.name == 'invokebuiltin' ? '-1' : '(rb_num_t)operands[1]' + %>); + fprintf(f, " stack[%u] = val;\n", sp - 1); + fprintf(f, "}\n"); +% if insn.name != 'opt_invokebuiltin_delegate_leave' + b->stack_size = sp; + break; +% end + } diff --git a/tool/ruby_vm/views/mjit_compile.inc.erb b/tool/ruby_vm/views/mjit_compile.inc.erb index e3be549181..6836d59a4f 100644 --- a/tool/ruby_vm/views/mjit_compile.inc.erb +++ b/tool/ruby_vm/views/mjit_compile.inc.erb @@ -63,15 +63,15 @@ switch (insn) { } % when 'getinstancevariable', 'setinstancevariable' <%= render 'mjit_compile_ivar', locals: { insn: insn } -%> +% when 'invokebuiltin', 'opt_invokebuiltin_delegate' + { +<%= render 'mjit_compile_invokebuiltin', locals: { insn: insn } -%> + } % when 'leave', 'opt_invokebuiltin_delegate_leave' { % # opt_invokebuiltin_delegate_leave also implements leave insn. We need to handle it here for inlining. % if insn.name == 'opt_invokebuiltin_delegate_leave' - fprintf(f, "{\n"); - fprintf(f, " VALUE val;\n"); <%= render 'mjit_compile_invokebuiltin', locals: { insn: insn } -%> - fprintf(f, " stack[0] = val;\n"); - fprintf(f, "}\n"); % else if (b->stack_size != 1) { if (mjit_opts.warnings || mjit_opts.verbose) -- cgit v1.2.1