mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* vm_trace.c: skip "exception check" and "reentrant check (only normal
events) for internal events. Reentrant check for internal events are remaining. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43855 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
5b40cb6a2c
commit
bd26be2b34
2 changed files with 91 additions and 53 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
Tue Nov 26 18:12:13 2013 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* vm_trace.c: skip "exception check" and "reentrant check (only normal
|
||||||
|
events) for internal events.
|
||||||
|
|
||||||
|
Reentrant check for internal events are remaining.
|
||||||
|
|
||||||
Tue Nov 26 17:38:16 2013 Koichi Sasada <ko1@atdot.net>
|
Tue Nov 26 17:38:16 2013 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
* vm_trace.c: prohibit to specify normal events and internal events
|
* vm_trace.c: prohibit to specify normal events and internal events
|
||||||
|
|
85
vm_trace.c
85
vm_trace.c
|
@ -251,22 +251,9 @@ clean_hooks(rb_hook_list_t *list)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
exec_hooks(rb_thread_t *th, rb_hook_list_t *list, const rb_trace_arg_t *trace_arg, int can_clean_hooks)
|
exec_hooks_body(rb_thread_t *th, rb_hook_list_t *list, const rb_trace_arg_t *trace_arg)
|
||||||
{
|
{
|
||||||
int state;
|
|
||||||
volatile int raised;
|
|
||||||
|
|
||||||
if (UNLIKELY(list->need_clean > 0) && can_clean_hooks) {
|
|
||||||
clean_hooks(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
raised = rb_threadptr_reset_raised(th);
|
|
||||||
|
|
||||||
/* TODO: Support !RUBY_EVENT_HOOK_FLAG_SAFE hooks */
|
|
||||||
|
|
||||||
TH_PUSH_TAG(th);
|
|
||||||
if ((state = TH_EXEC_TAG()) == 0) {
|
|
||||||
rb_event_hook_t *hook;
|
rb_event_hook_t *hook;
|
||||||
|
|
||||||
for (hook = list->hooks; hook; hook = hook->next) {
|
for (hook = list->hooks; hook; hook = hook->next) {
|
||||||
|
@ -280,6 +267,43 @@ exec_hooks(rb_thread_t *th, rb_hook_list_t *list, const rb_trace_arg_t *trace_ar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
exec_hooks_precheck(rb_thread_t *th, rb_hook_list_t *list, const rb_trace_arg_t *trace_arg)
|
||||||
|
{
|
||||||
|
if ((list->events & trace_arg->event) == 0) return 0;
|
||||||
|
|
||||||
|
if (UNLIKELY(list->need_clean > 0)) {
|
||||||
|
if (th->vm->trace_running <= 1) { /* only running this hooks */
|
||||||
|
clean_hooks(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
exec_hooks_unprotected(rb_thread_t *th, rb_hook_list_t *list, const rb_trace_arg_t *trace_arg)
|
||||||
|
{
|
||||||
|
if (exec_hooks_precheck(th, list, trace_arg) == 0) return;
|
||||||
|
exec_hooks_body(th, list, trace_arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
exec_hooks_protected(rb_thread_t *th, rb_hook_list_t *list, const rb_trace_arg_t *trace_arg)
|
||||||
|
{
|
||||||
|
int state;
|
||||||
|
volatile int raised;
|
||||||
|
|
||||||
|
if (exec_hooks_precheck(th, list, trace_arg) == 0) return 0;
|
||||||
|
|
||||||
|
raised = rb_threadptr_reset_raised(th);
|
||||||
|
|
||||||
|
/* TODO: Support !RUBY_EVENT_HOOK_FLAG_SAFE hooks */
|
||||||
|
|
||||||
|
TH_PUSH_TAG(th);
|
||||||
|
if ((state = TH_EXEC_TAG()) == 0) {
|
||||||
|
exec_hooks_body(th, list, trace_arg);
|
||||||
|
}
|
||||||
TH_POP_TAG();
|
TH_POP_TAG();
|
||||||
|
|
||||||
if (raised) {
|
if (raised) {
|
||||||
|
@ -293,9 +317,22 @@ static void
|
||||||
rb_threadptr_exec_event_hooks_orig(rb_trace_arg_t *trace_arg, int pop_p)
|
rb_threadptr_exec_event_hooks_orig(rb_trace_arg_t *trace_arg, int pop_p)
|
||||||
{
|
{
|
||||||
rb_thread_t *th = trace_arg->th;
|
rb_thread_t *th = trace_arg->th;
|
||||||
if (th->trace_arg == 0 &&
|
|
||||||
|
if (trace_arg->event & RUBY_INTERNAL_EVENT_MASK) {
|
||||||
|
if (th->trace_arg && (th->trace_arg->event & RUBY_INTERNAL_EVENT_MASK)) {
|
||||||
|
/* skip hooks because this thread doing INTERNAL_EVENT */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rb_trace_arg_t *prev_trace_arg = th->trace_arg;
|
||||||
|
th->trace_arg = trace_arg;
|
||||||
|
exec_hooks_unprotected(th, &th->event_hooks, trace_arg);
|
||||||
|
exec_hooks_unprotected(th, &th->vm->event_hooks, trace_arg);
|
||||||
|
th->trace_arg = prev_trace_arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (th->trace_arg == 0 && /* check reentrant */
|
||||||
trace_arg->self != rb_mRubyVMFrozenCore /* skip special methods. TODO: remove it. */) {
|
trace_arg->self != rb_mRubyVMFrozenCore /* skip special methods. TODO: remove it. */) {
|
||||||
const int vm_tracing = th->vm->trace_running;
|
|
||||||
const VALUE errinfo = th->errinfo;
|
const VALUE errinfo = th->errinfo;
|
||||||
const int outer_state = th->state;
|
const int outer_state = th->state;
|
||||||
int state = 0;
|
int state = 0;
|
||||||
|
@ -305,21 +342,14 @@ rb_threadptr_exec_event_hooks_orig(rb_trace_arg_t *trace_arg, int pop_p)
|
||||||
th->vm->trace_running++;
|
th->vm->trace_running++;
|
||||||
th->trace_arg = trace_arg;
|
th->trace_arg = trace_arg;
|
||||||
{
|
{
|
||||||
rb_hook_list_t *list;
|
|
||||||
|
|
||||||
/* thread local traces */
|
/* thread local traces */
|
||||||
list = &th->event_hooks;
|
state = exec_hooks_protected(th, &th->event_hooks, trace_arg);
|
||||||
if (list->events & trace_arg->event) {
|
|
||||||
state = exec_hooks(th, list, trace_arg, TRUE);
|
|
||||||
if (state) goto terminate;
|
if (state) goto terminate;
|
||||||
}
|
|
||||||
|
|
||||||
/* vm global traces */
|
/* vm global traces */
|
||||||
list = &th->vm->event_hooks;
|
state = exec_hooks_protected(th, &th->vm->event_hooks, trace_arg);
|
||||||
if (list->events & trace_arg->event) {
|
|
||||||
state = exec_hooks(th, list, trace_arg, !vm_tracing);
|
|
||||||
if (state) goto terminate;
|
if (state) goto terminate;
|
||||||
}
|
|
||||||
th->errinfo = errinfo;
|
th->errinfo = errinfo;
|
||||||
}
|
}
|
||||||
terminate:
|
terminate:
|
||||||
|
@ -338,6 +368,7 @@ rb_threadptr_exec_event_hooks_orig(rb_trace_arg_t *trace_arg, int pop_p)
|
||||||
th->state = outer_state;
|
th->state = outer_state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_threadptr_exec_event_hooks_and_pop_frame(rb_trace_arg_t *trace_arg)
|
rb_threadptr_exec_event_hooks_and_pop_frame(rb_trace_arg_t *trace_arg)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue