summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-07-26 10:28:21 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-07-26 10:28:21 +0000
commitbe5564a178ee453b7d6fedc7c312bec01e29dde2 (patch)
treeae1387d18aa71ee6359c1bfc6e055b216f090908
parent78e86f75ed7ba5b7cd0cbdd85b27c98e271fd2fc (diff)
* 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
-rw-r--r--ChangeLog8
-rw-r--r--eval.c2
-rw-r--r--insns.def5
-rw-r--r--vm.c21
-rw-r--r--vm_args.c2
-rw-r--r--vm_core.h1
-rw-r--r--vm_eval.c4
-rw-r--r--vm_insnhelper.c31
-rw-r--r--vm_trace.c2
9 files changed, 48 insertions, 28 deletions
diff --git a/ChangeLog b/ChangeLog
index de48c3b..01fb53e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Tue Jul 26 19:26:00 2016 Koichi Sasada <ko1@atdot.net>
+
+ * 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 <ko1@atdot.net>
* gc.c (rb_raw_obj_info): support to show Proc obj.
diff --git a/eval.c b/eval.c
index 475d6ca..3241cb8 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 c9d7204..7da7f89 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 77e08ab..c900eec 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 06760f5..1e310eb 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 94b5bce..1f61140 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 306f92a..7e131b2 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 3841801..40bc4b2 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 ebf8e69..b85839a 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);
}