ruby-changes:31776
From: ko1 <ko1@a...>
Date: Tue, 26 Nov 2013 18:42:14 +0900 (JST)
Subject: [ruby-changes:31776] ko1:r43855 (trunk): * vm_trace.c: skip "exception check" and "reentrant check (only normal
ko1 2013-11-26 18:42:04 +0900 (Tue, 26 Nov 2013) New Revision: 43855 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=43855 Log: * vm_trace.c: skip "exception check" and "reentrant check (only normal events) for internal events. Reentrant check for internal events are remaining. Modified files: trunk/ChangeLog trunk/vm_trace.c Index: ChangeLog =================================================================== --- ChangeLog (revision 43854) +++ ChangeLog (revision 43855) @@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Tue Nov 26 18:12:13 2013 Koichi Sasada <ko1@a...> + + * 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@a...> * vm_trace.c: prohibit to specify normal events and internal events Index: vm_trace.c =================================================================== --- vm_trace.c (revision 43854) +++ vm_trace.c (revision 43855) @@ -251,15 +251,50 @@ clean_hooks(rb_hook_list_t *list) https://github.com/ruby/ruby/blob/trunk/vm_trace.c#L251 } } +static void +exec_hooks_body(rb_thread_t *th, rb_hook_list_t *list, const rb_trace_arg_t *trace_arg) +{ + rb_event_hook_t *hook; + + for (hook = list->hooks; hook; hook = hook->next) { + if (!(hook->hook_flags & RUBY_EVENT_HOOK_FLAG_DELETED) && (trace_arg->event & hook->events)) { + if (!(hook->hook_flags & RUBY_EVENT_HOOK_FLAG_RAW_ARG)) { + (*hook->func)(trace_arg->event, hook->data, trace_arg->self, trace_arg->id, trace_arg->klass); + } + else { + (*((rb_event_hook_raw_arg_func_t)hook->func))(hook->data, trace_arg); + } + } + } +} + static int -exec_hooks(rb_thread_t *th, rb_hook_list_t *list, const rb_trace_arg_t *trace_arg, int can_clean_hooks) +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 (UNLIKELY(list->need_clean > 0) && can_clean_hooks) { - clean_hooks(list); - } + if (exec_hooks_precheck(th, list, trace_arg) == 0) return 0; raised = rb_threadptr_reset_raised(th); @@ -267,18 +302,7 @@ exec_hooks(rb_thread_t *th, rb_hook_list https://github.com/ruby/ruby/blob/trunk/vm_trace.c#L302 TH_PUSH_TAG(th); if ((state = TH_EXEC_TAG()) == 0) { - rb_event_hook_t *hook; - - for (hook = list->hooks; hook; hook = hook->next) { - if (!(hook->hook_flags & RUBY_EVENT_HOOK_FLAG_DELETED) && (trace_arg->event & hook->events)) { - if (!(hook->hook_flags & RUBY_EVENT_HOOK_FLAG_RAW_ARG)) { - (*hook->func)(trace_arg->event, hook->data, trace_arg->self, trace_arg->id, trace_arg->klass); - } - else { - (*((rb_event_hook_raw_arg_func_t)hook->func))(hook->data, trace_arg); - } - } - } + exec_hooks_body(th, list, trace_arg); } TH_POP_TAG(); @@ -293,49 +317,56 @@ static void https://github.com/ruby/ruby/blob/trunk/vm_trace.c#L317 rb_threadptr_exec_event_hooks_orig(rb_trace_arg_t *trace_arg, int pop_p) { rb_thread_t *th = trace_arg->th; - if (th->trace_arg == 0 && - 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 int outer_state = th->state; - int state = 0; - th->state = 0; - th->errinfo = Qnil; - - th->vm->trace_running++; - th->trace_arg = trace_arg; - { - rb_hook_list_t *list; - - /* thread local traces */ - list = &th->event_hooks; - if (list->events & trace_arg->event) { - state = exec_hooks(th, list, trace_arg, TRUE); + + 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. */) { + const VALUE errinfo = th->errinfo; + const int outer_state = th->state; + int state = 0; + th->state = 0; + th->errinfo = Qnil; + + th->vm->trace_running++; + th->trace_arg = trace_arg; + { + /* thread local traces */ + state = exec_hooks_protected(th, &th->event_hooks, trace_arg); if (state) goto terminate; - } - /* vm global traces */ - list = &th->vm->event_hooks; - if (list->events & trace_arg->event) { - state = exec_hooks(th, list, trace_arg, !vm_tracing); + /* vm global traces */ + state = exec_hooks_protected(th, &th->vm->event_hooks, trace_arg); if (state) goto terminate; + + th->errinfo = errinfo; } - th->errinfo = errinfo; - } - terminate: - th->trace_arg = 0; - th->vm->trace_running--; - - if (state) { - if (pop_p) { - if (VM_FRAME_TYPE_FINISH_P(th->cfp)) { - th->tag = th->tag->prev; + terminate: + th->trace_arg = 0; + th->vm->trace_running--; + + if (state) { + if (pop_p) { + if (VM_FRAME_TYPE_FINISH_P(th->cfp)) { + th->tag = th->tag->prev; + } + th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp); } - th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp); + TH_JUMP_TAG(th, state); } - TH_JUMP_TAG(th, state); + th->state = outer_state; } - th->state = outer_state; } } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/