mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									47a234954a
								
							
						
					
					
						commit
						5d8f112505
					
				
					 4 changed files with 25 additions and 3 deletions
				
			
		
							
								
								
									
										2
									
								
								mjit.c
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								mjit.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -802,7 +802,9 @@ mjit_pause(bool wait_p)
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -210,6 +210,8 @@ static bool in_jit;
 | 
			
		|||
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)
 | 
			
		|||
            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");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@ require 'rbconfig'
 | 
			
		|||
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],
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,6 +35,22 @@ class TestRubyVMMJIT < Test::Unit::TestCase
 | 
			
		|||
    )
 | 
			
		||||
  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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue