ruby-changes:64229
From: Takashi <ko1@a...>
Date: Thu, 17 Dec 2020 16:07:14 +0900 (JST)
Subject: [ruby-changes:64229] 5d74894f2b (master): Lazily move PC with RUBY_VM_CHECK_INTS
https://git.ruby-lang.org/ruby.git/commit/?id=5d74894f2b From 5d74894f2bc4a3a18aec952d946ead3d784cb4b4 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun <takashikkbn@g...> Date: Wed, 16 Dec 2020 22:08:04 -0800 Subject: Lazily move PC with RUBY_VM_CHECK_INTS ``` $ benchmark-driver -v --rbenv 'before --jit;after --jit' --repeat-count=12 --alternate --output=all benchmark.yml before --jit: ruby 3.0.0dev (2020-12-17T06:17:46Z master 3b4d698e0b) +JIT [x86_64-linux] after --jit: ruby 3.0.0dev (2020-12-17T07:01:48Z master 843abb96f0) +JIT [x86_64-linux] last_commit=Lazily move PC with RUBY_VM_CHECK_INTS Calculating ------------------------------------- before --jit after --jit Optcarrot Lan_Master.nes 80.29343646660429 83.15779723251525 fps 82.26755637885149 85.50197941326810 83.50682959728820 88.14657804306270 85.01236533133049 88.78201988978667 87.81799334561326 88.94841008936447 87.88228562393064 89.37925215601926 88.06695585889995 89.86143277214475 88.84730834922165 90.00773346420887 90.46317871213088 90.82603371104014 90.96308347148916 91.29797694822179 90.97945938504556 91.31086331868738 91.57127890154500 91.49949184318844 ``` diff --git a/insns.def b/insns.def index 1c94a7f..c62e2f7 100644 --- a/insns.def +++ b/insns.def @@ -961,7 +961,7 @@ jump https://github.com/ruby/ruby/blob/trunk/insns.def#L961 () () /* Same discussion as leave. */ -// attr bool leaf = false; /* has rb_threadptr_execute_interrupts() */ +// attr bool leaf = leafness_of_check_ints; /* has rb_threadptr_execute_interrupts() */ { RUBY_VM_CHECK_INTS(ec); JUMP(dst); @@ -974,7 +974,7 @@ branchif https://github.com/ruby/ruby/blob/trunk/insns.def#L974 (VALUE val) () /* Same discussion as jump. */ -// attr bool leaf = false; /* has rb_threadptr_execute_interrupts() */ +// attr bool leaf = leafness_of_check_ints; /* has rb_threadptr_execute_interrupts() */ { if (RTEST(val)) { RUBY_VM_CHECK_INTS(ec); @@ -989,7 +989,7 @@ branchunless https://github.com/ruby/ruby/blob/trunk/insns.def#L989 (VALUE val) () /* Same discussion as jump. */ -// attr bool leaf = false; /* has rb_threadptr_execute_interrupts() */ +// attr bool leaf = leafness_of_check_ints; /* has rb_threadptr_execute_interrupts() */ { if (!RTEST(val)) { RUBY_VM_CHECK_INTS(ec); @@ -1004,7 +1004,7 @@ branchnil https://github.com/ruby/ruby/blob/trunk/insns.def#L1004 (VALUE val) () /* Same discussion as jump. */ -// attr bool leaf = false; /* has rb_threadptr_execute_interrupts() */ +// attr bool leaf = leafness_of_check_ints; /* has rb_threadptr_execute_interrupts() */ { if (NIL_P(val)) { RUBY_VM_CHECK_INTS(ec); diff --git a/tool/ruby_vm/models/bare_instructions.rb b/tool/ruby_vm/models/bare_instructions.rb index b0cc83a..6b5f1f6 100755 --- a/tool/ruby_vm/models/bare_instructions.rb +++ b/tool/ruby_vm/models/bare_instructions.rb @@ -112,6 +112,10 @@ class RubyVM::BareInstructions https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/models/bare_instructions.rb#L112 @attrs.fetch('leaf').expr.expr == 'true;' end + def leaf_without_check_ints? + @attrs.fetch('leaf').expr.expr == 'leafness_of_check_ints;' + end + def handle_canary stmt # Stack canary is basically a good thing that we want to add, however: # diff --git a/tool/ruby_vm/views/_leaf_helpers.erb b/tool/ruby_vm/views/_leaf_helpers.erb index 2637f87..cbb7373 100644 --- a/tool/ruby_vm/views/_leaf_helpers.erb +++ b/tool/ruby_vm/views/_leaf_helpers.erb @@ -10,6 +10,10 @@ https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/_leaf_helpers.erb#L10 #include "iseq.h" +// This is used to tell MJIT that this insn would be leaf if CHECK_INTS didn't exist. +// It should be used only when RUBY_VM_CHECK_INTS is directly written in insns.def. +static bool leafness_of_check_ints = false; + static bool leafness_of_defined(rb_num_t op_type) { diff --git a/tool/ruby_vm/views/_mjit_compile_insn_body.erb b/tool/ruby_vm/views/_mjit_compile_insn_body.erb index bc77b02..900480d 100644 --- a/tool/ruby_vm/views/_mjit_compile_insn_body.erb +++ b/tool/ruby_vm/views/_mjit_compile_insn_body.erb @@ -20,14 +20,14 @@ https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/_mjit_compile_insn_body.erb#L20 % # For `leave`. We can't proceed next ISeq in the same JIT function. % expr.gsub!(/^(?<indent>\s*)RESTORE_REGS\(\);\n/) do % indent = Regexp.last_match[:indent] -% <<-RESTORE_REGS.gsub(/^ +/, '') +% <<-end.gsub(/^ +/, '') % #if OPT_CALL_THREADED_CODE % #{indent}rb_ec_thread_ptr(ec)->retval = val; % #{indent}return 0; % #else % #{indent}return val; % #endif -% RESTORE_REGS +% end % end % expr.gsub!(/^(?<indent>\s*)NEXT_INSN\(\);\n/) do % indent = Regexp.last_match[:indent] @@ -47,6 +47,15 @@ https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/_mjit_compile_insn_body.erb#L47 % # % # TODO: support combination of following macros in the same line % case line +% when /\A\s+RUBY_VM_CHECK_INTS\(ec\);\s+\z/ +% if insn.leaf_without_check_ints? # lazily move PC here + fprintf(f, " if (UNLIKELY(RUBY_VM_INTERRUPTED_ANY(ec))) {\n"); + fprintf(f, " reg_cfp->pc = original_body_iseq + %d;\n", next_pos); /* ADD_PC(INSN_ATTR(width)); */ + fprintf(f, " rb_threadptr_execute_interrupts(rb_ec_thread_ptr(ec), 0);\n"); + fprintf(f, " }\n"); +% else + fprintf(f, <%= to_cstr.call(line) %>); +% end % when /\A\s+JUMP\((?<dest>[^)]+)\);\s+\z/ % dest = Regexp.last_match[:dest] % diff --git a/tool/ruby_vm/views/_mjit_compile_pc_and_sp.erb b/tool/ruby_vm/views/_mjit_compile_pc_and_sp.erb index f6d6116..390b3ce 100644 --- a/tool/ruby_vm/views/_mjit_compile_pc_and_sp.erb +++ b/tool/ruby_vm/views/_mjit_compile_pc_and_sp.erb @@ -5,9 +5,10 @@ https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/_mjit_compile_pc_and_sp.erb#L5 % # conditions mentioned in the file COPYING are met. Consult the file for % # details. % -% # JIT: Move pc for catch table on catch_except_p, and for #caller_locations and rb_profile_frames on !insn.always_leaf? +% # JIT: When an insn is leaf, we don't need to Move pc for a catch table on catch_except_p, #caller_locations, +% # and rb_profile_frames. For check_ints, we lazily move PC when we have interruptions. MAYBE_UNUSED(bool pc_moved_p) = false; - if (<%= insn.always_leaf? ? 'false' : 'true' %>) { + if (<%= !(insn.always_leaf? || insn.leaf_without_check_ints?) %>) { fprintf(f, " reg_cfp->pc = original_body_iseq + %d;\n", next_pos); /* ADD_PC(INSN_ATTR(width)); */ pc_moved_p = true; } -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/