Files
Yusuke EndohandClaude Fable 5 c9e9101403 Cache a template of the method coverage result [Bug #22250]
Likewise for method coverage: walking me_set and cme2counter and hashing
the array keys on every peek dominated the cost.  Maintain
{ path => { key => me or [me, ...] } } incrementally (both hashes are
append-only) and fill in the counts from cme2counter on each peek.
Extract rb_coverage_method_data_of() from thread.c for that.

10k methods: 24 ms -> 0.7 ms per peek.  rack's test suite with SimpleCov
per-test tracking (lines+branches+methods): 30 s -> 8.4 s.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 16:50:27 +09:00

52 lines
1.6 KiB
C

#ifndef INTERNAL_COVERAGE_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_COVERAGE_H
/**
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @brief Internal header for Coverage.
*/
#include "ruby/ruby.h"
#define COVERAGE_INDEX_LINES 0
#define COVERAGE_INDEX_BRANCHES 1
#define COVERAGE_TARGET_LINES 1
#define COVERAGE_TARGET_BRANCHES 2
#define COVERAGE_TARGET_METHODS 4
#define COVERAGE_TARGET_ONESHOT_LINES 8
#define COVERAGE_TARGET_EVAL 16
struct rb_coverage_method_data {
VALUE owner;
VALUE method_id;
VALUE path;
VALUE first_lineno;
VALUE first_column;
VALUE last_lineno;
VALUE last_column;
VALUE count;
};
typedef void rb_coverage_method_callback(const struct rb_coverage_method_data *, void *);
RUBY_SYMBOL_EXPORT_BEGIN
VALUE rb_get_coverages(void);
void rb_set_coverages(VALUE coverages, int mode, VALUE cme2counter, VALUE me_set);
void rb_clear_coverages(void);
void rb_reset_coverages(void);
void rb_resume_coverages(void);
void rb_suspend_coverages(void);
void rb_coverage_each_method(rb_coverage_method_callback callback, void *data);
bool rb_coverage_method_data_of(VALUE me, VALUE count, struct rb_coverage_method_data *out);
RUBY_SYMBOL_EXPORT_END
int rb_get_coverage_mode(void);
VALUE rb_default_coverage(int n);
#endif /* INTERNAL_COVERAGE_H */