Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
251 changes: 249 additions & 2 deletions cli/args/flags.rs

Large diffs are not rendered by default.

51 changes: 51 additions & 0 deletions cli/args/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,57 @@ impl CliOptions {
}
}

pub fn cpu_prof_dir(&self) -> Option<PathBuf> {
let (cpu_prof, cpu_prof_dir) = match &self.flags.subcommand {
DenoSubcommand::Run(flags) => {
(flags.cpu_prof, flags.cpu_prof_dir.as_deref())
}
DenoSubcommand::Eval(flags) => {
(flags.cpu_prof, flags.cpu_prof_dir.as_deref())
}
_ => return None,
};
if let Some(dir) = cpu_prof_dir {
Some(self.initial_cwd.join(dir))
} else if cpu_prof {
Some(self.initial_cwd.clone())
} else {
None
}
}

pub fn cpu_prof_name(&self) -> Option<String> {
match &self.flags.subcommand {
DenoSubcommand::Run(flags) => flags.cpu_prof_name.clone(),
DenoSubcommand::Eval(flags) => flags.cpu_prof_name.clone(),
_ => None,
}
}

pub fn cpu_prof_interval(&self) -> i32 {
match &self.flags.subcommand {
DenoSubcommand::Run(flags) => flags.cpu_prof_interval.unwrap_or(1000),
DenoSubcommand::Eval(flags) => flags.cpu_prof_interval.unwrap_or(1000),
_ => 1000,
}
}

pub fn cpu_prof_md(&self) -> bool {
match &self.flags.subcommand {
DenoSubcommand::Run(flags) => flags.cpu_prof_md,
DenoSubcommand::Eval(flags) => flags.cpu_prof_md,
_ => false,
}
}

pub fn cpu_prof_flamegraph(&self) -> bool {
match &self.flags.subcommand {
DenoSubcommand::Run(flags) => flags.cpu_prof_flamegraph,
DenoSubcommand::Eval(flags) => flags.cpu_prof_flamegraph,
_ => false,
}
}

pub fn enable_op_summary_metrics(&self) -> bool {
self.flags.enable_op_summary_metrics
|| matches!(
Expand Down
21 changes: 21 additions & 0 deletions cli/factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ use deno_resolver::import_map::WorkspaceExternalImportMapLoader;
use deno_resolver::loader::MemoryFiles;
use deno_resolver::npm::DenoInNpmPackageChecker;
use deno_resolver::workspace::WorkspaceResolver;
use deno_runtime::CpuProfilerConfig;
use deno_runtime::FeatureChecker;
use deno_runtime::deno_fs;
use deno_runtime::deno_fs::RealFs;
Expand Down Expand Up @@ -112,6 +113,7 @@ use crate::util::progress_bar::ProgressBar;
use crate::util::progress_bar::ProgressBarStyle;
use crate::worker::CliMainWorkerFactory;
use crate::worker::CliMainWorkerOptions;
use crate::worker::CpuProfConfig;

struct CliRootCertStoreProvider {
cell: OnceCell<RootCertStore>,
Expand Down Expand Up @@ -1122,6 +1124,15 @@ impl CliFactory {
let module_loader_factory = self.create_module_loader_factory().await?;
self.maybe_start_inspector_server()?;

let maybe_cpu_prof_config_for_workers =
cli_options.cpu_prof_dir().map(|dir| CpuProfilerConfig {
dir,
name: cli_options.cpu_prof_name(),
interval: cli_options.cpu_prof_interval(),
md: cli_options.cpu_prof_md(),
flamegraph: cli_options.cpu_prof_flamegraph(),
});

let lib_main_worker_factory = LibMainWorkerFactory::new(
self.blob_store().clone(),
if cli_options.code_cache_enabled() {
Expand All @@ -1133,6 +1144,7 @@ impl CliFactory {
self.feature_checker()?.clone(),
fs.clone(),
cli_options.coverage_dir(),
maybe_cpu_prof_config_for_workers,
Box::new(module_loader_factory),
node_resolver.clone(),
create_npm_process_state_provider(npm_resolver),
Expand Down Expand Up @@ -1222,6 +1234,14 @@ impl CliFactory {
None
};
let maybe_coverage_dir = cli_options.coverage_dir();
let maybe_cpu_prof_config =
cli_options.cpu_prof_dir().map(|dir| CpuProfConfig {
dir,
name: cli_options.cpu_prof_name(),
interval: cli_options.cpu_prof_interval(),
md: cli_options.cpu_prof_md(),
flamegraph: cli_options.cpu_prof_flamegraph(),
});

let initial_cwd =
deno_path_util::url_from_directory_path(cli_options.initial_cwd())?;
Expand All @@ -1230,6 +1250,7 @@ impl CliFactory {
needs_test_modules: cli_options.sub_command().needs_test(),
create_hmr_runner,
maybe_coverage_dir,
maybe_cpu_prof_config,
default_npm_caching_strategy: cli_options.default_npm_caching_strategy(),
initial_cwd: Arc::new(initial_cwd),
})
Expand Down
5 changes: 5 additions & 0 deletions cli/lib/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use deno_path_util::url_to_file_path;
use deno_resolver::npm::DenoInNpmPackageChecker;
use deno_resolver::npm::NpmResolver;
use deno_runtime::BootstrapOptions;
use deno_runtime::CpuProfilerConfig;
use deno_runtime::FeatureChecker;
use deno_runtime::UNSTABLE_FEATURES;
use deno_runtime::WorkerExecutionMode;
Expand Down Expand Up @@ -274,6 +275,7 @@ struct LibWorkerFactorySharedState<TSys: DenoLibSys> {
feature_checker: Arc<FeatureChecker>,
fs: Arc<dyn deno_fs::FileSystem>,
maybe_coverage_dir: Option<PathBuf>,
maybe_cpu_prof_config: Option<CpuProfilerConfig>,
main_inspector_session_tx: MainInspectorSessionChannel,
module_loader_factory: Box<dyn ModuleLoaderFactory>,
node_resolver:
Expand Down Expand Up @@ -468,6 +470,7 @@ impl<TSys: DenoLibSys> LibWorkerFactorySharedState<TSys> {
close_on_idle: args.close_on_idle,
maybe_worker_metadata: args.maybe_worker_metadata,
maybe_coverage_dir: shared.maybe_coverage_dir.clone(),
maybe_cpu_prof_config: shared.maybe_cpu_prof_config.clone(),
enable_raw_imports: shared.options.enable_raw_imports,
enable_stack_trace_arg_in_ops: has_trace_permissions_enabled(),
};
Expand Down Expand Up @@ -518,6 +521,7 @@ impl<TSys: DenoLibSys> LibMainWorkerFactory<TSys> {
feature_checker: Arc<FeatureChecker>,
fs: Arc<dyn deno_fs::FileSystem>,
maybe_coverage_dir: Option<PathBuf>,
maybe_cpu_prof_config: Option<CpuProfilerConfig>,
module_loader_factory: Box<dyn ModuleLoaderFactory>,
node_resolver: Arc<
NodeResolver<DenoInNpmPackageChecker, NpmResolver<TSys>, TSys>,
Expand All @@ -541,6 +545,7 @@ impl<TSys: DenoLibSys> LibMainWorkerFactory<TSys> {
feature_checker,
fs,
maybe_coverage_dir,
maybe_cpu_prof_config,
main_inspector_session_tx: MainInspectorSessionChannel::new(),
module_loader_factory,
node_resolver,
Expand Down
3 changes: 2 additions & 1 deletion cli/rt/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1070,7 +1070,8 @@ pub async fn run(
sys.maybe_native_addon_loader(),
feature_checker,
fs,
None,
None, // maybe_coverage_dir
None, // maybe_cpu_prof_config
Box::new(module_loader_factory),
node_resolver.clone(),
create_npm_process_state_provider(&npm_resolver),
Expand Down
42 changes: 42 additions & 0 deletions cli/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use deno_npm_installer::PackageCaching;
use deno_npm_installer::graph::NpmCachingStrategy;
use deno_runtime::WorkerExecutionMode;
use deno_runtime::coverage::CoverageCollector;
use deno_runtime::cpu_profiler::CpuProfiler;
use deno_runtime::deno_permissions::PermissionsContainer;
use deno_runtime::worker::MainWorker;
use deno_semver::npm::NpmPackageReqReference;
Expand All @@ -37,9 +38,19 @@ use crate::util::progress_bar::ProgressBar;

pub type CreateHmrRunnerCb = Box<dyn Fn() -> HmrRunnerState + Send + Sync>;

#[derive(Clone)]
pub struct CpuProfConfig {
pub dir: PathBuf,
pub name: Option<String>,
pub interval: i32,
pub md: bool,
pub flamegraph: bool,
}

pub struct CliMainWorkerOptions {
pub create_hmr_runner: Option<CreateHmrRunnerCb>,
pub maybe_coverage_dir: Option<PathBuf>,
pub maybe_cpu_prof_config: Option<CpuProfConfig>,
pub default_npm_caching_strategy: NpmCachingStrategy,
pub needs_test_modules: bool,
pub initial_cwd: Arc<ModuleSpecifier>,
Expand All @@ -49,6 +60,7 @@ pub struct CliMainWorkerOptions {
struct SharedState {
pub create_hmr_runner: Option<CreateHmrRunnerCb>,
pub maybe_coverage_dir: Option<PathBuf>,
pub maybe_cpu_prof_config: Option<CpuProfConfig>,
pub maybe_file_watcher_communicator: Option<Arc<WatcherCommunicator>>,
pub initial_cwd: Arc<ModuleSpecifier>,
}
Expand All @@ -71,6 +83,7 @@ impl CliMainWorker {

pub async fn run(&mut self) -> Result<i32, CoreError> {
let mut maybe_coverage_collector = self.maybe_setup_coverage_collector();
let mut maybe_cpu_profiler = self.maybe_setup_cpu_profiler();
let mut maybe_hmr_runner = self.maybe_setup_hmr_runner();

// WARNING: Remember to update cli/lib/worker.rs to align with
Expand Down Expand Up @@ -129,6 +142,9 @@ impl CliMainWorker {
if let Some(coverage_collector) = maybe_coverage_collector.as_mut() {
coverage_collector.stop_collecting()?;
}
if let Some(cpu_profiler) = maybe_cpu_profiler.as_mut() {
cpu_profiler.stop_profiling()?;
}
if let Some(hmr_runner) = maybe_hmr_runner.as_mut() {
hmr_runner.stop();
}
Expand Down Expand Up @@ -241,6 +257,31 @@ impl CliMainWorker {
Some(coverage_collector)
}

pub fn maybe_setup_cpu_profiler(&mut self) -> Option<CpuProfiler> {
let cpu_prof_config = self.shared.maybe_cpu_prof_config.as_ref()?;

let filename = cpu_prof_config.name.clone().unwrap_or_else(|| {
let timestamp = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_millis();
let pid = std::process::id();
format!("CPU.{}.{}.cpuprofile", timestamp, pid)
});

let mut cpu_profiler = CpuProfiler::new(
self.worker.js_runtime(),
cpu_prof_config.dir.clone(),
filename,
cpu_prof_config.interval,
cpu_prof_config.md,
cpu_prof_config.flamegraph,
);
cpu_profiler.start_profiling();

Some(cpu_profiler)
}

pub fn execute_script_static(
&mut self,
name: &'static str,
Expand Down Expand Up @@ -311,6 +352,7 @@ impl CliMainWorkerFactory {
shared: Arc::new(SharedState {
create_hmr_runner: options.create_hmr_runner,
maybe_coverage_dir: options.maybe_coverage_dir,
maybe_cpu_prof_config: options.maybe_cpu_prof_config,
maybe_file_watcher_communicator,
initial_cwd: options.initial_cwd,
}),
Expand Down
Loading
Loading