name: ZJIT Ubuntu on: push: branches: - master paths-ignore: - 'doc/**' - '**/man/*' - '**.md' - '**.rdoc' - '**/.document' - '.*.yml' pull_request: types: - opened - synchronize - reopened # Do not use paths-ignore for required status checks # https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks merge_group: concurrency: group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} permissions: contents: read jobs: lint: name: cargo clippy runs-on: ubuntu-22.04 if: >- ${{!(false || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') )}} steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - run: cargo clippy --all-targets --all-features working-directory: zjit make: strategy: fail-fast: false matrix: include: - test_task: 'check' run_opts: '--zjit-call-threshold=1' specopts: '-T --zjit-call-threshold=1' configure: '--enable-zjit=dev' - test_task: 'check' run_opts: '--zjit-disable-hir-opt --zjit-call-threshold=1' specopts: '-T --zjit-disable-hir-opt -T --zjit-call-threshold=1' configure: '--enable-zjit=dev' # The optimizer benefits from at least 1 iteration of profiling. Also, many # regression tests in bootstraptest/test_yjit.rb assume call-threshold=2. - test_task: 'btest' run_opts: '--zjit-call-threshold=2' configure: '--enable-zjit=dev' - test_task: 'zjit-check' # zjit-test + quick feedback of test_zjit.rb configure: '--enable-yjit --enable-zjit=dev' rust_version: '1.85.0' - test_task: 'zjit-bindgen' hint: 'To fix: use patch in logs' # Build with YJIT+ZJIT for output that works in the most number of configurations configure: '--enable-zjit=dev --enable-yjit --with-gcc=clang-16' clang_path: '/usr/bin/clang-16' runs-on: 'ubuntu-24.04' # for clang-16 - test_task: 'test-bundled-gems' configure: '--enable-zjit=dev' run_opts: '--zjit-call-threshold=1' env: GITPULLOPTIONS: --no-tags origin ${{ github.ref }} RUN_OPTS: ${{ matrix.run_opts }} YJIT_BENCH_OPTS: ${{ matrix.yjit_bench_opts }} SPECOPTS: ${{ matrix.specopts }} TESTOPTS: ${{ matrix.testopts }} RUBY_DEBUG: ci BUNDLE_JOBS: 8 # for yjit-bench RUST_BACKTRACE: 1 ZJIT_RB_BUG: 1 runs-on: ${{ matrix.runs-on || 'ubuntu-22.04' }} if: >- ${{!(false || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') )}} steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: sparse-checkout-cone-mode: false sparse-checkout: /.github - uses: ./.github/actions/setup/ubuntu - uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0 with: ruby-version: '3.1' bundler: none - uses: taiki-e/install-action@v2 with: tool: nextest@0.9 if: ${{ matrix.test_task == 'zjit-check' }} - uses: ./.github/actions/setup/directories with: srcdir: src builddir: build makeup: true dummy-files: ${{ matrix.test_task == 'check' }} # Set fetch-depth: 10 so that Launchable can receive commits information. fetch-depth: 10 - name: Install Rust if: ${{ matrix.rust_version }} run: | rustup install ${{ matrix.rust_version }} --profile minimal rustup default ${{ matrix.rust_version }} - name: Install rustfmt if: ${{ matrix.test_task == 'zjit-bindgen' }} run: rustup component add rustfmt - name: Run configure run: ../src/configure -C --disable-install-doc --prefix=$(pwd)/install ${{ matrix.configure }} - run: make incs - run: make prepare-gems if: ${{ matrix.test_task == 'test-bundled-gems' }} - run: make - name: Verify that --zjit-dump-disasm works run: | ./miniruby --zjit-call-threshold=1 --zjit-dump-disasm -e0 | \ wc -l | \ ruby -ne 'raise "Disassembly seems broken in dev build (output has too few lines)" unless $_.to_i > 10' if: ${{ contains(matrix.configure, 'jit=dev') }} # Check that the binary was built with ZJIT - name: Check ZJIT enabled run: ./miniruby --zjit -v | grep "+ZJIT" if: ${{ matrix.configure != '--disable-zjit' }} - name: Set ENV for ZJIT run: | echo "RUBY_CRASH_REPORT=$(pwd)/rb_crash_%p.txt" >> $GITHUB_ENV - name: make ${{ matrix.test_task }} run: | set -x make -s ${{ matrix.test_task }} ${TESTS:+TESTS="$TESTS"} \ RUN_OPTS="$RUN_OPTS" MSPECOPT=--debug SPECOPTS="$SPECOPTS" \ TESTOPTS="$TESTOPTS" \ ZJIT_BINDGEN_DIFF_OPTS="$ZJIT_BINDGEN_DIFF_OPTS" timeout-minutes: 90 env: RUBY_TESTOPTS: '-q --tty=no' EXCLUDES: '../src/test/.excludes-zjit' TEST_BUNDLED_GEMS_ALLOW_FAILURES: '' PRECHECK_BUNDLED_GEMS: 'no' SYNTAX_SUGGEST_TIMEOUT: '5' ZJIT_BINDGEN_DIFF_OPTS: '--exit-code' CLANG_PATH: ${{ matrix.clang_path }} continue-on-error: ${{ matrix.continue-on-test_task || false }} - name: Dump crash logs if: ${{ failure() }} continue-on-error: true run: | tail --verbose --lines=+1 rb_crash_*.txt exit 1 - uses: ./.github/actions/slack with: label: ${{ matrix.test_task }} ${{ matrix.configure }} SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot if: ${{ failure() }} result: if: ${{ always() }} name: ${{ github.workflow }} result runs-on: ubuntu-22.04 needs: [make] steps: - name: ${{ github.workflow }} jobs have failed run: exit 1 working-directory: if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }} # Separated from `make` job to avoid making it a required status check for now ruby-bench: strategy: matrix: include: # Test --call-threshold=2 with 2 iterations in total - ruby_opts: '--zjit-call-threshold=2' bench_opts: '--warmup=1 --bench=1' configure: '--enable-zjit=dev_nodebug' # --enable-zjit=dev is too slow runs-on: ubuntu-24.04 if: >- ${{!(false || contains(github.event.head_commit.message, '[DOC]') || contains(github.event.pull_request.title, '[DOC]') || contains(github.event.pull_request.labels.*.name, 'Documentation') || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') )}} steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: ./.github/actions/setup/ubuntu - uses: ./.github/actions/setup/directories with: srcdir: src builddir: build makeup: true - name: Run configure run: ../src/configure -C --disable-install-doc --prefix="$(pwd)/install" ${{ matrix.configure }} - run: make install - name: Checkout ruby-bench uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: repository: ruby/ruby-bench path: ruby-bench # If you want to skip failing benchmark, consider using `--excludes`. # e.g. `bench_opts: '--warmup=1 --bench=1 --excludes=railsbench,lobsters'` - name: Run ruby-bench run: ruby run_benchmarks.rb -e "zjit::../build/install/bin/ruby ${{ matrix.ruby_opts }}" ${{ matrix.bench_opts }} working-directory: ruby-bench - uses: ./.github/actions/slack with: label: ruby-bench ${{ matrix.bench_opts }} ${{ matrix.ruby_opts }} SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot if: ${{ failure() }} defaults: run: working-directory: build