style: Move ExtraStyleData into CascadeData.

It logically belongs there, and the only reason it wasn't there before we were
working around it.

MozReview-Commit-ID: 5a5iksHAIdN
Signed-off-by: Emilio Cobos Álvarez <emilio@crisal.io>
This commit is contained in:
Emilio Cobos Álvarez 2017-09-13 17:07:13 +02:00
parent d461347adf
commit 541977efb3
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
4 changed files with 69 additions and 42 deletions

View file

@ -1198,11 +1198,9 @@ impl LayoutThread {
self.stylist.force_stylesheet_origins_dirty(Origin::Author.into()); self.stylist.force_stylesheet_origins_dirty(Origin::Author.into());
} }
let mut extra_data = Default::default();
self.stylist.flush( self.stylist.flush(
&guards, &guards,
Some(ua_stylesheets), Some(ua_stylesheets),
&mut extra_data,
Some(element), Some(element),
); );
} }

View file

@ -12,13 +12,13 @@ use gecko_bindings::structs::{StyleSheetInfo, ServoStyleSheetInner};
use gecko_bindings::structs::nsIDocument; use gecko_bindings::structs::nsIDocument;
use gecko_bindings::sugar::ownership::{HasArcFFI, HasBoxFFI, HasFFI, HasSimpleFFI}; use gecko_bindings::sugar::ownership::{HasArcFFI, HasBoxFFI, HasFFI, HasSimpleFFI};
use invalidation::media_queries::{MediaListKey, ToMediaListKey}; use invalidation::media_queries::{MediaListKey, ToMediaListKey};
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; use malloc_size_of::MallocSizeOfOps;
use media_queries::{Device, MediaList}; use media_queries::{Device, MediaList};
use properties::ComputedValues; use properties::ComputedValues;
use servo_arc::Arc; use servo_arc::Arc;
use shared_lock::{Locked, StylesheetGuards, SharedRwLockReadGuard}; use shared_lock::{Locked, StylesheetGuards, SharedRwLockReadGuard};
use stylesheets::{PerOrigin, StylesheetContents, StylesheetInDocument}; use stylesheets::{StylesheetContents, StylesheetInDocument};
use stylist::{ExtraStyleData, Stylist}; use stylist::Stylist;
/// Little wrapper to a Gecko style sheet. /// Little wrapper to a Gecko style sheet.
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
@ -113,9 +113,6 @@ impl StylesheetInDocument for GeckoStyleSheet {
pub struct PerDocumentStyleDataImpl { pub struct PerDocumentStyleDataImpl {
/// Rule processor. /// Rule processor.
pub stylist: Stylist, pub stylist: Stylist,
/// List of effective @font-face and @counter-style rules.
pub extra_style_data: PerOrigin<ExtraStyleData>,
} }
/// The data itself is an `AtomicRefCell`, which guarantees the proper semantics /// The data itself is an `AtomicRefCell`, which guarantees the proper semantics
@ -132,7 +129,6 @@ impl PerDocumentStyleData {
PerDocumentStyleData(AtomicRefCell::new(PerDocumentStyleDataImpl { PerDocumentStyleData(AtomicRefCell::new(PerDocumentStyleDataImpl {
stylist: Stylist::new(device, quirks_mode.into()), stylist: Stylist::new(device, quirks_mode.into()),
extra_style_data: Default::default(),
})) }))
} }
@ -160,7 +156,6 @@ impl PerDocumentStyleDataImpl {
self.stylist.flush( self.stylist.flush(
&StylesheetGuards::same(guard), &StylesheetGuards::same(guard),
/* ua_sheets = */ None, /* ua_sheets = */ None,
&mut self.extra_style_data,
document_element, document_element,
) )
} }
@ -189,7 +184,6 @@ impl PerDocumentStyleDataImpl {
/// Measure heap usage. /// Measure heap usage.
pub fn add_size_of_children(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) { pub fn add_size_of_children(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
self.stylist.add_size_of_children(ops, sizes); self.stylist.add_size_of_children(ops, sizes);
sizes.mStylistOther += self.extra_style_data.size_of(ops);
} }
} }

View file

@ -85,6 +85,10 @@ impl DocumentCascadeData {
self.per_origin.iter_origins() self.per_origin.iter_origins()
} }
fn iter_origins_rev(&self) -> PerOriginIter<CascadeData> {
self.per_origin.iter_origins_rev()
}
/// Rebuild the cascade data for the given document stylesheets, and /// Rebuild the cascade data for the given document stylesheets, and
/// optionally with a set of user agent stylesheets. Returns Err(..) /// optionally with a set of user agent stylesheets. Returns Err(..)
/// to signify OOM. /// to signify OOM.
@ -95,7 +99,6 @@ impl DocumentCascadeData {
flusher: StylesheetFlusher<'a, 'b, S>, flusher: StylesheetFlusher<'a, 'b, S>,
guards: &StylesheetGuards, guards: &StylesheetGuards,
ua_stylesheets: Option<&UserAgentStylesheets>, ua_stylesheets: Option<&UserAgentStylesheets>,
extra_data: &mut PerOrigin<ExtraStyleData>,
) -> Result<(), FailedAllocationError> ) -> Result<(), FailedAllocationError>
where where
'b: 'a, 'b: 'a,
@ -114,7 +117,6 @@ impl DocumentCascadeData {
self.precomputed_pseudo_element_decls.clear(); self.precomputed_pseudo_element_decls.clear();
} }
extra_data.borrow_mut_for_origin(&origin).clear();
if validity == OriginValidity::CascadeInvalid { if validity == OriginValidity::CascadeInvalid {
cascade_data.clear_cascade_data() cascade_data.clear_cascade_data()
} else { } else {
@ -152,7 +154,6 @@ impl DocumentCascadeData {
quirks_mode, quirks_mode,
stylesheet, stylesheet,
guards.ua_or_user, guards.ua_or_user,
extra_data,
SheetRebuildKind::Full, SheetRebuildKind::Full,
)?; )?;
} }
@ -181,7 +182,6 @@ impl DocumentCascadeData {
quirks_mode, quirks_mode,
&ua_stylesheets.quirks_mode_stylesheet, &ua_stylesheets.quirks_mode_stylesheet,
guards.ua_or_user, guards.ua_or_user,
extra_data,
SheetRebuildKind::Full, SheetRebuildKind::Full,
)?; )?;
} }
@ -194,7 +194,6 @@ impl DocumentCascadeData {
quirks_mode, quirks_mode,
stylesheet, stylesheet,
guards.author, guards.author,
extra_data,
rebuild_kind, rebuild_kind,
)?; )?;
} }
@ -209,7 +208,6 @@ impl DocumentCascadeData {
quirks_mode: QuirksMode, quirks_mode: QuirksMode,
stylesheet: &S, stylesheet: &S,
guard: &SharedRwLockReadGuard, guard: &SharedRwLockReadGuard,
_extra_data: &mut PerOrigin<ExtraStyleData>,
rebuild_kind: SheetRebuildKind, rebuild_kind: SheetRebuildKind,
) -> Result<(), FailedAllocationError> ) -> Result<(), FailedAllocationError>
where where
@ -345,26 +343,26 @@ impl DocumentCascadeData {
} }
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
CssRule::FontFace(ref rule) => { CssRule::FontFace(ref rule) => {
_extra_data origin_cascade_data
.borrow_mut_for_origin(&origin) .extra_data
.add_font_face(rule); .add_font_face(rule);
} }
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
CssRule::FontFeatureValues(ref rule) => { CssRule::FontFeatureValues(ref rule) => {
_extra_data origin_cascade_data
.borrow_mut_for_origin(&origin) .extra_data
.add_font_feature_values(rule); .add_font_feature_values(rule);
} }
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
CssRule::CounterStyle(ref rule) => { CssRule::CounterStyle(ref rule) => {
_extra_data origin_cascade_data
.borrow_mut_for_origin(&origin) .extra_data
.add_counter_style(guard, rule); .add_counter_style(guard, rule);
} }
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
CssRule::Page(ref rule) => { CssRule::Page(ref rule) => {
_extra_data origin_cascade_data
.borrow_mut_for_origin(&origin) .extra_data
.add_page(rule); .add_page(rule);
} }
// We don't care about any other rule. // We don't care about any other rule.
@ -500,6 +498,18 @@ impl Stylist {
} }
} }
/// Iterate over the extra data in origin order.
#[inline]
pub fn iter_extra_data_origins(&self) -> ExtraStyleDataIterator {
ExtraStyleDataIterator(self.cascade_data.iter_origins())
}
/// Iterate over the extra data in reverse origin order.
#[inline]
pub fn iter_extra_data_origins_rev(&self) -> ExtraStyleDataIterator {
ExtraStyleDataIterator(self.cascade_data.iter_origins_rev())
}
/// Returns the number of selectors. /// Returns the number of selectors.
pub fn num_selectors(&self) -> usize { pub fn num_selectors(&self) -> usize {
self.cascade_data.iter_origins().map(|(d, _)| d.num_selectors).sum() self.cascade_data.iter_origins().map(|(d, _)| d.num_selectors).sum()
@ -548,7 +558,6 @@ impl Stylist {
&mut self, &mut self,
guards: &StylesheetGuards, guards: &StylesheetGuards,
ua_sheets: Option<&UserAgentStylesheets>, ua_sheets: Option<&UserAgentStylesheets>,
extra_data: &mut PerOrigin<ExtraStyleData>,
document_element: Option<E>, document_element: Option<E>,
) -> bool ) -> bool
where where
@ -604,7 +613,6 @@ impl Stylist {
flusher, flusher,
guards, guards,
ua_sheets, ua_sheets,
extra_data,
).unwrap_or_else(|_| warn!("OOM in Stylist::flush")); ).unwrap_or_else(|_| warn!("OOM in Stylist::flush"));
had_invalidations had_invalidations
@ -1647,7 +1655,8 @@ impl Stylist {
/// This struct holds data which users of Stylist may want to extract /// This struct holds data which users of Stylist may want to extract
/// from stylesheets which can be done at the same time as updating. /// from stylesheets which can be done at the same time as updating.
#[derive(Default)] #[derive(Debug, Default)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct ExtraStyleData { pub struct ExtraStyleData {
/// A list of effective font-face rules and their origin. /// A list of effective font-face rules and their origin.
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
@ -1666,6 +1675,11 @@ pub struct ExtraStyleData {
pub pages: Vec<Arc<Locked<PageRule>>>, pub pages: Vec<Arc<Locked<PageRule>>>,
} }
// FIXME(emilio): This is kind of a lie, and relies on us not cloning
// nsCSSFontFaceRules or nsCSSCounterStyleRules OMT (which we don't).
#[cfg(feature = "gecko")]
unsafe impl Sync for ExtraStyleData {}
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
impl ExtraStyleData { impl ExtraStyleData {
/// Add the given @font-face rule. /// Add the given @font-face rule.
@ -1706,6 +1720,18 @@ impl ExtraStyleData {
} }
} }
/// An iterator over the different ExtraStyleData.
pub struct ExtraStyleDataIterator<'a>(PerOriginIter<'a, CascadeData>);
impl<'a> Iterator for ExtraStyleDataIterator<'a> {
type Item = (&'a ExtraStyleData, Origin);
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|d| (&d.0.extra_data, d.1))
}
}
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
impl MallocSizeOf for ExtraStyleData { impl MallocSizeOf for ExtraStyleData {
/// Measure heap usage. /// Measure heap usage.
@ -1951,6 +1977,9 @@ struct CascadeData {
/// Effective media query results cached from the last rebuild. /// Effective media query results cached from the last rebuild.
effective_media_query_results: EffectiveMediaQueryResults, effective_media_query_results: EffectiveMediaQueryResults,
/// Extra data, like different kinds of rules, etc.
extra_data: ExtraStyleData,
/// A monotonically increasing counter to represent the order on which a /// A monotonically increasing counter to represent the order on which a
/// style rule appears in a stylesheet, needed to sort them by source order. /// style rule appears in a stylesheet, needed to sort them by source order.
rules_source_order: u32, rules_source_order: u32,
@ -1968,6 +1997,7 @@ impl CascadeData {
element_map: SelectorMap::new(), element_map: SelectorMap::new(),
pseudos_map: PerPseudoElementMap::default(), pseudos_map: PerPseudoElementMap::default(),
animations: Default::default(), animations: Default::default(),
extra_data: ExtraStyleData::default(),
invalidation_map: InvalidationMap::new(), invalidation_map: InvalidationMap::new(),
attribute_dependencies: NonCountingBloomFilter::new(), attribute_dependencies: NonCountingBloomFilter::new(),
style_attribute_dependency: false, style_attribute_dependency: false,
@ -1998,6 +2028,7 @@ impl CascadeData {
self.element_map.clear(); self.element_map.clear();
self.pseudos_map.clear(); self.pseudos_map.clear();
self.animations.clear(); self.animations.clear();
self.extra_data.clear();
self.rules_source_order = 0; self.rules_source_order = 0;
self.num_selectors = 0; self.num_selectors = 0;
self.num_declarations = 0; self.num_declarations = 0;
@ -2032,6 +2063,7 @@ impl CascadeData {
sizes.mStylistRevalidationSelectors += self.selectors_for_cache_revalidation.size_of(ops); sizes.mStylistRevalidationSelectors += self.selectors_for_cache_revalidation.size_of(ops);
sizes.mStylistOther += self.effective_media_query_results.size_of(ops); sizes.mStylistOther += self.effective_media_query_results.size_of(ops);
sizes.mStylistOther += self.extra_data.size_of(ops);
} }
} }

View file

@ -1685,7 +1685,7 @@ pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null:
let page_decls = match pseudo { let page_decls = match pseudo {
PseudoElement::PageContent => { PseudoElement::PageContent => {
let mut declarations = vec![]; let mut declarations = vec![];
let iter = data.extra_style_data.iter_origins_rev(); let iter = data.stylist.iter_extra_data_origins_rev();
for (data, origin) in iter { for (data, origin) in iter {
let level = match origin { let level = match origin {
Origin::UserAgent => CascadeLevel::UANormal, Origin::UserAgent => CascadeLevel::UANormal,
@ -3610,15 +3610,17 @@ pub extern "C" fn Servo_StyleSet_GetFontFaceRules(raw_data: RawServoStyleSetBorr
let global_style_data = &*GLOBAL_STYLE_DATA; let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read(); let guard = global_style_data.shared_lock.read();
let len: u32 = data.extra_style_data let len: u32 = data
.iter_origins() .stylist
.iter_extra_data_origins()
.map(|(d, _)| d.font_faces.len() as u32) .map(|(d, _)| d.font_faces.len() as u32)
.sum(); .sum();
// Reversed iterator because Gecko expects rules to appear sorted // Reversed iterator because Gecko expects rules to appear sorted
// UserAgent first, Author last. // UserAgent first, Author last.
let font_face_iter = data.extra_style_data let font_face_iter = data
.iter_origins_rev() .stylist
.iter_extra_data_origins_rev()
.flat_map(|(d, o)| d.font_faces.iter().zip(iter::repeat(o))); .flat_map(|(d, o)| d.font_faces.iter().zip(iter::repeat(o)));
unsafe { rules.set_len(len) }; unsafe { rules.set_len(len) };
@ -3632,12 +3634,11 @@ pub extern "C" fn Servo_StyleSet_GetFontFaceRules(raw_data: RawServoStyleSetBorr
pub extern "C" fn Servo_StyleSet_GetCounterStyleRule(raw_data: RawServoStyleSetBorrowed, pub extern "C" fn Servo_StyleSet_GetCounterStyleRule(raw_data: RawServoStyleSetBorrowed,
name: *mut nsIAtom) -> *mut nsCSSCounterStyleRule { name: *mut nsIAtom) -> *mut nsCSSCounterStyleRule {
let data = PerDocumentStyleData::from_ffi(raw_data).borrow(); let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
let extra_data = &data.extra_style_data;
unsafe { unsafe {
Atom::with(name, |name| { Atom::with(name, |name| {
extra_data data.stylist
.iter_origins() .iter_extra_data_origins()
.filter_map(|(d, _)| d.counter_styles.get(name)) .filter_map(|(d, _)| d.counter_styles.get(name))
.next() .next()
}) })
@ -3656,17 +3657,19 @@ pub extern "C" fn Servo_StyleSet_BuildFontFeatureValueSet(
let global_style_data = &*GLOBAL_STYLE_DATA; let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read(); let guard = global_style_data.shared_lock.read();
let has_rule = data.extra_style_data let has_rule =
.iter_origins() data.stylist
.any(|(d, _)| !d.font_feature_values.is_empty()); .iter_extra_data_origins()
.any(|(d, _)| !d.font_feature_values.is_empty());
if !has_rule { if !has_rule {
return ptr::null_mut(); return ptr::null_mut();
} }
let font_feature_values_iter = data.extra_style_data let font_feature_values_iter =
.iter_origins_rev() data.stylist
.flat_map(|(d, _)| d.font_feature_values.iter()); .iter_extra_data_origins_rev()
.flat_map(|(d, _)| d.font_feature_values.iter());
let set = unsafe { Gecko_ConstructFontFeatureValueSet() }; let set = unsafe { Gecko_ConstructFontFeatureValueSet() };
for src in font_feature_values_iter { for src in font_feature_values_iter {