Refactor common infrastructure for creating memory reports. (#36579)

This removes a bunch of duplicated code needed to support
ConditionalMallocSizeOf correctly, and fixes multiple places where that
code was subtly wrong (the seen pointers hashset was never cleared).

Testing: Measuring https://www.nist.gov/image-gallery lots of times.

Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
Josh Matthews 2025-04-17 22:14:49 -04:00 committed by GitHub
parent 2a81987590
commit 5e2d42e944
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 68 additions and 57 deletions

View file

@ -6,12 +6,16 @@
#![deny(missing_docs)]
use std::cell::{LazyCell, RefCell};
use std::collections::HashSet;
use std::ffi::c_void;
use std::marker::Send;
use crossbeam_channel::Sender;
use ipc_channel::ipc::{self, IpcSender};
use ipc_channel::router::ROUTER;
use log::warn;
use malloc_size_of::MallocSizeOfOps;
use serde::{Deserialize, Serialize};
/// A trait to abstract away the various kinds of message senders we use.
@ -266,3 +270,21 @@ pub enum ProfilerMsg {
/// Triggers sending back the memory profiling metrics,
Report(IpcSender<MemoryReportResult>),
}
thread_local!(static SEEN_POINTERS: LazyCell<RefCell<HashSet<*const c_void>>> = const {
LazyCell::new(Default::default)
});
/// Invoke the provided function after initializing the memory profile tools.
/// The function is expected to call all the desired [MallocSizeOf::size_of]
/// for allocations reachable from the current thread.
pub fn perform_memory_report<F: FnOnce(&mut MallocSizeOfOps)>(f: F) {
SEEN_POINTERS.with(|pointers| pointers.borrow_mut().clear());
let seen_pointer = move |ptr| SEEN_POINTERS.with(|pointers| !pointers.borrow_mut().insert(ptr));
let mut ops = MallocSizeOfOps::new(
servo_allocator::usable_size,
None,
Some(Box::new(seen_pointer)),
);
f(&mut ops);
}