mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Measure LocalLayoutContexts in LayoutTask and LayoutWorkers.
The FreeType instances in layout workers are reasonably large and worth measuring. The one in LayoutTask is smaller but it's easy to measure at the same time. Sample output: ``` | 8.33 MiB -- pages | 8.33 MiB -- url(file:///home/njn/moz/servo/../servo-static-suite/wikipedia/Guardians%20of%20the%20Galaxy%20(film)%20-%20Wikipedia,%20the%20free%20encyclopedia.html) | 1.32 MiB -- layout-worker-0-local-context | 1.31 MiB -- layout-worker-1-local-context | 1.24 MiB -- layout-worker-3-local-context | 1.17 MiB -- layout-worker-4-local-context | 1.08 MiB -- layout-worker-2-local-context | 1.06 MiB -- layout-worker-5-local-context | 0.78 MiB -- paint-task | 0.78 MiB -- buffer-map | 0.38 MiB -- layout-task | 0.30 MiB -- display-list | 0.07 MiB -- local-context ``` This required adding a mechanism to WorkQueue to measure worker TLSes.
This commit is contained in:
parent
fdeebf86a1
commit
48a0725c01
5 changed files with 70 additions and 3 deletions
|
@ -5,6 +5,7 @@
|
|||
//! Data structure measurement.
|
||||
|
||||
use libc::{c_void, size_t};
|
||||
use std::cell::RefCell;
|
||||
use std::collections::LinkedList;
|
||||
use std::mem::transmute;
|
||||
use std::sync::Arc;
|
||||
|
@ -92,6 +93,12 @@ impl<T: HeapSizeOf> HeapSizeOf for Arc<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: HeapSizeOf> HeapSizeOf for RefCell<T> {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
self.borrow().heap_size_of_children()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: HeapSizeOf> HeapSizeOf for Vec<T> {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
heap_size_of(self.as_ptr() as *const c_void) +
|
||||
|
|
|
@ -36,6 +36,8 @@ enum WorkerMsg<QueueData: 'static, WorkData: 'static> {
|
|||
Start(Worker<WorkUnit<QueueData, WorkData>>, *mut AtomicUsize, *const QueueData),
|
||||
/// Tells the worker to stop. It can be restarted again with a `WorkerMsg::Start`.
|
||||
Stop,
|
||||
/// Tells the worker to measure the heap size of its TLS using the supplied function.
|
||||
HeapSizeOfTLS(fn() -> usize),
|
||||
/// Tells the worker thread to terminate.
|
||||
Exit,
|
||||
}
|
||||
|
@ -45,6 +47,7 @@ unsafe impl<QueueData: 'static, WorkData: 'static> Send for WorkerMsg<QueueData,
|
|||
/// Messages to the supervisor.
|
||||
enum SupervisorMsg<QueueData: 'static, WorkData: 'static> {
|
||||
Finished,
|
||||
HeapSizeOfTLS(usize),
|
||||
ReturnDeque(usize, Worker<WorkUnit<QueueData, WorkData>>),
|
||||
}
|
||||
|
||||
|
@ -90,6 +93,10 @@ impl<QueueData: Send, WorkData: Send> WorkerThread<QueueData, WorkData> {
|
|||
WorkerMsg::Start(deque, ref_count, queue_data) => (deque, ref_count, queue_data),
|
||||
WorkerMsg::Stop => panic!("unexpected stop message"),
|
||||
WorkerMsg::Exit => return,
|
||||
WorkerMsg::HeapSizeOfTLS(f) => {
|
||||
self.chan.send(SupervisorMsg::HeapSizeOfTLS(f())).unwrap();
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let mut back_off_sleep = 0 as u32;
|
||||
|
@ -315,11 +322,32 @@ impl<QueueData: Send, WorkData: Send> WorkQueue<QueueData, WorkData> {
|
|||
for _ in 0..self.workers.len() {
|
||||
match self.port.recv().unwrap() {
|
||||
SupervisorMsg::ReturnDeque(index, deque) => self.workers[index].deque = Some(deque),
|
||||
SupervisorMsg::HeapSizeOfTLS(_) => panic!("unexpected HeapSizeOfTLS message"),
|
||||
SupervisorMsg::Finished => panic!("unexpected finished message!"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Synchronously measure memory usage of any thread-local storage.
|
||||
pub fn heap_size_of_tls(&self, f: fn() -> usize) -> Vec<usize> {
|
||||
// Tell the workers to measure themselves.
|
||||
for worker in self.workers.iter() {
|
||||
worker.chan.send(WorkerMsg::HeapSizeOfTLS(f)).unwrap()
|
||||
}
|
||||
|
||||
// Wait for the workers to finish measuring themselves.
|
||||
let mut sizes = vec![];
|
||||
for _ in 0..self.workers.len() {
|
||||
match self.port.recv().unwrap() {
|
||||
SupervisorMsg::HeapSizeOfTLS(size) => {
|
||||
sizes.push(size);
|
||||
}
|
||||
_ => panic!("unexpected message!"),
|
||||
}
|
||||
}
|
||||
sizes
|
||||
}
|
||||
|
||||
pub fn shutdown(&mut self) {
|
||||
for worker in self.workers.iter() {
|
||||
worker.chan.send(WorkerMsg::Exit).unwrap()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue