Last active
June 30, 2026 15:56
-
-
Save nirvdrum/da1fc00d656c0d03281e553a843a6d87 to your computer and use it in GitHub Desktop.
Reproduction for a ZJIT stale value bug
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Minimal ZJIT miscompile repro -- no pub_grub, no RubyGems. | |
| # | |
| # Recipe (mirrors VersionSolver#add_incompatibility): | |
| # 1. `noop` is an empty method that takes a block. The trivial inliner folds | |
| # such a call to `nil` and DROPS the block, deleting the SendDirect and its | |
| # gen_spill_locals -- but the post-send local reload survives, orphaned. | |
| # 2. `callee(arg)` calls `noop { arg }` (block-passing) and THEN reads `arg`. | |
| # The orphaned reload overwrites `arg` with LoadField SP, :arg@-slot. | |
| # 3. `callee` is reached via a JIT-to-JIT SendDirect (from JIT-compiled | |
| # `caller`), so `arg` arrives in a register and its frame slot is never | |
| # written. The reload therefore reads a stale stack slot. | |
| # | |
| # Expected: with a correct JIT, callee returns its argument unchanged. | |
| class Empty | |
| def noop(&blk) | |
| end | |
| end | |
| class Driver | |
| def initialize | |
| @e = Empty.new | |
| end | |
| def callee(arg) | |
| @e.noop { arg } # trivially-inlined block-passing call -> orphans reload of arg | |
| arg # read arg again -> stale slot on direct entry | |
| end | |
| def caller(arg) | |
| callee(arg) | |
| end | |
| end | |
| d = Driver.new | |
| fails = 0 | |
| 2_000_000.times do |i| | |
| obj = Object.new | |
| got = d.caller(obj) | |
| unless got.equal?(obj) | |
| fails += 1 | |
| if fails <= 3 | |
| STDERR.puts "MISCOMPILE i=#{i}: got #{got.inspect}, expected fresh Object" | |
| end | |
| end | |
| end | |
| if fails > 0 | |
| STDERR.puts "FAIL: #{fails} miscompiled iterations" | |
| exit 1 | |
| else | |
| puts "OK" | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment