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

ruby-changes:57909

From: Takashi <ko1@a...>
Date: Thu, 26 Sep 2019 16:33:15 +0900 (JST)
Subject: [ruby-changes:57909] 5d8f112505 (master): RubyVM::MJIT.pause(wait: true) should wait

https://git.ruby-lang.org/ruby.git/commit/?id=5d8f112505

From 5d8f112505fbc3f9b008ce4ec40fc74f9f623c4a Mon Sep 17 00:00:00 2001
From: Takashi Kokubun <takashikkbn@g...>
Date: Thu, 26 Sep 2019 12:53:41 +0900
Subject: RubyVM::MJIT.pause(wait: true) should wait

for all compilations and compaction.

Prior to this commit, the last-compiled code has not been used because
MJIT worker is stopped before setting the code, and compaction has also
been skipped.

But it was not intentional and `wait: true` pause should wait until
those two things by its feature.

diff --git a/mjit.c b/mjit.c
index 3ae9410..69dc234 100644
--- a/mjit.c
+++ b/mjit.c
@@ -802,7 +802,9 @@ mjit_pause(bool wait_p) https://github.com/ruby/ruby/blob/trunk/mjit.c#L802
         }
     }
 
+    mjit_pause_wait_p = wait_p; // Avoid cancelling the last compilation after the unit fetch if wait_p.
     stop_worker();
+    mjit_pause_wait_p = false;
     return Qtrue;
 }
 
diff --git a/mjit_worker.c b/mjit_worker.c
index 516dd87..cc19e27 100644
--- a/mjit_worker.c
+++ b/mjit_worker.c
@@ -210,6 +210,8 @@ static bool in_jit; https://github.com/ruby/ruby/blob/trunk/mjit_worker.c#L210
 static bool stop_worker_p;
 // Set to true if worker is stopped.
 static bool worker_stopped;
+// Set to true only when worker is being stopped for `RubyVM::MJIT.pause(wait: true)`.
+static bool mjit_pause_wait_p;
 
 // Path of "/tmp", which can be changed to $TMP in MinGW.
 static char *tmp_dir;
@@ -1225,9 +1227,10 @@ mjit_worker(void) https://github.com/ruby/ruby/blob/trunk/mjit_worker.c#L1227
             mjit_func_t func = convert_unit_to_func(unit);
             (void)RB_DEBUG_COUNTER_INC_IF(mjit_compile_failures, func == (mjit_func_t)NOT_COMPILED_JIT_ISEQ_FUNC);
 
-            // `mjit_copy_cache_from_main_thread` in `mjit_compile` may wait for a long time
-            // and worker may be stopped during the compilation.
-            if (stop_worker_p)
+            // Checking `stop_worker_p` here because `mjit_copy_cache_from_main_thread` in `mjit_compile` may wait
+            // for a long time and worker may be stopped during the compilation.
+            // However, we do not want to stop here when the `stop_worker()` is from `MJIT.pause(wait: true)`.
+            if (stop_worker_p && !mjit_pause_wait_p)
                 break;
 
             CRITICAL_SECTION_START(3, "in jit func replace");
diff --git a/test/lib/jit_support.rb b/test/lib/jit_support.rb
index acda166..fc5c12e 100644
--- a/test/lib/jit_support.rb
+++ b/test/lib/jit_support.rb
@@ -3,6 +3,7 @@ require 'rbconfig' https://github.com/ruby/ruby/blob/trunk/test/lib/jit_support.rb#L3
 module JITSupport
   JIT_TIMEOUT = 600 # 10min for each...
   JIT_SUCCESS_PREFIX = 'JIT success \(\d+\.\dms\)'
+  JIT_COMPACTION_PREFIX = 'JIT compaction \(\d+\.\dms\)'
   UNSUPPORTED_COMPILERS = [
     %r[\Aicc\b],
     %r[\A/opt/developerstudio\d+\.\d+/bin/cc\z],
diff --git a/test/ruby/test_rubyvm_mjit.rb b/test/ruby/test_rubyvm_mjit.rb
index 1277232..ef74756 100644
--- a/test/ruby/test_rubyvm_mjit.rb
+++ b/test/ruby/test_rubyvm_mjit.rb
@@ -35,6 +35,22 @@ class TestRubyVMMJIT < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_rubyvm_mjit.rb#L35
     )
   end
 
+  def test_pause_waits_until_compaction
+    out, err = eval_with_jit(<<~'EOS', verbose: 1, min_calls: 1, wait: false)
+      def a() end; a
+      def b() end; b
+      RubyVM::MJIT.pause
+    EOS
+    assert_equal(
+      2, err.scan(/#{JITSupport::JIT_SUCCESS_PREFIX}/).size,
+      "unexpected stdout:\n```\n#{out}```\n\nstderr:\n```\n#{err}```",
+    )
+    assert_equal(
+      1, err.scan(/#{JITSupport::JIT_COMPACTION_PREFIX}/).size,
+      "unexpected stdout:\n```\n#{out}```\n\nstderr:\n```\n#{err}```",
+    ) unless RUBY_PLATFORM.match?(/mswin|mingw/) # compaction is not supported on Windows yet
+  end
+
   def test_pause_does_not_hang_on_full_units
     out, _ = eval_with_jit(<<~'EOS', verbose: 1, min_calls: 1, max_cache: 10, wait: false)
       i = 0
-- 
cgit v0.10.2


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

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