@@ -15,7 +15,7 @@ use cairo_native::{
1515 starknet_stub:: StubSyscallHandler ,
1616} ;
1717use clap:: { Parser , ValueEnum } ;
18- #[ cfg( feature = "with-libfunc-profiling" ) ]
18+ #[ cfg( any ( feature = "with-libfunc-profiling" , feature = "with-libfunc-counter" ) ) ]
1919use std:: collections:: HashMap ;
2020use std:: path:: PathBuf ;
2121use tracing_subscriber:: { EnvFilter , FmtSubscriber } ;
@@ -57,6 +57,11 @@ struct Args {
5757 /// The output path for the libfunc profilling results
5858 profiler_output : Option < PathBuf > ,
5959
60+ #[ cfg( feature = "with-libfunc-counter" ) ]
61+ #[ arg( long) ]
62+ /// The output path for the execution trace
63+ libfunc_counter_output : Option < PathBuf > ,
64+
6065 #[ cfg( feature = "with-trace-dump" ) ]
6166 #[ arg( long) ]
6267 /// The output path for the execution trace
@@ -120,6 +125,17 @@ fn main() -> anyhow::Result<()> {
120125 }
121126 }
122127
128+ #[ cfg( feature = "with-libfunc-counter" ) ]
129+ {
130+ use cairo_native:: metadata:: libfunc_counter:: LibfuncCounterBinding ;
131+ if let Some ( counter_id) =
132+ executor. find_symbol_ptr ( LibfuncCounterBinding :: CounterId . symbol ( ) )
133+ {
134+ let counter_id = counter_id. cast :: < u64 > ( ) ;
135+ unsafe { * counter_id = 0 } ;
136+ }
137+ }
138+
123139 Box :: new ( move |function_id, args, gas, syscall_handler| {
124140 executor. invoke_dynamic_with_syscall_handler (
125141 function_id,
@@ -154,6 +170,17 @@ fn main() -> anyhow::Result<()> {
154170 }
155171 }
156172
173+ #[ cfg( feature = "with-libfunc-counter" ) ]
174+ {
175+ use cairo_native:: metadata:: libfunc_counter:: LibfuncCounterBinding ;
176+ if let Some ( counter_id) =
177+ executor. find_symbol_ptr ( LibfuncCounterBinding :: CounterId . symbol ( ) )
178+ {
179+ let counter_id = counter_id. cast :: < u64 > ( ) ;
180+ unsafe { * counter_id = 0 } ;
181+ }
182+ }
183+
157184 Box :: new ( move |function_id, args, gas, syscall_handler| {
158185 executor. invoke_dynamic_with_syscall_handler (
159186 function_id,
@@ -186,6 +213,18 @@ fn main() -> anyhow::Result<()> {
186213 . insert ( 0 , ProfilerImpl :: new ( ) ) ;
187214 }
188215
216+ #[ cfg( feature = "with-libfunc-counter" ) ]
217+ {
218+ use cairo_native:: metadata:: libfunc_counter:: libfunc_counter_runtime:: {
219+ CounterImpl , LIBFUNC_COUNTER ,
220+ } ;
221+
222+ LIBFUNC_COUNTER . lock ( ) . unwrap ( ) . insert (
223+ 0 ,
224+ CounterImpl :: new ( sierra_program. libfunc_declarations . len ( ) ) ,
225+ ) ;
226+ }
227+
189228 let gas_metadata =
190229 GasMetadata :: new ( & sierra_program, Some ( MetadataComputationConfig :: default ( ) ) ) . unwrap ( ) ;
191230
@@ -281,6 +320,37 @@ fn main() -> anyhow::Result<()> {
281320 }
282321 }
283322
323+ #[ cfg( feature = "with-libfunc-counter" ) ]
324+ if let Some ( libfunc_counter_output) = args. libfunc_counter_output {
325+ use std:: collections:: HashMap ;
326+
327+ let counters =
328+ cairo_native:: metadata:: libfunc_counter:: libfunc_counter_runtime:: LIBFUNC_COUNTER
329+ . lock ( )
330+ . unwrap ( ) ;
331+ assert_eq ! ( counters. len( ) , 1 ) ;
332+
333+ let libfunc_counter = counters. values ( ) . next ( ) . unwrap ( ) ;
334+
335+ let libfunc_counts = libfunc_counter
336+ . array_counter
337+ . iter ( )
338+ . enumerate ( )
339+ . map ( |( i, count) | {
340+ let libfunc = & sierra_program. libfunc_declarations [ i] ;
341+ let debug_name = libfunc. id . debug_name . clone ( ) . unwrap ( ) . to_string ( ) ;
342+
343+ ( debug_name, * count)
344+ } )
345+ . collect :: < HashMap < String , u32 > > ( ) ;
346+ dbg ! ( & libfunc_counts) ;
347+ serde_json:: to_writer_pretty (
348+ std:: fs:: File :: create ( libfunc_counter_output) . unwrap ( ) ,
349+ & libfunc_counts,
350+ )
351+ . unwrap ( ) ;
352+ }
353+
284354 #[ cfg( feature = "with-trace-dump" ) ]
285355 if let Some ( trace_output) = args. trace_output {
286356 let traces = cairo_native:: metadata:: trace_dump:: trace_dump_runtime:: TRACE_DUMP
0 commit comments