From 3d8ccee7a8ccf4660f19ab2e266734593a763a39 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 23 Mar 2026 09:12:42 +0900 Subject: [PATCH] vm.c: optimize cipush/cipop for common cases CI_PROC_SET: split NULL/non-NULL proc paths so the compiler can eliminate the CFUNC/ALIAS checks when proc is a compile-time NULL (8 of 11 cipush call sites). cipop: add fast path for the common case where no env and no blk are set. skips ci_env_set, orphan check, and env_unshare entirely. most simple method calls (no blocks, no closures) take this path. Co-authored-by: Claude --- src/vm.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/vm.c b/src/vm.c index 21813c215..8664df1cf 100644 --- a/src/vm.c +++ b/src/vm.c @@ -271,8 +271,13 @@ top_proc(mrb_state *mrb, const struct RProc *proc, const struct REnv **envp) #define CI_PROC_SET(ci, p) do {\ ci->proc = p;\ - mrb_assert(!p || !MRB_PROC_ALIAS_P(p));\ - ci->pc = (p && !MRB_PROC_CFUNC_P(p) && p->body.irep) ? p->body.irep->iseq : NULL;\ + if (p) {\ + mrb_assert(!MRB_PROC_ALIAS_P(p));\ + ci->pc = (!MRB_PROC_CFUNC_P(p) && p->body.irep) ? p->body.irep->iseq : NULL;\ + }\ + else {\ + ci->pc = NULL;\ + }\ } while (0) void @@ -490,8 +495,14 @@ cipop(mrb_state *mrb) { struct mrb_context *c = mrb->c; mrb_callinfo *ci = c->ci; - struct REnv *env = CI_ENV(ci); + /* Fast path: no env and no blk (most common for simple method calls) */ + if (mrb_likely((!ci->u.env || ci->u.env->tt != MRB_TT_ENV) && !ci->blk)) { + c->ci--; + return c->ci; + } + + struct REnv *env = CI_ENV(ci); ci_env_set(ci, NULL); // make possible to free env by GC if not needed struct RProc *b = ci->blk; if (b && !MRB_PROC_STRICT_P(b) && MRB_PROC_ENV(b) == CI_ENV(&ci[-1])) {