Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Changelog

Monthly highlights of monoruby’s development, with representative PRs. The README carries the most recent two months; this page is the full record.

For a prose account of the same period rather than a list — what changed and why, over roughly 500 commits — see Progress summary (April 2025 – April 2026).

Maintenance. This page is the single source of truth. A scheduled Routine appends the previous month on the 1st of each month, then runs bin/sync-changelog-readme, which copies the two newest month sections verbatim into the README between its LATEST-MONTHS markers. The README’s month text is generated — edit this page instead, and re-run the script (bin/sync-changelog-readme --check verifies the two are in sync).

2026

August 2026

  • Broad early-month ruby/spec compliance drive across Kernel, Enumerator, IO and process handling: Enumerator::Lazy / Product / Chain, fiber-free #each/#with_index internals, ARGF reimplemented in Rust, Refinements, and a full spawn-exec engine with real Data subclasses (#1039#1065, notably #1046, #1054, #1064).
  • Signal delivery moved onto gated safepoint polls, and the safepoint word was reworked into one process-global, four-byte-lane poll; gc-stress then went opt-in and ran at every safepoint on both arches, catching a string of unrooted-Value and FP-pool bugs (#1070#1075, #1123#1125).
  • Hash subsystem overhaul: an AR-mode small-hash table embedded directly in the RValue cell, JIT-inlined accessors ([]=, size, default, …), and correctness fixes for tombstone deletes and iteration order (#1060, #1086#1108).
  • JIT dispatch modernization: polymorphic call and comparison sites now dispatch through the PIC instead of guarding and evicting, with BinOp/BinCmp lowering unified into one skeleton (#1110, #1127#1133).
  • Chain deopt became the sole recovery path off a stale JIT frame, followed by a multi-week abstract-state and frame-chain rework (unified joins, outer-frame float promotion across block calls) that got the ActiveRecord benchmark running both correctly and fast (#1134, #1136, #1149#1168, #1171#1198).
  • aarch64 kept pace with the chain-deopt work: outlined side-exit islands, branch-range relaxation past the Imm19 reach, and ports of the class-version recovery jump-back (#1153, #1175, #1176, #1182, #1183, #1189).
  • Late-month perf sprint: cached Symbol#to_proc procs, dispatch-free Array/Range scans and equality-by-identity fast paths, plus a JIT correctness fix for inlined send and method_missing dispatch (#1200#1214).
  • Consolidated the README and wiki into the mdBook documentation site and added this generated Changelog chapter (#1215, #1216).

July 2026

  • Big language-semantics compliance drive on the ruby/spec “language” group: destructuring, block-argument semantics, defined?, flip-flops, BEGIN/END, and predefined globals (#804#874, notably #861).
  • Implemented pattern matching (case/in, =>) (#883) and MRI’s full eigenclass tower (#877).
  • Green threads (M:1): scheduler core, real Thread / Mutex / Queue, scheduler-integrated blocking IO, and preemptive timeslice multithreading (#941#944, #962).
  • Real TCP / UDP / UNIX-domain sockets (#964, #981); IO::Buffer with mmap file mapping (#927, #931); IO.copy_stream (#924).
  • Added the setup-monoruby GitHub Action with prebuilt binaries (#884, #886) and CRuby-compatible command-line option processing (#891).
  • Completed the Exception API: raise-time backtraces, full_message, NameError / NoMethodError metadata (#893#896).
  • Brought the aarch64 JIT to optimization parity with x86-64 (#993#1004) and shrank call frames for ~7% faster fib (#850).
  • Completed Fiber — transfer / raise / kill / storage and a real root fiber, making core/fiber fully green (#1036) — and refined Thread semantics: the async Thread#raise protocol and structured Thread::Backtrace::Location (#1026, #1027).
  • JIT: object allocation emitted as inline machine code (free-list pop + bump) (#1011), guard-free slot dispatch for method calls on aarch64 (#1010), and trivial-method folding through ... forwards (#1012).
  • Encoding: streaming Encoding::Converter state and String#encode fallback / newline decorators (#1018, #1019); Regexp gained native-encoding byte matching for non-UTF-8 subjects plus upstream Onigmo engine fixes (#1037, #1038).
  • CRuby-compatible require / load / autoload resolution rules (#1033), a Rust fnmatch engine backing Dir.glob (#1017), and an mdBook documentation site published to the project portal (#1008).

June 2026

  • Completed the aarch64 JIT backend: full AsmInst coverage, inline methods, loop JIT, and recompilation on Apple Silicon (#645#704).
  • Introduced a generational GC (RGenGC-style) (#705); GC now also triggers on malloc growth (#732).
  • Completed the Prism migration and removed the old hand-written parser (ruruby-parse) (#657).
  • New JIT register allocation: LIR-based lowering with a per-basic-block GP register allocator; retired the R15 accumulator (#741, #756, #763).
  • Cut allocation/dispatch overhead by 12–26% on addressable benchmarks (#708); zero-copy String operations (gsub, slice, lines, scan) (#722#724).
  • Made the build host-Ruby independent and reproducible (#769).

May 2026

  • Switched the parser to Prism, the official Ruby parser (#412).
  • Encoding subsystem overhaul: real String#encode (#443), Encoding::Converter (#447, #451), ISO-2022-JP (#449), and EUC-JP / Shift_JIS-aware string operations (#536#545).
  • Native String fast paths (reverse, rindex, case mapping, …) that beat YJIT (#493#497); dropped per-builtin catch_unwind for +8–10% on optcarrot (#501).
  • JIT: virtual FP registers with spill-to-stack (#387), heap-constant folding and Object#is_a? inlining (#504, #505), non-deopting polymorphic comparisons (#519).
  • Decoupled monoruby from any host Ruby installation (#579, #595); completed the Marshal format tags (#588#603); real File::Stat (#607); frame-local $~ / $_ (#608).
  • Started the aarch64 port: VM-tier backend and macOS (Apple Silicon) support (#640, #641, #644).
  • Continuous yjit-bench benchmarking against YJIT, charted on GitHub Pages (#411, #416).

April 2026

  • Reimplemented Rational as a first-class Rust type with literal support (#266).
  • Broad ruby/spec compliance work on Integer / Float / Array / Symbol / Class / Module (e.g. #281, #284, #309), with a live spec dashboard published on GitHub Pages (#364, #365).
  • Moved shift / bitwise / ** / % into the inline-function JIT pipeline with constant folding (#307, #308), and added frame-free trivial-method optimization via ISeqHint (#290).
  • Struct: per-instance slot storage with JIT-inlined member accessors (#367#369).
  • String: encoding-aware data model — code ranges, Encoding::CompatibilityError, encoding-aware char iteration (#382#384).
  • Reworked autoload as a proper state machine (#376) and added lazy heap promotion for Proc / Lambda / Binding captures (#332).

March 2026

  • Implemented Marshal.dump / Marshal.load (#121, #125) and the Set class, a CRuby 4.0 built-in (#130).
  • Implemented the retry statement (#109), module/class lifecycle hooks (#127), anonymous block forwarding (#128), and regex backreferences / special variables (#129).
  • Added Kernel.#load (#105), correct Dir.glob (#106), Kernel.#format / sprintf (#162), and a SQLite3 FFI bridge for the sqlite3 gem (#160).
  • Started a large ruby/spec compatibility push: implicit type conversions (#225), frozen-object support (#240), Errno exceptions (#250), and many crash fixes on invalid UTF-8 input (#209#212).
  • Fixed many issues to run optcarrot (#115) and the rubyboy / lee benchmarks (#111, #120).

February 2026

  • Optimized rest / keyword-rest parameters in the JIT (#96).
  • Corrected / and % semantics for Integer and Float (#97) and fixed Integer#digits (#99).
  • Optimized the Range class (#98) and fixed Range#include? for string / beginless / endless ranges (#104).
  • Introduced continuation frames (#101) and reworked JIT slot write-back logic (#102).

January 2026

  • Hardened JIT frame handling so local frames are never captured by JIT-compiled code (#93).
  • Added SAFETY comments to unsafe blocks across the codebase (#94).
  • Introduced immediate operands (BytecodeInst::Immediate) into the bytecode (#95).