summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compile.c9
-rw-r--r--iseq.c1
-rw-r--r--iseq.h1
-rw-r--r--thread.c45
4 files changed, 30 insertions, 26 deletions
diff --git a/compile.c b/compile.c
index 7b2839e853..41fb7633b3 100644
--- a/compile.c
+++ b/compile.c
@@ -251,15 +251,12 @@ struct iseq_compile_data_ensure_node_stack {
#define ADD_TRACE(seq, event) \
ADD_ELEM((seq), (LINK_ELEMENT *)new_trace_body(iseq, (event)))
-#define ADD_TRACE_LINE_COVERAGE(seq, line) \
+#define SETUP_LINE_COVERAGE(seq, line) \
do { \
if (ISEQ_COVERAGE(iseq) && \
ISEQ_LINE_COVERAGE(iseq) && \
- (line) > 0 && \
- (line) != ISEQ_COMPILE_DATA(iseq)->last_coverable_line) { \
+ (line) > 0) { \
RARRAY_ASET(ISEQ_LINE_COVERAGE(iseq), (line) - 1, INT2FIX(0)); \
- ISEQ_COMPILE_DATA(iseq)->last_coverable_line = (line); \
- ADD_INSN2((seq), (line), trace2, INT2FIX(RUBY_EVENT_COVERAGE), INT2FIX(COVERAGE_INDEX_LINES)); \
} \
} while (0)
#define DECL_BRANCH_BASE(branches, first_line, first_column, last_line, last_column, type) \
@@ -5424,7 +5421,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, in
else {
if (node->flags & NODE_FL_NEWLINE) {
ISEQ_COMPILE_DATA(iseq)->last_line = line;
- ADD_TRACE_LINE_COVERAGE(ret, line);
+ SETUP_LINE_COVERAGE(ret, line);
ADD_TRACE(ret, RUBY_EVENT_LINE);
}
}
diff --git a/iseq.c b/iseq.c
index 6dd4addb45..998639eafc 100644
--- a/iseq.c
+++ b/iseq.c
@@ -330,7 +330,6 @@ prepare_iseq_build(rb_iseq_t *iseq,
ISEQ_COMPILE_DATA(iseq)->storage_head->size =
INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE;
ISEQ_COMPILE_DATA(iseq)->option = option;
- ISEQ_COMPILE_DATA(iseq)->last_coverable_line = -1;
ISEQ_COMPILE_DATA(iseq)->ivar_cache_table = NULL;
diff --git a/iseq.h b/iseq.h
index 8d2281881b..fb0a5d0d29 100644
--- a/iseq.h
+++ b/iseq.h
@@ -114,7 +114,6 @@ struct iseq_compile_data {
struct iseq_compile_data_storage *storage_head;
struct iseq_compile_data_storage *storage_current;
int last_line;
- int last_coverable_line;
int label_no;
int node_level;
unsigned int ci_index;
diff --git a/thread.c b/thread.c
index 536a6c5139..43c6f224b5 100644
--- a/thread.c
+++ b/thread.c
@@ -4976,30 +4976,35 @@ rb_check_deadlock(rb_vm_t *vm)
}
static void
+update_line_coverage(VALUE data, const rb_trace_arg_t *trace_arg)
+{
+ VALUE coverage = rb_iseq_coverage(GET_EC()->cfp->iseq);
+ if (RB_TYPE_P(coverage, T_ARRAY) && !RBASIC_CLASS(coverage)) {
+ VALUE lines = RARRAY_AREF(coverage, COVERAGE_INDEX_LINES);
+ if (lines) {
+ long line = rb_sourceline() - 1;
+ long count;
+ VALUE num;
+ if (line >= RARRAY_LEN(lines)) { /* no longer tracked */
+ return;
+ }
+ num = RARRAY_AREF(lines, line);
+ if (!FIXNUM_P(num)) return;
+ count = FIX2LONG(num) + 1;
+ if (POSFIXABLE(count)) {
+ RARRAY_ASET(lines, line, LONG2FIX(count));
+ }
+ }
+ }
+}
+
+static void
update_coverage(VALUE data, const rb_trace_arg_t *trace_arg)
{
VALUE coverage = rb_iseq_coverage(GET_EC()->cfp->iseq);
if (RB_TYPE_P(coverage, T_ARRAY) && !RBASIC_CLASS(coverage)) {
long arg = FIX2INT(trace_arg->data);
switch (arg % 16) {
- case COVERAGE_INDEX_LINES: {
- VALUE lines = RARRAY_AREF(coverage, COVERAGE_INDEX_LINES);
- if (lines) {
- long line = rb_sourceline() - 1;
- long count;
- VALUE num;
- if (line >= RARRAY_LEN(lines)) { /* no longer tracked */
- return;
- }
- num = RARRAY_AREF(lines, line);
- if (!FIXNUM_P(num)) return;
- count = FIX2LONG(num) + 1;
- if (POSFIXABLE(count)) {
- RARRAY_ASET(lines, line, LONG2FIX(count));
- }
- }
- break;
- }
case COVERAGE_INDEX_BRANCHES: {
VALUE branches = RARRAY_AREF(coverage, COVERAGE_INDEX_BRANCHES);
if (branches) {
@@ -5106,6 +5111,7 @@ rb_set_coverages(VALUE coverages, int mode, VALUE me2counter)
{
GET_VM()->coverages = coverages;
GET_VM()->coverage_mode = mode;
+ rb_add_event_hook2((rb_event_hook_func_t) update_line_coverage, RUBY_EVENT_LINE, Qnil, RUBY_EVENT_HOOK_FLAG_SAFE | RUBY_EVENT_HOOK_FLAG_RAW_ARG);
rb_add_event_hook2((rb_event_hook_func_t) update_coverage, RUBY_EVENT_COVERAGE, Qnil, RUBY_EVENT_HOOK_FLAG_SAFE | RUBY_EVENT_HOOK_FLAG_RAW_ARG);
if (mode & COVERAGE_TARGET_METHODS) {
rb_add_event_hook2((rb_event_hook_func_t) update_method_coverage, RUBY_EVENT_CALL, me2counter, RUBY_EVENT_HOOK_FLAG_SAFE | RUBY_EVENT_HOOK_FLAG_RAW_ARG);
@@ -5130,6 +5136,9 @@ rb_reset_coverages(void)
VALUE coverages = rb_get_coverages();
st_foreach(rb_hash_tbl_raw(coverages), reset_coverage_i, 0);
GET_VM()->coverages = Qfalse;
+ if (GET_VM()->coverage_mode & COVERAGE_TARGET_LINES) {
+ rb_remove_event_hook((rb_event_hook_func_t) update_line_coverage);
+ }
rb_remove_event_hook((rb_event_hook_func_t) update_coverage);
if (GET_VM()->coverage_mode & COVERAGE_TARGET_METHODS) {
rb_remove_event_hook((rb_event_hook_func_t) update_method_coverage);