style: Make the allocation of AuthorStyles for ShadowRoot lazy.

So that we don't waste a bunch of memory with stuff like <svg:use>. I
plan to shrink AuthorStyles further, but this should help regardless, and isn't
very complex.

Differential Revision: https://phabricator.services.mozilla.com/D4618
This commit is contained in:
Emilio Cobos Álvarez 2018-08-30 12:00:00 +00:00
parent 1bc452703b
commit 1e6aa62c6f
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
3 changed files with 41 additions and 28 deletions

View file

@ -342,7 +342,7 @@ pub trait TShadowRoot: Sized + Copy + Clone + PartialEq {
fn host(&self) -> <Self::ConcreteNode as TNode>::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;
if let Some(data) = shadow.style_data() {
f(
shadow.style_data(),
data,
self.as_node().owner_doc().quirks_mode(),
Some(shadow.host()),
);
}
}
if let Some(shadow) = self.shadow_root() {
if let Some(data) = shadow.style_data() {
f(
shadow.style_data(),
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();
if let Some(data) = shadow.style_data() {
f(
shadow.style_data(),
data,
self.as_node().owner_doc().quirks_mode(),
Some(shadow.host()),
);
}
current = slot.assigned_slot();
}

View file

@ -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]

View file

@ -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 <svg:use> 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);
}