aboutsummaryrefslogtreecommitdiffstats
path: root/thread.c
diff options
context:
space:
mode:
authorYusuke Endoh <mame@ruby-lang.org>2020-06-19 14:52:35 +0900
committerYusuke Endoh <mame@ruby-lang.org>2020-06-20 09:28:03 +0900
commit50efa18c6cf102e070ba0f95edc01c72516495a3 (patch)
tree66822bf40ec6e011945893630f2e50c5bdeaad71 /thread.c
parentbc0aea080446298eb4a778f941c8469842bbf033 (diff)
downloadruby-50efa18c6cf102e070ba0f95edc01c72516495a3.tar.gz
compile.c: Improve branch coverage instrumentation [Bug #16967]
Formerly, branch coverage measurement counters are generated for each compilation traverse of the AST. However, ensure clause node is traversed twice; one is for normal-exit case (the resulted bytecode is embedded in its outer scope), and the other is for exceptional case (the resulted bytecode is used in catch table). Two branch coverage counters are generated for the two cases, but it is not desired. This changeset revamps the internal representation of branch coverage measurement. Branch coverage counters are generated only at the first visit of a branch node. Visiting the same node reuses the already-generated counter, so double counting is avoided.
Diffstat (limited to 'thread.c')
-rw-r--r--thread.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/thread.c b/thread.c
index 91a953b9ab..6fdddde720 100644
--- a/thread.c
+++ b/thread.c
@@ -5644,20 +5644,31 @@ rb_default_coverage(int n)
RARRAY_ASET(coverage, COVERAGE_INDEX_LINES, lines);
if (mode & COVERAGE_TARGET_BRANCHES) {
- branches = rb_ary_tmp_new_fill(2);
- /* internal data structures for branch coverage:
- *
- * [[base_type, base_first_lineno, base_first_column, base_last_lineno, base_last_column,
- * target_type_1, target_first_lineno_1, target_first_column_1, target_last_lineno_1, target_last_column_1, target_counter_index_1,
- * target_type_2, target_first_lineno_2, target_first_column_2, target_last_lineno_2, target_last_column_2, target_counter_index_2, ...],
- * ...]
- *
- * Example: [[:case, 1, 0, 4, 3,
- * :when, 2, 8, 2, 9, 0,
- * :when, 3, 8, 3, 9, 1, ...],
- * ...]
- */
- RARRAY_ASET(branches, 0, rb_ary_tmp_new(0));
+ branches = rb_ary_tmp_new_fill(2);
+ /* internal data structures for branch coverage:
+ *
+ * { branch base node =>
+ * [base_type, base_first_lineno, base_first_column, base_last_lineno, base_last_column, {
+ * branch target id =>
+ * [target_type, target_first_lineno, target_first_column, target_last_lineno, target_last_column, target_counter_index],
+ * ...
+ * }],
+ * ...
+ * }
+ *
+ * Example:
+ * { NODE_CASE =>
+ * [1, 0, 4, 3, {
+ * NODE_WHEN => [2, 8, 2, 9, 0],
+ * NODE_WHEN => [3, 8, 3, 9, 1],
+ * ...
+ * }],
+ * ...
+ * }
+ */
+ VALUE structure = rb_hash_new();
+ rb_obj_hide(structure);
+ RARRAY_ASET(branches, 0, structure);
/* branch execution counters */
RARRAY_ASET(branches, 1, rb_ary_tmp_new(0));
}