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`.
This commit is contained in:
Yukihiro "Matz" Matsumoto
2017-10-26 01:13:57 +09:00
parent 3f9d00ded3
commit 93f5f22577
14 changed files with 263 additions and 269 deletions
+5 -2
View File
@@ -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);
}