Skip to content

Commit a197e2f

Browse files
committed
ZJIT: Add RubyVM::ZJIT.reset_stats! method
This allows for more precise tracking of stats programmatically which is particularly useful for our nightly benchmarking suite. - Define rust function - Expose to C - Wrap with Ruby API - Add a test
1 parent 5ee083c commit a197e2f

4 files changed

Lines changed: 45 additions & 0 deletions

File tree

test/ruby/test_zjit.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,6 +1847,28 @@ def test = 1
18471847
}, stats: true
18481848
end
18491849

1850+
def test_reset_stats
1851+
assert_runs 'true', %q{
1852+
def test = 1
1853+
100.times { test }
1854+
1855+
# Get initial stats and verify they're non-zero
1856+
initial_stats = RubyVM::ZJIT.stats
1857+
initial_count = initial_stats[:zjit_insn_count]
1858+
1859+
# Reset the stats
1860+
RubyVM::ZJIT.reset_stats!
1861+
1862+
# Get stats after reset
1863+
reset_stats = RubyVM::ZJIT.stats
1864+
reset_count = reset_stats[:zjit_insn_count]
1865+
1866+
# After reset, counters should be zero or at least much smaller
1867+
# (some instructions might execute between reset and reading stats)
1868+
initial_count > 0 && reset_count < initial_count / 10
1869+
}, stats: true
1870+
end
1871+
18501872
def test_zjit_option_uses_array_each_in_ruby
18511873
omit 'ZJIT wrongly compiles Array#each, so it is disabled for now'
18521874
assert_runs '"<internal:array>"', %q{

zjit.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ rb_zjit_insn_leaf(int insn, const VALUE *opes)
342342
// Primitives used by zjit.rb. Don't put other functions below, which wouldn't use them.
343343
VALUE rb_zjit_assert_compiles(rb_execution_context_t *ec, VALUE self);
344344
VALUE rb_zjit_stats(rb_execution_context_t *ec, VALUE self, VALUE target_key);
345+
VALUE rb_zjit_reset_stats_bang(rb_execution_context_t *ec, VALUE self);
345346
VALUE rb_zjit_stats_enabled_p(rb_execution_context_t *ec, VALUE self);
346347
VALUE rb_zjit_print_stats_p(rb_execution_context_t *ec, VALUE self);
347348

zjit.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ def stats(target_key = nil)
2929
Primitive.rb_zjit_stats(target_key)
3030
end
3131

32+
# Discard statistics collected for `--zjit-stats`.
33+
def reset_stats!
34+
Primitive.rb_zjit_reset_stats_bang
35+
end
36+
3237
# Get the summary of ZJIT statistics as a String
3338
def stats_string
3439
buf = +"***ZJIT: Printing ZJIT statistics on exit***\n"

zjit/src/stats.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,23 @@ pub fn exit_counter_ptr(reason: crate::hir::SideExitReason) -> *mut u64 {
237237
counter_ptr(counter)
238238
}
239239

240+
/// Primitive called in zjit.rb. Zero out all the counters.
241+
#[unsafe(no_mangle)]
242+
pub extern "C" fn rb_zjit_reset_stats_bang(_ec: EcPtr, _self: VALUE) -> VALUE {
243+
let counters = ZJITState::get_counters();
244+
let exit_counters = ZJITState::get_exit_counters();
245+
246+
// Reset all counters to zero
247+
*counters = Counters::default();
248+
249+
// Reset exit counters for YARV instructions
250+
for i in 0..(VM_INSTRUCTION_SIZE as usize) {
251+
exit_counters[i] = 0;
252+
}
253+
254+
Qnil
255+
}
256+
240257
/// Return a Hash object that contains ZJIT statistics
241258
#[unsafe(no_mangle)]
242259
pub extern "C" fn rb_zjit_stats(_ec: EcPtr, _self: VALUE, target_key: VALUE) -> VALUE {

0 commit comments

Comments
 (0)