diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-10-26 01:13:57 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-10-28 00:29:30 +0900 |
| commit | 93f5f225772c398be6e409da3d3ef0f07ffbe1cf (patch) | |
| tree | 37198a8c50baaf1a5714a581e049167073249ddc /include | |
| parent | 3f9d00ded3ce987927d975f7ce70637a973de1fc (diff) | |
| download | mruby-93f5f225772c398be6e409da3d3ef0f07ffbe1cf.tar.gz mruby-93f5f225772c398be6e409da3d3ef0f07ffbe1cf.zip | |
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`.
Diffstat (limited to 'include')
| -rw-r--r-- | include/mruby/irep.h | 3 | ||||
| -rw-r--r-- | include/mruby/proc.h | 43 |
2 files changed, 32 insertions, 14 deletions
diff --git a/include/mruby/irep.h b/include/mruby/irep.h index 91ca8b54d..efd226793 100644 --- a/include/mruby/irep.h +++ b/include/mruby/irep.h @@ -45,9 +45,6 @@ typedef struct mrb_irep { struct mrb_irep_debug_info* debug_info; int ilen, plen, slen, rlen, refcnt; - - struct mrb_irep *outer; /* Refers outer scope */ - struct RClass *target_class; } mrb_irep; #define MRB_ISEQ_NO_FREE 1 diff --git a/include/mruby/proc.h b/include/mruby/proc.h index 5a6741610..24c9b0c21 100644 --- a/include/mruby/proc.h +++ b/include/mruby/proc.h @@ -18,17 +18,19 @@ MRB_BEGIN_DECL struct REnv { MRB_OBJECT_HEADER; mrb_value *stack; - ptrdiff_t cioff; - union { - mrb_sym mid; - struct mrb_context *c; - } cxt; + struct mrb_context *cxt; + // struct RProc *proc; + mrb_sym mid; }; -#define MRB_SET_ENV_STACK_LEN(e,len) (e)->flags = (unsigned int)(len) -#define MRB_ENV_STACK_LEN(e) ((mrb_int)(e)->flags) -#define MRB_ENV_UNSHARE_STACK(e) ((e)->cioff = -1) -#define MRB_ENV_STACK_SHARED_P(e) ((e)->cioff >= 0) +/* flags (21bits): 1(shared flag):10(cioff/bidx):10(stack_len) */ +#define MRB_ENV_SET_STACK_LEN(e,len) (e)->flags = (((e)->flags & ~0x3ff)|(unsigned int)(len) & 0x3ff) +#define MRB_ENV_STACK_LEN(e) ((mrb_int)((e)->flags & 0x3ff)) +#define MRB_ENV_STACK_UNSHARED (1<<20) +#define MRB_ENV_UNSHARE_STACK(e) (e)->flags |= MRB_ENV_STACK_UNSHARED +#define MRB_ENV_STACK_SHARED_P(e) (((e)->flags & MRB_ENV_STACK_UNSHARED) == 0) +#define MRB_ENV_BIDX(e) (((e)->flags >> 10) & 0x3ff) +#define MRB_ENV_SET_BIDX(e,idx) (e)->flags = (((e)->flags & ~(0x3ff<<10))|((unsigned int)(idx) & 0x3ff)<<10) void mrb_env_unshare(mrb_state*, struct REnv*); @@ -38,8 +40,11 @@ struct RProc { mrb_irep *irep; mrb_func_t func; } body; - struct RClass *target_class; - struct REnv *env; + struct RProc *upper; + union { + struct RClass *target_class; + struct REnv *env; + } e; }; /* aspec access */ @@ -57,6 +62,22 @@ struct RProc { #define MRB_PROC_STRICT_P(p) (((p)->flags & MRB_PROC_STRICT) != 0) #define MRB_PROC_ORPHAN 512 #define MRB_PROC_ORPHAN_P(p) (((p)->flags & MRB_PROC_ORPHAN) != 0) +#define MRB_PROC_ENVSET 1024 +#define MRB_PROC_ENV_P(p) (((p)->flags & MRB_PROC_ENVSET) != 0) +#define MRB_PROC_ENV(p) (MRB_PROC_ENV_P(p) ? (p)->e.env : NULL) +#define MRB_PROC_TARGET_CLASS(p) (MRB_PROC_ENV_P(p) ? (p)->e.env->c : (p)->e.target_class ) +#define MRB_PROC_SET_TARGET_CLASS(p,tc) do {\ + if (MRB_PROC_ENV_P(p)) {\ + (p)->e.env->c = (tc);\ + mrb_field_write_barrier(mrb, (struct RBasic*)(p)->e.env, (struct RBasic*)tc);\ + }\ + else {\ + (p)->e.target_class = (tc);\ + mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)tc);\ + }\ +} while (0) +#define MRB_PROC_SCOPE 2048 +#define MRB_PROC_SCOPE_P(p) (((p)->flags & MRB_PROC_SCOPE) != 0) #define mrb_proc_ptr(v) ((struct RProc*)(mrb_ptr(v))) |
