summaryrefslogtreecommitdiff
path: root/test/lib/jit_support.rb
blob: adc89317dd4b308824e6a601b50d2d95f667f9b6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
module JITSupport
  JIT_TIMEOUT = 600 # 10min for each...
  JIT_SUCCESS_PREFIX = 'JIT success \(\d+\.\dms\)'
  SUPPORTED_COMPILERS = [
    'gcc',
    'clang',
  ]

  def self.check_support
    # Experimental. If you want to ensure JIT is working with this test, please set this for now.
    if ENV.key?('RUBY_FORCE_TEST_JIT')
      return true
    end

    # Very pessimistic check. With this check, we can't ensure JIT is working.
    begin
      _, err = JITSupport.eval_with_jit('proc {}.call', verbose: 1, min_calls: 1, timeout: 10)
    rescue Timeout::Error
      $stderr.puts "TestJIT: #jit_supported? check timed out"
      false
    else
      err.match?(JIT_SUCCESS_PREFIX)
    end
  end

  module_function
  def eval_with_jit(env = nil, script, verbose: 0, min_calls: 5, save_temps: false, timeout: JIT_TIMEOUT)
    args = ['--disable-gems', '--jit-wait', "--jit-verbose=#{verbose}", "--jit-min-calls=#{min_calls}"]
    args << '--jit-save-temps' if save_temps
    args << '-e' << script
    args.unshift(env) if env
    EnvUtil.invoke_ruby(args,
      '', true, true, timeout: timeout,
    )
  end

  def supported?
    return @supported if defined?(@supported)
    @supported = JITSupport.check_support.tap do |supported|
      unless supported
        warn "JIT tests are skiped since JIT seems not working. Set RUBY_FORCE_TEST_JIT=1 to let it fail.", uplevel: 1
      end
    end
  end

  def remove_mjit_logs(stderr)
    if RubyVM::MJIT.enabled?
      stderr.gsub(/^MJIT warning: Skipped to compile unsupported instruction: \w+\n/m, '')
    else
      stderr
    end
  end
end