Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ruby/ruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: Shopify/ruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: perfetto-trace-fallbacks
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 2 commits
  • 4 files changed
  • 3 contributors

Commits on Jun 12, 2026

  1. ZJIT: add --zjit-trace-fallbacks to trace JIT/interpreter execution

    Emit Perfetto duration slices for time spent in JIT code versus the
    interpreter, so a trace shows where a workload's time goes across the
    JIT/interpreter boundary. The codegen plants hooks at the boundary
    crossings:
    
      - the interpreter->JIT entry (gen_entry_point, interpreter entry only)
      - each send fallback to the interpreter (rb_vm_send and friends),
        bracketed by begin/end calls around the C call
      - the JIT exit trampoline (the common funnel for side exits)
    
    These call into stats.rs helpers that keep at most one execution span
    open at a time (depth <= 1), so slices never overlap: every transition
    ends the current span before beginning the next. Recording is limited to
    single-Ractor mode, where the GVL serializes JIT execution and tracer
    access is safe.
    
    Three things are deliberately not fully accounted for, and a trace
    should be read with them in mind:
    
      - The "interpreter" spans are really *fallback* spans. They are only
        opened at send-fallback call sites, so they measure interpreter time
        reached via a JIT fallback, not all interpreter execution. The slice
        name is kept constant ("interpreter") for easy filtering; the
        specific fallback kind (e.g. "invokesuper") rides along in the `kind`
        argument.
    
      - Interpreter time that never enters JIT code is unaccounted for. With
        no JIT entry there is no span to open, so top-level interpreter
        execution that never reaches a compiled method produces no slices at
        all.
    
      - jit->fallback->jit nesting leaves gaps. When a fallback's interpreter
        work itself calls a compiled method, that inner JIT entry ends the
        interpreter span and the inner exit ends the JIT span; the remaining
        interpreter time before control returns to the original fallback site
        is left with no open span. So a jit->fallback->jit sequence can have
        unaccounted-for portions.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    codex and claude committed Jun 12, 2026
    Configuration menu
    Copy the full SHA
    b79b411 View commit details
    Browse the repository at this point in the history

Commits on Jun 23, 2026

  1. ruby srcloc in addition

    XrXr committed Jun 23, 2026
    Configuration menu
    Copy the full SHA
    9dce3c7 View commit details
    Browse the repository at this point in the history
Loading