From 1e6aa62c6f272cbce49c6016a5f4396980128097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 30 Aug 2018 12:00:00 +0000 Subject: [PATCH] style: Make the allocation of AuthorStyles for ShadowRoot lazy. So that we don't waste a bunch of memory with stuff like . I plan to shrink AuthorStyles further, but this should help regardless, and isn't very complex. Differential Revision: https://phabricator.services.mozilla.com/D4618 --- components/style/dom.rs | 38 ++++++++++++++++++------------- components/style/gecko/wrapper.rs | 11 ++++----- components/style/stylist.rs | 20 +++++++++++----- 3 files changed, 41 insertions(+), 28 deletions(-) diff --git a/components/style/dom.rs b/components/style/dom.rs index 42f6e9ba0c0..7552505a752 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -342,7 +342,7 @@ pub trait TShadowRoot: Sized + Copy + Clone + PartialEq { fn host(&self) -> ::ConcreteElement; /// Get the style data for this ShadowRoot. - fn style_data<'a>(&self) -> &'a CascadeData + fn style_data<'a>(&self) -> Option<&'a CascadeData> where Self: 'a; @@ -824,30 +824,36 @@ pub trait TElement: if let Some(shadow) = self.containing_shadow() { doc_rules_apply = false; - f( - shadow.style_data(), - self.as_node().owner_doc().quirks_mode(), - Some(shadow.host()), - ); + if let Some(data) = shadow.style_data() { + f( + data, + self.as_node().owner_doc().quirks_mode(), + Some(shadow.host()), + ); + } } if let Some(shadow) = self.shadow_root() { - f( - shadow.style_data(), - self.as_node().owner_doc().quirks_mode(), - Some(shadow.host()), - ); + if let Some(data) = shadow.style_data() { + f( + data, + self.as_node().owner_doc().quirks_mode(), + Some(shadow.host()), + ); + } } let mut current = self.assigned_slot(); while let Some(slot) = current { // Slots can only have assigned nodes when in a shadow tree. let shadow = slot.containing_shadow().unwrap(); - f( - shadow.style_data(), - self.as_node().owner_doc().quirks_mode(), - Some(shadow.host()), - ); + if let Some(data) = shadow.style_data() { + f( + data, + self.as_node().owner_doc().quirks_mode(), + Some(shadow.host()), + ); + } current = slot.assigned_slot(); } diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 1ba850696d1..00b75b83512 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -167,15 +167,14 @@ impl<'lr> TShadowRoot for GeckoShadowRoot<'lr> { } #[inline] - fn style_data<'a>(&self) -> &'a CascadeData + fn style_data<'a>(&self) -> Option<&'a CascadeData> where Self: 'a, { - debug_assert!(!self.0.mServoStyles.mPtr.is_null()); - let author_styles = unsafe { - &*(self.0.mServoStyles.mPtr as *const structs::RawServoAuthorStyles - as *const bindings::RawServoAuthorStyles) + (self.0.mServoStyles.mPtr + as *const structs::RawServoAuthorStyles + as *const bindings::RawServoAuthorStyles).as_ref()? }; @@ -187,7 +186,7 @@ impl<'lr> TShadowRoot for GeckoShadowRoot<'lr> { author_styles.stylesheets.dirty() ); - &author_styles.data + Some(&author_styles.data) } #[inline] diff --git a/components/style/stylist.rs b/components/style/stylist.rs index 5dbb4dd5dc8..53e2a43b1d5 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -1206,7 +1206,7 @@ impl Stylist { // to add some sort of AuthorScoped cascade level or something. if matches_author_rules { if let Some(shadow) = rule_hash_target.shadow_root() { - if let Some(map) = shadow.style_data().host_rules(pseudo_element) { + if let Some(map) = shadow.style_data().and_then(|data| data.host_rules(pseudo_element)) { context.with_shadow_host(Some(rule_hash_target), |context| { map.get_all_matching_rules( element, @@ -1233,8 +1233,7 @@ impl Stylist { for slot in slots.iter().rev() { let shadow = slot.containing_shadow().unwrap(); - let styles = shadow.style_data(); - if let Some(map) = styles.slotted_rules(pseudo_element) { + if let Some(map) = shadow.style_data().and_then(|data| data.slotted_rules(pseudo_element)) { context.with_shadow_host(Some(shadow.host()), |context| { map.get_all_matching_rules( element, @@ -1253,7 +1252,7 @@ impl Stylist { if let Some(containing_shadow) = rule_hash_target.containing_shadow() { let cascade_data = containing_shadow.style_data(); let host = containing_shadow.host(); - if let Some(map) = cascade_data.normal_rules(pseudo_element) { + if let Some(map) = cascade_data.and_then(|data| data.normal_rules(pseudo_element)) { context.with_shadow_host(Some(host), |context| { map.get_all_matching_rules( element, @@ -1283,6 +1282,11 @@ impl Stylist { // // See: https://github.com/w3c/svgwg/issues/505 // + // FIXME(emilio, bug 1487259): We now do after bug 1483882, we + // should jump out of the shadow tree chain now. + // + // Unless the used node is cross-doc, I guess, in which case doc + // rules are probably ok... let host_is_svg_use = host.is_svg_element() && host.local_name() == &*local_name!("use"); @@ -1431,11 +1435,15 @@ impl Stylist { // [2]: https://github.com/w3c/csswg-drafts/issues/1995 // [3]: https://bugzil.la/1458189 if let Some(shadow) = element.shadow_root() { - try_find_in!(shadow.style_data()); + if let Some(data) = shadow.style_data() { + try_find_in!(data); + } } if let Some(shadow) = element.containing_shadow() { - try_find_in!(shadow.style_data()); + if let Some(data) = shadow.style_data() { + try_find_in!(data); + } } else { try_find_in!(self.cascade_data.author); }