[前][次][番号順一覧][スレッド一覧]

ruby-changes:60413

From: Takashi <ko1@a...>
Date: Sun, 15 Mar 2020 19:35:51 +0900 (JST)
Subject: [ruby-changes:60413] 17e925b991 (ruby_2_7): Avoid infinite loop on --jit-wait

https://git.ruby-lang.org/ruby.git/commit/?id=17e925b991

From 17e925b9917f4877f2da8c64316feb3ce1ca2932 Mon Sep 17 00:00:00 2001
From: Takashi Kokubun <takashikkbn@g...>
Date: Fri, 28 Feb 2020 23:20:44 -0800
Subject: Avoid infinite loop on --jit-wait

(cherry picked from commit a8dcab723316997d9e01c89d6df969edce75bdca)

diff --git a/mjit.c b/mjit.c
index 33abfbe..df0169e 100644
--- a/mjit.c
+++ b/mjit.c
@@ -366,7 +366,14 @@ unload_units(void) https://github.com/ruby/ruby/blob/trunk/mjit.c#L366
         remove_from_list(worst, &active_units);
         free_unit(worst);
     }
-    verbose(1, "Too many JIT code -- %d units unloaded", units_num - active_units.length);
+
+    if (units_num == active_units.length && mjit_opts.wait) {
+        mjit_opts.max_cache_size++; // avoid infinite loop on `rb_mjit_wait_call`. Note that --jit-wait is just for testing.
+        verbose(1, "No units can be unloaded -- incremented max-cache-size to %d for --jit-wait", mjit_opts.max_cache_size);
+    }
+    else {
+        verbose(1, "Too many JIT code -- %d units unloaded", units_num - active_units.length);
+    }
 }
 
 static void
diff --git a/test/ruby/test_jit.rb b/test/ruby/test_jit.rb
index f3dca57..adb6603 100644
--- a/test/ruby/test_jit.rb
+++ b/test/ruby/test_jit.rb
@@ -610,6 +610,28 @@ class TestJIT < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_jit.rb#L610
     assert_match(/^Successful MJIT finish$/, err)
   end
 
+  def test_nothing_to_unload_with_jit_wait
+    ignorable_patterns = [
+      /\AJIT compaction \([^)]+\): .+\n\z/,
+      /\ANo units can be unloaded -- .+\n\z/,
+    ]
+    assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: 'hello', success_count: 11, max_cache: 10, ignorable_patterns: ignorable_patterns)
+    begin;
+      def a1() a2() end
+      def a2() a3() end
+      def a3() a4() end
+      def a4() a5() end
+      def a5() a6() end
+      def a6() a7() end
+      def a7() a8() end
+      def a8() a9() end
+      def a9() a10() end
+      def a10() a11() end
+      def a11() print('hello') end
+      a1
+    end;
+  end
+
   def test_unload_units_and_compaction
     Dir.mktmpdir("jit_test_unload_units_") do |dir|
       # MIN_CACHE_SIZE is 10
@@ -1006,13 +1028,13 @@ class TestJIT < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_jit.rb#L1028
   end
 
   # Shorthand for normal test cases
-  def assert_eval_with_jit(script, stdout: nil, success_count:, min_calls: 1, insns: [], uplevel: 1)
-    out, err = eval_with_jit(script, verbose: 1, min_calls: min_calls)
+  def assert_eval_with_jit(script, stdout: nil, success_count:, min_calls: 1, max_cache: 1000, insns: [], uplevel: 1, ignorable_patterns: [])
+    out, err = eval_with_jit(script, verbose: 1, min_calls: min_calls, max_cache: max_cache)
     actual = err.scan(/^#{JIT_SUCCESS_PREFIX}:/).size
     # Add --jit-verbose=2 logs for cl.exe because compiler's error message is suppressed
     # for cl.exe with --jit-verbose=1. See `start_process` in mjit_worker.c.
     if RUBY_PLATFORM.match?(/mswin/) && success_count != actual
-      out2, err2 = eval_with_jit(script, verbose: 2, min_calls: min_calls)
+      out2, err2 = eval_with_jit(script, verbose: 2, min_calls: min_calls, max_cache: max_cache)
     end
 
     # Make sure that the script has insns expected to be tested
@@ -1032,7 +1054,7 @@ class TestJIT < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_jit.rb#L1054
       assert_equal(stdout, out, "Expected stdout #{out.inspect} to match #{stdout.inspect} with script:\n#{code_block(script)}")
     end
     err_lines = err.lines.reject! do |l|
-      l.chomp.empty? || l.match?(/\A#{JIT_SUCCESS_PREFIX}/) || IGNORABLE_PATTERNS.any? { |pat| pat.match?(l) }
+      l.chomp.empty? || l.match?(/\A#{JIT_SUCCESS_PREFIX}/) || (IGNORABLE_PATTERNS + ignorable_patterns).any? { |pat| pat.match?(l) }
     end
     unless err_lines.empty?
       warn err_lines.join(''), uplevel: uplevel
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]