summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2020-02-18 23:16:19 -0800
committerNARUSE, Yui <naruse@airemix.jp>2020-02-20 16:36:10 +0900
commiteaee631d5eda03f77ec39ec6fc1826a06ab06205 (patch)
tree4b9466f7af3bdd1963852dc5457b0b6a81398ac5
parentccc3b9119c39a6cb08a643ab3d15a9c07ec28b1a (diff)
Avoid jumping to a wrong destination
when the next insn is already compiled by former branches.
-rw-r--r--test/ruby/test_jit.rb10
-rw-r--r--tool/ruby_vm/views/_mjit_compile_insn.erb9
2 files changed, 17 insertions, 2 deletions
diff --git a/test/ruby/test_jit.rb b/test/ruby/test_jit.rb
index a8ce18b48c..f3dca57e83 100644
--- a/test/ruby/test_jit.rb
+++ b/test/ruby/test_jit.rb
@@ -828,6 +828,16 @@ class TestJIT < Test::Unit::TestCase
end;
end
+ def test_jump_to_precompiled_branch
+ assert_eval_with_jit("#{<<~'begin;'}\n#{<<~'end;'}", stdout: ".0", success_count: 1, min_calls: 1)
+ begin;
+ def test(foo)
+ ".#{foo unless foo == 1}" if true
+ end
+ print test(0)
+ end;
+ end
+
def test_clean_so
if RUBY_PLATFORM.match?(/mswin/)
skip 'Removing so file is randomly failing on AppVeyor/RubyCI mswin due to Permission Denied.'
diff --git a/tool/ruby_vm/views/_mjit_compile_insn.erb b/tool/ruby_vm/views/_mjit_compile_insn.erb
index b2dea03e38..8f45121615 100644
--- a/tool/ruby_vm/views/_mjit_compile_insn.erb
+++ b/tool/ruby_vm/views/_mjit_compile_insn.erb
@@ -76,9 +76,14 @@
}
fprintf(f, "}\n");
%
-% # compiler: If insn has conditional JUMP, the branch which is not targeted by JUMP should be compiled too.
+% # compiler: If insn has conditional JUMP, the code should go to the branch not targeted by JUMP next.
% if insn.expr.expr =~ /if\s+\([^{}]+\)\s+\{[^{}]+JUMP\([^)]+\);[^{}]+\}/
- compile_insns(f, body, b->stack_size, pos + insn_len(insn), status);
+ if (ALREADY_COMPILED_P(status, pos + insn_len(insn))) {
+ fprintf(f, "goto label_%d;\n", pos + insn_len(insn));
+ }
+ else {
+ compile_insns(f, body, b->stack_size, pos + insn_len(insn), status);
+ }
% end
%
% # compiler: If insn returns (leave) or does longjmp (throw), the branch should no longer be compiled. TODO: create attr for it?