зеркало из https://github.com/github/ruby.git
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
```
This commit is contained in:
Родитель
3b4d698e0b
Коммит
5d74894f2b
|
@ -961,7 +961,7 @@ jump
|
|||
()
|
||||
()
|
||||
/* 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
|
|||
(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
|
|||
(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
|
|||
(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);
|
||||
|
|
|
@ -112,6 +112,10 @@ class RubyVM::BareInstructions
|
|||
@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:
|
||||
#
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
|
||||
#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)
|
||||
{
|
||||
|
|
|
@ -20,14 +20,14 @@
|
|||
% # 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 @@
|
|||
% #
|
||||
% # 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]
|
||||
%
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
% # 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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче