From 2940270a500b0c123b4401a74f47db7789c9e785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 3 Aug 2017 16:39:33 +0200 Subject: [PATCH] style: Prevent cousin sharing if we haven't restyled the parents. This "fixes" bug 1381821 by disabling the optimization in the cases we can't prove this is correct. Bug 1387116 tracks fixing the optimization to apply more broadly. Bug: 1381821 Reviewed-by: bz MozReview-Commit-ID: COKdmHHokGx --- components/style/sharing/checks.rs | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/components/style/sharing/checks.rs b/components/style/sharing/checks.rs index e7f8db5a54f..259cadc958b 100644 --- a/components/style/sharing/checks.rs +++ b/components/style/sharing/checks.rs @@ -19,17 +19,38 @@ use sharing::{StyleSharingCandidate, StyleSharingTarget}; /// /// This is used to know whether we can share style across cousins (if the two /// parents have the same style). +/// +/// We can only prove that they have the same class list, state, etc if they've +/// been restyled at the same time, otherwise the invalidation pass could make +/// them keep the same computed values even though now we wouldn't be able to +/// prove we match the same selectors. pub fn same_computed_values(first: Option, second: Option) -> bool where E: TElement, { - let (a, b) = match (first, second) { + let (first, second) = match (first, second) { (Some(f), Some(s)) => (f, s), _ => return false, }; - let eq = Arc::ptr_eq(a.borrow_data().unwrap().styles.primary(), - b.borrow_data().unwrap().styles.primary()); - eq + debug_assert_ne!(first, second); + + let first_data = first.borrow_data().unwrap(); + let second_data = second.borrow_data().unwrap(); + + // FIXME(emilio): This check effectively disables cousin style sharing + // on the initial style. + // + // This is pretty bad, se the discussion in bug 1381821 for mor details. + // + // Bug 1387116 tracks fixing this, and various solutions are listed there. + if !first_data.restyle.is_restyle() || !second_data.restyle.is_restyle() { + return false; + } + + let same_computed_values = + Arc::ptr_eq(first_data.styles.primary(), second_data.styles.primary()); + + same_computed_values } /// Whether two elements have the same same style attribute (by pointer identity).