11use std:: { ffi:: CStr , os:: raw:: c_char} ;
22
3- // This option is exposed to the C side in a global variable for performance, see vm.c
4- // Number of method calls after which to start generating code
5- // Threshold==1 means compile on first execution
3+ /// Number of calls to start profiling YARV instructions.
4+ /// They are profiled `rb_zjit_call_threshold - rb_zjit_profile_threshold` times,
5+ /// which is equal to --zjit-num-profiles.
6+ #[ unsafe( no_mangle) ]
7+ #[ allow( non_upper_case_globals) ]
8+ pub static mut rb_zjit_profile_threshold: u64 = 1 ;
9+
10+ /// Number of calls to compile ISEQ with ZJIT at jit_compile() in vm.c.
11+ /// --zjit-call-threshold=1 compiles on first execution without profiling information.
612#[ unsafe( no_mangle) ]
713#[ allow( non_upper_case_globals) ]
814pub static mut rb_zjit_call_threshold: u64 = 2 ;
915
1016#[ derive( Clone , Copy , Debug ) ]
1117pub struct Options {
18+ /// Number of times YARV instructions should be profiled.
19+ pub num_profiles : u64 ,
20+
1221 /// Enable debug logging
1322 pub debug : bool ,
1423
@@ -57,6 +66,7 @@ pub extern "C" fn rb_zjit_init_options() -> *const u8 {
5766/// Return an Options with default values
5867pub fn init_options ( ) -> Options {
5968 Options {
69+ num_profiles : 1 ,
6070 debug : false ,
6171 dump_hir_init : None ,
6272 dump_hir_opt : None ,
@@ -91,7 +101,18 @@ fn parse_option(options: &mut Options, str_ptr: *const std::os::raw::c_char) ->
91101 ( "" , "" ) => { } , // Simply --zjit
92102
93103 ( "call-threshold" , _) => match opt_val. parse ( ) {
94- Ok ( n) => unsafe { rb_zjit_call_threshold = n } ,
104+ Ok ( n) => {
105+ unsafe { rb_zjit_call_threshold = n; }
106+ update_profile_threshold ( options) ;
107+ } ,
108+ Err ( _) => return None ,
109+ } ,
110+
111+ ( "num-profiles" , _) => match opt_val. parse ( ) {
112+ Ok ( n) => {
113+ options. num_profiles = n;
114+ update_profile_threshold ( options) ;
115+ } ,
95116 Err ( _) => return None ,
96117 } ,
97118
@@ -115,6 +136,19 @@ fn parse_option(options: &mut Options, str_ptr: *const std::os::raw::c_char) ->
115136 Some ( ( ) )
116137}
117138
139+ /// Update rb_zjit_profile_threshold based on rb_zjit_call_threshold and options.num_profiles
140+ fn update_profile_threshold ( options : & Options ) {
141+ unsafe {
142+ if rb_zjit_call_threshold == 1 {
143+ // If --zjit-call-threshold=1, never rewrite ISEQs to profile instructions.
144+ rb_zjit_profile_threshold = 0 ;
145+ } else {
146+ // Otherwise, profile instructions at least once.
147+ rb_zjit_profile_threshold = rb_zjit_call_threshold. saturating_sub ( options. num_profiles ) . max ( 1 ) ;
148+ }
149+ }
150+ }
151+
118152/// Macro to print a message only when --zjit-debug is given
119153macro_rules! debug {
120154 ( $( $msg: tt) * ) => {
0 commit comments