From 93f5f225772c398be6e409da3d3ef0f07ffbe1cf Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 26 Oct 2017 01:13:57 +0900 Subject: Heavily refactored how lexical scope links are implemented; fix #3821 Instead of `irep` links, we added a `upper` link to `struct RProc`. To make a space for the `upper` link, we moved `target_class` reference. If a `Proc` does not have `env`, `target_class` is saved in an `union` shared with `env` (if a `Proc` has env, you can tell it by `MRB_PROC_ENV_P()). Otherwise `target_class` is referenced from `env->c`. We removed links in `env` as well. This change removes 2 members from `mrb_irep` struct, thus saving 2 words per method/proc/block. This also fixes potential memory leaks due to the circular references caused by a link from `mrb_irep`. --- src/class.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/class.c') diff --git a/src/class.c b/src/class.c index a35eb4c92..77a7050da 100644 --- a/src/class.c +++ b/src/class.c @@ -436,8 +436,11 @@ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, struct RPro k = kh_put(mt, mrb, h, mid); kh_value(h, k) = p; if (p) { + p->flags |= MRB_PROC_SCOPE; p->c = NULL; - mrb_field_write_barrier(mrb, (struct RBasic *)c, (struct RBasic *)p); + mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)p); + MRB_PROC_SET_TARGET_CLASS(p, c); + mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)c); } mc_clear_by_id(mrb, c, mid); } @@ -449,7 +452,7 @@ mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t f int ai = mrb_gc_arena_save(mrb); p = mrb_proc_new_cfunc(mrb, func); - p->target_class = c; + MRB_PROC_SET_TARGET_CLASS(p, c); mrb_define_method_raw(mrb, c, mid, p); mrb_gc_arena_restore(mrb, ai); } -- cgit v1.2.3