summaryrefslogtreecommitdiff
path: root/iseq.c
diff options
context:
space:
mode:
authormame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-10-20 05:33:04 +0000
committermame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-10-20 05:33:04 +0000
commit47ea999b4689fc591478a05da1670d2008a4a705 (patch)
treebdc3770f0bbf8975189e1422cc18c545150e5dab /iseq.c
parentfadde099e637e875d382d9182651e4d7f23dcc76 (diff)
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.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/iseq.c b/iseq.c
index 343fc9e5b8..243afc2534 100644
--- a/iseq.c
+++ b/iseq.c
@@ -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);