@@ -262,7 +262,7 @@ pub struct InspectorData {
262262 pub traces : Option < SparsedTraceArena > ,
263263 pub line_coverage : Option < HitMaps > ,
264264 pub edge_coverage : Option < Vec < u8 > > ,
265- pub cheatcodes : Option < Cheatcodes > ,
265+ pub cheatcodes : Option < Box < Cheatcodes > > ,
266266 pub chisel_state : Option < ( Vec < U256 > , Vec < u8 > , Option < InstructionResult > ) > ,
267267 pub reverter : Option < Address > ,
268268}
@@ -290,7 +290,7 @@ pub struct InnerContextData {
290290/// collection, etc.
291291#[ derive( Clone , Debug , Default ) ]
292292pub struct InspectorStack {
293- pub cheatcodes : Option < Cheatcodes > ,
293+ pub cheatcodes : Option < Box < Cheatcodes > > ,
294294 pub inner : InspectorStackInner ,
295295}
296296
@@ -300,15 +300,17 @@ pub struct InspectorStack {
300300#[ derive( Default , Clone , Debug ) ]
301301pub struct InspectorStackInner {
302302 // Inspectors.
303- pub chisel_state : Option < ChiselState > ,
304- pub edge_coverage : Option < EdgeCovInspector > ,
305- pub fuzzer : Option < Fuzzer > ,
306- pub line_coverage : Option < LineCoverageCollector > ,
307- pub log_collector : Option < LogCollector > ,
308- pub printer : Option < CustomPrintTracer > ,
309- pub revert_diag : Option < RevertDiagnostic > ,
310- pub script_execution_inspector : Option < ScriptExecutionInspector > ,
311- pub tracer : Option < TracingInspector > ,
303+ // These are boxed to reduce the size of the struct and slightly improve performance of the
304+ // `if let Some` checks.
305+ pub chisel_state : Option < Box < ChiselState > > ,
306+ pub edge_coverage : Option < Box < EdgeCovInspector > > ,
307+ pub fuzzer : Option < Box < Fuzzer > > ,
308+ pub line_coverage : Option < Box < LineCoverageCollector > > ,
309+ pub log_collector : Option < Box < LogCollector > > ,
310+ pub printer : Option < Box < CustomPrintTracer > > ,
311+ pub revert_diag : Option < Box < RevertDiagnostic > > ,
312+ pub script_execution_inspector : Option < Box < ScriptExecutionInspector > > ,
313+ pub tracer : Option < Box < TracingInspector > > ,
312314
313315 // InspectorExt and other internal data.
314316 pub enable_isolation : bool ,
@@ -335,7 +337,7 @@ impl CheatcodesExecutor for InspectorStackInner {
335337 Box :: new ( InspectorStackRefMut { cheatcodes : Some ( cheats) , inner : self } )
336338 }
337339
338- fn tracing_inspector ( & mut self ) -> Option < & mut Option < TracingInspector > > {
340+ fn tracing_inspector ( & mut self ) -> Option < & mut Option < Box < TracingInspector > > > {
339341 Some ( & mut self . tracer )
340342 }
341343}
@@ -398,19 +400,19 @@ impl InspectorStack {
398400 /// Set the cheatcodes inspector.
399401 #[ inline]
400402 pub fn set_cheatcodes ( & mut self , cheatcodes : Cheatcodes ) {
401- self . cheatcodes = Some ( cheatcodes) ;
403+ self . cheatcodes = Some ( cheatcodes. into ( ) ) ;
402404 }
403405
404406 /// Set the fuzzer inspector.
405407 #[ inline]
406408 pub fn set_fuzzer ( & mut self , fuzzer : Fuzzer ) {
407- self . fuzzer = Some ( fuzzer) ;
409+ self . fuzzer = Some ( fuzzer. into ( ) ) ;
408410 }
409411
410412 /// Set the Chisel inspector.
411413 #[ inline]
412414 pub fn set_chisel ( & mut self , final_pc : usize ) {
413- self . chisel_state = Some ( ChiselState :: new ( final_pc) ) ;
415+ self . chisel_state = Some ( ChiselState :: new ( final_pc) . into ( ) ) ;
414416 }
415417
416418 /// Set whether to enable the line coverage collector.
@@ -422,7 +424,8 @@ impl InspectorStack {
422424 /// Set whether to enable the edge coverage collector.
423425 #[ inline]
424426 pub fn collect_edge_coverage ( & mut self , yes : bool ) {
425- self . edge_coverage = yes. then ( EdgeCovInspector :: new) ; // TODO configurable edge size?
427+ // TODO: configurable edge size?
428+ self . edge_coverage = yes. then ( EdgeCovInspector :: new) . map ( Into :: into) ;
426429 }
427430
428431 /// Set whether to enable call isolation.
@@ -459,11 +462,7 @@ impl InspectorStack {
459462 /// Revert diagnostic inspector is activated when `mode != TraceMode::None`
460463 #[ inline]
461464 pub fn tracing ( & mut self , mode : TraceMode ) {
462- if mode. is_none ( ) {
463- self . revert_diag = None ;
464- } else {
465- self . revert_diag = Some ( RevertDiagnostic :: default ( ) ) ;
466- }
465+ self . revert_diag = ( !mode. is_none ( ) ) . then ( RevertDiagnostic :: default) . map ( Into :: into) ;
467466
468467 if let Some ( config) = mode. into_config ( ) {
469468 * self . tracer . get_or_insert_with ( Default :: default) . config_mut ( ) = config;
@@ -480,7 +479,6 @@ impl InspectorStack {
480479 }
481480
482481 /// Collects all the data gathered during inspection into a single struct.
483- #[ inline]
484482 pub fn collect ( self ) -> InspectorData {
485483 let Self {
486484 mut cheatcodes,
@@ -531,7 +529,7 @@ impl InspectorStack {
531529
532530 #[ inline( always) ]
533531 fn as_mut ( & mut self ) -> InspectorStackRefMut < ' _ > {
534- InspectorStackRefMut { cheatcodes : self . cheatcodes . as_mut ( ) , inner : & mut self . inner }
532+ InspectorStackRefMut { cheatcodes : self . cheatcodes . as_deref_mut ( ) , inner : & mut self . inner }
535533 }
536534}
537535
@@ -740,17 +738,16 @@ impl InspectorStackRefMut<'_> {
740738 /// it.
741739 fn with_stack < O > ( & mut self , f : impl FnOnce ( & mut InspectorStack ) -> O ) -> O {
742740 let mut stack = InspectorStack {
743- cheatcodes : self
744- . cheatcodes
745- . as_deref_mut ( )
746- . map ( |cheats| core:: mem:: replace ( cheats, Cheatcodes :: new ( cheats. config . clone ( ) ) ) ) ,
741+ cheatcodes : self . cheatcodes . as_deref_mut ( ) . map ( |cheats| {
742+ core:: mem:: replace ( cheats, Cheatcodes :: new ( cheats. config . clone ( ) ) ) . into ( )
743+ } ) ,
747744 inner : std:: mem:: take ( self . inner ) ,
748745 } ;
749746
750747 let out = f ( & mut stack) ;
751748
752749 if let Some ( cheats) = self . cheatcodes . as_deref_mut ( ) {
753- * cheats = stack. cheatcodes . take ( ) . unwrap ( ) ;
750+ * cheats = * stack. cheatcodes . take ( ) . unwrap ( ) ;
754751 }
755752
756753 * self . inner = stack. inner ;
@@ -791,6 +788,11 @@ impl InspectorStackRefMut<'_> {
791788 }
792789 }
793790
791+ // We take extra care in optimizing `step` and `step_end`, as they're are likely the most
792+ // hot functions in all of Foundry.
793+ // We want to `#[inline(always)]` these functions so that `InspectorStack` does not
794+ // delegate to `InspectorStackRefMut` in this case.
795+
794796 #[ inline( always) ]
795797 fn step_inlined (
796798 & mut self ,
@@ -799,17 +801,18 @@ impl InspectorStackRefMut<'_> {
799801 ) {
800802 call_inspectors ! (
801803 [
804+ // These are sorted in definition order.
805+ & mut self . edge_coverage,
802806 & mut self . fuzzer,
803- & mut self . tracer,
804807 & mut self . line_coverage,
805- & mut self . edge_coverage,
806- & mut self . script_execution_inspector,
807808 & mut self . printer,
808809 & mut self . revert_diag,
810+ & mut self . script_execution_inspector,
811+ & mut self . tracer,
809812 // Keep `cheatcodes` last to make use of the tail call.
810813 & mut self . cheatcodes,
811814 ] ,
812- |inspector| ( * inspector) . step( interpreter, ecx) ,
815+ |inspector| ( * * inspector) . step( interpreter, ecx) ,
813816 ) ;
814817 }
815818
@@ -821,14 +824,15 @@ impl InspectorStackRefMut<'_> {
821824 ) {
822825 call_inspectors ! (
823826 [
824- & mut self . tracer ,
827+ // These are sorted in definition order.
825828 & mut self . chisel_state,
826829 & mut self . printer,
827830 & mut self . revert_diag,
831+ & mut self . tracer,
828832 // Keep `cheatcodes` last to make use of the tail call.
829833 & mut self . cheatcodes,
830834 ] ,
831- |inspector| ( * inspector) . step_end( interpreter, ecx) ,
835+ |inspector| ( * * inspector) . step_end( interpreter, ecx) ,
832836 ) ;
833837 }
834838}
0 commit comments