Skip to content

Raise ruby/spec floor 21970 -> 22140 after wave 28 - #646

Merged
tannevaled merged 1 commit into
mainfrom
wave28/floor
Sep 24, 2026
Merged

tannevaled merged 1 commit into
mainfrom
wave28/floor

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

Four units.

PR area gain
#645 the line map language/line_spec 0/6 → 6/6, real lines in backtraces, MRI-shaped frame labels
#640 Kernel#sleep + the fiber scheduler, File.open's mode/flags/perm contract, IO::Buffer.map +90 across core/file, core/io, core/kernel; sleep_spec 0 → 15
#639 regexp search anchoring and encoding, Refinement#import_methods, pack/unpack
go-ruby-parser v0.3.0 ast.Program.Lines the prerequisite for #645

The wall was one repository down

__LINE__ evaluated to 0 everywhere, and 101 examples across five directories were blocked on it — const_source_location, every Thread::Backtrace::Location spec, each_caller_location, warn(uplevel:), line_spec. Three earlier agents each reported it as the thing they could not get past, and each assumed the fix was in the compiler.

It was not. The parser's AST carried no position information at all: 55 node types, no line or column field anywhere, and the lexer — which knows every token's line — discarded it at the AST boundary. No amount of compiler work could have produced a line. That is why this took a parser release (ast.Program.Lines, v0.3.0) before the VM half could start.

The table itself is MRI's shape, not a line per instruction: insns_info[] beside positions[], written in emit() so a statement emitting nothing contributes no entry and one emitting twenty contributes one (iseq.c v3_4_0:673, read back by get_insn_info_binary_search at :2160).

Measurement

scripts/conformance/rubyspec/run.sh, pinned corpus 87b1631, 16-way, TIMEOUT=25, three consecutive runs:

passing examples: 22153   (files loaded: 2192, failed to load: 14)
passing examples: 22152
passing examples: 22152
frozen floor:     21970

Floor set twelve below the lowest run — the margin rule the last three bumps used: enough for the run-to-run jitter, not enough to hide the loss of a whole spec file. #615 is still open and still costs a file when it fires.

Worth recording from this wave

  • A regeneration of the frozen prelude came back byte-identical, which looked like good news and was not: the AOT emitter was dropping Lines, so every AOT-compiled frame would have reported line 0 — the old behaviour reintroduced silently on that one path. TestEmbeddedPreludeMatchesSource caught it.
  • A benchmark improvement of −0.2% turned out to be noise on a benchmark whose own spread is 870–1037 ms; fifteen interleaved runs put the real figure at +7.5%. The code comment that had recorded −0.2% was corrected, so nobody re-derives it.
  • IO.select carried a NaN guard that could never run — the coercion it calls raises on NaN itself rather than returning one. It read as an uncovered branch; it was dead code, and is deleted.

🤖 Generated with Claude Code

Four units, and one of them was a dependency away:

  #639  regexp search anchoring and encoding, Refinement#import_methods,
        pack/unpack
  #645  THE LINE MAP. __LINE__ evaluated to 0 everywhere because the ISeq
        carried no line table — 101 examples across five directories were
        blocked on it, and three earlier agents each reported it as the wall
        they could not pass. The wall was one repository down: the parser's
        AST carried no position information at all, 55 node types with no
        line field, and the lexer discarded every token's line at the AST
        boundary. go-ruby-parser v0.3.0 adds ast.Program.Lines; this PR
        builds MRI's compressed insns_info/positions table on it.
        language/line_spec 0/6 -> 6/6, backtraces carry real lines, frame
        labels name blocks the way MRI does.
  #640  Kernel#sleep with the fiber scheduler (sleep_spec 0 -> 15, one
        example had been hanging the whole file), File.open's mode/flags/perm
        contract driven by the open(2) flag set rather than a six-way mode
        string, IO::Buffer.map                     (+90 across core/file,
                                                    core/io, core/kernel)
  #537, #527 already in the previous floor's tree

Measured with scripts/conformance/rubyspec/run.sh against the pinned corpus at
87b1631, 16-way, TIMEOUT=25, three consecutive runs: 22153, 22152, 22152. The
floor is set twelve below the lowest, the margin rule the last three bumps
used: enough for the run-to-run jitter, not enough to hide the loss of a spec
file. #615 remains open and still costs a file when it fires.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@tannevaled
tannevaled merged commit c5008ba into main Sep 24, 2026
7 checks passed
@tannevaled
tannevaled deleted the wave28/floor branch September 24, 2026 16:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant