From be5564a178ee453b7d6fedc7c312bec01e29dde2 Mon Sep 17 00:00:00 2001 From: ko1 Date: Tue, 26 Jul 2016 10:28:21 +0000 Subject: * vm_insnhelper.c: introduce rb_vm_pop_frame() and use it instead of setting rb_thread_t::cfp directly. * vm_insnhelper.c (vm_pop_frame): return the result of finish frame or not. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55755 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 8 ++++++++ eval.c | 2 +- insns.def | 5 +---- vm.c | 21 +++++++++++---------- vm_args.c | 2 +- vm_core.h | 1 + vm_eval.c | 4 ++-- vm_insnhelper.c | 31 ++++++++++++++++++++++--------- vm_trace.c | 2 +- 9 files changed, 48 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index de48c3bc19..01fb53e011 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Tue Jul 26 19:26:00 2016 Koichi Sasada + + * vm_insnhelper.c: introduce rb_vm_pop_frame() and use it + instead of setting rb_thread_t::cfp directly. + + * vm_insnhelper.c (vm_pop_frame): return the result of + finish frame or not. + Tue Jul 26 19:06:39 2016 Koichi Sasada * gc.c (rb_raw_obj_info): support to show Proc obj. diff --git a/eval.c b/eval.c index 475d6ca7a8..3241cb8048 100644 --- a/eval.c +++ b/eval.c @@ -737,7 +737,7 @@ rb_raise_jump(VALUE mesg, VALUE cause) VALUE self = cfp->self; ID mid = me->called_id; - th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp); + rb_vm_pop_frame(th); EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, self, mid, klass, Qnil); setup_exception(th, TAG_RAISE, mesg, cause); diff --git a/insns.def b/insns.def index c9d7204b42..7da7f891ff 100644 --- a/insns.def +++ b/insns.def @@ -1128,9 +1128,7 @@ leave RUBY_VM_CHECK_INTS(th); - if (UNLIKELY(VM_FRAME_TYPE_FINISH_P(GET_CFP()))) { - vm_pop_frame(th); - + if (vm_pop_frame(th, GET_CFP(), GET_EP())) { #if OPT_CALL_THREADED_CODE th->retval = val; return 0; @@ -1139,7 +1137,6 @@ leave #endif } else { - vm_pop_frame(th); RESTORE_REGS(); } } diff --git a/vm.c b/vm.c index 77e08ab45c..c900eec570 100644 --- a/vm.c +++ b/vm.c @@ -434,11 +434,12 @@ void rb_vm_pop_cfunc_frame(void) { rb_thread_t *th = GET_THREAD(); - const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(th->cfp); + rb_control_frame_t *cfp = th->cfp; + const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp); - EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, th->cfp->self, me->called_id, me->owner, Qnil); + EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, cfp->self, me->called_id, me->owner, Qnil); RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, me->owner, me->called_id); - vm_pop_frame(th); + vm_pop_frame(th, cfp, cfp->ep); } void @@ -450,7 +451,7 @@ rb_vm_rewind_cfp(rb_thread_t *th, rb_control_frame_t *cfp) printf("skipped frame: %s\n", vm_frametype_name(th->cfp)); #endif if (VM_FRAME_TYPE(th->cfp) != VM_FRAME_MAGIC_CFUNC) { - vm_pop_frame(th); + rb_vm_pop_frame(th); } else { /* unlikely path */ rb_vm_pop_cfunc_frame(); @@ -900,7 +901,7 @@ rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars) vm_set_eval_stack(th, iseq, 0, base_block); bind->env = vm_make_env_object(th, th->cfp); - vm_pop_frame(th); + rb_vm_pop_frame(th); GetEnvPtr(bind->env, env); return env->env; @@ -1682,7 +1683,7 @@ vm_exec(rb_thread_t *th) rb_vm_frame_method_entry(th->cfp)->owner, rb_vm_frame_method_entry(th->cfp)->called_id); } - th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp); + rb_vm_pop_frame(th); } cfp = th->cfp; @@ -1715,7 +1716,7 @@ vm_exec(rb_thread_t *th) th->errinfo = Qnil; result = THROW_DATA_VAL(err); hook_before_rewind(th, th->cfp, TRUE); - vm_pop_frame(th); + rb_vm_pop_frame(th); goto finish_vme; } } @@ -1858,13 +1859,13 @@ vm_exec(rb_thread_t *th) hook_before_rewind(th, th->cfp, FALSE); if (VM_FRAME_TYPE_FINISH_P(th->cfp)) { - vm_pop_frame(th); + rb_vm_pop_frame(th); th->errinfo = (VALUE)err; TH_TMPPOP_TAG(); TH_JUMP_TAG(th, state); } else { - th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp); + rb_vm_pop_frame(th); goto exception_handler; } } @@ -1964,7 +1965,7 @@ rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, val = (*func)(arg); - vm_pop_frame(th); + rb_vm_pop_frame(th); return val; } diff --git a/vm_args.c b/vm_args.c index 06760f5c64..1e310eb25c 100644 --- a/vm_args.c +++ b/vm_args.c @@ -702,7 +702,7 @@ raise_argument_error(rb_thread_t *th, const rb_iseq_t *iseq, const VALUE exc) VM_ENVVAL_BLOCK_PTR(0) /* specval*/, Qfalse /* me or cref */, iseq->body->iseq_encoded, th->cfp->sp, 1 /* local_size (cref/me) */, 0 /* stack_max */); at = rb_vm_backtrace_object(); - vm_pop_frame(th); + rb_vm_pop_frame(th); } else { at = rb_vm_backtrace_object(); diff --git a/vm_core.h b/vm_core.h index 94b5bce87d..1f61140d7a 100644 --- a/vm_core.h +++ b/vm_core.h @@ -1023,6 +1023,7 @@ 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, const VALUE *argv, const rb_callable_method_entry_t *me); +void rb_vm_pop_frame(rb_thread_t *th); void rb_thread_start_timer_thread(void); void rb_thread_stop_timer_thread(void); diff --git a/vm_eval.c b/vm_eval.c index 306f92a30e..7e131b28e7 100644 --- a/vm_eval.c +++ b/vm_eval.c @@ -95,7 +95,7 @@ vm_call0_cfunc(rb_thread_t* th, struct rb_calling_info *calling, const struct rb rb_bug("vm_call0_cfunc: cfp consistency error"); } VM_PROFILE_UP(C2C_POPF); - vm_pop_frame(th); + rb_vm_pop_frame(th); } } EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, calling->recv, ci->mid, callnig->cc->me->owner, val); @@ -134,7 +134,7 @@ vm_call0_cfunc_with_frame(rb_thread_t* th, struct rb_calling_info *calling, cons rb_bug("vm_call0_cfunc_with_frame: cfp consistency error"); } VM_PROFILE_UP(C2C_POPF); - vm_pop_frame(th); + rb_vm_pop_frame(th); } EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, mid, me->owner, val); RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, me->owner, mid); diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 3841801c41..40bc4b228c 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -207,14 +207,26 @@ vm_push_frame(rb_thread_t *th, return cfp; } -static inline void -vm_pop_frame(rb_thread_t *th) +static inline int +vm_pop_frame(rb_thread_t *th, rb_control_frame_t *cfp, const VALUE *ep /* we'll use ep soon */) { - th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp); + if (VM_CHECK_MODE >= 4) rb_gc_verify_internal_consistency(); + if (VMDEBUG == 2) SDR(); - if (VMDEBUG == 2) { - SDR(); + th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); + + if (UNLIKELY(VM_FRAME_TYPE_FINISH_P(cfp))) { + return TRUE; } + else { + return FALSE; + } +} + +void +rb_vm_pop_frame(rb_thread_t *th) +{ + vm_pop_frame(th, th->cfp, th->cfp->ep); } /* method dispatch */ @@ -1425,7 +1437,8 @@ vm_call_iseq_setup_tailcall(rb_thread_t *th, rb_control_frame_t *cfp, struct rb_ VALUE *sp_orig, *sp; VALUE finish_flag = VM_FRAME_TYPE_FINISH_P(cfp) ? VM_FRAME_FLAG_FINISH : 0; - cfp = th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp); /* pop cf */ + vm_pop_frame(th, cfp, cfp->ep); + cfp = th->cfp; RUBY_VM_CHECK_INTS(th); @@ -1644,7 +1657,7 @@ vm_call_cfunc_with_frame(rb_thread_t *th, rb_control_frame_t *reg_cfp, struct rb rb_bug("vm_call_cfunc - cfp consistency error"); } - vm_pop_frame(th); + rb_vm_pop_frame(th); EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, me->called_id, me->owner, val); RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, me->owner, me->called_id); @@ -1679,7 +1692,7 @@ vm_call_cfunc_latter(rb_thread_t *th, rb_control_frame_t *reg_cfp, struct rb_cal if (UNLIKELY(reg_cfp != RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp))) { rb_bug("vm_call_cfunc_latter: cfp consistency error (%p, %p)", reg_cfp, th->cfp+1); } - vm_pop_frame(th); + vm_pop_frame(th, reg_cfp, reg_cfp->ep); VM_PROFILE_UP(R2C_POPF); } @@ -2338,8 +2351,8 @@ vm_yield_with_cfunc(rb_thread_t *th, const rb_block_t *block, VALUE self, data = (VALUE)ifunc->data; } val = (*func)(arg, data, argc, argv, blockarg); + rb_vm_pop_frame(th); - th->cfp++; return val; } diff --git a/vm_trace.c b/vm_trace.c index ebf8e6929d..b85839af35 100644 --- a/vm_trace.c +++ b/vm_trace.c @@ -362,7 +362,7 @@ rb_threadptr_exec_event_hooks_orig(rb_trace_arg_t *trace_arg, int pop_p) if (VM_FRAME_TYPE_FINISH_P(th->cfp)) { th->tag = th->tag->prev; } - th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp); + rb_vm_pop_frame(th); } TH_JUMP_TAG(th, state); } -- cgit v1.2.3