summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorAaron O'Mullan <aaron.omullan@gmail.com>2021-03-23 15:33:06 +0100
committerGitHub <noreply@github.com>2021-03-23 15:33:06 +0100
commit876f075ddebfaa69e8b80c5556a5da3c47a98764 (patch)
tree3fae034db15eeed8ca45b4db3d8f898df18a8e76 /core
parent26f7a3f185881c12081eb6d3cedbf9e637376d86 (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.rs103
-rw-r--r--core/lib.deno_core.d.ts3
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>;
}
}