From bf99039ea944c32f0247ad8b3d1057f20f921b40 Mon Sep 17 00:00:00 2001 From: Aaron O'Mullan Date: Mon, 12 Apr 2021 10:47:44 +0200 Subject: [PATCH] feat: Add Deno.memoryUsage() (#9986) --- cli/dts/lib.deno.unstable.d.ts | 9 ++++++ cli/tests/heapstats.js | 8 +++--- cli/tests/integration_tests.rs | 2 +- core/bindings.rs | 51 ++++++++++++---------------------- runtime/js/99_main.js | 1 + 5 files changed, 33 insertions(+), 38 deletions(-) diff --git a/cli/dts/lib.deno.unstable.d.ts b/cli/dts/lib.deno.unstable.d.ts index 3fbf3d94ddd43c..612ebeccc2679b 100644 --- a/cli/dts/lib.deno.unstable.d.ts +++ b/cli/dts/lib.deno.unstable.d.ts @@ -1166,6 +1166,15 @@ declare namespace Deno { bytesReceived: number; } + export interface MemoryUsage { + rss: number; + heapTotal: number; + heapUsed: number; + external: number; + } + + export function memoryUsage(): MemoryUsage; + export interface RequestEvent { readonly request: Request; respondWith(r: Response | Promise): void; diff --git a/cli/tests/heapstats.js b/cli/tests/heapstats.js index 0ed623e568d169..fba9e66d9c0ff6 100644 --- a/cli/tests/heapstats.js +++ b/cli/tests/heapstats.js @@ -2,15 +2,15 @@ "use strict"; function allocTest(alloc, allocAssert, deallocAssert) { - // Helper func that GCs then returns heapStats + // Helper func that GCs then returns memory usage const sample = () => { // deno-lint-ignore no-undef gc(); - return Deno.core.heapStats(); + return Deno.memoryUsage(); }; - const delta = (t1, t2) => t2.usedHeapSize - t1.usedHeapSize; + const delta = (t1, t2) => t2.heapUsed - t1.heapUsed; - // Sample "clean" heapStats + // Sample "clean" heap usage const t1 = sample(); // Alloc diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs index 5067b81637e8dc..f856b90b886b63 100644 --- a/cli/tests/integration_tests.rs +++ b/cli/tests/integration_tests.rs @@ -3250,7 +3250,7 @@ console.log("finish"); }); itest!(heapstats { - args: "run --quiet --v8-flags=--expose-gc heapstats.js", + args: "run --quiet --unstable --v8-flags=--expose-gc heapstats.js", output: "heapstats.js.out", }); diff --git a/core/bindings.rs b/core/bindings.rs index eaddcbfbccccb3..0a67be10229371 100644 --- a/core/bindings.rs +++ b/core/bindings.rs @@ -60,7 +60,7 @@ lazy_static::lazy_static! { function: get_proxy_details.map_fn_to() }, v8::ExternalReference { - function: heap_stats.map_fn_to(), + function: memory_usage.map_fn_to(), }, ]); } @@ -138,7 +138,7 @@ pub fn initialize_context<'s>( set_func(scope, core_val, "deserialize", deserialize); set_func(scope, core_val, "getPromiseDetails", get_promise_details); set_func(scope, core_val, "getProxyDetails", get_proxy_details); - set_func(scope, core_val, "heapStats", heap_stats); + set_func(scope, core_val, "memoryUsage", memory_usage); // Direct bindings on `window`. set_func(scope, global, "queueMicrotask", queue_microtask); @@ -862,50 +862,35 @@ fn throw_type_error(scope: &mut v8::HandleScope, message: impl AsRef) { scope.throw_exception(exception); } -fn heap_stats( +fn memory_usage( scope: &mut v8::HandleScope, _args: v8::FunctionCallbackArguments, mut rv: v8::ReturnValue, ) { - let stats = get_heap_stats(scope); + let stats = get_memory_usage(scope); rv.set(to_v8(scope, stats).unwrap()); } // HeapStats stores values from a isolate.get_heap_statistics() call #[derive(Serialize)] #[serde(rename_all = "camelCase")] -struct HeapStats { - total_heap_size: usize, - total_heap_size_executable: usize, - total_physical_size: usize, - total_available_size: usize, - total_global_handles_size: usize, - used_global_handles_size: usize, - used_heap_size: usize, - heap_size_limit: usize, - malloced_memory: usize, - external_memory: usize, - peak_malloced_memory: usize, - number_of_native_contexts: usize, - number_of_detached_contexts: usize, +struct MemoryUsage { + rss: usize, + heap_total: usize, + heap_used: usize, + external: usize, + // TODO: track ArrayBuffers, would require using a custom allocator to track + // but it's otherwise a subset of external so can be indirectly tracked + // array_buffers: usize, } -fn get_heap_stats(isolate: &mut v8::Isolate) -> HeapStats { +fn get_memory_usage(isolate: &mut v8::Isolate) -> MemoryUsage { let mut s = v8::HeapStatistics::default(); isolate.get_heap_statistics(&mut s); - HeapStats { - total_heap_size: s.total_heap_size(), - total_heap_size_executable: s.total_heap_size_executable(), - total_physical_size: s.total_physical_size(), - total_available_size: s.total_available_size(), - total_global_handles_size: s.total_global_handles_size(), - used_global_handles_size: s.used_global_handles_size(), - used_heap_size: s.used_heap_size(), - heap_size_limit: s.heap_size_limit(), - malloced_memory: s.malloced_memory(), - external_memory: s.external_memory(), - peak_malloced_memory: s.peak_malloced_memory(), - number_of_native_contexts: s.number_of_native_contexts(), - number_of_detached_contexts: s.number_of_detached_contexts(), + MemoryUsage { + rss: s.total_physical_size(), + heap_total: s.total_heap_size(), + heap_used: s.used_heap_size(), + external: s.external_memory(), } } diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index 596565bed1861d..7f24e10cd62ff8 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -433,6 +433,7 @@ delete Object.prototype.__proto__; [internalSymbol]: internals, resources: core.resources, close: core.close, + memoryUsage: core.memoryUsage, ...denoNs, }; Object.defineProperties(finalDenoNs, {