@@ -441,26 +441,61 @@ pub(crate) struct CompilationOptions {
441441 pub tracing : TracingOptions ,
442442 pub swarm : SwarmConfig , // is `scope` a better name?
443443 pub verbose : bool ,
444- pub debug_trace : bool ,
444+ pub debug_trace : DebugTrace ,
445445 pub kind : CompilationKind ,
446446 pub optimize_for_compilation_time : bool ,
447447}
448448
449+ #[ derive( Debug , Clone , Copy , Hash , PartialEq , Eq , Default , clap:: ValueEnum ) ]
450+ pub ( crate ) enum DebugTrace {
451+ #[ default]
452+ Disabled ,
453+ Function ,
454+ Instruction ,
455+ Line ,
456+ }
457+
458+ impl DebugTrace {
459+ fn from_str ( s : & str ) -> Option < Self > {
460+ match s {
461+ "thin" | "func" | "function" => Some ( Self :: Function ) ,
462+ "full" | "instr" | "instruction" | "1" => Some ( Self :: Instruction ) ,
463+ "line" => Some ( Self :: Line ) ,
464+ _ => None ,
465+ }
466+ }
467+ fn from_env ( ) -> Option < Self > {
468+ match std:: env:: var ( "JITTRACE" ) . ok ( ) . as_deref ( ) {
469+ Some ( s) => Self :: from_str ( s) ,
470+ _ => None ,
471+ }
472+ }
473+
474+ pub ( crate ) fn enabled ( self ) -> bool {
475+ !matches ! ( self , Self :: Disabled )
476+ }
477+
478+ pub ( crate ) fn include_instructions ( self ) -> bool {
479+ matches ! ( self , Self :: Instruction | Self :: Line )
480+ }
481+
482+ pub ( crate ) fn include_source_line ( self ) -> bool {
483+ matches ! ( self , Self :: Line )
484+ }
485+ }
486+
449487impl CompilationOptions {
450488 pub fn new (
451489 tracking : & TrackingOptions ,
452490 tracing : & TracingOptions ,
453491 swarm : & SwarmConfig ,
454492 kind : CompilationKind ,
455- debug_trace : bool ,
493+ debug_trace : DebugTrace ,
456494 verbose : bool ,
457495 optimize_for_compilation_time : bool ,
458496 ) -> Self {
459497 Self {
460- debug_trace : debug_trace
461- || std:: env:: var ( "JITTRACE" )
462- . map ( |el| el == "1" || el == "thin" || el == "line" )
463- . unwrap_or_default ( ) ,
498+ debug_trace : DebugTrace :: from_env ( ) . unwrap_or ( debug_trace) ,
464499 verbose : verbose
465500 || std:: env:: var ( "JITDEBUG" )
466501 . map ( |el| el == "1" )
@@ -708,8 +743,14 @@ impl JitStage {
708743 if let Some ( instance) = & mut self . instance
709744 && instance. vmctx . tainted
710745 {
711- // eprintln!("resetting vmctx because it's tainted");
712- self . inp_ptr = None ;
746+ if self . run_from_snapshot {
747+ // `snapshot()` after init sets `heap_snapshot_is_initial = false`, so `reset()`
748+ // cannot run. Any trap (including OutOfFuel) marks tainted; restore to the
749+ // post-init snapshot and keep `inp_ptr` — `run()` also restores before each exec.
750+ instance. vmctx . restore ( ) ;
751+ } else {
752+ self . inp_ptr = None ;
753+ }
713754 }
714755
715756 if self . inp_ptr . is_none ( ) {
@@ -774,9 +815,12 @@ impl JitStage {
774815 . expect ( "malloc shouldn't trap" ) ;
775816 self . inp_ptr = Some ( inp_ptr) ;
776817 instance. vmctx . fuel_init = opts. swarm . instruction_limit . unwrap_or ( u32:: MAX as u64 ) ;
777- instance. vmctx . heap_pages_limit_soft =
778- opts. swarm . memory_limit_pages . unwrap_or ( u32:: MAX ) ;
779- instance. vmctx . heap_pages_limit_hard = crate :: MEMORY_PAGES_LIMIT ;
818+ let mem_pages = opts. swarm . memory_limit_pages ;
819+ instance. vmctx . heap_pages_limit_soft = mem_pages. unwrap_or ( u32:: MAX ) ;
820+ // Honor `--memory-limit-pages` for the hard cap too (default remains MEMORY_PAGES_LIMIT).
821+ instance. vmctx . heap_pages_limit_hard = mem_pages
822+ . unwrap_or ( crate :: MEMORY_PAGES_LIMIT )
823+ . max ( crate :: MEMORY_PAGES_LIMIT ) ;
780824 if self . run_from_snapshot {
781825 instance. vmctx . snapshot ( ) ;
782826 }
@@ -833,7 +877,7 @@ impl JitStage {
833877pub ( crate ) struct JitFuzzingSessionBuilder {
834878 mod_spec : Arc < ModuleSpec > ,
835879 tracing : TracingOptions ,
836- debug_trace : bool ,
880+ debug_trace : DebugTrace ,
837881 verbose : bool ,
838882 swarm : SwarmConfig ,
839883 passes_generator : Arc < dyn PassesGen > ,
@@ -852,7 +896,7 @@ impl JitFuzzingSessionBuilder {
852896 } ;
853897 Self {
854898 tracing : TracingOptions :: default ( ) ,
855- debug_trace : false ,
899+ debug_trace : DebugTrace :: Disabled ,
856900 verbose : false ,
857901 swarm,
858902 passes_generator : Arc :: new ( FullFeedbackPasses {
@@ -882,8 +926,12 @@ impl JitFuzzingSessionBuilder {
882926 self
883927 }
884928
885- pub ( crate ) fn debug ( mut self , debug_trace : bool , verbose : bool ) -> Self {
929+ pub ( crate ) fn debug_trace ( mut self , debug_trace : DebugTrace ) -> Self {
886930 self . debug_trace = debug_trace;
931+ self
932+ }
933+
934+ pub ( crate ) fn verbose ( mut self , verbose : bool ) -> Self {
887935 self . verbose = verbose;
888936 self
889937 }
@@ -933,7 +981,7 @@ pub(crate) struct JitFuzzingSession {
933981 pub ( crate ) tracing_stage : JitStage ,
934982 reusable_exec_history : Vec < Vec < u8 > > ,
935983 run_from_snapshot : bool ,
936- debug_trace : bool ,
984+ debug_trace : DebugTrace ,
937985 verbose : bool ,
938986 optimize_for_compilation_time : bool ,
939987 pub ( crate ) swarm : SwarmConfig ,
0 commit comments