From 77238d1bbcb51f2968a2f73011e5f8ee7e6be51d Mon Sep 17 00:00:00 2001 From: joshua-spacetime Date: Fri, 10 Apr 2026 22:17:02 -0700 Subject: [PATCH 1/2] Cache V8 heap stats instead of querying them on every call --- crates/core/src/host/v8/mod.rs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/crates/core/src/host/v8/mod.rs b/crates/core/src/host/v8/mod.rs index 5dd5f7e2527..b9703be9a3b 100644 --- a/crates/core/src/host/v8/mod.rs +++ b/crates/core/src/host/v8/mod.rs @@ -329,6 +329,8 @@ fn env_on_isolate_unwrap(isolate: &mut Isolate) -> &mut JsInstanceEnv { struct JsInstanceEnv { instance_env: InstanceEnv, module_def: Option>, + /// Last used-heap sample captured by the worker's periodic heap checks. + cached_used_heap_size: usize, /// The slab of `BufferIters` created for this instance. iters: RowIters, @@ -353,6 +355,7 @@ impl JsInstanceEnv { Self { instance_env, module_def: None, + cached_used_heap_size: 0, call_times: CallTimes::new(), iters: <_>::default(), chunk_pool: <_>::default(), @@ -407,6 +410,16 @@ impl JsInstanceEnv { } } + /// Refresh the cached heap usage after an explicit V8 heap sample. + fn set_cached_used_heap_size(&mut self, bytes: usize) { + self.cached_used_heap_size = bytes; + } + + /// Return the last heap sample without forcing a fresh V8 query. + fn cached_used_heap_size(&self) -> usize { + self.cached_used_heap_size + } + fn set_module_def(&mut self, module_def: Arc) { self.module_def = Some(module_def); } @@ -924,7 +937,10 @@ fn adjust_gauge(gauge: &IntGauge, delta: i64) { } fn sample_heap_stats(scope: &mut PinScope<'_, '_>, metrics: &mut V8HeapMetrics) -> v8::HeapStatistics { + // Whenever we sample heap statistics, we cache them on the isolate so that + // the per-call execution stats can avoid querying them on each invocation. let stats = scope.get_heap_statistics(); + env_on_isolate_unwrap(scope).set_cached_used_heap_size(stats.used_heap_size()); metrics.observe(&stats); stats } @@ -1788,9 +1804,8 @@ where // Derive energy stats. let energy = energy_from_elapsed(budget, timings.total_duration); - // Fetch the currently used heap size in V8. - // The used size is ostensibly fairer than the total size. - let memory_allocation = scope.get_heap_statistics().used_heap_size(); + // Reuse the last periodic heap sample instead of querying V8 on every call. + let memory_allocation = env_on_isolate_unwrap(scope).cached_used_heap_size(); let stats = ExecutionStats { energy, From ba5c2cd237343d3360010de287bfc19ae4ada675 Mon Sep 17 00:00:00 2001 From: joshua-spacetime Date: Mon, 13 Apr 2026 09:19:48 -0700 Subject: [PATCH 2/2] Apply suggestion from @Centril Co-authored-by: Mazdak Farrokhzad Signed-off-by: joshua-spacetime --- crates/core/src/host/v8/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/core/src/host/v8/mod.rs b/crates/core/src/host/v8/mod.rs index b9703be9a3b..cf096839d47 100644 --- a/crates/core/src/host/v8/mod.rs +++ b/crates/core/src/host/v8/mod.rs @@ -1805,6 +1805,7 @@ where let energy = energy_from_elapsed(budget, timings.total_duration); // Reuse the last periodic heap sample instead of querying V8 on every call. + // We use this statistic for energy tracking, so eventual consistency is fine. let memory_allocation = env_on_isolate_unwrap(scope).cached_used_heap_size(); let stats = ExecutionStats {