mirror of
https://github.com/rkujawa/rk65c02.git
synced 2026-10-24 16:02:15 +00:00
setjmp was executed once per block dispatch to guard against longjmp from MMU faults and panics inside compiled blocks. One setjmp per rk65c02_run_jit call is equivalent: emu_stop_error sets a terminal state and clears in_jit_run before jumping, so the fault path lands before the loop, processes any write events the faulting block had recorded (shared jit_process_pending_writes helper), and the loop condition exits. disable_jit_for_run is volatile per setjmp rules. Result: functional ROM JIT speedup 2.40x -> 2.61x, extended 3.03x -> 3.28x (~8% less JIT time), fault paths still green (mmu fault tests, mmu_pae). Instrumentation added for dispatch-cost attribution: - insns_executed in rk65c02_jit_stats (blocks record num_insns); bench_functional prints avg insns/block and emulated MIPS - bench_functional takes an optional tick-interval argument - JIT_PAGE_INVALIDATION_THRESHOLD / JIT_MAX_INVALIDATIONS_PER_RUN overridable via -D for experiments (defaults unchanged) - msbasic host: RK65C02_JIT=0 disables JIT, RK65C02_JIT_STATS=1 dumps stats to stderr; bench.bas benchmark program for scripted runs Attribution findings (medians, this machine): - avg insns/block: 4.9 (Dormann functional), 3.5 (MS BASIC) - per- dispatch overhead is the dominant JIT-mode cost; block chaining is the next big lever - tick at interval 0 costs ~10% in BOTH modes (harness artifact, speedup ratio unchanged) - disabling page demotion makes things WORSE (functional drops to 0.97x: unbounded invalidation churn until the run budget disables JIT) - demotion is a net win, not a cost - MS BASIC: 2.5x under JIT (1.02s vs 2.55s); write_events=4, pages_demoted=1 - CHRGET-style zero-page SMC gets its page demoted at startup, so BASIC's hottest routine runs interpreted all session; dynamic-operand recompilation (Tier 4) is the targeted fix Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>