From 204928120bb6c81d660ac1c94fbd3284041b8920 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 25 Sep 2024 14:12:50 +0900 Subject: [PATCH] vm.c (cipop): fix improper code to check if env is reclaimed; fix #6369 The callinfo refers blk since #5786 but not marked at the time. Later we added reclamation check by #5791 but its repeated heap scans decrease the performance drastically in some cases. So the original @dearblue's solution should be taken Probably we need to always keep the original block at the bottom of arguments. And the explicit block argument should be a normal local variable. We will investigate it later. --- src/gc.c | 1 + src/vm.c | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gc.c b/src/gc.c index a9549e730..32b39a59d 100644 --- a/src/gc.c +++ b/src/gc.c @@ -582,6 +582,7 @@ mark_context(mrb_state *mrb, struct mrb_context *c) if (c->cibase) { for (ci = c->cibase; ci <= c->ci; ci++) { mrb_gc_mark(mrb, (struct RBasic*)ci->proc); + mrb_gc_mark(mrb, (struct RBasic*)ci->blk); mrb_gc_mark(mrb, (struct RBasic*)ci->u.target_class); } } diff --git a/src/vm.c b/src/vm.c index 4d685e265..936808a3d 100644 --- a/src/vm.c +++ b/src/vm.c @@ -460,8 +460,7 @@ cipop(mrb_state *mrb) ci_env_set(ci, NULL); // make possible to free env by GC if not needed struct RProc *b = ci->blk; - if (b && !mrb_object_dead_p(mrb, (struct RBasic*)b) && b->tt == MRB_TT_PROC && - !MRB_PROC_STRICT_P(b) && MRB_PROC_ENV(b) == CI_ENV(&ci[-1])) { + if (b && !MRB_PROC_STRICT_P(b) && MRB_PROC_ENV(b) == CI_ENV(&ci[-1])) { b->flags |= MRB_PROC_ORPHAN; } if (env && !mrb_env_unshare(mrb, env, TRUE)) {