diff options
author | mame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-10-20 05:33:04 +0000 |
---|---|---|
committer | mame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-10-20 05:33:04 +0000 |
commit | 47ea999b4689fc591478a05da1670d2008a4a705 (patch) | |
tree | bdc3770f0bbf8975189e1422cc18c545150e5dab /iseq.c | |
parent | fadde099e637e875d382d9182651e4d7f23dcc76 (diff) | |
download | ruby-47ea999b4689fc591478a05da1670d2008a4a705.tar.gz |
ext/coverage/: add the oneshot mode
This patch introduces "oneshot_lines" mode for `Coverage.start`, which
checks "whether each line was executed at least once or not", instead of
"how many times each line was executed". A hook for each line is fired
at most once, and after it is fired, the hook flag was removed; it runs
with zero overhead.
See [Feature #15022] in detail.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65195 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'iseq.c')
-rw-r--r-- | iseq.c | 24 |
1 files changed, 23 insertions, 1 deletions
@@ -656,7 +656,8 @@ rb_iseq_new_top(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath VALUE coverages = rb_get_coverages(); if (RTEST(coverages)) { if (ast->line_count >= 0) { - VALUE coverage = rb_default_coverage(ast->line_count); + int len = (rb_get_coverage_mode() & COVERAGE_TARGET_ONESHOT_LINES) ? 0 : ast->line_count; + VALUE coverage = rb_default_coverage(len); rb_hash_aset(coverages, path, coverage); } } @@ -1655,6 +1656,19 @@ rb_iseq_event_flags(const rb_iseq_t *iseq, size_t pos) } } +void +rb_iseq_clear_event_flags(const rb_iseq_t *iseq, size_t pos, rb_event_flag_t reset) +{ + struct iseq_insn_info_entry *entry = (struct iseq_insn_info_entry *)get_insn_info(iseq, pos); + if (entry) { + entry->events &= ~reset; + if (!(entry->events & iseq->aux.trace_events)) { + void rb_iseq_trace_flag_cleared(const rb_iseq_t *iseq, int pos); + rb_iseq_trace_flag_cleared(iseq, pos); + } + } +} + static VALUE local_var_name(const rb_iseq_t *diseq, VALUE level, VALUE op) { @@ -2935,6 +2949,14 @@ encoded_iseq_trace_instrument(VALUE *iseq_encoded_insn, rb_event_flag_t turnon) } void +rb_iseq_trace_flag_cleared(const rb_iseq_t *iseq, int pos) +{ + const struct rb_iseq_constant_body *const body = iseq->body; + VALUE *iseq_encoded = (VALUE *)body->iseq_encoded; + encoded_iseq_trace_instrument(&iseq_encoded[pos], 0); +} + +void rb_iseq_trace_set(const rb_iseq_t *iseq, rb_event_flag_t turnon_events) { VM_ASSERT((turnon_events & ~ISEQ_TRACE_EVENTS) == 0); |