[前][次][番号順一覧][スレッド一覧]

ruby-changes:47622

From: mame <ko1@a...>
Date: Sun, 3 Sep 2017 23:26:11 +0900 (JST)
Subject: [ruby-changes:47622] mame:r59738 (trunk): Refactor the internal data format for coverage measurement

mame	2017-09-03 23:26:06 +0900 (Sun, 03 Sep 2017)

  New Revision: 59738

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=59738

  Log:
    Refactor the internal data format for coverage measurement
    
    To prepare new measuring targets: branch and method coverages.
    So far, iseq->coverage was an array of counts executed for line coverage.
    Now, it is a three-element array for each measuring target,
    whose first element is an array for line coverage.
    The second element is planned for branch coverage, and the third will be
    for method coverage.

  Modified files:
    trunk/compile.c
    trunk/ext/coverage/coverage.c
    trunk/internal.h
    trunk/iseq.h
    trunk/parse.y
    trunk/thread.c
    trunk/vm_core.h
Index: thread.c
===================================================================
--- thread.c	(revision 59737)
+++ thread.c	(revision 59738)
@@ -4090,13 +4090,17 @@ static int https://github.com/ruby/ruby/blob/trunk/thread.c#L4090
 clear_coverage_i(st_data_t key, st_data_t val, st_data_t dummy)
 {
     int i;
-    VALUE lines = (VALUE)val;
+    VALUE coverage = (VALUE)val;
+    VALUE lines = RARRAY_AREF(coverage, COVERAGE_INDEX_LINES);
 
-    for (i = 0; i < RARRAY_LEN(lines); i++) {
-	if (RARRAY_AREF(lines, i) != Qnil) {
-	    RARRAY_ASET(lines, i, INT2FIX(0));
+    if (lines) {
+	for (i = 0; i < RARRAY_LEN(lines); i++) {
+	    if (RARRAY_AREF(lines, i) != Qnil) {
+		RARRAY_ASET(lines, i, INT2FIX(0));
+	    }
 	}
     }
+
     return ST_CONTINUE;
 }
 
@@ -4970,17 +4974,20 @@ update_coverage(rb_event_flag_t event, V https://github.com/ruby/ruby/blob/trunk/thread.c#L4974
 {
     VALUE coverage = rb_iseq_coverage(GET_THREAD()->ec.cfp->iseq);
     if (RB_TYPE_P(coverage, T_ARRAY) && !RBASIC_CLASS(coverage)) {
-	long line = rb_sourceline() - 1;
-	long count;
-	VALUE num;
-	if (line >= RARRAY_LEN(coverage)) { /* no longer tracked */
-	    return;
-	}
-	num = RARRAY_AREF(coverage, line);
-	if (!FIXNUM_P(num)) return;
-	count = FIX2LONG(num) + 1;
-	if (POSFIXABLE(count)) {
-	    RARRAY_ASET(coverage, line, LONG2FIX(count));
+	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));
+	    }
 	}
     }
 }
@@ -4992,9 +4999,10 @@ rb_get_coverages(void) https://github.com/ruby/ruby/blob/trunk/thread.c#L4999
 }
 
 void
-rb_set_coverages(VALUE coverages)
+rb_set_coverages(VALUE coverages, int mode)
 {
     GET_VM()->coverages = coverages;
+    GET_VM()->coverage_mode = mode;
     rb_add_event_hook(update_coverage, RUBY_EVENT_COVERAGE, Qnil);
 }
 
@@ -5003,7 +5011,8 @@ static int https://github.com/ruby/ruby/blob/trunk/thread.c#L5011
 reset_coverage_i(st_data_t key, st_data_t val, st_data_t dummy)
 {
     VALUE coverage = (VALUE)val;
-    rb_ary_clear(coverage);
+    VALUE lines = RARRAY_AREF(coverage, COVERAGE_INDEX_LINES);
+    rb_ary_clear(lines);
     return ST_CONTINUE;
 }
 
@@ -5017,6 +5026,31 @@ rb_reset_coverages(void) https://github.com/ruby/ruby/blob/trunk/thread.c#L5026
 }
 
 VALUE
+rb_default_coverage(int n)
+{
+    VALUE coverage = rb_ary_tmp_new_fill(3);
+    VALUE lines = Qfalse, branches = Qfalse, methods = Qfalse;
+    int mode = GET_VM()->coverage_mode;
+
+    if (mode & COVERAGE_TARGET_LINES) {
+	lines = n > 0 ? rb_ary_tmp_new_fill(n) : rb_ary_tmp_new(0);
+    }
+    RARRAY_ASET(coverage, COVERAGE_INDEX_LINES, lines);
+
+    if (mode & COVERAGE_TARGET_BRANCHES) {
+	/* not implemented yet */
+    }
+    RARRAY_ASET(coverage, COVERAGE_INDEX_BRANCHES, branches);
+
+    if (mode & COVERAGE_TARGET_METHODS) {
+	/* not implemented yet */
+    }
+    RARRAY_ASET(coverage, COVERAGE_INDEX_METHODS, methods);
+
+    return coverage;
+}
+
+VALUE
 rb_uninterruptible(VALUE (*b_proc)(ANYARGS), VALUE data)
 {
     VALUE interrupt_mask = rb_ident_hash_new();
Index: internal.h
===================================================================
--- internal.h	(revision 59737)
+++ internal.h	(revision 59738)
@@ -1677,11 +1677,19 @@ VALUE rb_struct_lookup(VALUE s, VALUE id https://github.com/ruby/ruby/blob/trunk/internal.h#L1677
 struct timeval rb_time_timeval(VALUE);
 
 /* thread.c */
+#define COVERAGE_INDEX_LINES    0
+#define COVERAGE_INDEX_BRANCHES 1
+#define COVERAGE_INDEX_METHODS  2
+#define COVERAGE_TARGET_LINES    1
+#define COVERAGE_TARGET_BRANCHES 2
+#define COVERAGE_TARGET_METHODS  4
+
 VALUE rb_obj_is_mutex(VALUE obj);
 VALUE rb_suppress_tracing(VALUE (*func)(VALUE), VALUE arg);
 void rb_thread_execute_interrupts(VALUE th);
 void rb_clear_trace_func(void);
 VALUE rb_get_coverages(void);
+VALUE rb_default_coverage(int);
 VALUE rb_thread_shield_new(void);
 VALUE rb_thread_shield_wait(VALUE self);
 VALUE rb_thread_shield_release(VALUE self);
Index: vm_core.h
===================================================================
--- vm_core.h	(revision 59737)
+++ vm_core.h	(revision 59738)
@@ -566,6 +566,7 @@ typedef struct rb_vm_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L566
 
     VALUE verbose, debug, orig_progname, progname;
     VALUE coverages;
+    int coverage_mode;
 
     VALUE defined_module_hash;
 
@@ -1686,7 +1687,7 @@ RUBY_SYMBOL_EXPORT_BEGIN https://github.com/ruby/ruby/blob/trunk/vm_core.h#L1687
 int rb_thread_check_trap_pending(void);
 
 extern VALUE rb_get_coverages(void);
-extern void rb_set_coverages(VALUE);
+extern void rb_set_coverages(VALUE, int);
 extern void rb_reset_coverages(void);
 
 void rb_postponed_job_flush(rb_vm_t *vm);
Index: compile.c
===================================================================
--- compile.c	(revision 59737)
+++ compile.c	(revision 59738)
@@ -243,9 +243,10 @@ struct iseq_compile_data_ensure_node_sta https://github.com/ruby/ruby/blob/trunk/compile.c#L243
 #define ADD_TRACE(seq, line, event) \
   do { \
       if ((event) == RUBY_EVENT_LINE && ISEQ_COVERAGE(iseq) && \
+	  ISEQ_LINE_COVERAGE(iseq) && \
 	  (line) > 0 && \
 	  (line) != ISEQ_COMPILE_DATA(iseq)->last_coverable_line) { \
-	  RARRAY_ASET(ISEQ_COVERAGE(iseq), (line) - 1, INT2FIX(0)); \
+	  RARRAY_ASET(ISEQ_LINE_COVERAGE(iseq), (line) - 1, INT2FIX(0)); \
 	  ISEQ_COMPILE_DATA(iseq)->last_coverable_line = (line); \
 	  ADD_INSN1((seq), (line), trace, INT2FIX(RUBY_EVENT_COVERAGE)); \
       } \
Index: parse.y
===================================================================
--- parse.y	(revision 59737)
+++ parse.y	(revision 59738)
@@ -5237,9 +5237,12 @@ coverage(VALUE fname, int n) https://github.com/ruby/ruby/blob/trunk/parse.y#L5237
 {
     VALUE coverages = rb_get_coverages();
     if (RTEST(coverages) && RBASIC(coverages)->klass == 0) {
-	VALUE lines = n > 0 ? rb_ary_tmp_new_fill(n) : rb_ary_tmp_new(0);
-	rb_hash_aset(coverages, fname, lines);
-	return lines;
+	VALUE coverage = rb_default_coverage(n);
+	VALUE lines = RARRAY_AREF(coverage, COVERAGE_INDEX_LINES);
+
+	rb_hash_aset(coverages, fname, coverage);
+
+	return lines == Qnil ? Qfalse : lines;
     }
     return 0;
 }
Index: ext/coverage/coverage.c
===================================================================
--- ext/coverage/coverage.c	(revision 59737)
+++ ext/coverage/coverage.c	(revision 59738)
@@ -24,7 +24,7 @@ rb_coverage_start(VALUE klass) https://github.com/ruby/ruby/blob/trunk/ext/coverage/coverage.c#L24
     if (!RTEST(coverages)) {
 	coverages = rb_hash_new();
 	rb_obj_hide(coverages);
-	rb_set_coverages(coverages);
+	rb_set_coverages(coverages, COVERAGE_TARGET_LINES);
     }
     return Qnil;
 }
@@ -35,9 +35,12 @@ coverage_peek_result_i(st_data_t key, st https://github.com/ruby/ruby/blob/trunk/ext/coverage/coverage.c#L35
     VALUE path = (VALUE)key;
     VALUE coverage = (VALUE)val;
     VALUE coverages = (VALUE)h;
-    coverage = rb_ary_dup(coverage);
-    rb_ary_freeze(coverage);
-    rb_hash_aset(coverages, path, coverage);
+    VALUE lines = RARRAY_AREF(coverage, COVERAGE_INDEX_LINES);
+    if (lines) {
+	lines = rb_ary_dup(lines);
+	rb_ary_freeze(lines);
+    }
+    rb_hash_aset(coverages, path, lines);
     return ST_CONTINUE;
 }
 
Index: iseq.h
===================================================================
--- iseq.h	(revision 59737)
+++ iseq.h	(revision 59738)
@@ -47,6 +47,9 @@ iseq_mark_ary_create(int flip_cnt) https://github.com/ruby/ruby/blob/trunk/iseq.h#L47
 
 #define ISEQ_COVERAGE(iseq)           RARRAY_AREF(ISEQ_MARK_ARY(iseq), ISEQ_MARK_ARY_COVERAGE)
 #define ISEQ_COVERAGE_SET(iseq, cov)  RARRAY_ASET(ISEQ_MARK_ARY(iseq), ISEQ_MARK_ARY_COVERAGE, cov)
+#define ISEQ_LINE_COVERAGE(iseq)      RARRAY_AREF(ISEQ_COVERAGE(iseq), COVERAGE_INDEX_LINES)
+#define ISEQ_BRANCH_COVERAGE(iseq)    RARRAY_AREF(ISEQ_COVERAGE(iseq), COVERAGE_INDEX_BRANCHES)
+#define ISEQ_METHOD_COVERAGE(iseq)    RARRAY_AREF(ISEQ_COVERAGE(iseq), COVERAGE_INDEX_METHODS)
 
 #define ISEQ_FLIP_CNT(iseq) FIX2INT(RARRAY_AREF(ISEQ_MARK_ARY(iseq), ISEQ_MARK_ARY_FLIP_CNT))
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]