diff options
author | k0kubun <k0kubun@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-11-18 08:25:48 +0000 |
---|---|---|
committer | k0kubun <k0kubun@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-11-18 08:25:48 +0000 |
commit | fe6974a8fcca42f4f83171097a3bc29fbe0f2f67 (patch) | |
tree | 01f157d468dc018c5765144f344e98a37a584c62 /test | |
parent | 0a7a5a7ad4da3ec8bed425502f5012908a0e77c8 (diff) |
mjit_worker.c: support MJIT in forked Ruby process
by launching MJIT worker thread in child Ruby process.
See the comment before `mjit_child_after_fork` for details.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65785 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'test')
-rw-r--r-- | test/ruby/test_jit.rb | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/test/ruby/test_jit.rb b/test/ruby/test_jit.rb index 451ed91a56..b25a9b15a2 100644 --- a/test/ruby/test_jit.rb +++ b/test/ruby/test_jit.rb @@ -567,7 +567,7 @@ class TestJIT < Test::Unit::TestCase assert_match(/^Successful MJIT finish$/, err) end - def test_unload_units + def test_unload_units_and_compaction Dir.mktmpdir("jit_test_unload_units_") do |dir| # MIN_CACHE_SIZE is 10 out, err = eval_with_jit({"TMPDIR"=>dir}, "#{<<~"begin;"}\n#{<<~'end;'}", verbose: 1, min_calls: 1, max_cache: 10) @@ -582,6 +582,12 @@ class TestJIT < Test::Unit::TestCase EOS i += 1 end + + if defined?(fork) + # test the child does not try to delete files which are deleted by parent, + # and test possible deadlock on fork during MJIT unload and JIT compaction on child + Process.waitpid(Process.fork {}) + end end; debug_info = "stdout:\n```\n#{out}\n```\n\nstderr:\n```\n#{err}```\n" @@ -598,7 +604,7 @@ class TestJIT < Test::Unit::TestCase # On --jit-wait, when the number of JIT-ed code reaches --jit-max-cache, # it should trigger compaction. unless RUBY_PLATFORM.match?(/mswin|mingw/) # compaction is not supported on Windows yet - assert_equal(2, compactions.size, debug_info) + assert_equal(3, compactions.size, debug_info) end if appveyor_mswin? @@ -838,6 +844,36 @@ class TestJIT < Test::Unit::TestCase assert_equal("-e:8:in `a'\n", lines[1]) end + def test_fork_with_mjit_worker_thread + Dir.mktmpdir("jit_test_fork_with_mjit_worker_thread_") do |dir| + # min_calls: 2 to skip fork block + out, err = eval_with_jit({ "TMPDIR" => dir }, "#{<<~"begin;"}\n#{<<~"end;"}", min_calls: 2, verbose: 1) + begin; + def before_fork; end + def after_fork; end + + before_fork; before_fork # the child should not delete this .o file + pid = Process.fork do # this child should not delete shared .pch file + after_fork; after_fork # this child does not share JIT-ed after_fork with parent + end + after_fork; after_fork # this parent does not share JIT-ed after_fork with child + + Process.waitpid(pid) + end; + success_count = err.scan(/^#{JIT_SUCCESS_PREFIX}:/).size + assert_equal(3, success_count) + + # assert no remove error + lines = err.lines + assert_match(/^Successful MJIT finish$/, lines[3]) + assert_match(/^Successful MJIT finish$/, lines[4]) + + # ensure objects are deleted + debug_info = "stdout:\n```\n#{out}\n```\n\nstderr:\n```\n#{err}```\n" + assert_send([Dir, :empty?, dir], debug_info) + end + end if defined?(fork) + private def appveyor_mswin? |