mirror of
https://github.com/servo/servo.git
synced 2025-08-07 22:45:34 +01:00
Various memory measurement improvements (#36834)
The two significant changes here are 1) a commit that frees memory used to perform memory reporting once the reporting is complete, 2) memory reporting for the system font service. There are various other commits that remove `#[ignore_malloc_size_of]` attributes for data that we are now able to measure, but they do not significantly change our measurements when testing servo.org. Testing: Comparing the output of about:memory on servo.org. --------- Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
parent
e9f364ef51
commit
ba8f923201
19 changed files with 135 additions and 49 deletions
|
@ -38,6 +38,7 @@ memmap2 = { workspace = true }
|
|||
net_traits = { workspace = true }
|
||||
num-traits = { workspace = true }
|
||||
parking_lot = { workspace = true }
|
||||
profile_traits = { workspace = true }
|
||||
range = { path = "../range" }
|
||||
serde = { workspace = true }
|
||||
servo_arc = { workspace = true }
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use atomic_refcell::AtomicRefCell;
|
||||
use log::warn;
|
||||
use malloc_size_of_derive::MallocSizeOf;
|
||||
use parking_lot::RwLock;
|
||||
use style::stylesheets::DocumentStyleSheet;
|
||||
use style::values::computed::{FontStyle, FontWeight};
|
||||
|
@ -15,7 +15,7 @@ use crate::font::FontDescriptor;
|
|||
use crate::font_template::{FontTemplate, FontTemplateRef, FontTemplateRefMethods, IsOblique};
|
||||
use crate::system_font_service::{FontIdentifier, LowercaseFontFamilyName};
|
||||
|
||||
#[derive(Default)]
|
||||
#[derive(Default, MallocSizeOf)]
|
||||
pub struct FontStore {
|
||||
pub(crate) families: HashMap<LowercaseFontFamilyName, FontTemplates>,
|
||||
web_fonts_loading_for_stylesheets: Vec<(DocumentStyleSheet, usize)>,
|
||||
|
@ -134,7 +134,7 @@ impl FontStore {
|
|||
///
|
||||
/// This optimization is taken from:
|
||||
/// <https://searchfox.org/mozilla-central/source/gfx/thebes/gfxFontEntry.cpp>.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
#[derive(Clone, Debug, Default, MallocSizeOf)]
|
||||
struct SimpleFamily {
|
||||
regular: Option<FontTemplateRef>,
|
||||
bold: Option<FontTemplateRef>,
|
||||
|
@ -190,7 +190,7 @@ impl SimpleFamily {
|
|||
}
|
||||
}
|
||||
/// A list of font templates that make up a given font family.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, MallocSizeOf)]
|
||||
pub struct FontTemplates {
|
||||
pub(crate) templates: Vec<FontTemplateRef>,
|
||||
simple_family: Option<SimpleFamily>,
|
||||
|
@ -263,7 +263,7 @@ impl FontTemplates {
|
|||
}
|
||||
}
|
||||
|
||||
let new_template = Arc::new(AtomicRefCell::new(new_template));
|
||||
let new_template = FontTemplateRef::new(new_template);
|
||||
self.templates.push(new_template.clone());
|
||||
self.update_simple_family(new_template);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::fmt::{Debug, Error, Formatter};
|
||||
use std::ops::RangeInclusive;
|
||||
use std::ops::{Deref, RangeInclusive};
|
||||
use std::sync::Arc;
|
||||
|
||||
use atomic_refcell::AtomicRefCell;
|
||||
|
@ -20,7 +20,21 @@ use crate::system_font_service::{
|
|||
};
|
||||
|
||||
/// A reference to a [`FontTemplate`] with shared ownership and mutability.
|
||||
pub type FontTemplateRef = Arc<AtomicRefCell<FontTemplate>>;
|
||||
#[derive(Clone, Debug, MallocSizeOf)]
|
||||
pub struct FontTemplateRef(#[conditional_malloc_size_of] Arc<AtomicRefCell<FontTemplate>>);
|
||||
|
||||
impl FontTemplateRef {
|
||||
pub fn new(template: FontTemplate) -> Self {
|
||||
Self(Arc::new(AtomicRefCell::new(template)))
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for FontTemplateRef {
|
||||
type Target = Arc<AtomicRefCell<FontTemplate>>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes how to select a font from a given family. This is very basic at the moment and needs
|
||||
/// to be expanded or refactored when we support more of the font styling parameters.
|
||||
|
|
|
@ -6,16 +6,19 @@ use std::borrow::ToOwned;
|
|||
use std::cell::OnceCell;
|
||||
use std::collections::HashMap;
|
||||
use std::ops::{Deref, RangeInclusive};
|
||||
use std::sync::Arc;
|
||||
use std::{fmt, thread};
|
||||
|
||||
use app_units::Au;
|
||||
use atomic_refcell::AtomicRefCell;
|
||||
use compositing_traits::CrossProcessCompositorApi;
|
||||
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||
use log::debug;
|
||||
use malloc_size_of::MallocSizeOf as MallocSizeOfTrait;
|
||||
use malloc_size_of_derive::MallocSizeOf;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use profile_traits::mem::{
|
||||
ProcessReports, ProfilerChan, Report, ReportKind, ReportsChan, perform_memory_report,
|
||||
};
|
||||
use profile_traits::path;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use servo_config::pref;
|
||||
use servo_url::ServoUrl;
|
||||
|
@ -66,11 +69,12 @@ pub enum SystemFontServiceMessage {
|
|||
),
|
||||
GetFontKey(IpcSender<FontKey>),
|
||||
GetFontInstanceKey(IpcSender<FontInstanceKey>),
|
||||
CollectMemoryReport(ReportsChan),
|
||||
Exit(IpcSender<()>),
|
||||
Ping,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
#[derive(Default, MallocSizeOf)]
|
||||
struct ResolvedGenericFontFamilies {
|
||||
default: OnceCell<LowercaseFontFamilyName>,
|
||||
serif: OnceCell<LowercaseFontFamilyName>,
|
||||
|
@ -84,6 +88,7 @@ struct ResolvedGenericFontFamilies {
|
|||
/// The system font service. There is one of these for every Servo instance. This is a thread,
|
||||
/// responsible for reading the list of system fonts, handling requests to match against
|
||||
/// them, and ensuring that only one copy of system font data is loaded at a time.
|
||||
#[derive(MallocSizeOf)]
|
||||
pub struct SystemFontService {
|
||||
port: IpcReceiver<SystemFontServiceMessage>,
|
||||
local_families: FontStore,
|
||||
|
@ -118,8 +123,12 @@ impl SystemFontServiceProxySender {
|
|||
}
|
||||
|
||||
impl SystemFontService {
|
||||
pub fn spawn(compositor_api: CrossProcessCompositorApi) -> SystemFontServiceProxySender {
|
||||
pub fn spawn(
|
||||
compositor_api: CrossProcessCompositorApi,
|
||||
memory_profiler_sender: ProfilerChan,
|
||||
) -> SystemFontServiceProxySender {
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
let memory_reporter_sender = sender.clone();
|
||||
|
||||
thread::Builder::new()
|
||||
.name("SystemFontService".to_owned())
|
||||
|
@ -138,7 +147,13 @@ impl SystemFontService {
|
|||
|
||||
cache.fetch_new_keys();
|
||||
cache.refresh_local_families();
|
||||
cache.run();
|
||||
|
||||
memory_profiler_sender.run_with_memory_reporting(
|
||||
|| cache.run(),
|
||||
"system-fonts".to_owned(),
|
||||
memory_reporter_sender,
|
||||
SystemFontServiceMessage::CollectMemoryReport,
|
||||
);
|
||||
})
|
||||
.expect("Thread spawning failed");
|
||||
|
||||
|
@ -172,6 +187,9 @@ impl SystemFontService {
|
|||
self.fetch_new_keys();
|
||||
let _ = result_sender.send(self.free_font_instance_keys.pop().unwrap());
|
||||
},
|
||||
SystemFontServiceMessage::CollectMemoryReport(report_sender) => {
|
||||
self.collect_memory_report(report_sender);
|
||||
},
|
||||
SystemFontServiceMessage::Ping => (),
|
||||
SystemFontServiceMessage::Exit(result) => {
|
||||
let _ = result.send(());
|
||||
|
@ -181,6 +199,17 @@ impl SystemFontService {
|
|||
}
|
||||
}
|
||||
|
||||
fn collect_memory_report(&self, report_sender: ReportsChan) {
|
||||
perform_memory_report(|ops| {
|
||||
let reports = vec![Report {
|
||||
path: path!["system-fonts"],
|
||||
kind: ReportKind::ExplicitSystemHeapSize,
|
||||
size: self.size_of(ops),
|
||||
}];
|
||||
report_sender.send(ProcessReports::new(reports));
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(skip_all, fields(servo_profiling = true), level = "trace")
|
||||
|
@ -528,11 +557,7 @@ impl SystemFontServiceProxy {
|
|||
panic!("SystemFontService has already exited.");
|
||||
};
|
||||
|
||||
let templates: Vec<_> = templates
|
||||
.into_iter()
|
||||
.map(AtomicRefCell::new)
|
||||
.map(Arc::new)
|
||||
.collect();
|
||||
let templates: Vec<_> = templates.into_iter().map(FontTemplateRef::new).collect();
|
||||
self.templates.write().insert(cache_key, templates.clone());
|
||||
|
||||
templates
|
||||
|
|
|
@ -5,14 +5,13 @@
|
|||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use app_units::Au;
|
||||
use euclid::num::Zero;
|
||||
use fonts::platform::font::PlatformFont;
|
||||
use fonts::{
|
||||
Font, FontData, FontDescriptor, FontIdentifier, FontTemplate, PlatformFontMethods,
|
||||
ShapingFlags, ShapingOptions,
|
||||
Font, FontData, FontDescriptor, FontIdentifier, FontTemplate, FontTemplateRef,
|
||||
PlatformFontMethods, ShapingFlags, ShapingOptions,
|
||||
};
|
||||
use servo_url::ServoUrl;
|
||||
use style::properties::longhands::font_variant_caps::computed_value::T as FontVariantCaps;
|
||||
|
@ -42,13 +41,7 @@ fn make_font(path: PathBuf) -> Font {
|
|||
variant: FontVariantCaps::Normal,
|
||||
pt_size: Au::from_px(24),
|
||||
};
|
||||
Font::new(
|
||||
Arc::new(atomic_refcell::AtomicRefCell::new(template)),
|
||||
descriptor,
|
||||
Some(data),
|
||||
None,
|
||||
)
|
||||
.unwrap()
|
||||
Font::new(FontTemplateRef::new(template), descriptor, Some(data), None).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -137,6 +137,7 @@ mod font_context {
|
|||
break;
|
||||
},
|
||||
SystemFontServiceMessage::Ping => {},
|
||||
SystemFontServiceMessage::CollectMemoryReport(..) => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue