diff options
author | Aaron O'Mullan <aaron.omullan@gmail.com> | 2021-03-23 15:33:06 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-23 15:33:06 +0100 |
commit | 876f075ddebfaa69e8b80c5556a5da3c47a98764 (patch) | |
tree | 3fae034db15eeed8ca45b4db3d8f898df18a8e76 /core | |
parent | 26f7a3f185881c12081eb6d3cedbf9e637376d86 (diff) |
feat(core): Deno.core.heapStats() (#9659)
This commit implements "Deno.core.heapStats()" function
that allows to programatically measure isolate heap-usage.
Diffstat (limited to 'core')
-rw-r--r-- | core/bindings.rs | 103 | ||||
-rw-r--r-- | core/lib.deno_core.d.ts | 3 |
2 files changed, 106 insertions, 0 deletions
diff --git a/core/bindings.rs b/core/bindings.rs index 23cd86a17..c5ed5b601 100644 --- a/core/bindings.rs +++ b/core/bindings.rs @@ -59,6 +59,9 @@ lazy_static! { v8::ExternalReference { function: get_proxy_details.map_fn_to() }, + v8::ExternalReference { + function: heap_stats.map_fn_to(), + }, ]); } @@ -135,6 +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); let shared_key = v8::String::new(scope, "shared").unwrap(); core_val.set_accessor(scope, shared_key.into(), shared_getter); @@ -923,3 +927,102 @@ fn throw_type_error(scope: &mut v8::HandleScope, message: impl AsRef<str>) { let exception = v8::Exception::type_error(scope, message); scope.throw_exception(exception); } + +fn heap_stats( + scope: &mut v8::HandleScope, + _args: v8::FunctionCallbackArguments, + mut rv: v8::ReturnValue, +) { + fn set_prop( + scope: &mut v8::HandleScope, + obj: v8::Local<v8::Object>, + name: &'static str, + value: usize, + ) { + let key = v8::String::new(scope, name).unwrap(); + let val = v8::Number::new(scope, value as f64); + obj.set(scope, key.into(), val.into()); + } + + let s = get_heap_stats(scope); + + // TODO: use serde for this once we have serde_v8 + let obj = v8::Object::new(scope); + set_prop(scope, obj, "totalHeapSize", s.total_heap_size); + set_prop( + scope, + obj, + "totalHeapSizexecutable", + s.total_heap_size_executable, + ); + set_prop(scope, obj, "totalPhysicalSize", s.total_physical_size); + set_prop(scope, obj, "totalAvailableSize", s.total_available_size); + set_prop( + scope, + obj, + "totalGlobalHandlesSize", + s.total_global_handles_size, + ); + set_prop( + scope, + obj, + "usedGlobalHandlesSize", + s.used_global_handles_size, + ); + set_prop(scope, obj, "usedHeapSize", s.used_heap_size); + set_prop(scope, obj, "heapSizeLimit", s.heap_size_limit); + set_prop(scope, obj, "mallocedMemory", s.malloced_memory); + set_prop(scope, obj, "externalMemory", s.external_memory); + set_prop(scope, obj, "peakMallocedMemory", s.peak_malloced_memory); + set_prop( + scope, + obj, + "numberOfNativeContexts", + s.number_of_native_contexts, + ); + set_prop( + scope, + obj, + "numberOfDetachedContexts", + s.number_of_detached_contexts, + ); + + rv.set(obj.into()); +} + +// HeapStats stores values from a isolate.get_heap_statistics() call +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, +} +fn get_heap_stats(isolate: &mut v8::Isolate) -> HeapStats { + 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(), + } +} diff --git a/core/lib.deno_core.d.ts b/core/lib.deno_core.d.ts index 1efb92dc6..004ed0529 100644 --- a/core/lib.deno_core.d.ts +++ b/core/lib.deno_core.d.ts @@ -35,5 +35,8 @@ declare namespace Deno { /** Close the resource with the specified op id. */ function close(rid: number): void; + + /** Get heap stats for current isolate/worker */ + function heapStats(): Record<string, number>; } } |