fonts: Add MallocSizeOf implementation for FontContext (#32206)

* fonts: Add `MallocSizeOf` implementation for `FontContext`

Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
Signed-off-by: Martin Robinson <mrobinson@igalia.com>

* android: remove unused imports in font_list.rs

Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com>

---------

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com>
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
This commit is contained in:
Martin Robinson 2024-05-03 11:54:29 +02:00 committed by GitHub
parent 160c7c0b0f
commit 1c9120c293
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 119 additions and 25 deletions

1
Cargo.lock generated
View file

@ -1993,6 +1993,7 @@ dependencies = [
"libc", "libc",
"log", "log",
"malloc_size_of", "malloc_size_of",
"malloc_size_of_derive",
"net_traits", "net_traits",
"parking_lot", "parking_lot",
"range", "range",

View file

@ -28,6 +28,7 @@ lazy_static = { workspace = true }
libc = { workspace = true } libc = { workspace = true }
log = { workspace = true } log = { workspace = true }
malloc_size_of = { workspace = true } malloc_size_of = { workspace = true }
malloc_size_of_derive = { workspace = true }
net_traits = { workspace = true } net_traits = { workspace = true }
parking_lot = { workspace = true } parking_lot = { workspace = true }
range = { path = "../range" } range = { path = "../range" }

View file

@ -13,6 +13,7 @@ use app_units::Au;
use bitflags::bitflags; use bitflags::bitflags;
use euclid::default::{Point2D, Rect, Size2D}; use euclid::default::{Point2D, Rect, Size2D};
use log::debug; use log::debug;
use malloc_size_of_derive::MallocSizeOf;
use parking_lot::RwLock; use parking_lot::RwLock;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use servo_atoms::{atom, Atom}; use servo_atoms::{atom, Atom};
@ -116,7 +117,7 @@ pub trait FontTableMethods {
fn buffer(&self) -> &[u8]; fn buffer(&self) -> &[u8];
} }
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] #[derive(Clone, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub struct FontMetrics { pub struct FontMetrics {
pub underline_size: Au, pub underline_size: Au,
pub underline_offset: Au, pub underline_offset: Au,
@ -161,7 +162,7 @@ impl FontMetrics {
/// template at a particular size, with a particular font-variant-caps applied, etc. This contrasts /// template at a particular size, with a particular font-variant-caps applied, etc. This contrasts
/// with `FontTemplateDescriptor` in that the latter represents only the parameters inherent in the /// with `FontTemplateDescriptor` in that the latter represents only the parameters inherent in the
/// font data (weight, stretch, etc.). /// font data (weight, stretch, etc.).
#[derive(Clone, Debug, Deserialize, Hash, PartialEq, Serialize)] #[derive(Clone, Debug, Deserialize, Hash, MallocSizeOf, PartialEq, Serialize)]
pub struct FontDescriptor { pub struct FontDescriptor {
pub weight: FontWeight, pub weight: FontWeight,
pub stretch: FontStretch, pub stretch: FontStretch,
@ -191,6 +192,19 @@ struct CachedShapeData {
shaped_text: HashMap<ShapeCacheEntry, Arc<GlyphStore>>, shaped_text: HashMap<ShapeCacheEntry, Arc<GlyphStore>>,
} }
impl malloc_size_of::MallocSizeOf for CachedShapeData {
fn size_of(&self, ops: &mut malloc_size_of::MallocSizeOfOps) -> usize {
// Estimate the size of the shaped text cache. This will be smaller, because
// HashMap has some overhead, but we are mainly interested in the actual data.
let shaped_text_size = self
.shaped_text
.iter()
.map(|(key, value)| key.size_of(ops) + (*value).size_of(ops))
.sum::<usize>();
self.glyph_advances.size_of(ops) + self.glyph_indices.size_of(ops) + shaped_text_size
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct Font { pub struct Font {
pub handle: PlatformFont, pub handle: PlatformFont,
@ -207,6 +221,17 @@ pub struct Font {
pub synthesized_small_caps: Option<FontRef>, pub synthesized_small_caps: Option<FontRef>,
} }
impl malloc_size_of::MallocSizeOf for Font {
fn size_of(&self, ops: &mut malloc_size_of::MallocSizeOfOps) -> usize {
// TODO: Collect memory usage for platform fonts and for shapers.
// This skips the template, because they are already stored in the template cache.
self.metrics.size_of(ops) +
self.descriptor.size_of(ops) +
self.cached_shape_data.read().size_of(ops) +
self.font_key.size_of(ops)
}
}
impl Font { impl Font {
pub fn new( pub fn new(
template: FontTemplateRef, template: FontTemplateRef,
@ -428,10 +453,11 @@ pub type FontRef = Arc<Font>;
/// A `FontGroup` is a prioritised list of fonts for a given set of font styles. It is used by /// A `FontGroup` is a prioritised list of fonts for a given set of font styles. It is used by
/// `TextRun` to decide which font to render a character with. If none of the fonts listed in the /// `TextRun` to decide which font to render a character with. If none of the fonts listed in the
/// styles are suitable, a fallback font may be used. /// styles are suitable, a fallback font may be used.
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
pub struct FontGroup { pub struct FontGroup {
descriptor: FontDescriptor, descriptor: FontDescriptor,
families: SmallVec<[FontGroupFamily; 8]>, families: SmallVec<[FontGroupFamily; 8]>,
#[ignore_malloc_size_of = "This measured in the FontContext font cache."]
last_matching_fallback: Option<FontRef>, last_matching_fallback: Option<FontRef>,
} }
@ -584,9 +610,11 @@ impl FontGroup {
/// `unicode-range` descriptors. In this case, font selection will select a single member /// `unicode-range` descriptors. In this case, font selection will select a single member
/// that contains the necessary unicode character. Unicode ranges are specified by the /// that contains the necessary unicode character. Unicode ranges are specified by the
/// [`FontGroupFamilyMember::template`] member. /// [`FontGroupFamilyMember::template`] member.
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
struct FontGroupFamilyMember { struct FontGroupFamilyMember {
#[ignore_malloc_size_of = "This measured in the FontContext template cache."]
template: FontTemplateRef, template: FontTemplateRef,
#[ignore_malloc_size_of = "This measured in the FontContext font cache."]
font: Option<FontRef>, font: Option<FontRef>,
loaded: bool, loaded: bool,
} }
@ -595,7 +623,7 @@ struct FontGroupFamilyMember {
/// families listed in the `font-family` CSS property. The corresponding font data is lazy-loaded, /// families listed in the `font-family` CSS property. The corresponding font data is lazy-loaded,
/// only if actually needed. A single `FontGroupFamily` can have multiple fonts, in the case that /// only if actually needed. A single `FontGroupFamily` can have multiple fonts, in the case that
/// individual fonts only cover part of the Unicode range. /// individual fonts only cover part of the Unicode range.
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
struct FontGroupFamily { struct FontGroupFamily {
family_descriptor: FontFamilyDescriptor, family_descriptor: FontFamilyDescriptor,
members: Option<Vec<FontGroupFamilyMember>>, members: Option<Vec<FontGroupFamilyMember>>,
@ -700,7 +728,7 @@ pub fn get_and_reset_text_shaping_performance_counter() -> usize {
} }
/// The scope within which we will look for a font. /// The scope within which we will look for a font.
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] #[derive(Clone, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
pub enum FontSearchScope { pub enum FontSearchScope {
/// All fonts will be searched, including those specified via `@font-face` rules. /// All fonts will be searched, including those specified via `@font-face` rules.
Any, Any,
@ -710,7 +738,7 @@ pub enum FontSearchScope {
} }
/// A font family name used in font selection. /// A font family name used in font selection.
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] #[derive(Clone, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
pub enum FontFamilyName { pub enum FontFamilyName {
/// A specific name such as `"Arial"` /// A specific name such as `"Arial"`
Specific(Atom), Specific(Atom),
@ -755,7 +783,7 @@ impl<'a> From<&'a str> for FontFamilyName {
} }
/// The font family parameters for font selection. /// The font family parameters for font selection.
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] #[derive(Clone, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
pub struct FontFamilyDescriptor { pub struct FontFamilyDescriptor {
pub name: FontFamilyName, pub name: FontFamilyName,
pub scope: FontSearchScope, pub scope: FontSearchScope,

View file

@ -13,6 +13,7 @@ use atomic_refcell::AtomicRefCell;
use gfx_traits::WebrenderApi; use gfx_traits::WebrenderApi;
use ipc_channel::ipc::{self, IpcBytesSender, IpcReceiver, IpcSender}; use ipc_channel::ipc::{self, IpcBytesSender, IpcReceiver, IpcSender};
use log::{debug, trace}; use log::{debug, trace};
use malloc_size_of_derive::MallocSizeOf;
use net_traits::request::{Destination, Referrer, RequestBuilder}; use net_traits::request::{Destination, Referrer, RequestBuilder};
use net_traits::{fetch_async, CoreResourceThread, FetchResponseMsg}; use net_traits::{fetch_async, CoreResourceThread, FetchResponseMsg};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -46,7 +47,7 @@ pub struct FontTemplates {
templates: Vec<FontTemplateRef>, templates: Vec<FontTemplateRef>,
} }
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] #[derive(Clone, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
pub enum FontIdentifier { pub enum FontIdentifier {
Local(LocalFontIdentifier), Local(LocalFontIdentifier),
Web(ServoUrl), Web(ServoUrl),

View file

@ -10,6 +10,8 @@ use std::sync::Arc;
use app_units::Au; use app_units::Au;
use fnv::FnvHasher; use fnv::FnvHasher;
use log::debug; use log::debug;
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use malloc_size_of_derive::MallocSizeOf;
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use servo_arc::Arc as ServoArc; use servo_arc::Arc as ServoArc;
use style::computed_values::font_variant_caps::T as FontVariantCaps; use style::computed_values::font_variant_caps::T as FontVariantCaps;
@ -55,6 +57,39 @@ pub struct FontContext<S: FontSource> {
RwLock<HashMap<FontGroupCacheKey, Arc<RwLock<FontGroup>>, BuildHasherDefault<FnvHasher>>>, RwLock<HashMap<FontGroupCacheKey, Arc<RwLock<FontGroup>>, BuildHasherDefault<FnvHasher>>>,
} }
impl<S: FontSource> MallocSizeOf for FontContext<S> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
let font_cache_size = self
.font_cache
.read()
.iter()
.map(|(key, font)| {
key.size_of(ops) + font.as_ref().map_or(0, |font| (*font).size_of(ops))
})
.sum::<usize>();
let font_template_cache_size = self
.font_template_cache
.read()
.iter()
.map(|(key, templates)| {
let templates_size = templates
.iter()
.map(|template| template.borrow().size_of(ops))
.sum::<usize>();
key.size_of(ops) + templates_size
})
.sum::<usize>();
let font_group_cache_size = self
.font_group_cache
.read()
.iter()
.map(|(key, font_group)| key.size_of(ops) + (*font_group.read()).size_of(ops))
.sum::<usize>();
font_cache_size + font_template_cache_size + font_group_cache_size
}
}
impl<S: FontSource> FontContext<S> { impl<S: FontSource> FontContext<S> {
pub fn new(font_source: S) -> FontContext<S> { pub fn new(font_source: S) -> FontContext<S> {
#[allow(clippy::default_constructed_unit_structs)] #[allow(clippy::default_constructed_unit_structs)]
@ -226,20 +261,21 @@ impl<S: FontSource> FontContext<S> {
} }
} }
#[derive(Debug, Eq, Hash, PartialEq)] #[derive(Debug, Eq, Hash, MallocSizeOf, PartialEq)]
struct FontCacheKey { struct FontCacheKey {
font_identifier: FontIdentifier, font_identifier: FontIdentifier,
font_descriptor: FontDescriptor, font_descriptor: FontDescriptor,
} }
#[derive(Debug, Eq, Hash, PartialEq)] #[derive(Debug, Eq, Hash, MallocSizeOf, PartialEq)]
struct FontTemplateCacheKey { struct FontTemplateCacheKey {
font_descriptor: FontDescriptor, font_descriptor: FontDescriptor,
family_descriptor: FontFamilyDescriptor, family_descriptor: FontFamilyDescriptor,
} }
#[derive(Debug)] #[derive(Debug, MallocSizeOf)]
struct FontGroupCacheKey { struct FontGroupCacheKey {
#[ignore_malloc_size_of = "This is also stored as part of styling."]
style: ServoArc<FontStyleStruct>, style: ServoArc<FontStyleStruct>,
size: Au, size: Au,
} }

View file

@ -7,6 +7,7 @@ use std::ops::RangeInclusive;
use std::sync::Arc; use std::sync::Arc;
use atomic_refcell::AtomicRefCell; use atomic_refcell::AtomicRefCell;
use malloc_size_of_derive::MallocSizeOf;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use servo_url::ServoUrl; use servo_url::ServoUrl;
use style::computed_values::font_stretch::T as FontStretch; use style::computed_values::font_stretch::T as FontStretch;
@ -27,11 +28,12 @@ pub type FontTemplateRef = Arc<AtomicRefCell<FontTemplate>>;
/// to be expanded or refactored when we support more of the font styling parameters. /// to be expanded or refactored when we support more of the font styling parameters.
/// ///
/// NB: If you change this, you will need to update `style::properties::compute_font_hash()`. /// NB: If you change this, you will need to update `style::properties::compute_font_hash()`.
#[derive(Clone, Debug, Deserialize, Hash, PartialEq, Serialize)] #[derive(Clone, Debug, Deserialize, Hash, MallocSizeOf, PartialEq, Serialize)]
pub struct FontTemplateDescriptor { pub struct FontTemplateDescriptor {
pub weight: (FontWeight, FontWeight), pub weight: (FontWeight, FontWeight),
pub stretch: (FontStretch, FontStretch), pub stretch: (FontStretch, FontStretch),
pub style: (FontStyle, FontStyle), pub style: (FontStyle, FontStyle),
#[ignore_malloc_size_of = "MallocSizeOf does not yet support RangeInclusive"]
pub unicode_range: Option<Vec<RangeInclusive<u32>>>, pub unicode_range: Option<Vec<RangeInclusive<u32>>>,
} }
@ -134,6 +136,14 @@ pub struct FontTemplate {
pub data: Option<Arc<Vec<u8>>>, pub data: Option<Arc<Vec<u8>>>,
} }
impl malloc_size_of::MallocSizeOf for FontTemplate {
fn size_of(&self, ops: &mut malloc_size_of::MallocSizeOfOps) -> usize {
self.identifier.size_of(ops) +
self.descriptor.size_of(ops) +
self.data.as_ref().map_or(0, |data| (*data).size_of(ops))
}
}
impl Debug for FontTemplate { impl Debug for FontTemplate {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
self.identifier.fmt(f) self.identifier.fmt(f)

View file

@ -4,16 +4,16 @@
use std::fs::File; use std::fs::File;
use std::io::Read; use std::io::Read;
use std::path::{Path, PathBuf}; use std::path::Path;
use log::warn; use log::warn;
use malloc_size_of_derive::MallocSizeOf;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use style::values::computed::{ use style::values::computed::{
FontStretch as StyleFontStretch, FontStyle as StyleFontStyle, FontWeight as StyleFontWeight, FontStretch as StyleFontStretch, FontStyle as StyleFontStyle, FontWeight as StyleFontWeight,
}; };
use style::Atom; use style::Atom;
use ucd::{Codepoint, UnicodeBlock}; use ucd::{Codepoint, UnicodeBlock};
use webrender_api::NativeFontHandle;
use super::xml::{Attribute, Node}; use super::xml::{Attribute, Node};
use crate::font_template::{FontTemplate, FontTemplateDescriptor}; use crate::font_template::{FontTemplate, FontTemplateDescriptor};
@ -24,7 +24,7 @@ lazy_static::lazy_static! {
} }
/// An identifier for a local font on Android systems. /// An identifier for a local font on Android systems.
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] #[derive(Clone, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
pub struct LocalFontIdentifier { pub struct LocalFontIdentifier {
/// The path to the font. /// The path to the font.
pub path: Atom, pub path: Atom,

View file

@ -24,6 +24,7 @@ use fontconfig_sys::{
}; };
use libc::{c_char, c_int}; use libc::{c_char, c_int};
use log::debug; use log::debug;
use malloc_size_of_derive::MallocSizeOf;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use style::values::computed::{FontStretch, FontStyle, FontWeight}; use style::values::computed::{FontStretch, FontStyle, FontWeight};
use style::Atom; use style::Atom;
@ -34,7 +35,7 @@ use crate::font_template::{FontTemplate, FontTemplateDescriptor};
use crate::text::util::is_cjk; use crate::text::util::is_cjk;
/// An identifier for a local font on systems using Freetype. /// An identifier for a local font on systems using Freetype.
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] #[derive(Clone, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
pub struct LocalFontIdentifier { pub struct LocalFontIdentifier {
/// The path to the font. /// The path to the font.
pub path: Atom, pub path: Atom,

View file

@ -7,6 +7,7 @@ use std::io::Read;
use std::path::Path; use std::path::Path;
use log::debug; use log::debug;
use malloc_size_of_derive::MallocSizeOf;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use style::Atom; use style::Atom;
use ucd::{Codepoint, UnicodeBlock}; use ucd::{Codepoint, UnicodeBlock};
@ -20,7 +21,7 @@ use crate::text::util::unicode_plane;
/// An identifier for a local font on a MacOS system. These values comes from the CoreText /// An identifier for a local font on a MacOS system. These values comes from the CoreText
/// CTFontCollection. Note that `path` here is required. We do not load fonts that do not /// CTFontCollection. Note that `path` here is required. We do not load fonts that do not
/// have paths. /// have paths.
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] #[derive(Clone, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
pub struct LocalFontIdentifier { pub struct LocalFontIdentifier {
pub postscript_name: Atom, pub postscript_name: Atom,
pub path: Atom, pub path: Atom,

View file

@ -6,6 +6,7 @@ use std::hash::Hash;
use std::sync::Arc; use std::sync::Arc;
use dwrote::{Font, FontCollection, FontDescriptor, FontStretch, FontStyle}; use dwrote::{Font, FontCollection, FontDescriptor, FontStretch, FontStyle};
use malloc_size_of_derive::MallocSizeOf;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use style::values::computed::{FontStyle as StyleFontStyle, FontWeight as StyleFontWeight}; use style::values::computed::{FontStyle as StyleFontStyle, FontWeight as StyleFontWeight};
use style::values::specified::font::FontStretchKeyword; use style::values::specified::font::FontStretchKeyword;
@ -31,9 +32,10 @@ where
} }
/// An identifier for a local font on a Windows system. /// An identifier for a local font on a Windows system.
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] #[derive(Clone, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub struct LocalFontIdentifier { pub struct LocalFontIdentifier {
/// The FontDescriptor of this font. /// The FontDescriptor of this font.
#[ignore_malloc_size_of = "dwrote does not support MallocSizeOf"]
pub font_descriptor: Arc<FontDescriptor>, pub font_descriptor: Arc<FontDescriptor>,
} }

View file

@ -10,6 +10,7 @@ use app_units::Au;
use euclid::default::Point2D; use euclid::default::Point2D;
pub use gfx_traits::ByteIndex; pub use gfx_traits::ByteIndex;
use log::debug; use log::debug;
use malloc_size_of_derive::MallocSizeOf;
use range::{self, EachIndex, Range, RangeIndex}; use range::{self, EachIndex, Range, RangeIndex};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -21,7 +22,7 @@ use serde::{Deserialize, Serialize};
/// In the uncommon case (multiple glyphs per unicode character, large glyph index/advance, or /// In the uncommon case (multiple glyphs per unicode character, large glyph index/advance, or
/// glyph offsets), we pack the glyph count into GlyphEntry, and store the other glyph information /// glyph offsets), we pack the glyph count into GlyphEntry, and store the other glyph information
/// in DetailedGlyphStore. /// in DetailedGlyphStore.
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] #[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub struct GlyphEntry { pub struct GlyphEntry {
value: u32, value: u32,
} }
@ -145,7 +146,7 @@ impl GlyphEntry {
// Stores data for a detailed glyph, in the case that several glyphs // Stores data for a detailed glyph, in the case that several glyphs
// correspond to one character, or the glyph's data couldn't be packed. // correspond to one character, or the glyph's data couldn't be packed.
#[derive(Clone, Copy, Debug, Deserialize, Serialize)] #[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, Serialize)]
struct DetailedGlyph { struct DetailedGlyph {
id: GlyphId, id: GlyphId,
// glyph's advance, in the text's direction (LTR or RTL) // glyph's advance, in the text's direction (LTR or RTL)
@ -164,7 +165,7 @@ impl DetailedGlyph {
} }
} }
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)] #[derive(Clone, Copy, Debug, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)]
struct DetailedGlyphRecord { struct DetailedGlyphRecord {
// source string offset/GlyphEntry offset in the TextRun // source string offset/GlyphEntry offset in the TextRun
entry_offset: ByteIndex, entry_offset: ByteIndex,
@ -188,7 +189,7 @@ impl PartialOrd for DetailedGlyphRecord {
// until a lookup is actually performed; this matches the expected // until a lookup is actually performed; this matches the expected
// usage pattern of setting/appending all the detailed glyphs, and // usage pattern of setting/appending all the detailed glyphs, and
// then querying without setting. // then querying without setting.
#[derive(Clone, Deserialize, Serialize)] #[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
struct DetailedGlyphStore { struct DetailedGlyphStore {
// TODO(pcwalton): Allocation of this buffer is expensive. Consider a small-vector // TODO(pcwalton): Allocation of this buffer is expensive. Consider a small-vector
// optimization. // optimization.
@ -416,7 +417,7 @@ impl<'a> GlyphInfo<'a> {
/// | +---+---+ | /// | +---+---+ |
/// +---------------------------------------------+ /// +---------------------------------------------+
/// ~~~ /// ~~~
#[derive(Clone, Deserialize, Serialize)] #[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
pub struct GlyphStore { pub struct GlyphStore {
// TODO(pcwalton): Allocation of this buffer is expensive. Consider a small-vector // TODO(pcwalton): Allocation of this buffer is expensive. Consider a small-vector
// optimization. // optimization.

View file

@ -530,6 +530,12 @@ impl Layout for LayoutThread {
kind: ReportKind::ExplicitJemallocHeapSize, kind: ReportKind::ExplicitJemallocHeapSize,
size: self.stylist.size_of(&mut ops), size: self.stylist.size_of(&mut ops),
}); });
reports.push(Report {
path: path![formatted_url, "layout-thread", "font-context"],
kind: ReportKind::ExplicitJemallocHeapSize,
size: self.font_context.size_of(&mut ops),
});
} }
fn reflow(&mut self, script_reflow: script_layout_interface::ScriptReflow) { fn reflow(&mut self, script_reflow: script_layout_interface::ScriptReflow) {

View file

@ -425,7 +425,7 @@ impl Layout for LayoutThread {
// malloc_enclosing_size_of function. // malloc_enclosing_size_of function.
let mut ops = MallocSizeOfOps::new(servo_allocator::usable_size, None, None); let mut ops = MallocSizeOfOps::new(servo_allocator::usable_size, None, None);
// FIXME(njn): Just measuring the display tree for now. // TODO: Measure more than just display list, stylist, and font context.
let formatted_url = &format!("url({})", self.url); let formatted_url = &format!("url({})", self.url);
reports.push(Report { reports.push(Report {
path: path![formatted_url, "layout-thread", "display-list"], path: path![formatted_url, "layout-thread", "display-list"],
@ -438,6 +438,12 @@ impl Layout for LayoutThread {
kind: ReportKind::ExplicitJemallocHeapSize, kind: ReportKind::ExplicitJemallocHeapSize,
size: self.stylist.size_of(&mut ops), size: self.stylist.size_of(&mut ops),
}); });
reports.push(Report {
path: path![formatted_url, "layout-thread", "font-context"],
kind: ReportKind::ExplicitJemallocHeapSize,
size: self.font_context.size_of(&mut ops),
});
} }
fn set_quirks_mode(&mut self, quirks_mode: QuirksMode) { fn set_quirks_mode(&mut self, quirks_mode: QuirksMode) {