diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-11-26 20:16:14 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-11-26 20:16:14 +0000 |
commit | 72e60a04372c03e40d3954063e6e520541d5ca2d (patch) | |
tree | 3a64c81a0545e2770905e6ec7f2ac39247218a48 /iseq.c | |
parent | 6e33c16ffdabf6b8c64a49344f830a25a2b5bccf (diff) |
`TracePoint#enable(target_line:)` is supported. [Feature #15289]
* vm_trace.c: `TracePoint#enable(target_line:)` is supported.
This option enables a hook only at specified target_line.
target_line should be combination with target and :line event.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66008 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'iseq.c')
-rw-r--r-- | iseq.c | 27 |
1 files changed, 20 insertions, 7 deletions
@@ -2980,7 +2980,7 @@ rb_iseq_trace_flag_cleared(const rb_iseq_t *iseq, size_t pos) } static int -iseq_add_local_tracepoint(const rb_iseq_t *iseq, rb_event_flag_t turnon_events, VALUE tpval) +iseq_add_local_tracepoint(const rb_iseq_t *iseq, rb_event_flag_t turnon_events, VALUE tpval, unsigned int target_line) { unsigned int pc; int n = 0; @@ -2990,18 +2990,29 @@ iseq_add_local_tracepoint(const rb_iseq_t *iseq, rb_event_flag_t turnon_events, VM_ASSERT((iseq->flags & ISEQ_USE_COMPILE_DATA) == 0); for (pc=0; pc<body->iseq_size;) { - rb_event_flag_t pc_events = rb_iseq_event_flags(iseq, pc); - if (pc_events & turnon_events) { + const struct iseq_insn_info_entry *entry = get_insn_info(iseq, pc); + rb_event_flag_t pc_events = entry->events; + rb_event_flag_t target_events = turnon_events; + unsigned int line = (int)entry->line_no; + + if (target_line == 0 || target_line == line) { + /* ok */ + } + else { + target_events &= ~RUBY_EVENT_LINE; + } + + if (pc_events & target_events) { n++; } - pc += encoded_iseq_trace_instrument(&iseq_encoded[pc], pc_events & (turnon_events | iseq->aux.global_trace_events)); + pc += encoded_iseq_trace_instrument(&iseq_encoded[pc], pc_events & (target_events | iseq->aux.global_trace_events)); } if (n > 0) { if (iseq->local_hooks == NULL) { ((rb_iseq_t *)iseq)->local_hooks = RB_ZALLOC(rb_hook_list_t); } - rb_hook_list_connect_tracepoint((VALUE)iseq, iseq->local_hooks, tpval); + rb_hook_list_connect_tracepoint((VALUE)iseq, iseq->local_hooks, tpval, target_line); } return n; @@ -3010,6 +3021,7 @@ iseq_add_local_tracepoint(const rb_iseq_t *iseq, rb_event_flag_t turnon_events, struct trace_set_local_events_struct { rb_event_flag_t turnon_events; VALUE tpval; + unsigned int target_line; int n; }; @@ -3017,16 +3029,17 @@ static void iseq_add_local_tracepoint_i(const rb_iseq_t *iseq, void *p) { struct trace_set_local_events_struct *data = (struct trace_set_local_events_struct *)p; - data->n += iseq_add_local_tracepoint(iseq, data->turnon_events, data->tpval); + data->n += iseq_add_local_tracepoint(iseq, data->turnon_events, data->tpval, data->target_line); iseq_iterate_children(iseq, iseq_add_local_tracepoint_i, p); } int -rb_iseq_add_local_tracepoint_recursively(const rb_iseq_t *iseq, rb_event_flag_t turnon_events, VALUE tpval) +rb_iseq_add_local_tracepoint_recursively(const rb_iseq_t *iseq, rb_event_flag_t turnon_events, VALUE tpval, unsigned int target_line) { struct trace_set_local_events_struct data; data.turnon_events = turnon_events; data.tpval = tpval; + data.target_line = target_line; data.n = 0; iseq_add_local_tracepoint_i(iseq, (void *)&data); |