mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-12-25 00:29:14 -05:00
Add Isolate::get_heap_statistics() (#440)
This commit is contained in:
parent
d6528c7300
commit
fd5458c959
4 changed files with 179 additions and 0 deletions
|
@ -115,6 +115,11 @@ void v8__Isolate__Enter(v8::Isolate* isolate) { isolate->Enter(); }
|
|||
|
||||
void v8__Isolate__Exit(v8::Isolate* isolate) { isolate->Exit(); }
|
||||
|
||||
void v8__Isolate__GetHeapStatistics(v8::Isolate* isolate,
|
||||
v8::HeapStatistics* s) {
|
||||
isolate->GetHeapStatistics(s);
|
||||
}
|
||||
|
||||
const v8::Context* v8__Isolate__GetCurrentContext(v8::Isolate* isolate) {
|
||||
return local_to_ptr(isolate->GetCurrentContext());
|
||||
}
|
||||
|
@ -1778,4 +1783,35 @@ int v8__internal__Object__GetHash(const v8::Data& data) {
|
|||
return hash;
|
||||
}
|
||||
|
||||
void v8__HeapStatistics__CONSTRUCT(uninit_t<v8::HeapStatistics>* buf) {
|
||||
// Should be <= than its counterpart in src/isolate.rs
|
||||
static_assert(sizeof(v8::HeapStatistics) <= sizeof(uintptr_t[16]),
|
||||
"HeapStatistics mismatch");
|
||||
construct_in_place<v8::HeapStatistics>(buf);
|
||||
}
|
||||
|
||||
// The const_cast doesn't violate const correctness, the methods
|
||||
// are simple getters that don't mutate the object or global state.
|
||||
#define V(name) \
|
||||
size_t v8__HeapStatistics__##name(const v8::HeapStatistics* s) { \
|
||||
return const_cast<v8::HeapStatistics*>(s)->name(); \
|
||||
}
|
||||
|
||||
V(total_heap_size)
|
||||
V(total_heap_size_executable)
|
||||
V(total_physical_size)
|
||||
V(total_available_size)
|
||||
V(total_global_handles_size)
|
||||
V(used_global_handles_size)
|
||||
V(used_heap_size)
|
||||
V(heap_size_limit)
|
||||
V(malloced_memory)
|
||||
V(external_memory)
|
||||
V(peak_malloced_memory)
|
||||
V(number_of_native_contexts)
|
||||
V(number_of_detached_contexts)
|
||||
V(does_zap_garbage) // Returns size_t, not bool like you'd expect.
|
||||
|
||||
#undef V
|
||||
|
||||
} // extern "C"
|
||||
|
|
116
src/isolate.rs
116
src/isolate.rs
|
@ -20,6 +20,7 @@ use std::any::TypeId;
|
|||
use std::cell::{Ref, RefCell, RefMut};
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::c_void;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::ops::Deref;
|
||||
use std::ops::DerefMut;
|
||||
use std::ptr::null_mut;
|
||||
|
@ -75,6 +76,14 @@ pub type NearHeapLimitCallback = extern "C" fn(
|
|||
initial_heap_limit: usize,
|
||||
) -> usize;
|
||||
|
||||
/// Collection of V8 heap information.
|
||||
///
|
||||
/// Instances of this class can be passed to v8::Isolate::GetHeapStatistics to
|
||||
/// get heap statistics from V8.
|
||||
// Must be >= sizeof(v8::HeapStatistics), see v8__HeapStatistics__CONSTRUCT().
|
||||
#[repr(C)]
|
||||
pub struct HeapStatistics([usize; 16]);
|
||||
|
||||
extern "C" {
|
||||
fn v8__Isolate__New(params: *const raw::CreateParams) -> *mut Isolate;
|
||||
fn v8__Isolate__Dispose(this: *mut Isolate);
|
||||
|
@ -83,6 +92,7 @@ extern "C" {
|
|||
fn v8__Isolate__GetNumberOfDataSlots(this: *const Isolate) -> u32;
|
||||
fn v8__Isolate__Enter(this: *mut Isolate);
|
||||
fn v8__Isolate__Exit(this: *mut Isolate);
|
||||
fn v8__Isolate__GetHeapStatistics(this: *mut Isolate, s: *mut HeapStatistics);
|
||||
fn v8__Isolate__SetCaptureStackTraceForUncaughtExceptions(
|
||||
this: *mut Isolate,
|
||||
caputre: bool,
|
||||
|
@ -133,6 +143,37 @@ extern "C" {
|
|||
callback: extern "C" fn(*mut c_void, *const u8, usize) -> bool,
|
||||
arg: *mut c_void,
|
||||
);
|
||||
|
||||
fn v8__HeapStatistics__CONSTRUCT(s: *mut MaybeUninit<HeapStatistics>);
|
||||
fn v8__HeapStatistics__total_heap_size(s: *const HeapStatistics) -> usize;
|
||||
fn v8__HeapStatistics__total_heap_size_executable(
|
||||
s: *const HeapStatistics,
|
||||
) -> usize;
|
||||
fn v8__HeapStatistics__total_physical_size(s: *const HeapStatistics)
|
||||
-> usize;
|
||||
fn v8__HeapStatistics__total_available_size(
|
||||
s: *const HeapStatistics,
|
||||
) -> usize;
|
||||
fn v8__HeapStatistics__total_global_handles_size(
|
||||
s: *const HeapStatistics,
|
||||
) -> usize;
|
||||
fn v8__HeapStatistics__used_global_handles_size(
|
||||
s: *const HeapStatistics,
|
||||
) -> usize;
|
||||
fn v8__HeapStatistics__used_heap_size(s: *const HeapStatistics) -> usize;
|
||||
fn v8__HeapStatistics__heap_size_limit(s: *const HeapStatistics) -> usize;
|
||||
fn v8__HeapStatistics__malloced_memory(s: *const HeapStatistics) -> usize;
|
||||
fn v8__HeapStatistics__external_memory(s: *const HeapStatistics) -> usize;
|
||||
fn v8__HeapStatistics__peak_malloced_memory(
|
||||
s: *const HeapStatistics,
|
||||
) -> usize;
|
||||
fn v8__HeapStatistics__number_of_native_contexts(
|
||||
s: *const HeapStatistics,
|
||||
) -> usize;
|
||||
fn v8__HeapStatistics__number_of_detached_contexts(
|
||||
s: *const HeapStatistics,
|
||||
) -> usize;
|
||||
fn v8__HeapStatistics__does_zap_garbage(s: *const HeapStatistics) -> usize;
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
@ -305,6 +346,11 @@ impl Isolate {
|
|||
unsafe { v8__Isolate__Exit(self) }
|
||||
}
|
||||
|
||||
/// Get statistics about the heap memory usage.
|
||||
pub fn get_heap_statistics(&mut self, s: &mut HeapStatistics) {
|
||||
unsafe { v8__Isolate__GetHeapStatistics(self, s) }
|
||||
}
|
||||
|
||||
/// Tells V8 to capture current stack trace when uncaught exception occurs
|
||||
/// and report it to the message listeners. The option is off by default.
|
||||
pub fn set_capture_stack_trace_for_uncaught_exceptions(
|
||||
|
@ -621,3 +667,73 @@ impl DerefMut for OwnedIsolate {
|
|||
unsafe { self.cxx_isolate.as_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
impl HeapStatistics {
|
||||
pub fn total_heap_size(&self) -> usize {
|
||||
unsafe { v8__HeapStatistics__total_heap_size(self) }
|
||||
}
|
||||
|
||||
pub fn total_heap_size_executable(&self) -> usize {
|
||||
unsafe { v8__HeapStatistics__total_heap_size_executable(self) }
|
||||
}
|
||||
|
||||
pub fn total_physical_size(&self) -> usize {
|
||||
unsafe { v8__HeapStatistics__total_physical_size(self) }
|
||||
}
|
||||
|
||||
pub fn total_available_size(&self) -> usize {
|
||||
unsafe { v8__HeapStatistics__total_available_size(self) }
|
||||
}
|
||||
|
||||
pub fn total_global_handles_size(&self) -> usize {
|
||||
unsafe { v8__HeapStatistics__total_global_handles_size(self) }
|
||||
}
|
||||
|
||||
pub fn used_global_handles_size(&self) -> usize {
|
||||
unsafe { v8__HeapStatistics__used_global_handles_size(self) }
|
||||
}
|
||||
|
||||
pub fn used_heap_size(&self) -> usize {
|
||||
unsafe { v8__HeapStatistics__used_heap_size(self) }
|
||||
}
|
||||
|
||||
pub fn heap_size_limit(&self) -> usize {
|
||||
unsafe { v8__HeapStatistics__heap_size_limit(self) }
|
||||
}
|
||||
|
||||
pub fn malloced_memory(&self) -> usize {
|
||||
unsafe { v8__HeapStatistics__malloced_memory(self) }
|
||||
}
|
||||
|
||||
pub fn external_memory(&self) -> usize {
|
||||
unsafe { v8__HeapStatistics__external_memory(self) }
|
||||
}
|
||||
|
||||
pub fn peak_malloced_memory(&self) -> usize {
|
||||
unsafe { v8__HeapStatistics__peak_malloced_memory(self) }
|
||||
}
|
||||
|
||||
pub fn number_of_native_contexts(&self) -> usize {
|
||||
unsafe { v8__HeapStatistics__number_of_native_contexts(self) }
|
||||
}
|
||||
|
||||
pub fn number_of_detached_contexts(&self) -> usize {
|
||||
unsafe { v8__HeapStatistics__number_of_detached_contexts(self) }
|
||||
}
|
||||
|
||||
/// Returns a 0/1 boolean, which signifies whether the V8 overwrite heap
|
||||
/// garbage with a bit pattern.
|
||||
pub fn does_zap_garbage(&self) -> usize {
|
||||
unsafe { v8__HeapStatistics__does_zap_garbage(self) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HeapStatistics {
|
||||
fn default() -> Self {
|
||||
let mut s = MaybeUninit::<Self>::uninit();
|
||||
unsafe {
|
||||
v8__HeapStatistics__CONSTRUCT(&mut s);
|
||||
s.assume_init()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,6 +82,7 @@ pub use function::*;
|
|||
pub use handle::Global;
|
||||
pub use handle::Handle;
|
||||
pub use handle::Local;
|
||||
pub use isolate::HeapStatistics;
|
||||
pub use isolate::HostImportModuleDynamicallyCallback;
|
||||
pub use isolate::HostInitializeImportMetaObjectCallback;
|
||||
pub use isolate::Isolate;
|
||||
|
|
|
@ -3365,3 +3365,29 @@ fn heap_limits() {
|
|||
}
|
||||
assert_eq!(1, test_state.near_heap_limit_callback_calls);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn heap_statistics() {
|
||||
let _setup_guard = setup();
|
||||
|
||||
let params = v8::CreateParams::default().heap_limits(0, 10 << 20); // 10 MB.
|
||||
let isolate = &mut v8::Isolate::new(params);
|
||||
|
||||
let mut s = v8::HeapStatistics::default();
|
||||
isolate.get_heap_statistics(&mut s);
|
||||
assert!(s.heap_size_limit() > 0);
|
||||
assert!(s.total_heap_size() > 0);
|
||||
assert!(s.total_global_handles_size() >= s.used_global_handles_size());
|
||||
assert!(s.used_heap_size() > 0);
|
||||
assert!(s.heap_size_limit() >= s.used_heap_size());
|
||||
assert!(s.peak_malloced_memory() >= s.malloced_memory());
|
||||
assert_eq!(s.number_of_native_contexts(), 0);
|
||||
|
||||
let scope = &mut v8::HandleScope::new(isolate);
|
||||
let context = v8::Context::new(scope);
|
||||
let scope = &mut v8::ContextScope::new(scope, context);
|
||||
let _ = eval(scope, "").unwrap();
|
||||
|
||||
scope.get_heap_statistics(&mut s);
|
||||
assert_ne!(s.number_of_native_contexts(), 0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue