From 0a71db8a7497df37b984ea97abfce6b6ffd82df3 Mon Sep 17 00:00:00 2001 From: ko1 Date: Mon, 11 Jun 2012 03:14:59 +0000 Subject: * vm_core.h: remove lfp (local frame pointer) and rename dfp (dynamic frame pointer) to ep (environment pointer). This change make VM `normal' (similar to other interpreters). Before this commit: Each frame has two env pointers lfp and dfp. lfp points local environment which is method/class/toplevel frame. lfp[0] is block pointer. dfp is block local frame. dfp[0] points previous (parent) environment pointer. lfp == dfp when frame is method/class/toplevel. You can get lfp from dfp by traversing previous environment pointers. After this commit: Each frame has only `ep' to point respective enviornoment. If there is parent environment, then ep[0] points parent envioenment (as dfp). If there are no more environment, then ep[0] points block pointer (as lfp). We call such ep as `LEP' (local EP). We add some macros to get LEP and to detect LEP or not. In short, we replace dfp and lfp with ep and LEP. rb_block_t and rb_binding_t member `lfp' and `dfp' are removed and member `ep' is added. rename rb_thread_t's member `local_lfp' and `local_svar' to `root_lep' and `root_svar'. (VM_EP_PREV_EP(ep)): get previous environment pointer. This macro assume that ep is not LEP. (VM_EP_BLOCK_PTR(ep)): get block pointer. This macro assume that ep is LEP. (VM_EP_LEP_P(ep)): detect ep is LEP or not. (VM_ENVVAL_BLOCK_PTR(ptr)): make block pointer. (VM_ENVVAL_BLOCK_PTR_P(v)): detect v is block pointer. (VM_ENVVAL_PREV_EP_PTR(ptr)): make prev environment pointer. (VM_ENVVAL_PREV_EP_PTR_P(v)): detect v is prev env pointer. * vm.c: apply above changes. (VM_EP_LEP(ep)): get LEP. (VM_CF_LEP(cfp)): get LEP of cfp->ep. (VM_CF_PREV_EP(cfp)): utility function VM_EP_PREV_EP(cfp->ep). (VM_CF_BLOCK_PTR(cfp)): utility function VM_EP_BLOCK_PTR(cfp->ep). * vm.c, vm_eval.c, vm_insnhelper.c, vm_insnhelper.h, insns.def: apply above changes. * cont.c: ditto. * eval.c, eval_intern.h: ditto. * proc.c: ditto. * thread.c: ditto. * vm_dump.c: ditto. * vm_exec.h: fix function name (on vm debug mode). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36030 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 57 +++++++++++++++ cont.c | 9 ++- eval.c | 10 +-- eval_intern.h | 2 +- insns.def | 48 ++++++------- proc.c | 14 ++-- thread.c | 4 +- vm.c | 211 ++++++++++++++++++++++++++++++++------------------------ vm_core.h | 43 +++++++++--- vm_dump.c | 78 +++++++++------------ vm_eval.c | 30 ++++---- vm_exec.h | 4 +- vm_insnhelper.c | 192 +++++++++++++++++++++++---------------------------- vm_insnhelper.h | 45 +++++++----- 14 files changed, 413 insertions(+), 334 deletions(-) diff --git a/ChangeLog b/ChangeLog index 66f0197216..0c4f839bbb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,60 @@ +Mon Jun 11 12:14:37 2012 Koichi Sasada + + * vm_core.h: remove lfp (local frame pointer) and rename + dfp (dynamic frame pointer) to ep (environment pointer). + This change make VM `normal' (similar to other interpreters). + Before this commit: + Each frame has two env pointers lfp and dfp. lfp points + local environment which is method/class/toplevel frame. + lfp[0] is block pointer. + dfp is block local frame. dfp[0] points previous (parent) + environment pointer. + lfp == dfp when frame is method/class/toplevel. + You can get lfp from dfp by traversing previous environment + pointers. + After this commit: + Each frame has only `ep' to point respective enviornoment. + If there is parent environment, then ep[0] points parent + envioenment (as dfp). If there are no more environment, + then ep[0] points block pointer (as lfp). We call such ep + as `LEP' (local EP). We add some macros to get LEP and to + detect LEP or not. + In short, we replace dfp and lfp with ep and LEP. + rb_block_t and rb_binding_t member `lfp' and `dfp' are removed + and member `ep' is added. + rename rb_thread_t's member `local_lfp' and `local_svar' to + `root_lep' and `root_svar'. + (VM_EP_PREV_EP(ep)): get previous environment pointer. This macro + assume that ep is not LEP. + (VM_EP_BLOCK_PTR(ep)): get block pointer. This macro assume + that ep is LEP. + (VM_EP_LEP_P(ep)): detect ep is LEP or not. + (VM_ENVVAL_BLOCK_PTR(ptr)): make block pointer. + (VM_ENVVAL_BLOCK_PTR_P(v)): detect v is block pointer. + (VM_ENVVAL_PREV_EP_PTR(ptr)): make prev environment pointer. + (VM_ENVVAL_PREV_EP_PTR_P(v)): detect v is prev env pointer. + + * vm.c: apply above changes. + (VM_EP_LEP(ep)): get LEP. + (VM_CF_LEP(cfp)): get LEP of cfp->ep. + (VM_CF_PREV_EP(cfp)): utility function VM_EP_PREV_EP(cfp->ep). + (VM_CF_BLOCK_PTR(cfp)): utility function VM_EP_BLOCK_PTR(cfp->ep). + + * vm.c, vm_eval.c, vm_insnhelper.c, vm_insnhelper.h, insns.def: + apply above changes. + + * cont.c: ditto. + + * eval.c, eval_intern.h: ditto. + + * proc.c: ditto. + + * thread.c: ditto. + + * vm_dump.c: ditto. + + * vm_exec.h: fix function name (on vm debug mode). + Mon Jun 11 11:52:18 2012 URABE Shyouhei * compile.c (iseq_set_sequence): nonstatic initializer of an diff --git a/cont.c b/cont.c index 4ca1279d02..83769abb59 100644 --- a/cont.c +++ b/cont.c @@ -1059,9 +1059,8 @@ fiber_init(VALUE fibval, VALUE proc) th->cfp->pc = 0; th->cfp->sp = th->stack + 1; th->cfp->bp = 0; - th->cfp->lfp = th->stack; - *th->cfp->lfp = 0; - th->cfp->dfp = th->stack; + th->cfp->ep = th->stack; + *th->cfp->ep = VM_ENVVAL_BLOCK_PTR(0); th->cfp->self = Qnil; th->cfp->flag = 0; th->cfp->iseq = 0; @@ -1155,8 +1154,8 @@ rb_fiber_start(void) argv = (argc = cont->argc) > 1 ? RARRAY_PTR(args) : &args; cont->value = Qnil; th->errinfo = Qnil; - th->local_lfp = proc->block.lfp; - th->local_svar = Qnil; + th->root_lep = rb_vm_ep_local_ep(proc->block.ep); + th->root_svar = Qnil; fib->status = RUNNING; cont->value = rb_vm_invoke_proc(th, proc, proc->block.self, argc, argv, 0); diff --git a/eval.c b/eval.c index 54884850e9..3ec0e1a282 100644 --- a/eval.c +++ b/eval.c @@ -604,7 +604,7 @@ rb_block_given_p(void) { rb_thread_t *th = GET_THREAD(); - if (RUBY_VM_GET_BLOCK_PTR(th->cfp)) { + if (rb_vm_control_frame_block_ptr(th->cfp)) { return TRUE; } else { @@ -1054,12 +1054,12 @@ errinfo_place(rb_thread_t *th) while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) { if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) { if (cfp->iseq->type == ISEQ_TYPE_RESCUE) { - return &cfp->dfp[-2]; + return &cfp->ep[-2]; } else if (cfp->iseq->type == ISEQ_TYPE_ENSURE && - !RB_TYPE_P(cfp->dfp[-2], T_NODE) && - !FIXNUM_P(cfp->dfp[-2])) { - return &cfp->dfp[-2]; + !RB_TYPE_P(cfp->ep[-2], T_NODE) && + !FIXNUM_P(cfp->ep[-2])) { + return &cfp->ep[-2]; } } cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); diff --git a/eval_intern.h b/eval_intern.h index dd1092020b..fb852cbca5 100644 --- a/eval_intern.h +++ b/eval_intern.h @@ -5,7 +5,7 @@ #include "vm_core.h" #define PASS_PASSED_BLOCK_TH(th) do { \ - (th)->passed_block = GC_GUARDED_PTR_REF((rb_block_t *)(th)->cfp->lfp[0]); \ + (th)->passed_block = rb_vm_control_frame_block_ptr(th->cfp); \ (th)->cfp->flag |= VM_FRAME_FLAG_PASSED; \ } while (0) diff --git a/insns.def b/insns.def index a4f792897b..379dbfba03 100644 --- a/insns.def +++ b/insns.def @@ -55,7 +55,7 @@ getlocal () (VALUE val) { - val = *(GET_LFP() - idx); + val = *(GET_LEP() - idx); } /** @@ -69,7 +69,7 @@ setlocal (VALUE val) () { - (*(GET_LFP() - idx)) = val; + *(GET_LEP() - idx) = val; } /** @@ -83,7 +83,7 @@ getspecial () (VALUE val) { - val = vm_getspecial(th, GET_LFP(), key, type); + val = vm_getspecial(th, GET_LEP(), key, type); } /** @@ -97,7 +97,7 @@ setspecial (VALUE obj) () { - lfp_svar_set(th, GET_LFP(), key, obj); + lep_svar_set(th, GET_LEP(), key, obj); } /** @@ -114,11 +114,11 @@ getdynamic (VALUE val) { rb_num_t i; - VALUE *dfp2 = GET_DFP(); + VALUE *ep = GET_EP(); for (i = 0; i < level; i++) { - dfp2 = GET_PREV_DFP(dfp2); + ep = GET_PREV_EP(ep); } - val = *(dfp2 - idx); + val = *(ep - idx); } /** @@ -135,11 +135,11 @@ setdynamic () { rb_num_t i; - VALUE *dfp2 = GET_DFP(); + VALUE *ep = GET_EP(); for (i = 0; i < level; i++) { - dfp2 = GET_PREV_DFP(dfp2); + ep = GET_PREV_EP(ep); } - *(dfp2 - idx) = val; + *(ep - idx) = val; } /** @@ -183,7 +183,7 @@ getclassvariable () (VALUE val) { - NODE * const cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP()); + NODE *cref = vm_get_cref(GET_ISEQ(), GET_EP()); val = rb_cvar_get(vm_get_cvar_base(cref), id); } @@ -198,7 +198,7 @@ setclassvariable (VALUE val) () { - NODE * const cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP()); + NODE *cref = vm_get_cref(GET_ISEQ(), GET_EP()); rb_cvar_set(vm_get_cvar_base(cref), id, val); } @@ -343,10 +343,10 @@ putspecialobject val = rb_mRubyVMFrozenCore; break; case VM_SPECIAL_OBJECT_CBASE: - val = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP()); + val = vm_get_cbase(GET_ISEQ(), GET_EP()); break; case VM_SPECIAL_OBJECT_CONST_BASE: - val = vm_get_const_base(GET_ISEQ(), GET_LFP(), GET_DFP()); + val = vm_get_const_base(GET_ISEQ(), GET_EP()); break; default: rb_bug("putspecialobject insn: unknown value_type"); @@ -768,7 +768,7 @@ defined } break; case DEFINED_IVAR2: - klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP()); + klass = vm_get_cbase(GET_ISEQ(), GET_EP()); break; case DEFINED_GVAR: if (rb_gvar_defined(rb_global_entry(SYM2ID(obj)))) { @@ -777,7 +777,7 @@ defined break; case DEFINED_CVAR: { - NODE *cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP()); + NODE *cref = vm_get_cref(GET_ISEQ(), GET_EP()); klass = vm_get_cvar_base(cref); if (rb_cvar_defined(klass, SYM2ID(obj))) { expr_type = "class variable"; @@ -842,7 +842,7 @@ defined break; } case DEFINED_REF:{ - val = vm_getspecial(th, GET_LFP(), Qfalse, FIX2INT(obj)); + val = vm_getspecial(th, GET_LEP(), Qfalse, FIX2INT(obj)); if (val != Qnil) { expr_type = "global-variable"; } @@ -971,9 +971,9 @@ defineclass COPY_CREF(class_iseq->cref_stack, vm_cref_push(th, klass, NOEX_PUBLIC, NULL)); /* enter scope */ - vm_push_frame(th, class_iseq, - VM_FRAME_MAGIC_CLASS, klass, (VALUE) GET_BLOCK_PTR(), - class_iseq->iseq_encoded, GET_SP(), 0, + vm_push_frame(th, class_iseq, VM_FRAME_MAGIC_CLASS, + klass, VM_ENVVAL_BLOCK_PTR(GET_BLOCK_PTR()), + class_iseq->iseq_encoded, GET_SP(), class_iseq->local_size); RESTORE_REGS(); @@ -1315,11 +1315,11 @@ opt_checkenv () () { - if (GET_CFP()->bp != GET_DFP() + 1) { - VALUE *new_dfp = GET_CFP()->bp - 1; + if (GET_CFP()->bp != GET_EP() + 1) { + VALUE *ep = GET_CFP()->bp - 1; /* TODO: copy env and clean stack at creating env? */ - *new_dfp = *GET_DFP(); - SET_DFP(new_dfp); + *ep = *GET_EP(); + SET_EP(ep); } } diff --git a/proc.c b/proc.c index b0437db9cd..1298c21c93 100644 --- a/proc.c +++ b/proc.c @@ -383,17 +383,13 @@ proc_new(VALUE klass, int is_lambda) rb_control_frame_t *cfp = th->cfp; rb_block_t *block; - if ((GC_GUARDED_PTR_REF(cfp->lfp[0])) != 0) { - - block = GC_GUARDED_PTR_REF(cfp->lfp[0]); + if ((block = rb_vm_control_frame_block_ptr(cfp)) != 0) { + /* block found */ } else { cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); - if ((GC_GUARDED_PTR_REF(cfp->lfp[0])) != 0) { - - block = GC_GUARDED_PTR_REF(cfp->lfp[0]); - + if ((block = rb_vm_control_frame_block_ptr(cfp)) != 0) { if (is_lambda) { rb_warn("tried to create Proc object without a block"); } @@ -418,7 +414,7 @@ proc_new(VALUE klass, int is_lambda) } procval = rb_vm_make_proc(th, block, klass); - rb_vm_rewrite_dfp_in_errinfo(th, cfp); + rb_vm_rewrite_ep_in_errinfo(th, cfp); if (is_lambda) { rb_proc_t *proc; @@ -801,7 +797,7 @@ rb_hash_proc(st_index_t hash, VALUE prc) GetProcPtr(prc, proc); hash = rb_hash_uint(hash, (st_index_t)proc->block.iseq); hash = rb_hash_uint(hash, (st_index_t)proc->envval); - return rb_hash_uint(hash, (st_index_t)proc->block.lfp >> 16); + return rb_hash_uint(hash, (st_index_t)proc->block.ep >> 16); } /* diff --git a/thread.c b/thread.c index 609e726620..6ad4503470 100644 --- a/thread.c +++ b/thread.c @@ -454,8 +454,8 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_s if (!th->first_func) { GetProcPtr(th->first_proc, proc); th->errinfo = Qnil; - th->local_lfp = proc->block.lfp; - th->local_svar = Qnil; + th->root_lep = rb_vm_ep_local_ep(proc->block.ep); + th->root_svar = Qnil; th->value = rb_vm_invoke_proc(th, proc, proc->block.self, (int)RARRAY_LEN(args), RARRAY_PTR(args), 0); } diff --git a/vm.c b/vm.c index 0f7f0923d4..7a7de59f3a 100644 --- a/vm.c +++ b/vm.c @@ -19,6 +19,48 @@ #include "iseq.h" #include "eval_intern.h" +static inline VALUE * +VM_EP_LEP(VALUE *ep) +{ + while (1) { + if (VM_EP_LEP_P(ep)) { + return ep; + } + ep = VM_EP_PREV_EP(ep); + } +} + +VALUE * +rb_vm_ep_local_ep(VALUE *ep) +{ + return VM_EP_LEP(ep); +} + +static inline VALUE * +VM_CF_LEP(rb_control_frame_t *cfp) +{ + return VM_EP_LEP(cfp->ep); +} + +static inline VALUE * +VM_CF_PREV_EP(rb_control_frame_t * cfp) +{ + return VM_EP_PREV_EP((cfp)->ep); +} + +static inline rb_block_t * +VM_CF_BLOCK_PTR(rb_control_frame_t *cfp) +{ + VALUE *ep = VM_CF_LEP(cfp); + return VM_EP_BLOCK_PTR(ep); +} + +rb_block_t * +rb_vm_control_frame_block_ptr(rb_control_frame_t *cfp) +{ + return VM_CF_BLOCK_PTR(cfp); +} + #include "vm_insnhelper.h" #include "vm_insnhelper.c" #include "vm_exec.h" @@ -85,8 +127,8 @@ static inline VALUE rb_vm_set_finish_env(rb_thread_t * th) { vm_push_frame(th, 0, VM_FRAME_MAGIC_FINISH, - Qnil, th->cfp->lfp[0], 0, - th->cfp->sp, 0, 1); + Qnil, VM_ENVVAL_BLOCK_PTR(VM_CF_BLOCK_PTR(th->cfp)), 0, + th->cfp->sp, 1); th->cfp->pc = (VALUE *)&finish_insn_seq[0]; return Qtrue; } @@ -106,8 +148,8 @@ vm_set_top_stack(rb_thread_t * th, VALUE iseqval) CHECK_STACK_OVERFLOW(th->cfp, iseq->local_size + iseq->stack_max); vm_push_frame(th, iseq, VM_FRAME_MAGIC_TOP, - th->top_self, 0, iseq->iseq_encoded, - th->cfp->sp, 0, iseq->local_size); + th->top_self, VM_ENVVAL_BLOCK_PTR(0), iseq->iseq_encoded, + th->cfp->sp, iseq->local_size); } static void @@ -122,11 +164,11 @@ vm_set_eval_stack(rb_thread_t * th, VALUE iseqval, const NODE *cref) CHECK_STACK_OVERFLOW(th->cfp, iseq->local_size + iseq->stack_max); vm_push_frame(th, iseq, VM_FRAME_MAGIC_EVAL, block->self, - GC_GUARDED_PTR(block->dfp), iseq->iseq_encoded, - th->cfp->sp, block->lfp, iseq->local_size); + VM_ENVVAL_PREV_EP_PTR(block->ep), iseq->iseq_encoded, + th->cfp->sp, iseq->local_size); if (cref) { - th->cfp->dfp[-1] = (VALUE)cref; + th->cfp->ep[-1] = (VALUE)cref; } } @@ -298,11 +340,10 @@ static int check_env(rb_env_t * const env) { fprintf(stderr, "---\n"); - fprintf(stderr, "envptr: %p\n", (void *)&env->block.dfp[0]); - fprintf(stderr, "envval: %10p ", (void *)env->block.dfp[1]); - dp(env->block.dfp[1]); - fprintf(stderr, "lfp: %10p\n", (void *)env->block.lfp); - fprintf(stderr, "dfp: %10p\n", (void *)env->block.dfp); + fprintf(stderr, "envptr: %p\n", (void *)&env->block.ep[0]); + fprintf(stderr, "envval: %10p ", (void *)env->block.ep[1]); + dp(env->block.ep[1]); + fprintf(stderr, "ep: %10p\n", (void *)env->block.ep); if (env->prev_envval) { fprintf(stderr, ">>\n"); check_env_value(env->prev_envval); @@ -345,16 +386,15 @@ vm_make_env_each(rb_thread_t * const th, rb_control_frame_t * const cfp, penvval = ENV_VAL(penvptr); } else { - while (pcfp->dfp != penvptr) { + while (pcfp->ep != penvptr) { pcfp++; - if (pcfp->dfp == 0) { + if (pcfp->ep == 0) { SDR(); - rb_bug("invalid dfp"); + rb_bug("invalid ep"); } } penvval = vm_make_env_each(th, pcfp, penvptr, endptr); - cfp->lfp = pcfp->lfp; - *envptr = GC_GUARDED_PTR(pcfp->dfp); + *envptr = VM_ENVVAL_PREV_EP_PTR(pcfp->ep); } } @@ -389,23 +429,19 @@ vm_make_env_each(rb_thread_t * const th, rb_control_frame_t * const cfp, nenvptr = &env->env[i - 1]; nenvptr[1] = envval; /* frame self */ - /* reset lfp/dfp in cfp */ - cfp->dfp = nenvptr; - if (envptr == endptr) { - cfp->lfp = nenvptr; - } + /* reset ep in cfp */ + cfp->ep = nenvptr; /* as Binding */ env->block.self = cfp->self; - env->block.lfp = cfp->lfp; - env->block.dfp = cfp->dfp; + env->block.ep = cfp->ep; env->block.iseq = cfp->iseq; if (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) { /* TODO */ env->block.iseq = 0; } else { - rb_vm_rewrite_dfp_in_errinfo(th, cfp); + rb_vm_rewrite_ep_in_errinfo(th, cfp); } return envval; } @@ -436,11 +472,11 @@ collect_local_variables_in_env(rb_env_t * env, const VALUE ary) } static int -vm_collect_local_variables_in_heap(rb_thread_t *th, VALUE *dfp, VALUE ary) +vm_collect_local_variables_in_heap(rb_thread_t *th, VALUE *ep, VALUE ary) { - if (ENV_IN_HEAP_P(th, dfp)) { + if (ENV_IN_HEAP_P(th, ep)) { rb_env_t *env; - GetEnvPtr(ENV_VAL(dfp), env); + GetEnvPtr(ENV_VAL(ep), env); collect_local_variables_in_env(env, ary); return 1; } @@ -459,7 +495,7 @@ rb_vm_make_env_object(rb_thread_t * th, rb_control_frame_t *cfp) cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); } - envval = vm_make_env_each(th, cfp, cfp->dfp, cfp->lfp); + envval = vm_make_env_each(th, cfp, cfp->ep, VM_CF_LEP(cfp)); if (PROCDEBUG) { check_env_value(envval); @@ -469,21 +505,21 @@ rb_vm_make_env_object(rb_thread_t * th, rb_control_frame_t *cfp) } void -rb_vm_rewrite_dfp_in_errinfo(rb_thread_t *th, rb_control_frame_t *cfp) +rb_vm_rewrite_ep_in_errinfo(rb_thread_t *th, rb_control_frame_t *cfp) { - /* rewrite dfp in errinfo to point to heap */ + /* rewrite ep in errinfo to point to heap */ if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq) && (cfp->iseq->type == ISEQ_TYPE_RESCUE || cfp->iseq->type == ISEQ_TYPE_ENSURE)) { - VALUE errinfo = cfp->dfp[-2]; /* #$! */ + VALUE errinfo = cfp->ep[-2]; /* #$! */ if (RB_TYPE_P(errinfo, T_NODE)) { - VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(errinfo); - if (! ENV_IN_HEAP_P(th, escape_dfp)) { - VALUE dfpval = *escape_dfp; - if (CLASS_OF(dfpval) == rb_cEnv) { - rb_env_t *dfpenv; - GetEnvPtr(dfpval, dfpenv); - SET_THROWOBJ_CATCH_POINT(errinfo, (VALUE)(dfpenv->env + dfpenv->local_size)); + VALUE *escape_ep = GET_THROWOBJ_CATCH_POINT(errinfo); + if (! ENV_IN_HEAP_P(th, escape_ep)) { + VALUE epval = *escape_ep; + if (CLASS_OF(epval) == rb_cEnv) { + rb_env_t *epenv; + GetEnvPtr(epval, epenv); + SET_THROWOBJ_CATCH_POINT(errinfo, (VALUE)(epenv->env + epenv->local_size)); } } } @@ -517,19 +553,19 @@ rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass) VALUE procval, envval, blockprocval = 0; rb_proc_t *proc; rb_control_frame_t *cfp = RUBY_VM_GET_CFP_FROM_BLOCK_PTR(block); + rb_block_t *block2; if (block->proc) { rb_bug("rb_vm_make_proc: Proc value is already created."); } - if (GC_GUARDED_PTR_REF(cfp->lfp[0])) { + if ((block2 = VM_CF_BLOCK_PTR(cfp)) != 0) { rb_proc_t *p; - blockprocval = vm_make_proc_from_block( - th, (rb_block_t *)GC_GUARDED_PTR_REF(*cfp->lfp)); + blockprocval = vm_make_proc_from_block(th, block2); GetProcPtr(blockprocval, p); - *cfp->lfp = GC_GUARDED_PTR(&p->block); + *VM_CF_LEP(cfp) = VM_ENVVAL_BLOCK_PTR(&p->block); } envval = rb_vm_make_env_object(th, cfp); @@ -541,19 +577,15 @@ rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass) GetProcPtr(procval, proc); proc->blockprocval = blockprocval; proc->block.self = block->self; - proc->block.lfp = block->lfp; - proc->block.dfp = block->dfp; + proc->block.ep = block->ep; proc->block.iseq = block->iseq; proc->block.proc = procval; proc->envval = envval; proc->safe_level = th->safe_level; if (VMDEBUG) { - if (th->stack < block->dfp && block->dfp < th->stack + th->stack_size) { - rb_bug("invalid ptr: block->dfp"); - } - if (th->stack < block->lfp && block->lfp < th->stack + th->stack_size) { - rb_bug("invalid ptr: block->lfp"); + if (th->stack < block->ep && block->ep < th->stack + th->stack_size) { + rb_bug("invalid ptr: block->ep"); } } @@ -590,15 +622,14 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block, type == VM_FRAME_MAGIC_LAMBDA); ncfp = vm_push_frame(th, iseq, type, - self, GC_GUARDED_PTR(block->dfp), - iseq->iseq_encoded + opt_pc, cfp->sp + arg_size, block->lfp, - iseq->local_size - arg_size); + self, VM_ENVVAL_PREV_EP_PTR(block->ep), + iseq->iseq_encoded + opt_pc, cfp->sp + arg_size, iseq->local_size - arg_size); ncfp->me = th->passed_me; th->passed_me = 0; th->passed_block = blockptr; if (cref) { - th->cfp->dfp[-1] = (VALUE)cref; + th->cfp->ep[-1] = (VALUE)cref; } return vm_exec(th); @@ -611,7 +642,7 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block, static inline const rb_block_t * check_block(rb_thread_t *th) { - const rb_block_t *blockptr = GC_GUARDED_PTR_REF(th->cfp->lfp[0]); + const rb_block_t *blockptr = VM_CF_BLOCK_PTR(th->cfp); if (blockptr == 0) { rb_vm_localjump_error("no block given", Qnil, 0); @@ -679,14 +710,14 @@ static VALUE vm_cfp_svar_get(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key) { cfp = vm_normal_frame(th, cfp); - return lfp_svar_get(th, cfp ? cfp->lfp : 0, key); + return lep_svar_get(th, cfp ? VM_CF_LEP(cfp) : 0, key); } static void vm_cfp_svar_set(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key, const VALUE val) { cfp = vm_normal_frame(th, cfp); - lfp_svar_set(th, cfp ? cfp->lfp : 0, key, val); + lep_svar_set(th, cfp ? VM_CF_LEP(cfp) : 0, key, val); } static VALUE @@ -780,7 +811,7 @@ rb_vm_cref(void) if (cfp == 0) { rb_raise(rb_eRuntimeError, "Can't call on top of Fiber or Thread"); } - return vm_get_cref(cfp->iseq, cfp->lfp, cfp->dfp); + return vm_get_cref(cfp->iseq, cfp->ep); } #if 0 @@ -804,7 +835,7 @@ rb_vm_cbase(void) if (cfp == 0) { rb_raise(rb_eRuntimeError, "Can't call on top of Fiber or Thread"); } - return vm_get_cbase(cfp->iseq, cfp->lfp, cfp->dfp); + return vm_get_cbase(cfp->iseq, cfp->ep); } /* jump */ @@ -896,10 +927,10 @@ static void vm_iter_break(rb_thread_t *th, VALUE val) { rb_control_frame_t *cfp = th->cfp; - VALUE *dfp = GC_GUARDED_PTR_REF(*cfp->dfp); + VALUE *ep = VM_CF_PREV_EP(cfp); th->state = TAG_BREAK; - th->errinfo = (VALUE)NEW_THROW_OBJECT(val, (VALUE)dfp, TAG_BREAK); + th->errinfo = (VALUE)NEW_THROW_OBJECT(val, (VALUE)ep, TAG_BREAK); TH_JUMP_TAG(th, TAG_BREAK); } @@ -1028,16 +1059,14 @@ vm_frametype_name(const rb_control_frame_t *cfp) rb_iseq_t *iseq; // cfp[3], iseq VALUE flag; // cfp[4], magic VALUE self; // cfp[5], self - VALUE *lfp; // cfp[6], local frame pointer - VALUE *dfp; // cfp[7], dynamic frame pointer - rb_iseq_t * block_iseq; // cfp[8], block iseq - VALUE proc; // cfp[9], always 0 + VALUE *ep; // cfp[6], env pointer + rb_iseq_t * block_iseq; // cfp[7], block iseq + VALUE proc; // cfp[8], always 0 }; struct BLOCK { VALUE self; - VALUE *lfp; - VALUE *dfp; + VALUE *ep; rb_iseq_t *block_iseq; VALUE proc; }; @@ -1054,8 +1083,8 @@ vm_frametype_name(const rb_control_frame_t *cfp) ... VALUE paramN; VALUE cref; - VALUE special; // lfp [1] - struct block_object *block_ptr | 0x01; // lfp [0] + VALUE special; // lep [1] + struct block_object *block_ptr | 0x01; // lep [0] }; struct BLOCK_CONTROL_FRAME { @@ -1070,7 +1099,7 @@ vm_frametype_name(const rb_control_frame_t *cfp) ... VALUE paramN; VALUE cref; - VALUE *(prev_ptr | 0x01); // DFP[0] + VALUE *(prev_ptr | 0x01); // ep[0] }; struct CLASS_CONTROL_FRAME { @@ -1082,30 +1111,28 @@ vm_frametype_name(const rb_control_frame_t *cfp) ... VALUE paramN; VALUE cref; - VALUE prev_dfp; // for frame jump + VALUE prev_ep; // for frame jump }; struct C_METHOD_CONTROL_FRAME { VALUE *pc; // 0 VALUE *sp; // stack pointer VALUE *bp; // base pointer (used in exception) - rb_iseq_t *iseq; // cmi + rb_iseq_t *iseq; // cmi VALUE magic; // C_METHOD_FRAME VALUE self; // ? - VALUE *lfp; // lfp - VALUE *dfp; // == lfp - rb_iseq_t * block_iseq; // + VALUE *ep; // ep == lep + rb_iseq_t * block_iseq; // VALUE proc; // always 0 }; struct C_BLOCK_CONTROL_FRAME { VALUE *pc; // point only "finish" insn VALUE *sp; // sp - rb_iseq_t *iseq; // ? + rb_iseq_t *iseq; // ? VALUE magic; // C_METHOD_FRAME VALUE self; // needed? - VALUE *lfp; // lfp - VALUE *dfp; // lfp + VALUE *ep; // ep rb_iseq_t * block_iseq; // 0 }; */ @@ -1117,7 +1144,7 @@ vm_exec(rb_thread_t *th) int state; VALUE result, err; VALUE initial = 0; - VALUE *escape_dfp = NULL; + VALUE *escape_ep = NULL; TH_PUSH_TAG(th); _tag.retval = Qnil; @@ -1155,12 +1182,12 @@ vm_exec(rb_thread_t *th) epc = cfp->pc - cfp->iseq->iseq_encoded; if (state == TAG_BREAK || state == TAG_RETURN) { - escape_dfp = GET_THROWOBJ_CATCH_POINT(err); + escape_ep = GET_THROWOBJ_CATCH_POINT(err); - if (cfp->dfp == escape_dfp) { + if (cfp->ep == escape_ep) { if (state == TAG_RETURN) { if ((cfp + 1)->pc != &finish_insn_seq[0]) { - SET_THROWOBJ_CATCH_POINT(err, (VALUE)(cfp + 1)->dfp); + SET_THROWOBJ_CATCH_POINT(err, (VALUE)(cfp + 1)->ep); SET_THROWOBJ_STATE(err, state = TAG_BREAK); } else { @@ -1224,9 +1251,9 @@ vm_exec(rb_thread_t *th) break; } else if (entry->type == CATCH_TYPE_RETRY) { - VALUE *escape_dfp; - escape_dfp = GET_THROWOBJ_CATCH_POINT(err); - if (cfp->dfp == escape_dfp) { + VALUE *escape_ep; + escape_ep = GET_THROWOBJ_CATCH_POINT(err); + if (cfp->ep == escape_ep) { cfp->pc = cfp->iseq->iseq_encoded + entry->cont; th->errinfo = Qnil; goto vm_loop_start; @@ -1235,7 +1262,7 @@ vm_exec(rb_thread_t *th) } } } - else if (state == TAG_BREAK && ((VALUE)escape_dfp & ~0x03) == 0) { + else if (state == TAG_BREAK && ((VALUE)escape_ep & ~0x03) == 0) { type = CATCH_TYPE_BREAK; search_restart_point: @@ -1302,8 +1329,8 @@ vm_exec(rb_thread_t *th) /* push block frame */ cfp->sp[0] = err; vm_push_frame(th, catch_iseq, VM_FRAME_MAGIC_BLOCK, - cfp->self, (VALUE)cfp->dfp, catch_iseq->iseq_encoded, - cfp->sp + 1 /* push value */, cfp->lfp, catch_iseq->local_size - 1); + cfp->self, VM_ENVVAL_PREV_EP_PTR(cfp->ep), catch_iseq->iseq_encoded, + cfp->sp + 1 /* push value */, catch_iseq->local_size - 1); state = 0; th->state = 0; @@ -1438,7 +1465,7 @@ rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, VALUE val; vm_push_frame(th, DATA_PTR(iseqval), VM_FRAME_MAGIC_TOP, - recv, (VALUE)blockptr, 0, reg_cfp->sp, 0, 1); + recv, VM_ENVVAL_BLOCK_PTR(blockptr), 0, reg_cfp->sp, 1); val = (*func)(arg); @@ -1645,7 +1672,7 @@ rb_thread_mark(void *ptr) RUBY_MARK_UNLESS_NULL(th->value); RUBY_MARK_UNLESS_NULL(th->errinfo); RUBY_MARK_UNLESS_NULL(th->thrown_errinfo); - RUBY_MARK_UNLESS_NULL(th->local_svar); + RUBY_MARK_UNLESS_NULL(th->root_svar); RUBY_MARK_UNLESS_NULL(th->top_self); RUBY_MARK_UNLESS_NULL(th->top_wrapper); RUBY_MARK_UNLESS_NULL(th->fiber); @@ -1781,8 +1808,8 @@ th_init(rb_thread_t *th, VALUE self) th->cfp = (void *)(th->stack + th->stack_size); - vm_push_frame(th, 0, VM_FRAME_MAGIC_TOP, Qnil, 0, 0, - th->stack, 0, 1); + vm_push_frame(th, 0 /* dummy iseq */, VM_FRAME_MAGIC_TOP, Qnil /* dummy self */, + VM_ENVVAL_BLOCK_PTR(0), 0 /* dummy pc */, th->stack, 1); th->status = THREAD_RUNNABLE; th->errinfo = Qnil; diff --git a/vm_core.h b/vm_core.h index d71e34a899..e00f32ad09 100644 --- a/vm_core.h +++ b/vm_core.h @@ -349,17 +349,15 @@ typedef struct { rb_iseq_t *iseq; /* cfp[3] */ VALUE flag; /* cfp[4] */ VALUE self; /* cfp[5] / block[0] */ - VALUE *lfp; /* cfp[6] / block[1] */ - VALUE *dfp; /* cfp[7] / block[2] */ - rb_iseq_t *block_iseq; /* cfp[8] / block[3] */ - VALUE proc; /* cfp[9] / block[4] */ - const rb_method_entry_t *me;/* cfp[10] */ + VALUE *ep; /* cfp[6] / block[1] */ + rb_iseq_t *block_iseq; /* cfp[7] / block[2] */ + VALUE proc; /* cfp[8] / block[3] */ + const rb_method_entry_t *me;/* cfp[9] */ } rb_control_frame_t; typedef struct rb_block_struct { VALUE self; /* share with method frame if it's only block */ - VALUE *lfp; /* share with method frame if it's only block */ - VALUE *dfp; /* share with method frame if it's only block */ + VALUE *ep; /* share with method frame if it's only block */ rb_iseq_t *iseq; VALUE proc; } rb_block_t; @@ -434,8 +432,8 @@ typedef struct rb_thread_struct { /* eval env */ rb_block_t *base_block; - VALUE *local_lfp; - VALUE local_svar; + VALUE *root_lep; + VALUE root_svar; /* thread control */ rb_thread_id_t thread_id; @@ -622,7 +620,27 @@ typedef rb_control_frame_t * #define GC_GUARDED_PTR_REF(p) ((void *)(((VALUE)(p)) & ~0x03)) #define GC_GUARDED_PTR_P(p) (((VALUE)(p)) & 0x01) -#define RUBY_VM_GET_BLOCK_PTR(cfp) ((rb_block_t *)(GC_GUARDED_PTR_REF((cfp)->lfp[0]))) +/* + * block frame: + * ep[ 0]: prev frame + * ep[-1]: CREF (for *_eval) + * + * method frame: + * ep[ 0]: block pointer (ptr | VM_ENVVAL_BLOCK_PTR_FLAG) + */ + +#define VM_ENVVAL_BLOCK_PTR_FLAG 0x02 +#define VM_ENVVAL_BLOCK_PTR(v) (GC_GUARDED_PTR(v) | VM_ENVVAL_BLOCK_PTR_FLAG) +#define VM_ENVVAL_BLOCK_PTR_P(v) ((v) & VM_ENVVAL_BLOCK_PTR_FLAG) +#define VM_ENVVAL_PREV_EP_PTR(v) ((VALUE)GC_GUARDED_PTR(v)) +#define VM_ENVVAL_PREV_EP_PTR_P(v) (!(VM_ENVVAL_BLOCK_PTR_P(v))) + +#define VM_EP_PREV_EP(ep) ((VALUE *)GC_GUARDED_PTR_REF((ep)[0])) +#define VM_EP_BLOCK_PTR(ep) ((rb_block_t *)GC_GUARDED_PTR_REF((ep)[0])) +#define VM_EP_LEP_P(ep) VM_ENVVAL_BLOCK_PTR_P((ep)[0]) + +VALUE *rb_vm_ep_local_ep(VALUE *ep); +rb_block_t *rb_vm_control_frame_block_ptr(rb_control_frame_t *cfp); #define RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp) ((cfp)+1) #define RUBY_VM_NEXT_CONTROL_FRAME(cfp) ((cfp)-1) @@ -647,6 +665,9 @@ VALUE rb_proc_alloc(VALUE klass); /* for debug */ extern void rb_vmdebug_stack_dump_raw(rb_thread_t *, rb_control_frame_t *); +extern void rb_vmdebug_debug_print_pre(rb_thread_t *th, rb_control_frame_t *cfp); +extern void rb_vmdebug_debug_print_post(rb_thread_t *th, rb_control_frame_t *cfp); + #define SDR() rb_vmdebug_stack_dump_raw(GET_THREAD(), GET_THREAD()->cfp) #define SDR2(cfp) rb_vmdebug_stack_dump_raw(GET_THREAD(), (cfp)) void rb_vm_bugreport(void); @@ -666,7 +687,7 @@ VALUE rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self, int argc, const VALUE *argv, const rb_block_t *blockptr); VALUE rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass); VALUE rb_vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp); -void rb_vm_rewrite_dfp_in_errinfo(rb_thread_t *th, rb_control_frame_t *cfp); +void rb_vm_rewrite_ep_in_errinfo(rb_thread_t *th, rb_control_frame_t *cfp); void rb_vm_inc_const_missing_count(void); void rb_vm_gvl_destroy(rb_vm_t *vm); VALUE rb_vm_call(rb_thread_t *th, VALUE recv, VALUE id, int argc, diff --git a/vm_dump.c b/vm_dump.c index 2766677cf3..d38f114b86 100644 --- a/vm_dump.c +++ b/vm_dump.c @@ -28,9 +28,8 @@ static void control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp) { ptrdiff_t pc = -1, bp = -1; - ptrdiff_t lfp = cfp->lfp - th->stack; - ptrdiff_t dfp = cfp->dfp - th->stack; - char lfp_in_heap = ' ', dfp_in_heap = ' '; + ptrdiff_t ep = cfp->ep - th->stack; + char ep_in_heap = ' '; char posbuf[MAX_POSBUF+1]; int line = 0; int nopos = 0; @@ -42,13 +41,9 @@ control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp) biseq_name = ""; /* RSTRING(cfp->block_iseq->location.label)->ptr; */ } - if (lfp < 0 || (size_t)lfp > th->stack_size) { - lfp = (ptrdiff_t)cfp->lfp; - lfp_in_heap = 'p'; - } - if (dfp < 0 || (size_t)dfp > th->stack_size) { - dfp = (ptrdiff_t)cfp->dfp; - dfp_in_heap = 'p'; + if (ep < 0 || (size_t)ep > th->stack_size) { + ep = (ptrdiff_t)cfp->ep; + ep_in_heap = 'p'; } if (cfp->bp) { bp = cfp->bp - th->stack; @@ -133,8 +128,7 @@ control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp) fprintf(stderr, "p:%04"PRIdPTRDIFF" ", pc); } fprintf(stderr, "s:%04"PRIdPTRDIFF" b:%04"PRIdPTRDIFF" ", (cfp->sp - th->stack), bp); - fprintf(stderr, lfp_in_heap == ' ' ? "l:%06"PRIdPTRDIFF" " : "l:%06"PRIxPTRDIFF" ", lfp % 10000); - fprintf(stderr, dfp_in_heap == ' ' ? "d:%06"PRIdPTRDIFF" " : "d:%06"PRIxPTRDIFF" ", dfp % 10000); + fprintf(stderr, ep_in_heap == ' ' ? "e:%06"PRIdPTRDIFF" " : "e:%06"PRIxPTRDIFF" ", ep % 10000); fprintf(stderr, "%-6s", magic); if (line && !nopos) { fprintf(stderr, " %s", posbuf); @@ -152,9 +146,7 @@ void rb_vmdebug_stack_dump_raw(rb_thread_t *th, rb_control_frame_t *cfp) { #if 0 - VALUE *sp = cfp->sp, *bp = cfp->bp; - VALUE *lfp = cfp->lfp; - VALUE *dfp = cfp->dfp; + VALUE *sp = cfp->sp, *bp = cfp->bp, *ep = cfp->ep; VALUE *p, *st, *t; fprintf(stderr, "-- stack frame ------------\n"); @@ -166,10 +158,8 @@ rb_vmdebug_stack_dump_raw(rb_thread_t *th, rb_control_frame_t *cfp) fprintf(stderr, " (= %ld)", (long)((VALUE *)GC_GUARDED_PTR_REF(t) - th->stack)); } - if (p == lfp) - fprintf(stderr, " <- lfp"); - if (p == dfp) - fprintf(stderr, " <- dfp"); + if (p == ep) + fprintf(stderr, " <- ep"); if (p == bp) fprintf(stderr, " <- bp"); /* should not be */ @@ -194,7 +184,7 @@ rb_vmdebug_stack_dump_raw_current(void) } void -rb_vmdebug_env_dump_raw(rb_env_t *env, VALUE *lfp, VALUE *dfp) +rb_vmdebug_env_dump_raw(rb_env_t *env, VALUE *ep) { int i; fprintf(stderr, "-- env --------------------\n"); @@ -204,10 +194,8 @@ rb_vmdebug_env_dump_raw(rb_env_t *env, VALUE *lfp, VALUE *dfp) for (i = 0; i < env->env_size; i++) { fprintf(stderr, "%04d: %08"PRIxVALUE" (%p)", -env->local_size + i, env->env[i], (void *)&env->env[i]); - if (&env->env[i] == lfp) - fprintf(stderr, " <- lfp"); - if (&env->env[i] == dfp) - fprintf(stderr, " <- dfp"); + if (&env->env[i] == ep) + fprintf(stderr, " <- ep"); fprintf(stderr, "\n"); } @@ -232,7 +220,7 @@ rb_vmdebug_proc_dump_raw(rb_proc_t *proc) fprintf(stderr, "-- proc -------------------\n"); fprintf(stderr, "self: %s\n", selfstr); GetEnvPtr(proc->envval, env); - rb_vmdebug_env_dump_raw(env, proc->block.lfp, proc->block.dfp); + rb_vmdebug_env_dump_raw(env, proc->block.ep); } void @@ -251,8 +239,7 @@ vm_stack_dump_each(rb_thread_t *th, rb_control_frame_t *cfp) VALUE rstr; VALUE *sp = cfp->sp; - VALUE *lfp = cfp->lfp; - VALUE *dfp = cfp->dfp; + VALUE *ep = cfp->ep; int argc = 0, local_size = 0; const char *name; @@ -287,14 +274,11 @@ vm_stack_dump_each(rb_thread_t *th, rb_control_frame_t *cfp) VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_IFUNC || VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_EVAL) { - VALUE *ptr = dfp - local_size; + VALUE *ptr = ep - local_size; vm_stack_dump_each(th, cfp + 1); control_frame_dump(th, cfp); - if (lfp != dfp) { - local_size++; - } for (i = 0; i < argc; i++) { rstr = rb_inspect(*ptr); fprintf(stderr, " arg %2d: %8s (%p)\n", i, StringValueCStr(rstr), @@ -337,22 +321,20 @@ rb_vmdebug_debug_print_register(rb_thread_t *th) { rb_control_frame_t *cfp = th->cfp; ptrdiff_t pc = -1; - ptrdiff_t lfp = cfp->lfp - th->stack; - ptrdiff_t dfp = cfp->dfp - th->stack; + ptrdiff_t ep = cfp->ep - th->stack; ptrdiff_t cfpi; if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) { pc = cfp->pc - cfp->iseq->iseq_encoded; } - if (lfp < 0 || (size_t)lfp > th->stack_size) - lfp = -1; - if (dfp < 0 || (size_t)dfp > th->stack_size) - dfp = -1; + if (ep < 0 || (size_t)ep > th->stack_size) { + ep = -1; + } cfpi = ((rb_control_frame_t *)(th->stack + th->stack_size)) - cfp; - fprintf(stderr, " [PC] %04"PRIdPTRDIFF", [SP] %04"PRIdPTRDIFF", [LFP] %04"PRIdPTRDIFF", [DFP] %04"PRIdPTRDIFF", [CFP] %04"PRIdPTRDIFF"\n", - pc, (cfp->sp - th->stack), lfp, dfp, cfpi); + fprintf(stderr, " [PC] %04"PRIdPTRDIFF", [SP] %04"PRIdPTRDIFF", [EP] %04"PRIdPTRDIFF", [CFP] %04"PRIdPTRDIFF"\n", + pc, (cfp->sp - th->stack), ep, cfpi); } void @@ -371,8 +353,13 @@ rb_vmdebug_debug_print_pre(rb_thread_t *th, rb_control_frame_t *cfp) if (iseq != 0 && VM_FRAME_TYPE(cfp) != VM_FRAME_MAGIC_FINISH) { VALUE *seq = iseq->iseq; ptrdiff_t pc = cfp->pc - iseq->iseq_encoded; + int i; - printf("%3"PRIdPTRDIFF" ", VM_CFP_CNT(th, cfp)); + for (i=0; i<(int)VM_CFP_CNT(th, cfp); i++) { + printf(" "); + } + printf("| "); + /* printf("%3"PRIdPTRDIFF" ", VM_CFP_CNT(th, cfp)); */ if (pc >= 0) { rb_iseq_disasm_insn(0, seq, (size_t)pc, iseq, 0); } @@ -518,11 +505,10 @@ vm_analysis_register(int reg, int isset) static const char regstrs[][5] = { "pc", /* 0 */ "sp", /* 1 */ - "cfp", /* 2 */ - "lfp", /* 3 */ - "dfp", /* 4 */ - "self", /* 5 */ - "iseq", /* 6 */ + "ep", /* 2 */ + "cfp", /* 3 */ + "self", /* 4 */ + "iseq", /* 5 */ }; static const char getsetstr[][4] = { "get", @@ -568,7 +554,7 @@ rb_vmdebug_thread_dump_state(VALUE self) fprintf(stderr, "Thread state dump:\n"); fprintf(stderr, "pc : %p, sp : %p\n", (void *)cfp->pc, (void *)cfp->sp); - fprintf(stderr, "cfp: %p, lfp: %p, dfp: %p\n", (void *)cfp, (void *)cfp->lfp, (void *)cfp->dfp); + fprintf(stderr, "cfp: %p, ep : %p\n", (void *)cfp, (void *)cfp->ep); return Qnil; } diff --git a/vm_eval.c b/vm_eval.c index 8ea149c459..31511b986f 100644 --- a/vm_eval.c +++ b/vm_eval.c @@ -74,7 +74,7 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv, rb_control_frame_t *reg_cfp = th->cfp; rb_control_frame_t *cfp = vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC, - recv, (VALUE)blockptr, 0, reg_cfp->sp, 0, 1); + recv, VM_ENVVAL_BLOCK_PTR(blockptr), 0, reg_cfp->sp, 1); cfp->me = me; val = call_cfunc(def->body.cfunc.func, recv, def->body.cfunc.argc, argc, argv); @@ -896,7 +896,7 @@ rb_iterate(VALUE (* it_proc) (VALUE), VALUE data1, blockptr->proc = 0; } else { - blockptr = GC_GUARDED_PTR_REF(th->cfp->lfp[0]); + blockptr = VM_CF_BLOCK_PTR(th->cfp); } th->passed_block = blockptr; } @@ -905,10 +905,10 @@ rb_iterate(VALUE (* it_proc) (VALUE), VALUE data1, else { VALUE err = th->errinfo; if (state == TAG_BREAK) { - VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(err); - VALUE *cdfp = cfp->dfp; + VALUE *escape_ep = GET_THROWOBJ_CATCH_POINT(err); + VALUE *cep = cfp->ep; - if (cdfp == escape_dfp) { + if (cep == escape_ep) { state = 0; th->state = 0; th->errinfo = Qnil; @@ -932,10 +932,10 @@ rb_iterate(VALUE (* it_proc) (VALUE), VALUE data1, } } else if (state == TAG_RETRY) { - VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(err); - VALUE *cdfp = cfp->dfp; + VALUE *escape_ep = GET_THROWOBJ_CATCH_POINT(err); + VALUE *cep = cfp->ep; - if (cdfp == escape_dfp) { + if (cep == escape_ep) { state = 0; th->state = 0; th->errinfo = Qnil; @@ -1247,10 +1247,10 @@ yield_under(VALUE under, VALUE self, VALUE values) rb_block_t block, *blockptr; NODE *cref; - if ((blockptr = GC_GUARDED_PTR_REF(th->cfp->lfp[0])) != 0) { + if ((blockptr = VM_CF_BLOCK_PTR(th->cfp)) != 0) { block = *blockptr; block.self = self; - th->cfp->lfp[0] = GC_GUARDED_PTR(&block); + VM_CF_LEP(th->cfp)[0] = VM_ENVVAL_BLOCK_PTR(&block); } cref = vm_cref_push(th, under, NOEX_PUBLIC, blockptr); cref->flags |= NODE_FL_CREF_PUSHED_BY_EVAL; @@ -1611,15 +1611,15 @@ rb_f_local_variables(void) } } } - if (cfp->lfp != cfp->dfp) { + if (!VM_EP_LEP_P(cfp->ep)) { /* block */ - VALUE *dfp = GC_GUARDED_PTR_REF(cfp->dfp[0]); + VALUE *ep = VM_CF_PREV_EP(cfp); - if (vm_collect_local_variables_in_heap(th, dfp, ary)) { + if (vm_collect_local_variables_in_heap(th, ep, ary)) { break; } else { - while (cfp->dfp != dfp) { + while (cfp->ep != ep) { cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); } } @@ -1660,7 +1660,7 @@ rb_f_block_given_p(void) rb_control_frame_t *cfp = th->cfp; cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)); - if (cfp != 0 && RUBY_VM_GET_BLOCK_PTR(cfp)) { + if (cfp != 0 && VM_CF_BLOCK_PTR(cfp)) { return Qtrue; } else { diff --git a/vm_exec.h b/vm_exec.h index caf752a76b..4f8b030e68 100644 --- a/vm_exec.h +++ b/vm_exec.h @@ -38,7 +38,7 @@ typedef rb_iseq_t *ISEQ; #if VMDEBUG > 0 #define debugs printf #define DEBUG_ENTER_INSN(insn) \ - debug_print_pre(th, GET_CFP()); + rb_vmdebug_debug_print_pre(th, GET_CFP()); #if OPT_STACK_CACHING #define SC_REGS() , reg_a, reg_b @@ -47,7 +47,7 @@ typedef rb_iseq_t *ISEQ; #endif #define DEBUG_END_INSN() \ - debug_print_post(th, GET_CFP() SC_REGS()); + rb_vmdebug_debug_print_post(th, GET_CFP() SC_REGS()); #else diff --git a/vm_insnhelper.c b/vm_insnhelper.c index a4b4b8fe78..2e00c0e1de 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -23,53 +23,47 @@ static rb_control_frame_t *vm_get_ruby_level_caller_cfp(rb_thread_t *th, rb_control_frame_t *cfp); static inline rb_control_frame_t * -vm_push_frame(rb_thread_t * th, const rb_iseq_t * iseq, - VALUE type, VALUE self, VALUE specval, - const VALUE *pc, VALUE *sp, VALUE *lfp, +vm_push_frame(rb_thread_t *th, + const rb_iseq_t *iseq, + VALUE type, + VALUE self, + VALUE specval, + const VALUE *pc, + VALUE *sp, int local_size) { - rb_control_frame_t * const cfp = th->cfp - 1; + rb_control_frame_t *const cfp = th->cfp - 1; int i; + /* check stack overflow */ if ((void *)(sp + local_size) >= (void *)cfp) { rb_exc_raise(sysstack_error); } th->cfp = cfp; + /* setup vm value stack */ - /* nil initialize */ + /* initialize local variables */ for (i=0; i < local_size; i++) { - *sp = Qnil; - sp++; + *sp++ = Qnil; } /* set special val */ - *sp = GC_GUARDED_PTR(specval); - - if (lfp == 0) { - lfp = sp; - } + *sp = specval; /* setup vm control frame stack */ cfp->pc = (VALUE *)pc; cfp->sp = sp + 1; cfp->bp = sp + 1; + cfp->ep = sp; cfp->iseq = (rb_iseq_t *) iseq; cfp->flag = type; cfp->self = self; - cfp->lfp = lfp; - cfp->dfp = sp; cfp->block_iseq = 0; cfp->proc = 0; cfp->me = 0; -#define COLLECT_PROFILE 0 -#if COLLECT_PROFILE - cfp->prof_time_self = clock(); - cfp->prof_time_chld = 0; -#endif - if (VMDEBUG == 2) { SDR(); } @@ -80,23 +74,6 @@ vm_push_frame(rb_thread_t * th, const rb_iseq_t * iseq, static inline void vm_pop_frame(rb_thread_t *th) { -#if COLLECT_PROFILE - rb_control_frame_t *cfp = th->cfp; - - if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) { - VALUE current_time = clock(); - rb_control_frame_t *cfp = th->cfp; - cfp->prof_time_self = current_time - cfp->prof_time_self; - (cfp+1)->prof_time_chld += cfp->prof_time_self; - - cfp->iseq->profile.count++; - cfp->iseq->profile.time_cumu = cfp->prof_time_self; - cfp->iseq->profile.time_self = cfp->prof_time_self - cfp->prof_time_chld; - } - else if (0 /* c method? */) { - - } -#endif th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp); if (VMDEBUG == 2) { @@ -445,8 +422,9 @@ vm_call_cfunc(rb_thread_t *th, rb_control_frame_t *reg_cfp, EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, me->called_id, me->klass); - cfp = vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC, - recv, (VALUE) blockptr, 0, reg_cfp->sp, 0, 1); + cfp = vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC, recv, + VM_ENVVAL_BLOCK_PTR(blockptr), 0, th->cfp->sp, 1); + cfp->me = me; reg_cfp->sp -= num + 1; @@ -528,9 +506,9 @@ vm_setup_method(rb_thread_t *th, rb_control_frame_t *cfp, *sp++ = Qnil; } - vm_push_frame(th, iseq, - VM_FRAME_MAGIC_METHOD, recv, (VALUE) blockptr, - iseq->iseq_encoded + opt_pc, sp, 0, 0); + vm_push_frame(th, iseq, VM_FRAME_MAGIC_METHOD, recv, + VM_ENVVAL_BLOCK_PTR(blockptr), + iseq->iseq_encoded + opt_pc, sp, 0); cfp->sp = rsp - 1 /* recv */; } @@ -551,9 +529,9 @@ vm_setup_method(rb_thread_t *th, rb_control_frame_t *cfp, *sp++ = Qnil; } - vm_push_frame(th, iseq, - VM_FRAME_MAGIC_METHOD, recv, (VALUE) blockptr, - iseq->iseq_encoded + opt_pc, sp, 0, 0); + vm_push_frame(th, iseq, VM_FRAME_MAGIC_METHOD, recv, + VM_ENVVAL_BLOCK_PTR(blockptr), + iseq->iseq_encoded + opt_pc, sp, 0); } } @@ -757,6 +735,7 @@ vm_yield_with_cfunc(rb_thread_t *th, const rb_block_t *block, NODE *ifunc = (NODE *) block->iseq; VALUE val, arg, blockarg; int lambda = block_proc_is_lambda(block->proc); + rb_control_frame_t *cfp; if (lambda) { arg = rb_ary_new4(argc, argv); @@ -780,12 +759,11 @@ vm_yield_with_cfunc(rb_thread_t *th, const rb_block_t *block, blockarg = Qnil; } - vm_push_frame(th, (rb_iseq_t *)ifunc, VM_FRAME_MAGIC_IFUNC, - self, (VALUE)block->dfp, - 0, th->cfp->sp, block->lfp, 1); + cfp = vm_push_frame(th, (rb_iseq_t *)ifunc, VM_FRAME_MAGIC_IFUNC, self, + VM_ENVVAL_PREV_EP_PTR(block->ep), 0, th->cfp->sp, 1); if (blockargptr) { - th->cfp->lfp[0] = GC_GUARDED_PTR((VALUE)blockargptr); + VM_CF_LEP(cfp)[0] = VM_ENVVAL_BLOCK_PTR(blockargptr); } val = (*ifunc->nd_cfnc) (arg, ifunc->nd_tval, argc, argv, blockarg); @@ -976,7 +954,7 @@ vm_yield_setup_args(rb_thread_t * const th, const rb_iseq_t *iseq, static VALUE vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t num, rb_num_t flag) { - const rb_block_t *block = GET_BLOCK_PTR(); + const rb_block_t *block = VM_CF_BLOCK_PTR(reg_cfp); rb_iseq_t *iseq; int argc = (int)num; VALUE type = GET_ISEQ()->local_iseq->type; @@ -998,9 +976,10 @@ vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t num, rb_n opt_pc = vm_yield_setup_args(th, iseq, argc, rsp, 0, block_proc_is_lambda(block->proc)); - vm_push_frame(th, iseq, - VM_FRAME_MAGIC_BLOCK, block->self, (VALUE) block->dfp, - iseq->iseq_encoded + opt_pc, rsp + arg_size, block->lfp, + vm_push_frame(th, iseq, VM_FRAME_MAGIC_BLOCK, block->self, + VM_ENVVAL_PREV_EP_PTR(block->ep), + iseq->iseq_encoded + opt_pc, + rsp + arg_size, iseq->local_size - arg_size); return Qundef; @@ -1015,15 +994,15 @@ vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t num, rb_n /* svar */ static inline NODE * -lfp_svar_place(rb_thread_t *th, VALUE *lfp) +lep_svar_place(rb_thread_t *th, VALUE *lep) { VALUE *svar; - if (lfp && th->local_lfp != lfp) { - svar = &lfp[-1]; + if (lep && th->root_lep != lep) { + svar = &lep[-1]; } else { - svar = &th->local_svar; + svar = &th->root_svar; } if (NIL_P(*svar)) { *svar = (VALUE)NEW_IF(Qnil, Qnil, Qnil); @@ -1032,9 +1011,9 @@ lfp_svar_place(rb_thread_t *th, VALUE *lfp) } static VALUE -lfp_svar_get(rb_thread_t *th, VALUE *lfp, VALUE key) +lep_svar_get(rb_thread_t *th, VALUE *lep, VALUE key) { - NODE *svar = lfp_svar_place(th, lfp); + NODE *svar = lep_svar_place(th, lep); switch (key) { case 0: @@ -1055,9 +1034,9 @@ lfp_svar_get(rb_thread_t *th, VALUE *lfp, VALUE key) } static void -lfp_svar_set(rb_thread_t *th, VALUE *lfp, VALUE key, VALUE val) +lep_svar_set(rb_thread_t *th, VALUE *lep, VALUE key, VALUE val) { - NODE *svar = lfp_svar_place(th, lfp); + NODE *svar = lep_svar_place(th, lep); switch (key) { case 0: @@ -1078,7 +1057,7 @@ lfp_svar_set(rb_thread_t *th, VALUE *lfp, VALUE key, VALUE val) } static inline VALUE -vm_getspecial(rb_thread_t *th, VALUE *lfp, VALUE key, rb_num_t type) +vm_getspecial(rb_thread_t *th, VALUE *lep, VALUE key, rb_num_t type) { VALUE val; @@ -1087,10 +1066,10 @@ vm_getspecial(rb_thread_t *th, VALUE *lfp, VALUE key, rb_num_t type) if (FIXNUM_P(key)) { k = FIX2INT(key); } - val = lfp_svar_get(th, lfp, k); + val = lep_svar_get(th, lep, k); } else { - VALUE backref = lfp_svar_get(th, lfp, 1); + VALUE backref = lep_svar_get(th, lep, 1); if (type & 0x01) { switch (type >> 1) { @@ -1118,24 +1097,24 @@ vm_getspecial(rb_thread_t *th, VALUE *lfp, VALUE key, rb_num_t type) } static NODE * -vm_get_cref0(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp) +vm_get_cref0(const rb_iseq_t *iseq, const VALUE *ep) { while (1) { - if (lfp == dfp) { + if (VM_EP_LEP_P(ep)) { if (!RUBY_VM_NORMAL_ISEQ_P(iseq)) return NULL; return iseq->cref_stack; } - else if (dfp[-1] != Qnil) { - return (NODE *)dfp[-1]; + else if (ep[-1] != Qnil) { + return (NODE *)ep[-1]; } - dfp = GET_PREV_DFP(dfp); + ep = VM_EP_PREV_EP(ep); } } static NODE * -vm_get_cref(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp) +vm_get_cref(const rb_iseq_t *iseq, const VALUE *ep) { - NODE *cref = vm_get_cref0(iseq, lfp, dfp); + NODE *cref = vm_get_cref0(iseq, ep); if (cref == 0) { rb_bug("vm_get_cref: unreachable"); @@ -1151,19 +1130,19 @@ vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr) cref->nd_visi = noex; if (blockptr) { - cref->nd_next = vm_get_cref0(blockptr->iseq, blockptr->lfp, blockptr->dfp); + cref->nd_next = vm_get_cref0(blockptr->iseq, blockptr->ep); } else if (cfp) { - cref->nd_next = vm_get_cref0(cfp->iseq, cfp->lfp, cfp->dfp); + cref->nd_next = vm_get_cref0(cfp->iseq, cfp->ep); } return cref; } static inline VALUE -vm_get_cbase(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp) +vm_get_cbase(const rb_iseq_t *iseq, const VALUE *ep) { - NODE *cref = vm_get_cref(iseq, lfp, dfp); + NODE *cref = vm_get_cref(iseq, ep); VALUE klass = Qundef; while (cref) { @@ -1177,9 +1156,9 @@ vm_get_cbase(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp) } static inline VALUE -vm_get_const_base(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp) +vm_get_const_base(const rb_iseq_t *iseq, const VALUE *ep) { - NODE *cref = vm_get_cref(iseq, lfp, dfp); + NODE *cref = vm_get_cref(iseq, ep); VALUE klass = Qundef; while (cref) { @@ -1216,7 +1195,7 @@ vm_get_ev_const(rb_thread_t *th, const rb_iseq_t *iseq, if (orig_klass == Qnil) { /* in current lexical scope */ - const NODE *root_cref = vm_get_cref(iseq, th->cfp->lfp, th->cfp->dfp); + const NODE *root_cref = vm_get_cref(iseq, th->cfp->ep); const NODE *cref; VALUE klass = orig_klass; @@ -1494,14 +1473,14 @@ vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq, while (lcfp->iseq != iseq) { rb_thread_t *th = GET_THREAD(); - VALUE *tdfp = GET_PREV_DFP(lcfp->dfp); + VALUE *tep = VM_EP_PREV_EP(lcfp->ep); while (1) { lcfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(lcfp); if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, lcfp)) { rb_raise(rb_eNoMethodError, "super called outside of method"); } - if (lcfp->dfp == tdfp) { + if (lcfp->ep == tep) { break; } } @@ -1539,7 +1518,7 @@ vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp, else { if (state == TAG_BREAK) { rb_control_frame_t *cfp = GET_CFP(); - VALUE *dfp = GET_DFP(); + VALUE *ep = GET_EP(); int is_orphan = 1; rb_iseq_t *base_iseq = GET_ISEQ(); @@ -1547,14 +1526,14 @@ vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp, if (cfp->iseq->type != ISEQ_TYPE_BLOCK) { if (cfp->iseq->type == ISEQ_TYPE_CLASS) { cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); - dfp = cfp->dfp; + ep = cfp->ep; goto search_parent; } - dfp = GC_GUARDED_PTR_REF((VALUE *) *dfp); + ep = VM_EP_PREV_EP(ep); base_iseq = base_iseq->parent_iseq; while ((VALUE *) cfp < th->stack + th->stack_size) { - if (cfp->dfp == dfp) { + if (cfp->ep == ep) { goto search_parent; } cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); @@ -1565,14 +1544,14 @@ vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp, if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA) { /* lambda{... break ...} */ is_orphan = 0; - pt = cfp->dfp; + pt = cfp->ep; state = TAG_RETURN; } else { - dfp = GC_GUARDED_PTR_REF((VALUE *) *dfp); + ep = VM_EP_PREV_EP(ep); while ((VALUE *)cfp < th->stack + th->stack_size) { - if (cfp->dfp == dfp) { + if (cfp->ep == ep) { VALUE epc = cfp->pc - cfp->iseq->iseq_encoded; rb_iseq_t *iseq = cfp->iseq; int i; @@ -1593,7 +1572,7 @@ vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp, break; found: - pt = dfp; + pt = ep; is_orphan = 0; break; } @@ -1607,50 +1586,53 @@ vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp, } else if (state == TAG_RETRY) { rb_num_t i; - pt = GC_GUARDED_PTR_REF((VALUE *) * GET_DFP()); + pt = VM_EP_PREV_EP(GET_EP()); for (i = 0; i < level; i++) { pt = GC_GUARDED_PTR_REF((VALUE *) * pt); } } else if (state == TAG_RETURN) { rb_control_frame_t *cfp = GET_CFP(); - VALUE *dfp = GET_DFP(); - VALUE *lfp = GET_LFP(); + VALUE *ep = GET_EP(); + VALUE *target_lep = VM_CF_LEP(cfp); int in_class_frame = 0; /* check orphan and get dfp */ while ((VALUE *) cfp < th->stack + th->stack_size) { - if (!lfp) { - lfp = cfp->lfp; + VALUE *lep = VM_CF_LEP(cfp); + + if (!target_lep) { + target_lep = lep; } - if (cfp->dfp == lfp && cfp->iseq->type == ISEQ_TYPE_CLASS) { + + if (lep == target_lep && cfp->iseq->type == ISEQ_TYPE_CLASS) { in_class_frame = 1; - lfp = 0; + target_lep = 0; } - if (cfp->lfp == lfp) { + if (lep == target_lep) { if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA) { - VALUE *tdfp = dfp; + VALUE *tep = ep; if (in_class_frame) { /* lambda {class A; ... return ...; end} */ - dfp = cfp->dfp; + ep = cfp->ep; goto valid_return; } - while (lfp != tdfp) { - if (cfp->dfp == tdfp) { + while (target_lep != tep) { + if (cfp->ep == tep) { /* in lambda */ - dfp = cfp->dfp; + ep = cfp->ep; goto valid_return; } - tdfp = GC_GUARDED_PTR_REF((VALUE *)*tdfp); + tep = VM_EP_PREV_EP(tep); } } } - if (cfp->dfp == lfp && cfp->iseq->type == ISEQ_TYPE_METHOD) { - dfp = lfp; + if (cfp->ep == target_lep && cfp->iseq->type == ISEQ_TYPE_METHOD) { + ep = target_lep; goto valid_return; } @@ -1660,7 +1642,7 @@ vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_vm_localjump_error("unexpected return", throwobj, TAG_RETURN); valid_return: - pt = dfp; + pt = ep; } else { rb_bug("isns(throw): unsupport throw type"); diff --git a/vm_insnhelper.h b/vm_insnhelper.h index 97e2b1e2ba..ffabbda23d 100644 --- a/vm_insnhelper.h +++ b/vm_insnhelper.h @@ -81,8 +81,7 @@ extern VALUE ruby_vm_const_missing_count; #define REG_CFP (reg_cfp) #define REG_PC (REG_CFP->pc) #define REG_SP (REG_CFP->sp) -#define REG_LFP (REG_CFP->lfp) -#define REG_DFP (REG_CFP->dfp) +#define REG_EP (REG_CFP->ep) #define RESTORE_REGS() do { \ REG_CFP = th->cfp; \ @@ -91,16 +90,29 @@ extern VALUE ruby_vm_const_missing_count; #define REG_A reg_a #define REG_B reg_b +enum vm_regan_regtype { + VM_REGAN_PC = 0, + VM_REGAN_SP = 1, + VM_REGAN_EP = 2, + VM_REGAN_CFP = 3, + VM_REGAN_SELF = 4, + VM_REGAN_ISEQ = 5, +}; +enum vm_regan_acttype { + VM_REGAN_ACT_GET = 0, + VM_REGAN_ACT_SET = 1, +}; + #ifdef COLLECT_USAGE_ANALYSIS #define USAGE_ANALYSIS_REGISTER_HELPER(a, b, v) \ - (USAGE_ANALYSIS_REGISTER((a), (b)), (v)) + (USAGE_ANALYSIS_REGISTER((VM_REGAN_#a), (VM_REGAN_ACT_#b)), (v)) #else #define USAGE_ANALYSIS_REGISTER_HELPER(a, b, v) (v) #endif /* PC */ -#define GET_PC() (USAGE_ANALYSIS_REGISTER_HELPER(0, 0, REG_PC)) -#define SET_PC(x) (REG_PC = (USAGE_ANALYSIS_REGISTER_HELPER(0, 1, (x)))) +#define GET_PC() (USAGE_ANALYSIS_REGISTER_HELPER(PC, GET, REG_PC)) +#define SET_PC(x) (REG_PC = (USAGE_ANALYSIS_REGISTER_HELPER(PC, SET, (x)))) #define GET_CURRENT_INSN() (*GET_PC()) #define GET_OPERAND(n) (GET_PC()[(n)]) #define ADD_PC(n) (SET_PC(REG_PC + (n))) @@ -108,18 +120,17 @@ extern VALUE ruby_vm_const_missing_count; #define GET_PC_COUNT() (REG_PC - GET_ISEQ()->iseq_encoded) #define JUMP(dst) (REG_PC += (dst)) -/* FP */ -#define GET_CFP() (USAGE_ANALYSIS_REGISTER_HELPER(2, 0, REG_CFP)) -#define GET_LFP() (USAGE_ANALYSIS_REGISTER_HELPER(3, 0, REG_LFP)) -#define SET_LFP(x) (REG_LFP = (USAGE_ANALYSIS_REGISTER_HELPER(3, 1, (x)))) -#define GET_DFP() (USAGE_ANALYSIS_REGISTER_HELPER(4, 0, REG_DFP)) -#define SET_DFP(x) (REG_DFP = (USAGE_ANALYSIS_REGISTER_HELPER(4, 1, (x)))) +/* frame pointer, environment pointer */ +#define GET_CFP() (USAGE_ANALYSIS_REGISTER_HELPER(CFP, GET, REG_CFP)) +#define GET_EP() (USAGE_ANALYSIS_REGISTER_HELPER(EP, GET, REG_EP)) +#define SET_EP(x) (REG_EP = (USAGE_ANALYSIS_REGISTER_HELPER(EP, SET, (x)))) +#define GET_LEP() (VM_EP_LEP(GET_EP())) /* SP */ -#define GET_SP() (USAGE_ANALYSIS_REGISTER_HELPER(1, 0, REG_SP)) -#define SET_SP(x) (REG_SP = (USAGE_ANALYSIS_REGISTER_HELPER(1, 1, (x)))) -#define INC_SP(x) (REG_SP += (USAGE_ANALYSIS_REGISTER_HELPER(1, 1, (x)))) -#define DEC_SP(x) (REG_SP -= (USAGE_ANALYSIS_REGISTER_HELPER(1, 1, (x)))) +#define GET_SP() (USAGE_ANALYSIS_REGISTER_HELPER(SP, GET, REG_SP)) +#define SET_SP(x) (REG_SP = (USAGE_ANALYSIS_REGISTER_HELPER(SP, SET, (x)))) +#define INC_SP(x) (REG_SP += (USAGE_ANALYSIS_REGISTER_HELPER(SP, SET, (x)))) +#define DEC_SP(x) (REG_SP -= (USAGE_ANALYSIS_REGISTER_HELPER(SP, SET, (x)))) #define SET_SV(x) (*GET_SP() = (x)) /* set current stack value as x */ @@ -132,7 +143,7 @@ extern VALUE ruby_vm_const_missing_count; /* deal with variables */ /**********************************************************/ -#define GET_PREV_DFP(dfp) ((VALUE *)((dfp)[0] & ~0x03)) +#define GET_PREV_EP(ep) ((VALUE *)((ep)[0] & ~0x03)) #define GET_GLOBAL(entry) rb_gvar_get((struct rb_global_entry*)(entry)) #define SET_GLOBAL(entry, val) rb_gvar_set((struct rb_global_entry*)(entry), (val)) @@ -170,7 +181,7 @@ extern VALUE ruby_vm_const_missing_count; } \ } while (0) -#define GET_BLOCK_PTR() ((rb_block_t *)(GC_GUARDED_PTR_REF(GET_LFP()[0]))) +#define GET_BLOCK_PTR() ((rb_block_t *)(GC_GUARDED_PTR_REF(GET_LEP()[0]))) /**********************************************************/ /* deal with control flow 3: exception */ -- cgit v1.2.3