diff --git a/src/cli/exec/mod.rs b/src/cli/exec/mod.rs index 253078d9..2302f483 100644 --- a/src/cli/exec/mod.rs +++ b/src/cli/exec/mod.rs @@ -60,6 +60,8 @@ fn build_orchestrator_config( let modes = args.shared.resolve_modes()?; let cycle_estimation = args.shared.resolve_cycle_estimation(); let exclude_allocations = args.shared.resolve_exclude_allocations(); + let memory_track_physical = args.shared.resolve_memory_track_physical(); + let memory_capture_stack = args.shared.resolve_memory_capture_stack(); let raw_upload_url = args .shared .upload_url @@ -95,12 +97,12 @@ fn build_orchestrator_config( cycle_estimation, exclude_allocations, simulation_track_subprocess: args.shared.simulation_track_subprocess, - memory_track_physical: args.shared.experimental.experimental_memory_track_physical, + memory_track_physical, disable_pythonmalloc_override: args .shared .experimental .experimental_disable_pythonmalloc_override, - memory_capture_stack: args.shared.experimental.experimental_memory_capture_stack, + memory_capture_stack, }) } diff --git a/src/cli/experimental.rs b/src/cli/experimental.rs index b4e90ebb..ec315568 100644 --- a/src/cli/experimental.rs +++ b/src/cli/experimental.rs @@ -17,24 +17,6 @@ pub struct ExperimentalArgs { )] pub experimental_fair_sched: bool, - /// Enable physical (resident) memory tracking in memory mode. - #[arg( - long, - default_value_t = false, - help_heading = "Experimental", - env = "CODSPEED_MEMTRACK_TRACK_PHYSICAL", - value_parser = clap::builder::FalseyValueParser::new() - )] - pub experimental_memory_track_physical: bool, - /// Capture allocation call stacks in memory mode. - #[arg( - long, - default_value_t = false, - help_heading = "Experimental", - env = "CODSPEED_EXPERIMENTAL_MEMORY_CAPTURE_STACK" - )] - pub experimental_memory_capture_stack: bool, - /// Do not set PYTHONMALLOC for simulation runs. #[arg( long, @@ -51,6 +33,30 @@ pub struct ExperimentalArgs { /// Deprecated alias for `--exclude-allocations`, still honored for now. #[arg(long, hide = true, env = "CODSPEED_EXPERIMENTAL_EXCLUDE_ALLOCATIONS")] pub experimental_exclude_allocations: bool, + + /// Deprecated: physical memory tracking is enabled by default. + /// Passing a falsey value (`0`, `false`) disables it. + #[arg( + long, + hide = true, + env = "CODSPEED_MEMTRACK_TRACK_PHYSICAL", + num_args = 0..=1, + require_equals = true, + default_missing_value = "true", + value_parser = clap::builder::FalseyValueParser::new() + )] + pub experimental_memory_track_physical: Option, + + /// Deprecated: allocation call stack capture is enabled by default. + #[arg( + long, + hide = true, + env = "CODSPEED_EXPERIMENTAL_MEMORY_CAPTURE_STACK", + num_args = 0..=1, + require_equals = true, + default_missing_value = "true" + )] + pub experimental_memory_capture_stack: Option, } impl ExperimentalArgs { @@ -60,15 +66,9 @@ impl ExperimentalArgs { if self.experimental_fair_sched { flags.push("--experimental-fair-sched"); } - if self.experimental_memory_track_physical { - flags.push("--experimental-memory-track-physical"); - } if self.experimental_disable_pythonmalloc_override { flags.push("--experimental-disable-pythonmalloc-override"); } - if self.experimental_memory_capture_stack { - flags.push("--experimental-memory-capture-stack"); - } flags } @@ -96,25 +96,33 @@ impl ExperimentalArgs { } /// Warns about deprecated flags that graduated to stable options. They are still - /// honored, but will be removed in a future release. + /// accepted, but will be removed in a future release. pub fn warn_if_deprecated(&self) { let deprecated = [ ( self.experimental_cycle_estimation, "--experimental-cycle-estimation", - "--cycle-estimation", + "use --cycle-estimation instead", ), ( self.experimental_exclude_allocations, "--experimental-exclude-allocations", - "--exclude-allocations", + "use --exclude-allocations instead", + ), + ( + self.experimental_memory_track_physical.is_some(), + "--experimental-memory-track-physical", + "physical memory tracking is now controlled by --disable-memory-track-physical", + ), + ( + self.experimental_memory_capture_stack.is_some(), + "--experimental-memory-capture-stack", + "stack capture is now controlled by --disable-memory-capture-stack", ), ]; - for (_, flag, new_flag) in deprecated.iter().filter(|(set, ..)| *set) { - eprintln!( - "{flag} is deprecated and will be removed in a future release: use {new_flag} instead." - ); + for (_, flag, hint) in deprecated.iter().filter(|(set, ..)| *set) { + eprintln!("{flag} is deprecated and will be removed in a future release: {hint}."); } } } diff --git a/src/cli/run/mod.rs b/src/cli/run/mod.rs index 28349907..e6750c1e 100644 --- a/src/cli/run/mod.rs +++ b/src/cli/run/mod.rs @@ -72,6 +72,8 @@ impl RunArgs { cycle_estimation: true, exclude_allocations: false, simulation_track_subprocess: false, + disable_memory_track_physical: false, + disable_memory_capture_stack: false, profiler_run_args: ProfilerRunArgs { enable_profiler: false, enable_perf: None, @@ -81,10 +83,10 @@ impl RunArgs { }, experimental: ExperimentalArgs { experimental_fair_sched: false, - experimental_memory_capture_stack: false, + experimental_memory_capture_stack: None, experimental_cycle_estimation: false, experimental_exclude_allocations: false, - experimental_memory_track_physical: false, + experimental_memory_track_physical: None, experimental_disable_pythonmalloc_override: false, }, }, @@ -105,6 +107,8 @@ fn build_orchestrator_config( let modes = args.shared.resolve_modes()?; let cycle_estimation = args.shared.resolve_cycle_estimation(); let exclude_allocations = args.shared.resolve_exclude_allocations(); + let memory_track_physical = args.shared.resolve_memory_track_physical(); + let memory_capture_stack = args.shared.resolve_memory_capture_stack(); let raw_upload_url = args .shared .upload_url @@ -140,12 +144,12 @@ fn build_orchestrator_config( cycle_estimation, exclude_allocations, simulation_track_subprocess: args.shared.simulation_track_subprocess, - memory_track_physical: args.shared.experimental.experimental_memory_track_physical, + memory_track_physical, disable_pythonmalloc_override: args .shared .experimental .experimental_disable_pythonmalloc_override, - memory_capture_stack: args.shared.experimental.experimental_memory_capture_stack, + memory_capture_stack, }) } diff --git a/src/cli/shared.rs b/src/cli/shared.rs index 7aba09db..6ea9acd1 100644 --- a/src/cli/shared.rs +++ b/src/cli/shared.rs @@ -139,6 +139,14 @@ pub struct ExecAndRunSharedArgs { #[arg(long, env = "CODSPEED_SIMULATION_TRACK_SUBPROCESS")] pub simulation_track_subprocess: bool, + /// Disable physical (resident) memory tracking in memory mode. + #[arg(long, env = "CODSPEED_DISABLE_MEMORY_TRACK_PHYSICAL")] + pub disable_memory_track_physical: bool, + + /// Disable allocation call stack capture in memory mode. + #[arg(long, env = "CODSPEED_DISABLE_MEMORY_CAPTURE_STACK")] + pub disable_memory_capture_stack: bool, + #[command(flatten)] pub profiler_run_args: ProfilerRunArgs, @@ -180,6 +188,21 @@ impl ExecAndRunSharedArgs { pub fn resolve_exclude_allocations(&self) -> bool { self.exclude_allocations || self.experimental.experimental_exclude_allocations } + + /// Resolves physical memory tracking. Any explicit opt-out wins: the + /// `--disable-memory-track-physical` flag overrides the deprecated enable alias, + /// and the deprecated flag's falsey value (`0`, `false`) overrides the default. + pub fn resolve_memory_track_physical(&self) -> bool { + !self.disable_memory_track_physical + && self.experimental.experimental_memory_track_physical != Some(false) + } + + /// Resolves allocation call stack capture, with the same precedence rules as + /// [`Self::resolve_memory_track_physical`]. + pub fn resolve_memory_capture_stack(&self) -> bool { + !self.disable_memory_capture_stack + && self.experimental.experimental_memory_capture_stack != Some(false) + } } #[derive(Debug, Copy, Clone, PartialEq, ValueEnum, Default)] diff --git a/src/executor/config.rs b/src/executor/config.rs index 45a61f0b..f3ec640c 100644 --- a/src/executor/config.rs +++ b/src/executor/config.rs @@ -268,9 +268,9 @@ impl OrchestratorConfig { cycle_estimation: true, exclude_allocations: false, simulation_track_subprocess: false, - memory_track_physical: false, + memory_track_physical: true, disable_pythonmalloc_override: false, - memory_capture_stack: false, + memory_capture_stack: true, } } }