1- // Maxime would like to rebuild an improved stats system
2- // Individual stats should be tagged as always available, or only available in stats mode
3- // We could also tag which stats are fallback or exit counters, etc. Maybe even tag units?
4- //
5- // Comptime vs Runtime stats?
1+ use std:: time:: Instant ;
62
73use crate :: { cruby:: * , options:: get_option, state:: { zjit_enabled_p, ZJITState } } ;
84
95macro_rules! make_counters {
10- ( $( $counter_name: ident, ) +) => {
6+ (
7+ default {
8+ $( $default_counter_name: ident, ) +
9+ }
10+ $( $counter_name: ident, ) +
11+ ) => {
1112 /// Struct containing the counter values
1213 #[ derive( Default , Debug ) ]
13- pub struct Counters { $( pub $counter_name: u64 ) ,+ }
14+ pub struct Counters {
15+ $( pub $default_counter_name: u64 , ) +
16+ $( pub $counter_name: u64 , ) +
17+ }
1418
1519 /// Enum to represent a counter
1620 #[ allow( non_camel_case_types) ]
1721 #[ derive( Clone , Copy , PartialEq , Eq , Debug ) ]
18- pub enum Counter { $( $counter_name) ,+ }
22+ pub enum Counter {
23+ $( $default_counter_name, ) +
24+ $( $counter_name, ) +
25+ }
26+
27+ impl Counter {
28+ pub fn name( & self ) -> String {
29+ match self {
30+ $( Counter :: $default_counter_name => stringify!( $default_counter_name) . to_string( ) , ) +
31+ $( Counter :: $counter_name => stringify!( $counter_name) . to_string( ) , ) +
32+ }
33+ }
34+ }
1935
2036 /// Map a counter to a pointer
2137 pub fn counter_ptr( counter: Counter ) -> * mut u64 {
2238 let counters = $crate:: state:: ZJITState :: get_counters( ) ;
2339 match counter {
24- $( Counter :: $counter_name => std:: ptr:: addr_of_mut!( counters. $counter_name) ) ,+
40+ $( Counter :: $default_counter_name => std:: ptr:: addr_of_mut!( counters. $default_counter_name) , ) +
41+ $( Counter :: $counter_name => std:: ptr:: addr_of_mut!( counters. $counter_name) , ) +
2542 }
2643 }
44+
45+ /// The list of counters that are available without --zjit-stats.
46+ /// They are incremented only by `incr_counter()` and don't use `gen_incr_counter()`.
47+ pub const DEFAULT_COUNTERS : & ' static [ Counter ] = & [
48+ $( Counter :: $default_counter_name, ) +
49+ ] ;
2750 }
2851}
2952
3053// Declare all the counters we track
3154make_counters ! {
55+ // Default counters that are available without --zjit-stats
56+ default {
57+ compile_time_ns,
58+ profile_time_ns,
59+ gc_time_ns,
60+ invalidation_time_ns,
61+ }
62+
3263 // The number of times YARV instructions are executed on JIT code
3364 zjit_insns_count,
3465}
3566
67+ /// Increase a counter by a specified amount
68+ fn incr_counter ( counter : Counter , amount : u64 ) {
69+ let ptr = counter_ptr ( counter) ;
70+ unsafe { * ptr += amount; }
71+ }
72+
3673pub fn zjit_alloc_size ( ) -> usize {
3774 0 // TODO: report the actual memory usage
3875}
@@ -49,14 +86,30 @@ pub extern "C" fn rb_zjit_stats(_ec: EcPtr, _self: VALUE) -> VALUE {
4986 }
5087
5188 let hash = unsafe { rb_hash_new ( ) } ;
52- // TODO: Set counters that are always available here
89+ let counters = ZJITState :: get_counters ( ) ;
90+
91+ for & counter in DEFAULT_COUNTERS {
92+ let counter_val = unsafe { * counter_ptr ( counter) } ;
93+ set_stat ( hash, & counter. name ( ) , counter_val) ;
94+ }
5395
5496 // Set counters that are enabled when --zjit-stats is enabled
5597 if get_option ! ( stats) {
56- let counters = ZJITState :: get_counters ( ) ;
5798 set_stat ( hash, "zjit_insns_count" , counters. zjit_insns_count ) ;
58- set_stat ( hash, "vm_insns_count" , unsafe { rb_vm_insns_count } ) ;
99+
100+ if unsafe { rb_vm_insns_count } > 0 {
101+ set_stat ( hash, "vm_insns_count" , unsafe { rb_vm_insns_count } ) ;
102+ }
59103 }
60104
61105 hash
62106}
107+
108+ /// Measure the time taken by func() and add that to zjit_compile_time.
109+ pub fn with_time_stat < F , R > ( counter : Counter , func : F ) -> R where F : FnOnce ( ) -> R {
110+ let start = Instant :: now ( ) ;
111+ let ret = func ( ) ;
112+ let nanos = Instant :: now ( ) . duration_since ( start) . as_nanos ( ) ;
113+ incr_counter ( counter, nanos as u64 ) ;
114+ ret
115+ }
0 commit comments