1
0
Fork 0
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:
ko1 2013-11-26 09:42:04 +00:00
parent 5b40cb6a2c
commit bd26be2b34
2 changed files with 91 additions and 53 deletions

View file

@ -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>
* vm_trace.c: prohibit to specify normal events and internal events

View file

@ -251,22 +251,9 @@ clean_hooks(rb_hook_list_t *list)
}
}
static int
exec_hooks(rb_thread_t *th, rb_hook_list_t *list, const rb_trace_arg_t *trace_arg, int can_clean_hooks)
static void
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;
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();
if (raised) {
@ -293,9 +317,22 @@ static void
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 &&
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 int vm_tracing = th->vm->trace_running;
const VALUE errinfo = th->errinfo;
const int outer_state = th->state;
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->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);
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);
state = exec_hooks_protected(th, &th->vm->event_hooks, trace_arg);
if (state) goto terminate;
}
th->errinfo = errinfo;
}
terminate:
@ -338,6 +368,7 @@ rb_threadptr_exec_event_hooks_orig(rb_trace_arg_t *trace_arg, int pop_p)
th->state = outer_state;
}
}
}
void
rb_threadptr_exec_event_hooks_and_pop_frame(rb_trace_arg_t *trace_arg)