summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authork0kubun <k0kubun@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-11-18 08:25:48 +0000
committerk0kubun <k0kubun@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-11-18 08:25:48 +0000
commitfe6974a8fcca42f4f83171097a3bc29fbe0f2f67 (patch)
tree01f157d468dc018c5765144f344e98a37a584c62 /test
parent0a7a5a7ad4da3ec8bed425502f5012908a0e77c8 (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.rb40
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?