aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2019-07-14 18:04:14 +0900
committerTakashi Kokubun <takashikkbn@gmail.com>2019-07-14 18:04:19 +0900
commitd30d404bc4b848f84959799b543de4bdbd8eef2b (patch)
tree4b89685b73c05fae3d7d8013efaed8be1dbea193
parent043e3d2cdc02a3571e3e2c3b9252a65d3c049740 (diff)
downloadruby-d30d404bc4b848f84959799b543de4bdbd8eef2b.tar.gz
MJIT Support for getblockparamproxy
-rw-r--r--test/ruby/test_jit.rb14
-rw-r--r--tool/ruby_vm/views/_mjit_compile_insn_body.erb3
-rw-r--r--tool/ruby_vm/views/mjit_compile.inc.erb1
-rw-r--r--vm.c3
-rw-r--r--vm_insnhelper.h2
5 files changed, 18 insertions, 5 deletions
diff --git a/test/ruby/test_jit.rb b/test/ruby/test_jit.rb
index 0cfc980aac..727043fd00 100644
--- a/test/ruby/test_jit.rb
+++ b/test/ruby/test_jit.rb
@@ -18,7 +18,6 @@ class TestJIT < Test::Unit::TestCase
# trace_* insns are not compiled for now...
TEST_PENDING_INSNS = RubyVM::INSTRUCTION_NAMES.select { |n| n.start_with?('trace_') }.map(&:to_sym) + [
# not supported yet
- :getblockparamproxy,
:defineclass,
:opt_call_c_function,
@@ -94,7 +93,18 @@ class TestJIT < Test::Unit::TestCase
end
def test_compile_insn_getblockparamproxy
- skip "support this in mjit_compile"
+ assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '4', success_count: 3, insns: %i[getblockparamproxy])
+ begin;
+ def bar(&b)
+ b.call
+ end
+
+ def foo(&b)
+ bar(&b) * bar(&b)
+ end
+
+ print foo { 2 }
+ end;
end
def test_compile_insn_getspecial
diff --git a/tool/ruby_vm/views/_mjit_compile_insn_body.erb b/tool/ruby_vm/views/_mjit_compile_insn_body.erb
index 7035779221..a2a750fbdc 100644
--- a/tool/ruby_vm/views/_mjit_compile_insn_body.erb
+++ b/tool/ruby_vm/views/_mjit_compile_insn_body.erb
@@ -81,6 +81,9 @@
fprintf(f, " reg_cfp->pc = original_body_iseq + %d;\n", pos);
fprintf(f, " RB_DEBUG_COUNTER_INC(mjit_cancel_opt_insn);\n");
fprintf(f, " goto cancel;\n");
+% when /\A(?<prefix>.+\b)INSN_LABEL\((?<name>[^)]+)\)(?<suffix>.+)\z/m
+% prefix, name, suffix = Regexp.last_match[:prefix], Regexp.last_match[:name], Regexp.last_match[:suffix]
+ fprintf(f, " <%= prefix.gsub(/\t/, ' ' * 8) %>INSN_LABEL(<%= name %>_%d)<%= suffix.sub(/\n/, '\n') %>", pos);
% else
% if insn.handles_sp?
% # If insn.handles_sp? is true, cfp->sp might be changed inside insns (like vm_caller_setup_arg_block)
diff --git a/tool/ruby_vm/views/mjit_compile.inc.erb b/tool/ruby_vm/views/mjit_compile.inc.erb
index 1812dabf4a..d9092a756d 100644
--- a/tool/ruby_vm/views/mjit_compile.inc.erb
+++ b/tool/ruby_vm/views/mjit_compile.inc.erb
@@ -16,7 +16,6 @@
} -%>
%
% unsupported_insns = [
-% 'getblockparamproxy', # TODO: support this
% 'defineclass', # low priority
% 'opt_call_c_function', # low priority
% ]
diff --git a/vm.c b/vm.c
index b5412d1a6d..939c0fc6ff 100644
--- a/vm.c
+++ b/vm.c
@@ -323,8 +323,6 @@ extern VALUE rb_vm_invoke_bmethod(rb_execution_context_t *ec, rb_proc_t *proc, V
const rb_callable_method_entry_t *me);
static VALUE vm_invoke_proc(rb_execution_context_t *ec, rb_proc_t *proc, VALUE self, int argc, const VALUE *argv, VALUE block_handler);
-static VALUE rb_block_param_proxy;
-
#include "mjit.h"
#include "vm_insnhelper.h"
#include "vm_exec.h"
@@ -352,6 +350,7 @@ rb_next_class_serial(void)
VALUE rb_cRubyVM;
VALUE rb_cThread;
VALUE rb_mRubyVMFrozenCore;
+VALUE rb_block_param_proxy;
#define ruby_vm_redefined_flag GET_VM()->redefined_flag
VALUE ruby_vm_const_missing_count = 0;
diff --git a/vm_insnhelper.h b/vm_insnhelper.h
index 98aee9d46c..59c82e5d76 100644
--- a/vm_insnhelper.h
+++ b/vm_insnhelper.h
@@ -14,6 +14,8 @@
RUBY_SYMBOL_EXPORT_BEGIN
+RUBY_EXTERN VALUE rb_block_param_proxy;
+
RUBY_EXTERN VALUE ruby_vm_const_missing_count;
RUBY_EXTERN rb_serial_t ruby_vm_global_method_state;
RUBY_EXTERN rb_serial_t ruby_vm_global_constant_state;