summaryrefslogtreecommitdiff
path: root/iseq.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-11-26 20:16:14 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-11-26 20:16:14 +0000
commit72e60a04372c03e40d3954063e6e520541d5ca2d (patch)
tree3a64c81a0545e2770905e6ec7f2ac39247218a48 /iseq.c
parent6e33c16ffdabf6b8c64a49344f830a25a2b5bccf (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.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/iseq.c b/iseq.c
index 063c872c24..930a88d28f 100644
--- a/iseq.c
+++ b/iseq.c
@@ -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);