diff --git a/src/bun.js.zig b/src/bun.js.zig index fe61c8151a..d7abd36838 100644 --- a/src/bun.js.zig +++ b/src/bun.js.zig @@ -285,7 +285,9 @@ pub const Run = struct { .dir = cpu_prof_opts.dir, .md_format = cpu_prof_opts.md_format, .json_format = cpu_prof_opts.json_format, + .interval = cpu_prof_opts.interval, }; + CPUProfiler.setSamplingInterval(cpu_prof_opts.interval); CPUProfiler.startCPUProfiler(vm.jsc_vm); bun.analytics.Features.cpu_profile += 1; } diff --git a/src/bun.js/bindings/BunCPUProfiler.cpp b/src/bun.js/bindings/BunCPUProfiler.cpp index c879ced1f3..5cbafb227c 100644 --- a/src/bun.js/bindings/BunCPUProfiler.cpp +++ b/src/bun.js/bindings/BunCPUProfiler.cpp @@ -19,6 +19,12 @@ extern "C" void Bun__startCPUProfiler(JSC::VM* vm); extern "C" void Bun__stopCPUProfiler(JSC::VM* vm, BunString* outJSON, BunString* outText); +extern "C" void Bun__setSamplingInterval(int intervalMicroseconds); + +void Bun__setSamplingInterval(int intervalMicroseconds) +{ + Bun::setSamplingInterval(intervalMicroseconds); +} namespace Bun { diff --git a/src/bun.js/bindings/BunCPUProfiler.zig b/src/bun.js/bindings/BunCPUProfiler.zig index b0d9c04cf2..01d461534a 100644 --- a/src/bun.js/bindings/BunCPUProfiler.zig +++ b/src/bun.js/bindings/BunCPUProfiler.zig @@ -3,11 +3,17 @@ pub const CPUProfilerConfig = struct { dir: []const u8, md_format: bool = false, json_format: bool = false, + interval: u32 = 1000, }; // C++ function declarations extern fn Bun__startCPUProfiler(vm: *jsc.VM) void; extern fn Bun__stopCPUProfiler(vm: *jsc.VM, outJSON: ?*bun.String, outText: ?*bun.String) void; +extern fn Bun__setSamplingInterval(intervalMicroseconds: c_int) void; + +pub fn setSamplingInterval(interval: u32) void { + Bun__setSamplingInterval(@intCast(interval)); +} pub fn startCPUProfiler(vm: *jsc.VM) void { Bun__startCPUProfiler(vm); diff --git a/src/cli.zig b/src/cli.zig index d3cdbd3b2f..3d459f067d 100644 --- a/src/cli.zig +++ b/src/cli.zig @@ -392,6 +392,7 @@ pub const Command = struct { enabled: bool = false, name: []const u8 = "", dir: []const u8 = "", + interval: u32 = 1000, md_format: bool = false, json_format: bool = false, } = .{}, diff --git a/src/cli/Arguments.zig b/src/cli/Arguments.zig index ee24944abc..2a9c84c880 100644 --- a/src/cli/Arguments.zig +++ b/src/cli/Arguments.zig @@ -91,6 +91,7 @@ pub const runtime_params_ = [_]ParamType{ clap.parseParam("--cpu-prof-name Specify the name of the CPU profile file") catch unreachable, clap.parseParam("--cpu-prof-dir Specify the directory where the CPU profile will be saved") catch unreachable, clap.parseParam("--cpu-prof-md Output CPU profile in markdown format (grep-friendly, designed for LLM analysis)") catch unreachable, + clap.parseParam("--cpu-prof-interval Specify the sampling interval in microseconds for CPU profiling (default: 1000)") catch unreachable, clap.parseParam("--heap-prof Generate V8 heap snapshot on exit (.heapsnapshot)") catch unreachable, clap.parseParam("--heap-prof-name Specify the name of the heap profile file") catch unreachable, clap.parseParam("--heap-prof-dir Specify the directory where the heap profile will be saved") catch unreachable, @@ -864,6 +865,9 @@ pub fn parse(allocator: std.mem.Allocator, ctx: Command.Context, comptime cmd: C ctx.runtime_options.cpu_prof.md_format = cpu_prof_md_flag; // json_format is true if --cpu-prof is passed (regardless of --cpu-prof-md) ctx.runtime_options.cpu_prof.json_format = cpu_prof_flag; + if (args.option("--cpu-prof-interval")) |interval_str| { + ctx.runtime_options.cpu_prof.interval = std.fmt.parseInt(u32, interval_str, 10) catch 1000; + } } else { // Warn if --cpu-prof-name or --cpu-prof-dir is used without a profiler flag if (args.option("--cpu-prof-name")) |_| { @@ -872,6 +876,9 @@ pub fn parse(allocator: std.mem.Allocator, ctx: Command.Context, comptime cmd: C if (args.option("--cpu-prof-dir")) |_| { Output.warn("--cpu-prof-dir requires --cpu-prof or --cpu-prof-md to be enabled", .{}); } + if (args.option("--cpu-prof-interval")) |_| { + Output.warn("--cpu-prof-interval requires --cpu-prof or --cpu-prof-md to be enabled", .{}); + } } const heap_prof_v8 = args.flag("--heap-prof");