mirror of
https://github.com/servo/servo.git
synced 2025-08-08 15:05:35 +01:00
stylo: Measure Elements and ComputedValues.
The patch provides FFI access to Gecko's SeenPtrs type from Rust, in order to record what has already been measured when measuring Arcs. (The SeenPtrs must be initialized on the Gecko side because the same table is reused for measuring all Elements within a window, because Elements can share ComputedValues.) I have confirmed with DMD that this is working correctly. The patch also introduces MallocSizeOfRepeats, which is like MallocSizeOf but takes a SizeOfState, which holds a SeenPtrs table.
This commit is contained in:
parent
e07beacd4d
commit
526e9691f8
9 changed files with 161 additions and 5 deletions
|
@ -4,6 +4,12 @@
|
|||
|
||||
//! Memory reporting for the style system when running inside of Gecko.
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
use gecko_bindings::bindings::Gecko_HaveSeenPtr;
|
||||
#[cfg(feature = "gecko")]
|
||||
use gecko_bindings::structs::SeenPtrs;
|
||||
#[cfg(feature = "gecko")]
|
||||
use servo_arc::Arc;
|
||||
use shared_lock::SharedRwLockReadGuard;
|
||||
use std::os::raw::c_void;
|
||||
|
||||
|
@ -14,11 +20,24 @@ use std::os::raw::c_void;
|
|||
/// do_malloc_size_of(), rather than directly.
|
||||
pub type MallocSizeOfFn = unsafe extern "C" fn(ptr: *const c_void) -> usize;
|
||||
|
||||
/// Servo-side counterpart to mozilla::SizeOfState. The only difference is that
|
||||
/// this struct doesn't contain the SeenPtrs table, just a pointer to it.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub struct SizeOfState {
|
||||
/// Function that measures the size of heap blocks.
|
||||
pub malloc_size_of: MallocSizeOfFn,
|
||||
/// Table recording heap blocks that have already been measured.
|
||||
pub seen_ptrs: *mut SeenPtrs,
|
||||
}
|
||||
|
||||
/// Call malloc_size_of on ptr, first checking that the allocation isn't empty.
|
||||
pub unsafe fn is_empty<T>(ptr: *const T) -> bool {
|
||||
return ptr as usize <= ::std::mem::align_of::<T>();
|
||||
}
|
||||
|
||||
/// Call malloc_size_of on ptr, first checking that the allocation isn't empty.
|
||||
pub unsafe fn do_malloc_size_of<T>(malloc_size_of: MallocSizeOfFn, ptr: *const T) -> usize {
|
||||
use std::mem::align_of;
|
||||
|
||||
if ptr as usize <= align_of::<T>() {
|
||||
if is_empty(ptr) {
|
||||
0
|
||||
} else {
|
||||
malloc_size_of(ptr as *const c_void)
|
||||
|
@ -32,6 +51,15 @@ pub trait MallocSizeOf {
|
|||
fn malloc_size_of_children(&self, malloc_size_of: MallocSizeOfFn) -> usize;
|
||||
}
|
||||
|
||||
/// Like MallocSizeOf, but takes a SizeOfState which allows it to measure
|
||||
/// graph-like structures such as those containing Arcs.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub trait MallocSizeOfWithRepeats {
|
||||
/// Measure the size of any heap-allocated structures that hang off this
|
||||
/// value, but not the space taken up by the value itself.
|
||||
fn malloc_size_of_children(&self, state: &mut SizeOfState) -> usize;
|
||||
}
|
||||
|
||||
/// Like MallocSizeOf, but operates with the global SharedRwLockReadGuard
|
||||
/// locked.
|
||||
pub trait MallocSizeOfWithGuard {
|
||||
|
@ -58,6 +86,19 @@ impl<T: MallocSizeOf> MallocSizeOf for Vec<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
impl<T: MallocSizeOfWithRepeats> MallocSizeOfWithRepeats for Arc<T> {
|
||||
fn malloc_size_of_children(&self, state: &mut SizeOfState) -> usize {
|
||||
let mut n = 0;
|
||||
let heap_ptr = self.heap_ptr();
|
||||
if unsafe { !is_empty(heap_ptr) && !Gecko_HaveSeenPtr(state.seen_ptrs, heap_ptr) } {
|
||||
n += unsafe { (state.malloc_size_of)(heap_ptr) };
|
||||
n += (**self).malloc_size_of_children(state);
|
||||
}
|
||||
n
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: MallocSizeOfWithGuard> MallocSizeOfWithGuard for Vec<T> {
|
||||
fn malloc_size_of_children(
|
||||
&self,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue