@@ -2266,9 +2266,9 @@ impl Function {
22662266 self_type : Type ,
22672267 send : Insn ,
22682268 send_insn_id : InsnId ,
2269- ) -> Result < ( ) , Option < * const rb_callable_method_entry_struct > > {
2269+ ) -> Result < ( ) , ( ) > {
22702270 let Insn :: SendWithoutBlock { mut recv, cd, mut args, state, .. } = send else {
2271- return Err ( None ) ;
2271+ return Err ( ( ) ) ;
22722272 } ;
22732273
22742274 let call_info = unsafe { ( * cd) . ci } ;
@@ -2280,20 +2280,20 @@ impl Function {
22802280 ( class, None )
22812281 } else {
22822282 let iseq_insn_idx = fun. frame_state ( state) . insn_idx ;
2283- let Some ( recv_type) = fun. profiled_type_of_at ( recv, iseq_insn_idx) else { return Err ( None ) } ;
2283+ let Some ( recv_type) = fun. profiled_type_of_at ( recv, iseq_insn_idx) else { return Err ( ( ) ) } ;
22842284 ( recv_type. class ( ) , Some ( recv_type) )
22852285 } ;
22862286
22872287 // Do method lookup
22882288 let method: * const rb_callable_method_entry_struct = unsafe { rb_callable_method_entry ( recv_class, method_id) } ;
22892289 if method. is_null ( ) {
2290- return Err ( None ) ;
2290+ return Err ( ( ) ) ;
22912291 }
22922292
22932293 // Filter for C methods
22942294 let def_type = unsafe { get_cme_def_type ( method) } ;
22952295 if def_type != VM_METHOD_TYPE_CFUNC {
2296- return Err ( None ) ;
2296+ return Err ( ( ) ) ;
22972297 }
22982298
22992299 // Find the `argc` (arity) of the C method, which describes the parameters it expects
@@ -2305,13 +2305,13 @@ impl Function {
23052305 //
23062306 // Bail on argc mismatch
23072307 if argc != cfunc_argc as u32 {
2308- return Err ( Some ( method ) ) ;
2308+ return Err ( ( ) ) ;
23092309 }
23102310
23112311 let ci_flags = unsafe { vm_ci_flag ( call_info) } ;
23122312
23132313 if ci_flags & VM_CALL_ARGS_SIMPLE == 0 {
2314- return Err ( Some ( method ) ) ;
2314+ return Err ( ( ) ) ;
23152315 }
23162316
23172317 gen_patch_points_for_optimized_ccall ( fun, block, recv_class, method_id, method, state) ;
@@ -2334,6 +2334,9 @@ impl Function {
23342334 let ccall = fun. push_insn ( block, Insn :: CCall { cfun, args : cfunc_args, name : method_id, return_type, elidable } ) ;
23352335 fun. make_equal_to ( send_insn_id, ccall) ;
23362336 } else {
2337+ if get_option ! ( stats) {
2338+ count_full_frame_cfunc ( fun, block, method) ;
2339+ }
23372340 let ccall = fun. push_insn ( block, Insn :: CallCFunc { cfun, args : cfunc_args, cme : method, name : method_id, state } ) ;
23382341 fun. make_equal_to ( send_insn_id, ccall) ;
23392342 }
@@ -2343,7 +2346,7 @@ impl Function {
23432346 // Variadic method
23442347 -1 => {
23452348 if unsafe { rb_zjit_method_tracing_currently_enabled ( ) } {
2346- return Err ( None ) ;
2349+ return Err ( ( ) ) ;
23472350 }
23482351 // The method gets a pointer to the first argument
23492352 // func(int argc, VALUE *argv, VALUE recv)
@@ -2383,7 +2386,20 @@ impl Function {
23832386 _ => unreachable ! ( "unknown cfunc kind: argc={argc}" )
23842387 }
23852388
2386- Err ( Some ( method) )
2389+ Err ( ( ) )
2390+ }
2391+
2392+ fn count_full_frame_cfunc ( fun : & mut Function , block : BlockId , cme : * const rb_callable_method_entry_t ) {
2393+ let owner = unsafe { ( * cme) . owner } ;
2394+ let called_id = unsafe { ( * cme) . called_id } ;
2395+ let class_name = get_class_name ( owner) ;
2396+ let method_name = called_id. contents_lossy ( ) ;
2397+ let qualified_method_name = format ! ( "{}#{}" , class_name, method_name) ;
2398+ let full_frame_cfunc_counter_pointers = ZJITState :: get_full_frame_cfunc_counter_pointers ( ) ;
2399+ let counter_ptr = full_frame_cfunc_counter_pointers. entry ( qualified_method_name. clone ( ) ) . or_insert_with ( || Box :: new ( 0 ) ) ;
2400+ let counter_ptr = & mut * * counter_ptr as * mut u64 ;
2401+
2402+ fun. push_insn ( block, Insn :: IncrCounterPtr { counter_ptr } ) ;
23872403 }
23882404
23892405 for block in self . rpo ( ) {
@@ -2392,23 +2408,8 @@ impl Function {
23922408 for insn_id in old_insns {
23932409 if let send @ Insn :: SendWithoutBlock { recv, .. } = self . find ( insn_id) {
23942410 let recv_type = self . type_of ( recv) ;
2395- match reduce_to_ccall ( self , block, recv_type, send, insn_id) {
2396- Ok ( ( ) ) => continue ,
2397- Err ( Some ( cme) ) => {
2398- if get_option ! ( stats) {
2399- let owner = unsafe { ( * cme) . owner } ;
2400- let called_id = unsafe { ( * cme) . called_id } ;
2401- let class_name = get_class_name ( owner) ;
2402- let method_name = called_id. contents_lossy ( ) ;
2403- let qualified_method_name = format ! ( "{}#{}" , class_name, method_name) ;
2404- let unoptimized_cfunc_counter_pointers = ZJITState :: get_unoptimized_cfunc_counter_pointers ( ) ;
2405- let counter_ptr = unoptimized_cfunc_counter_pointers. entry ( qualified_method_name. clone ( ) ) . or_insert_with ( || Box :: new ( 0 ) ) ;
2406- let counter_ptr = & mut * * counter_ptr as * mut u64 ;
2407-
2408- self . push_insn ( block, Insn :: IncrCounterPtr { counter_ptr } ) ;
2409- }
2410- }
2411- _ => { }
2411+ if reduce_to_ccall ( self , block, recv_type, send, insn_id) . is_ok ( ) {
2412+ continue ;
24122413 }
24132414 }
24142415 self . push_insn_id ( block, insn_id) ;
0 commit comments